This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Problems with double arguments to varargs on MIPS


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]