App1 contains the following files:
Figure 4-1 : Call Tree for App1 The source code for the original versions of main.c, foo.c, gp.s. and regs.s are shown below.
/* main.c */ extern void foo(); 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 <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); } /* gp.s */ #include <regdef.h> #include <asm.h> LEAF(get_gp) move v0, gp j ra .end get_gp /* regs.s */ #include <regdef.h> .text .globlregs # make regs external .entregs 2 regs: .set noreorder .cploadt9 # setup gp .set reorder subu sp, 32 # create stack frame sw ra, 28(sp) # save return address .cprestore 24 # for caller saved gp # save gp 24(sp) sw gp, 0(a0) # return gp in first arg sw ra, 0(a1) # return ra in second arg sw sp, 0(a2) # return sp in third arg li a0, 1000 # call libc routines jal malloc # for illustrative purposes move a0, v0 # to make regs jal free # a nested function lw t0, 56(sp) # get fifth argument from stack lwc1 $f4, 4(t0) # load it in fp register lwc1 $f5, 0(t0) # fp values are stored in LE # format lwc1 $f6, 52(sp) # get fourth argument from stack lwc1 $f7, 48(sp) # fp values are stored in LE # format add.d $f8, $f4, $f6 # do the calculation lw t0, 60(sp) # get the sixth argument # from the stack swc1 $f8, 4(t0) # save the result swc1 $f9, 0(t0) # fp values are stored in LE lw ra, 28(sp) # get return address addu sp, 32 # pop stack j ra # return to caller .end regs