Mercurial > hg > CbC > old > device
diff mc-code-powerpc.c @ 128:d497c39add36 args-works
arg.c works (?)
author | kono |
---|---|
date | Thu, 03 Apr 2003 03:04:16 +0900 |
parents | eb4d8975926c |
children | 948977254fa6 |
line wrap: on
line diff
--- a/mc-code-powerpc.c Tue Apr 01 10:31:40 2003 +0900 +++ b/mc-code-powerpc.c Thu Apr 03 03:04:16 2003 +0900 @@ -140,7 +140,7 @@ code segment stack frame * gotoを呼び出した関数のr1 ! r1(goto前のr1) - # * r30 <---------------r1_offset---------------> r1 + # * r30 <---r1_offset---------> r1 r+ +----------+--+----------+----------------+-----------+----------+----+ cousin arg xx reg save !callee arg !code local caller arg xx r20-r29 lvar>0 lvar<0 lvar>0x1000 000 @@ -920,14 +920,20 @@ printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",crn,retcont,code_base,crn); } +#define R1SAVE 1 void code_environment(int creg) { /* save frame pointer */ - printf("\tmr %s,r30\n",register_name(creg)); +#if R1SAVE + printf("\tlwz %s,0(r1)\n",register_name(creg)); +#else + int l = 0; + printf("\tla %s,",register_name(creg)); + printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); +#endif } - void code_bool(int e1) { char *xrn; @@ -1449,23 +1455,33 @@ void code_frame_pointer(int e3) { +#if R1SAVE + printf("\tmr r1,%s\n",register_name(e3)); +#else printf("\tmr r30,%s\n",register_name(e3)); +#endif } void code_fix_frame_pointer(int disp_offset) { - printf("\tla r1,%d(r30)\n",disp_offset); + int l = 0; + printf("\tla r30,"); + printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); } void code_jmp(char *s) { + max_reg_var = REG_VAR_BASE-REG_VAR_MIN; + max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; printf("\tb L_%s$stub\n",s); } void code_indirect_jmp(int e2) { + max_reg_var = REG_VAR_BASE-REG_VAR_MIN; + max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; printf("\tmtctr %s\n",register_name(e2)); printf("\tbctr\n"); } @@ -1755,7 +1771,7 @@ #endif printf("_%s:\n",name); code_disp_label=fwdlabel(); - printf("\tstwu r1,lo16(L_%d)(r30)\n",code_disp_label); + printf("\tla r1,lo16(L_%d)(r30)\n",code_disp_label); printf("\tbcl 20,31,L_%d\n",code_base = fwdlabel()); fwddef(code_base); printf("\tmflr r31\n"); @@ -1766,7 +1782,6 @@ void code_enter1(int args) { - printf("## args %d disp %d code_arg_offset=%d code_disp_offset=%d\n",args,disp,code_arg_offset,code_disp_offset); set_creg(CREG_REGISTER,0); set_freg(FREG_FREGISTER,0); } @@ -1774,10 +1789,12 @@ void code_leave(char *name) { + int r1_offsetv; disp&= -size_of_int; - printf(".set L_%d,%d\n",code_disp_label,disp+code_disp_offset); + r1_offsetv = -disp+max_func_args*size_of_int+code_disp_offset; + + printf(".set L_%d,%d\n",code_disp_label,-r1_offsetv); local_table(); - labelno++; free_all_register(); } @@ -1826,24 +1843,42 @@ void leave(int control, char *name) { + int retcont1,sz; + + if (max_freg_var>=0 && max_freg_var<=3) max_freg_var=3; + reg_save = reg_save_offset(); if (control) { code_set_return_register(1); } if (retcont) { if (control) jmp(retlabel); + retcont1 = fwdlabel(); fwddef(retcont); - printf("\tmr r1,r30\n"); if (cadr(fnptr->ty)==FLOAT||cadr(fnptr->ty)==DOUBLE) { printf("\tfmr f1,f31\n"); + } else if (cadr(fnptr->ty)>0&&( + car(cadr(fnptr->ty))==STRUCT || + car(cadr(fnptr->ty))==UNION)) { + sz = size(cadr(fnptr->ty)); + printf("\tli r7,%d\n",sz); + printf("\tsubl r6,r7,r30\n"); + printf("\tlwz r3,lo16(%d)(r30)\n",(my_func_args-1)*size_of_int); + emit_copy(6,3,sz,0,1,1); } else if (cadr(fnptr->ty)!=VOID) { printf("\tmr r3,r29\n"); } +#if !R1SAVE + printf("\tla r1,lo16(%d)(r30)\n", + -reg_save+my_func_args*size_of_int); +#endif + printf("\tb L_%d\n",retcont1); } fwddef(retlabel); printf("\tlwz r1,0(r1)\n"); - if (max_freg_var>=0 && max_freg_var<=3) max_freg_var=3; - reg_save = reg_save_offset(); + if (retcont) { + fwddef(retcont1); + } if (max_freg_var>=0) { printf("\tlmw r%d,%d(r1)\n", REG_VAR_BASE-max_reg_var,reg_save);