Problems with double arguments to varargs on MIPS
Simon Kagstrom
simon.kagstrom@bth.se
Tue Jan 9 08:36:00 GMT 2007
Hello,
I have a problem with code generated by GCC for varargs on MIPS. The
GCC version is from the emdebian repositories,
mips-linux-gnu-gcc (GCC) 4.1.2 20061028 (prerelease) (Debian 4.1.1-19)
The options I compile with are
-DCIBYL=1 -msoft-float -fno-optimize-sibling-calls -nostdinc -Wall \
-Wa,--no-warn -mips1 -mno-check-zero-division -Os -fno-pic -mno-abicalls
I use the system stdarg.h file so __builtin_va_arg and friends are
used.
My problem is that 'double' arguments are incorrectly handled. A
program which shows this behavior is given below:
double scratch;
void maboo(int fmt, ...) {
va_list ap;
va_start(ap, fmt);
scratch = (double)va_arg(ap, double);
va_end(ap);
}
int main(int argc, char* argv[]) {
maboo(0, 1.9F);
if ( !(scratch >= 1.89 && scratch <= 1.91) )
printf("ERRORERROR!\n");
}
The problem is that the offset from which the double is read in
va_arg() is wrong. The arguments are passed in this order (as MIPS
registers, but it uses the stack):
a0: int fmt
a1: (unused)
a2: bit 0..31 of 1.9
a3: bit 32..63 of 1.9
I.e., the double value is in [a2,a3]. However, the varargs stuff takes
the value from [a1,a2] and thus all hell breaks loose.
Disassembled, maboo looks like below, with some annotations of how I
think it's supposed to work:
01000074 <maboo>:
1000074: addiu sp,sp,-8
1000078: addiu v0,sp,12 <- The va_list "pointer", 0x142d98 in this case
100007c: sw v0,0(sp)
1000080: addiu v1,v0,7 <- 0x142d98 + 7
1000084: li v0,-8
1000088: sw a1,12(sp) <- Flush the variable arguments to the stack
100008c: sw a2,16(sp)
1000090: sw a3,20(sp)
1000094: and v1,v1,v0 <- (0x142d98 + 7) & -8 == 0x142d98
1000098: lw v0,0(v1) <- a1 is loaded
100009c: lw v1,4(v1) <- a2 is loaded
10000a0: lui a0,0x0
10000a4: addiu sp,sp,8
10000a8: sw v1,540(a0) <- Doh!
10000ac: jr ra
10000b0: sw v0,536(a0) <- Doh!
010000b4 <main>:
10000b4: lui v0,0x0
10000b8: lw a3,428(v0) <- Argument 3
10000bc: lw a2,424(v0) <- Argument 2
10000c4: move a0,zero <- Argument 0 (no arg 1)
...
10000ec: jal 1000074 <maboo>
This seems too trivial to be a GCC bug, so I suspect that it's some
misconception from my side, but can anyone spot the problem? I've
attached the preprocessed file.
I've often suspected GCC bugs before, but never really this much. Of
course, I've always been wrong before, so... ;-)
// Simon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: main.i
Type: application/octet-stream
Size: 8095 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc-help/attachments/20070109/b1a2e9ca/attachment.obj>
More information about the Gcc-help
mailing list