Mercurial > hg > CbC > old > device
changeset 128:d497c39add36 args-works
arg.c works (?)
author | kono |
---|---|
date | Thu, 03 Apr 2003 03:04:16 +0900 |
parents | eb4d8975926c |
children | 948977254fa6 |
files | Changes mc-code-ia32.c mc-code-powerpc.c mc-codegen.c mc-parse.c |
diffstat | 5 files changed, 115 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Tue Apr 01 10:31:40 2003 +0900 +++ b/Changes Thu Apr 03 03:04:16 2003 +0900 @@ -2674,7 +2674,7 @@ に入っている。だよね。 * 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 @@ -2688,3 +2688,36 @@ それで、code segment から関数呼出しするときは? (ってことは、 それようのテストも必要なわけか...) + +Wed Apr 2 17:40:32 JST 2003 + +register 変数が既に使われていても、わざわざsaveする必要はない。 +戻って来ないから。register を使ったことにするには、used_max_register_var +を設定してやれば良い。 + +Interl版で goto が動かなくなったのは、arg_offset が、register 変数分 +も取るようになったから。save することを考えると、その方が良い。実際、 +function call があるとsaveされてしまう。ということは、別に r20-r29 +である必要はないってことか。通常のinput register varで良い。とすると、 +register変数をsaveする必要もないね。 +ただ、input regsiter var は、function callの前には saveする必要が +ある。でも、これは、やっぱり手遅れか。ってことは、やっぱり、 +r20-r29が良いってことか。 + +jump() では、呼出し引数は、-arg_size つまり、局所変数と +同じ扱いになっている。ってことは、 + + * gotoを呼び出した関数のr1 ! r1(goto前の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 + f20-f31 <-my_func_args--><--disp-----><-max_func_arg-> + *size_of_int *size_of_int + + r1 <----------------------r30 (return continuation) + +で、callee arg は保存されたまま、code local だけ変わるってことだね。 + +return continuation で、構造体を返そうと思うと難しい。そもそも、 +浮動小数点が、ちゃんと返るのか?
--- a/mc-code-ia32.c Tue Apr 01 10:31:40 2003 +0900 +++ b/mc-code-ia32.c Thu Apr 03 03:04:16 2003 +0900 @@ -35,13 +35,13 @@ int MAX_CODE_INPUT_DREGISTER_VAR = 0; /* - -16 -8 local2 - -12 -4 local1 - -8 8 arg3 - -4 4 arg2 - 0 0 arg1 - local2 -20 4 0 (%edi) - local1 <-- -16 0 local variable 0 (%esi) + -28 -8 local2 + -24 -4 local1 + -20 8 arg3 + -16 4 arg2 + -12 0 arg1 + local2 -20 4 -8 (%edi) + local1 <-- -16 0 local variable -4 (%esi) %edi -12 <- disp_offset %ebp %esi -8 %ebx -4 @@ -1392,20 +1392,31 @@ void leave(int control, char *name) { + int sz; + + disp &= -size_of_int; if (control) code_set_return_register(1); if (retcont) { if (control) jmp(retlabel); fwddef(retcont); - use_register(creg,REG_EAX,0); - printf("\tmovl %s,%s\n",reg_name[REG_ESI],register_name(creg,0)); - /* printf("\tleave\n"); */ + if (cadr(fnptr->ty)==FLOAT||cadr(fnptr->ty)==DOUBLE) { + printf("\tfldl %d(%%ebp)\n",-size_of_double); + } else if (cadr(fnptr->ty)>0&&( + car(cadr(fnptr->ty))==STRUCT || + car(cadr(fnptr->ty))==UNION)) { + sz = size(cadr(fnptr->ty)); + printf("\tlea %d(%%ebp),%s\n",-sz,register_name(dreg,0)); + printf("\tmovl %d(%%ebp),%s\n",disp-size_of_int, + register_name(creg,0)); + emit_copy(dreg,creg,sz,0,1,1); + } else if (cadr(fnptr->ty)!=VOID) { + use_register(creg,REG_EAX,0); + printf("\tmovl %s,%s\n",reg_name[REG_ESI],register_name(creg,0)); + } } fwddef(retlabel); - /* use_register(creg,REG_EAX,0); too late */ - /* if(disp) printf("\taddl $%d,%%esp\n",-disp); */ - disp &= -size_of_int; printf("\tlea %d(%%ebp),%%esp\n",disp_offset); printf("\tpopl %%edi\n");
--- 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);
--- a/mc-codegen.c Tue Apr 01 10:31:40 2003 +0900 +++ b/mc-codegen.c Thu Apr 03 03:04:16 2003 +0900 @@ -754,8 +754,9 @@ target,ty,e2); } else { target=list4(list2(LVAR,0), target,ty,e2); - arg_size += sz; } + /* keep arg space for register variables */ + arg_size += sz; #if DEBUG_PARALLEL_ASSIGN printf("# target %d ty %d+%d sz %d\n",car(car(target)),ty,cadr(car(target)),sz); #endif @@ -778,8 +779,8 @@ if(car(t0)==LVAR) { /* ここで、書込先アドレスを決める */ cadr(t0)=-arg_size; - arg_size-=sz; } + arg_size-=sz; if (!is_simple(car(s0))) { g_expr_u(assign_expr0((e4=list2(LVAR,new_lvar(sz))),s0,ty,ty)); use=list3(ty,use,e1); @@ -838,6 +839,13 @@ code_frame_pointer(e3); emit_pop_free(e3); } else if (is_function(fnptr)) { + if (car(e2) != FNAME) { + e2 = emit_pop(0); + code_fix_frame_pointer(disp_offset); + code_indirect_jmp(e2); + emit_pop_free(e2); + return; + } code_fix_frame_pointer(disp_offset); }