%cc -n32 -O -o app1 main.c foo.c gp2.s
foo.c
!!! Warning (user routine 'foo'):
!!! Prototype required when passing floating point parameter to varargs routine: printf
!!! Use '#include <stdio.h>' (see ANSI X3.159-1989, Section 3.3.2.2)
ld32: WARNING 110: floating-point parameters exist in the call for "foo", a VARARG function, in object "main.o" without a prototype -- would result in invalid result. Definition can be found in object "foo.o"
ld32: WARNING 110: floating-point parameters exist in the call for "printf", a VARARG function, in object "foo.o" without a prototype -- would result in invalid result. Definition can be found in object "/usr/lib32/mips4/libc.so"
The first warning points out that printf() is a varargs routine that is being called with floating point arguments. Under these circumstances, a prototype must exist for printf(). This is accomplished by adding the following line to the top of foo.c:
The second warning points out that foo() is also a varargs routine with floating point arguments and must also be prototyped. This is fixed by changing the declaration of foo() in main.c to:#include <stdio.h>
For completeness, <stdio.h> is also included in main.c to provide a prototype for printf() should it ever use floating point arguments.foo(int, ...)
As a result of these small changes, the C files are fixed and ready to be compiled -n32. The new versions are shown below.
/* main.c */ #include <stdio.h> extern void foo(int, ...); main() { unsigned gp,ra,sp, get_regs(); double d1 = 1.0; double d2 = 2.0; double res; gp = get_gp(); printf("gp is 0x%x\n", gp); foo(7, 3.14, &gp, &ra, &sp, d1, &d2, &res); } /* foo.c */ #include <stdio.h> #include <stdarg.h> void foo(int narg, ...) { va_list ap; double d1; double daddr1, *daddr2, *resaddr; unsigned *gp, *ra, *sp; va_start(ap, narg); printf("Number of Arguments is: %d\n",narg); d1 = va_arg(ap, double); printf("%e\n",d1); gp = va_arg(ap, unsigned*); ra = va_arg(ap, unsigned*); sp = va_arg(ap, unsigned*); daddr1 = va_arg(ap, double); daddr2 = va_arg(ap, double*); resaddr = va_arg(ap, double*); printf("first double precision argument is %e\n",daddr1); printf("second double precision argument is %e\n",*daddr2); regs(gp, ra, sp, daddr1, daddr2, resaddr); printf("Back from assembly routine\n"); printf("gp is 0x%x\n",*gp); printf("ra is 0x%x\n",*ra); printf("sp is 0x%x\n",*sp); printf("result of double precision add is %e\n",*resaddr); va_end(ap); }