Newlib-1.11.0 Bug
Marcio Rogério Juliato
marcio.juliato@ic.unicamp.br
Fri Jul 23 22:35:00 GMT 2004
Dear Sirs,
I found a bug in the file newlib-1.11.0/newlib/libc/machine/mips/strlen.c
when using newlib to compile programs to the R3000 processor (a 32-bits
MIPS 1 processor supported by newlib).
The "lbu $3,0($4)" instruction loads a value into the register $3, which
is going to be used by the next instruction "bnez $3,1b". But notice that
the R3000 does not have pipeline stall, i.e. there is no time enough to
load a correct value into the $3 register before its use. It means that
the instruction "bnez $3,1b" gets the wrong value to the comparison.
The problematic source code is shown below.
...
#else
__asm__("" /* 32-bit MIPS targets */
" .set noreorder\n"
" .set nomacro\n"
" .globl strlen\n"
" .ent strlen\n"
"strlen:\n"
" addiu $2,$4,1\n"
"\n"
"1: lbu $3,0($4)\n"
" bnez $3,1b\n" /* <================ PROBLEM with the
$3 value!!!!!! */
" addiu $4,$4,1\n"
"\n"
" jr $31\n"
" subu $2,$4,$2\n"
" .end strlen\n"
" .set macro\n"
" .set reorder\n");
#endif
THE PATCH:
A simplier correction to this problem could be the insertion of a NOP
instruction among the other two. We could also insert another instruction
instead od NOP, but we should take care with data dependency.
Below is shown the simplier aproach.
...
#else
__asm__("" /* 32-bit MIPS targets */
" .set noreorder\n"
" .set nomacro\n"
" .globl strlen\n"
" .ent strlen\n"
"strlen:\n"
" addiu $2,$4,1\n"
"\n"
"1: lbu $3,0($4)\n"
" nop\n" /* <======= NOP INSERTION */
" bnez $3,1b\n"
" addiu $4,$4,1\n"
"\n"
" jr $31\n"
" subu $2,$4,$2\n"
" .end strlen\n"
" .set macro\n"
" .set reorder\n");
#endif
I would like to know if there is a standard bug submission that I should
follow...
Best regards,
Marcio Juliato
More information about the Newlib
mailing list