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
Attachment:
main.i
Description: Binary data