Mercurial > hg > CbC > old > device
changeset 268:3a368fc37559
MIPS binary continue...
author | kono |
---|---|
date | Tue, 18 May 2004 14:20:46 +0900 |
parents | e7ab23c992e5 |
children | d9f4026de4e3 |
files | .gdbinit Changes mc-code-mips.c mc-code-powerpc.c |
diffstat | 4 files changed, 124 insertions(+), 86 deletions(-) [+] |
line wrap: on
line diff
--- a/.gdbinit Mon May 17 11:41:51 2004 +0900 +++ b/.gdbinit Tue May 18 14:20:46 2004 +0900 @@ -1,6 +1,6 @@ tb main -# run -s -ob00.s test/basic.c -run -s -ob00.s mc-parse.c +run -s -ob00.s test/basic.c +# run -s -ob00.s mc-parse.c # run -s test/code-gen-all.c define regs printf "pc =%08x lr =%08x r0 =%08x r1 =%08x r3= %08x r4= %08x\n",$pc,$lr,$r0,$r1,$r3,$r4
--- a/Changes Mon May 17 11:41:51 2004 +0900 +++ b/Changes Tue May 18 14:20:46 2004 +0900 @@ -4313,4 +4313,9 @@ あと、int の後のdouble/longlong は、$3 のあと、$5,$6 と 来るみたいですね。 - +さて、いよいよ、オフセット合わせか。 + +Tue May 18 13:05:24 JST 2004 + +なんかレジスタセーブがぼろぼろじゃん。max_reg_var とかが、 +ちゃんとレジスタの個数を表すようにしろよ。
--- a/mc-code-mips.c Mon May 17 11:41:51 2004 +0900 +++ b/mc-code-mips.c Tue May 18 14:20:46 2004 +0900 @@ -45,9 +45,6 @@ static int max_func_args = 0; -static int reg_save; -static int freg_save; - static int freg,ireg,lreg; static int cmpreg; @@ -87,10 +84,10 @@ #define PTRC_REG 3 -#define FREG_VAR_BASE 29 -#define FREG_VAR_MIN 18 -#define MIN_TMP_FREG 4 -#define MAX_TMP_FREG 17 +#define FREG_VAR_BASE 31 +#define FREG_VAR_MIN 20 +#define MIN_TMP_FREG 0 +#define MAX_TMP_FREG 11 int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ int MAX_FREGISTER=31; @@ -104,7 +101,7 @@ int MAX_INPUT_REGISTER_VAR = 4; int MAX_CODE_INPUT_REGISTER_VAR = 7-MIN_TMP_REG; int MAX_INPUT_DREGISTER_VAR = 2; -int MAX_INPUT_FREGISTER_VAR = 1; +int MAX_INPUT_FREGISTER_VAR = 4; int MAX_CODE_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; @@ -292,7 +289,7 @@ $f20-$f31 saved register variable function call stack frame - <------r1_offset------------------------------> + <----------r1_offset------------------------------> <------------lvar_offset-------> r+ +------------+---+---------------+----------+--------------+----+ - callee arg xx register save local caller arg xx @@ -312,10 +309,10 @@ prev $sp=$fp $fp $sp */ -int arg_offset = 24; int arg_offset1 = 24; int disp_offset = -12; -// #define func_disp_offset 60 -#define func_disp_offset 68 -#define r1_offset func_disp_offset+12 +static int arg_offset = 0,arg_offset1 = 0,disp_offset = 0; + +#define func_disp_offset 8 +#define r1_offset func_disp_offset int code_disp_offset = 0; int jump_offset = 0; #define CODE_LVAR l+code_disp_offset #define CODE_CALLER_ARG (l-ARG_LVAR_OFFSET)+arg_offset1 @@ -332,8 +329,8 @@ #endif int lvar_offsetv = -disp+max_func_args*SIZE_OF_INT+func_disp_offset; int r1_offsetv = -disp+max_func_args*SIZE_OF_INT-reg_save+r1_offset; - printf(".set $L_%d,%d\n",lvar_offset_label,lvar_offsetv); - printf(".set $L_%d,%d\n",r1_offset_label,r1_offsetv); + fprintf(asi,"$L_%d=%d\n",lvar_offset_label,lvar_offsetv); + fprintf(asi,"$L_%d=%d\n",r1_offset_label,r1_offsetv); #if 0 printf("# function %s\n",fnptr->nm); l = ARG_LVAR_OFFSET; @@ -711,11 +708,11 @@ if(!(i<FREG_VAR_BASE-FREG_VAR_MIN)) return 0; i = FREG_VAR_BASE-i+FREG_OFFSET; } else { - if (i<0||i>=MAX_INPUT_FREGISTER_VAR) return 0; - if (i==1) i = 6; - else if (i==2) i = 7; - else - i = i+MIN_TMP_FREG+FREG_OFFSET; + if (i==0) i=12+FREG_OFFSET; + else if (i==1) i=14+FREG_OFFSET; + else if (i==2) return list3(REGISTER,6,(int)n); + else if (i==3) return list3(REGISTER,7,(int)n); + else return 0; } return list3(FREGISTER,i,(int)n); } @@ -1631,7 +1628,6 @@ NMTBL *n; int reg; int tag; - int lvar; int t; /* fnptr->dsp=list4(type,fnptr->dsp,(int)n,0); */ int reg_offset = 0; @@ -1652,7 +1648,12 @@ /* regs[reg]==INPUT_REG case should be considered */ n->dsp = offset; t = n->ty; - if(t==FLOAT) { offset+=SIZE_OF_FLOAT; reg_offset+=1; } + if(t==FLOAT) { + offset+=SIZE_OF_FLOAT; reg_offset+=1; + if (reg==6||reg==7) { // int register case + tag = REGISTER; t = INT; + } + } else if(t==DOUBLE) { offset+=SIZE_OF_DOUBLE; reg_offset+=2; } else error(-1); } else if (tag==DREGISTER) { @@ -1670,8 +1671,7 @@ continue; } n->sc = LVAR; - lvar = list2(LVAR,n->dsp); - g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),n->ty,t)); + g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),t,t)); if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER||tag==LREGISTER) { free_register(reg); } @@ -1767,7 +1767,7 @@ break; case FRLVAR: lvar_intro(cadr(e2)); - printf("\tlw %s,",fregister_name(freg)); lvar(cadr(e2)); + printf("\tlw %s,",frn); lvar(cadr(e2)); default: g_expr(e2); case FREGISTER: @@ -1795,7 +1795,7 @@ int t=caddr(e3); if(scalar(t)) { nargs ++ ; reg_arg++; - } else if (t==LONGLONG||t==ULONGLONG||DOUBLE) { + } else if (t==LONGLONG||t==ULONGLONG||t==DOUBLE) { nargs ++ ; reg_arg++; nargs ++ ; reg_arg++; } else if (t==FLOAT) { @@ -1897,8 +1897,8 @@ code_register(creg,cadr(jmp)); /* g_expr(assign_expr0(jmp,e2,INT,INT)); functions are lvalue */ } - /* first we execute complex argument to avoid interaction with - input variables */ + /* First we execute complex argument to avoid interaction with + input variables. Remain the last complex argument in complex_. */ stargs = 0; complex_ = 0; nargs = reg_arg = freg_arg = 0; @@ -1940,21 +1940,37 @@ set_freg(FREG_FREGISTER,0); set_ireg(CREG_REGISTER,0); - if (complex_) { - arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg); - compute_complex_arg(complex_,reg_arg_list,arg); - } - for(stargs=reverse0(stargs);stargs;stargs = cadr(stargs)) { - e3 = car(stargs); - e4 = car(e3); - t = caddr(e3); - arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0); - struct_push(e4,t,arg); - car(e3)=0; // done + // Struct arguments need emit_copy. it destructs 3 input registers. + // But it returns no value on a register. So calcurate it here. + // We cannot do this in the previous loop, because the copied struct may be + // override by other complex arguments. But bofore this we have to check + // complex_. + + if (stargs) { + if (complex_) { + arg = get_input_arg(caddr(complex_),AS_SAVE, + pnargs,preg_arg,pfreg_arg); + compute_complex_arg(complex_,reg_arg_list,arg); + } + for(stargs=reverse0(stargs);stargs;stargs = cadr(stargs)) { + e3 = car(stargs); + e4 = car(e3); + t = caddr(e3); + arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0); + struct_push(e4,t,arg); + car(e3)=0; // done + } + } else { + // last complex argument can use input register + if (complex_) { + arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg); + compute_complex_arg(complex_,reg_arg_list,arg); + } } nargs = reg_arg = freg_arg = arg_assign = 0; - // calc stack arguments first + // calc stack arguments first, it may requires extra registers, + // and we can still use input registers now. for (e3 = e1; e3; increment_function_arg(e3,&nargs,®_arg,&freg_arg), e3 = cadr(e3)) { @@ -2542,38 +2558,42 @@ } static int -code_register_save(reg_save,freg_save,disp) +code_register_save(int reg_save,int freg_save,int disp) { int i; for(i=0;i<32;i++) { - if (reg_var_num(0)>i&&i>reg_var_num(max_reg_var)) { - printf("\tsw %s,%d($sp)\n",register_name(i),disp); - disp += SIZE_OF_INT; + if (reg_var_num(0)>i&&i>reg_var_num(reg_save)) { + printf("\tsw %s,$L_%d+%d($sp)\n",register_name(i), + r1_offset_label,disp); + disp -= SIZE_OF_INT; } } for(i=0;i<32;i++) { - if (freg_var_num(0)>i&&i>freg_var_num(max_reg_var)) { - printf("\ts.s %s,%d($sp)\n",register_name(i),disp); - disp += SIZE_OF_FLOAT; + if (freg_var_num(0)>i&&i>freg_var_num(freg_save)) { + printf("\ts.s %s,$L_%d+%d($sp)\n",register_name(i), + r1_offset_label,disp); + disp -= SIZE_OF_FLOAT; } } return disp; } static int -code_register_restore(reg_save,freg_save,disp) +code_register_restore(int reg_save,int freg_save,int disp) { int i; for(i=0;i<32;i++) { - if (reg_var_num(0)>i&&i>reg_var_num(max_reg_var)) { - printf("\tlw %s,%d($sp)\n",register_name(i),disp); - disp += SIZE_OF_INT; + if (reg_var_num(0)>i&&i>reg_var_num(reg_save)) { + printf("\tlw %s,$L_%d+%d($sp)\n",register_name(i), + r1_offset_label,disp); + disp -= SIZE_OF_INT; } } for(i=0;i<32;i++) { - if (freg_var_num(0)>i&&i>freg_var_num(max_reg_var)) { - printf("\tl.s %s,%d($sp)\n",register_name(i),disp); - disp += SIZE_OF_FLOAT; + if (freg_var_num(0)>i&&i>freg_var_num(freg_save)) { + printf("\tl.s %s,$L_%d+%d($sp)\n",register_name(i), + r1_offset_label,disp); + disp -= SIZE_OF_FLOAT; } } return disp; @@ -2651,7 +2671,7 @@ disp&= -SIZE_OF_INT; r1_offsetv = -disp+max_func_args*SIZE_OF_INT+code_disp_offset; - printf(".set L_%d,%d\n",r1_offset_label,r1_offsetv); + printf("L_%d=%d\n",r1_offset_label,r1_offsetv); local_table(); printf("\t.end %s\n",name); @@ -2673,15 +2693,17 @@ printf("\t.globl\t%s\n",name); printf(".ent %s\n",name); printf("%s:\n",name); - printf("\t.frame $fp,$L_%d,$31\t",r1_offset_label=fwdlabel()); - printf("\t.mask 0x%x,%d\n",mask_label=fwdlabel(), + printf("\t.frame $fp,$L_%d,$31\n",r1_offset_label=fwdlabel()); + printf("\t.mask $L_%d,$L_%d\n",mask_label=fwdlabel(), mask_offset_label=fwdlabel()); - printf("\t.fmask 0x%x,%d\n",fmask_label=fwdlabel(), + printf("\t.fmask $L_%d,$L_%d\n",fmask_label=fwdlabel(), fmask_offset_label=fwdlabel()); printf("\t.set noreorder\n"); printf("\t.cpload $25\n"); printf("\t.set reorder\n"); printf("\tsubu $sp,$sp,$L_%d\n",r1_offset_label); + printf("\tsw $31,$L_%d+%d($sp)\n",r1_offset_label,r1_offset); + printf("\tsw $fp,$L_%d+%d($sp)\n",r1_offset_label,r1_offset-SIZE_OF_INT); printf("\t.cprestore $L_%d\n",cprestore_label=fwdlabel()); printf("\tj $L_%d\n",register_save_label=fwdlabel()); register_save_return_label = backdef(); @@ -2706,12 +2728,6 @@ int r1_offsetv; int lvar_offsetv; - // if (max_freg_var>=0 && max_freg_var<=3) max_freg_var=3; - reg_save = - (REAL_MAX_REGISTER-(REG_VAR_BASE-max_reg_var))*SIZE_OF_INT; - freg_save = - (REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*SIZE_OF_FLOAT; - if (control) { code_set_return_register(1); } else @@ -2748,18 +2764,19 @@ disp &= -SIZE_OF_INT; - r1_offsetv = round16(-disp) + - max_reg_var*SIZE_OF_INT+max_freg_var*SIZE_OF_FLOAT+ - round16(max_func_args); + lvar_offsetv = round16(-disp) + + round16(max_func_args)+r1_offset; + r1_offsetv = lvar_offsetv + + max_reg_var*SIZE_OF_INT+max_freg_var*SIZE_OF_FLOAT+2*SIZE_OF_INT; fprintf(asi,"$L_%d=%d\n",r1_offset_label,r1_offsetv); fprintf(asi,"$L_%d=%d\n",lvar_offset_label,lvar_offsetv); printf("\tmove $sp,$fp\n"); + printf("\tlw $31,$L_%d+%d($sp)\n",r1_offset_label,r1_offset); + printf("\tlw $fp,$L_%d+%d($sp)\n",r1_offset_label,r1_offset-SIZE_OF_INT); if (max_reg_var+max_freg_var) - code_register_restore(disp); - printf("\tlw $31,%d($sp)\n",-disp); - printf("\tlw $fp,%d($sp)\n",-disp-4); + code_register_restore(max_reg_var,max_freg_var,r1_offset-SIZE_OF_INT*2); printf("\taddu $sp,$sp,%d\n",r1_offsetv); printf("\tj $31\n"); @@ -2781,7 +2798,7 @@ register_save_label,register_save_return_label); } else { code_label(register_save_label); - code_register_save(disp); + code_register_save(max_reg_var,max_freg_var,r1_offset-SIZE_OF_INT*2); jmp(register_save_return_label); }
--- a/mc-code-powerpc.c Mon May 17 11:41:51 2004 +0900 +++ b/mc-code-powerpc.c Tue May 18 14:20:46 2004 +0900 @@ -1866,21 +1866,37 @@ set_freg(FREG_FREGISTER,0); set_ireg(CREG_REGISTER,0); - if (complex_) { - arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg); - compute_complex_arg(complex_,reg_arg_list,arg); - } - for(stargs=reverse0(stargs);stargs;stargs = cadr(stargs)) { - e3 = car(stargs); - e4 = car(e3); - t = caddr(e3); - arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0); - struct_push(e4,t,arg); - car(e3)=0; // done + // Struct arguments need emit_copy. it destructs 3 input registers. + // But it returns no value on a register. So calcurate it here. + // We cannot do this in the previous loop, because the copied struct may be + // override by other complex arguments. But bofore this we have to check + // complex_. + + if (stargs) { + if (complex_) { + arg = get_input_arg(caddr(complex_),AS_SAVE, + pnargs,preg_arg,pfreg_arg); + compute_complex_arg(complex_,reg_arg_list,arg); + } + for(stargs=reverse0(stargs);stargs;stargs = cadr(stargs)) { + e3 = car(stargs); + e4 = car(e3); + t = caddr(e3); + arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0); + struct_push(e4,t,arg); + car(e3)=0; // done + } + } else { + // last complex argument can use input register + if (complex_) { + arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg); + compute_complex_arg(complex_,reg_arg_list,arg); + } } nargs = reg_arg = freg_arg = arg_assign = 0; - // calc stack arguments first + // calc stack arguments first, it may requires extra registers, + // and we can still use input registers now. for (e3 = e1; e3; increment_function_arg(e3,&nargs,®_arg,&freg_arg), e3 = cadr(e3)) {