Mercurial > hg > CbC > old > device
changeset 269:d9f4026de4e3
MIPS continue...
author | kono |
---|---|
date | Wed, 19 May 2004 09:56:53 +0900 |
parents | 3a368fc37559 |
children | 0c6bf0e3e475 |
files | .gdbinit mc-code-mips.c mc-code-powerpc.c mc-codegen.c |
diffstat | 4 files changed, 243 insertions(+), 213 deletions(-) [+] |
line wrap: on
line diff
--- a/.gdbinit Tue May 18 14:20:46 2004 +0900 +++ b/.gdbinit Wed May 19 09:56:53 2004 +0900 @@ -1,7 +1,7 @@ tb main -run -s -ob00.s test/basic.c +# run -s test/basic.c # run -s -ob00.s mc-parse.c -# run -s test/code-gen-all.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 printf "r10=%08x r11=%08x r12=%08x r13=%08x r14=%08x r15=%08x\n",$r10,$r11,$r12,$r13,$r14,$r15
--- a/mc-code-mips.c Tue May 18 14:20:46 2004 +0900 +++ b/mc-code-mips.c Wed May 19 09:56:53 2004 +0900 @@ -77,8 +77,8 @@ #define REG_fp 1 #define REG_sp 30 -#define REG_VAR_BASE 29 -#define REG_VAR_MIN 18 +#define REG_VAR_BASE 23 +#define REG_VAR_MIN 16 #define MIN_TMP_REG 4 #define MAX_TMP_REG 11 @@ -221,7 +221,7 @@ if (!is_float_reg(i)) { if (lreg) { free_register(lreg); lreg = 0; } if (!freg) freg = get_dregister(0); - else if (freg!=i) free_register(i); + // else if (freg!=i) free_register(i); i = freg; } if (!regs[i]) regs[i]=USING_REG; @@ -288,15 +288,6 @@ $f14,$f12 input register $f20-$f31 saved register variable - function call stack frame - <----------r1_offset------------------------------> - <------------lvar_offset-------> - r+ +------------+---+---------------+----------+--------------+----+ - - callee arg xx register save local caller arg xx - ($fp) reg_save disp max_func_args*SIZE_OF_INT - lvar>0 lvar<0 lvar>0x1000 0000 - prev $sp=$fp $sp=$fp - code segment stack frame * gotoを呼び出した関数のr1 ! r1(goto前のr1) @@ -309,16 +300,19 @@ prev $sp=$fp $fp $sp */ -static int arg_offset = 0,arg_offset1 = 0,disp_offset = 0; +#define arg_offset 8 +#define arg_offset1 0 +#define disp_offset 8 #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 -#define FUNC_LVAR l+disp_offset -#define CALLER_ARG (l-ARG_LVAR_OFFSET)+arg_offset1 -#define CALLEE_ARG l+arg_offset +#define code_disp_offset 0 +#define jump_offset 0 + +#define CODE_LVAR(l) ((l)+code_disp_offset) +#define CODE_CALLER_ARG(l) ((l)+arg_offset1) +#define FUNC_LVAR(l) (l+disp_offset) +#define CALLER_ARG(l) ((l)+arg_offset1) +#define CALLEE_ARG(l) ((l)+arg_offset) #if 0 void @@ -336,18 +330,18 @@ l = ARG_LVAR_OFFSET; printf("# offset call0\t%d\n",CALLER_ARG); l = ARG_LVAR_OFFSET+max_func_args*SIZE_OF_INT; -printf("# offset calln\t%d %d\n",CALLER_ARG,max_func_args*SIZE_OF_INT); +printf("# offset calln\t%d %d\n",CALLER_ARG(l),max_func_args*SIZE_OF_INT); l = disp; -printf("# offset lvarn\t%d %d\n",FUNC_LVAR+lvar_offsetv,disp); +printf("# offset lvarn\t%d %d\n",FUNC_LVAR(l)+lvar_offsetv,disp); l = 0; -printf("# offset lvar0\t%d\n",FUNC_LVAR+lvar_offsetv); +printf("# offset lvar0\t%d\n",FUNC_LVAR(l)+lvar_offsetv); l = -reg_save; -printf("# offset regs\t%d\n",FUNC_LVAR+lvar_offsetv); +printf("# offset regs\t%d\n",FUNC_LVAR(l)+lvar_offsetv); printf("# offset r1off\t%d\n",r1_offsetv); l = 0; -printf("# offset carg0\t%d\n",CALLEE_ARG+r1_offsetv); +printf("# offset carg0\t%d\n",CALLEE_ARG(l)+r1_offsetv); l = my_func_args; -printf("# offset cargn\t%d %d\n",CALLEE_ARG+r1_offsetv,my_func_args); +printf("# offset cargn\t%d %d\n",CALLEE_ARG(l)+r1_offsetv,my_func_args); #endif } #endif @@ -357,15 +351,15 @@ { if (fnptr->sc==CODE) { if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("%d($fp)\n",CODE_CALLER_ARG); + printf("%d($fp)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); } else - printf("%d($fp)\n",CODE_LVAR); + printf("%d($fp)\n",CODE_LVAR(l-ARG_LVAR_OFFSET)); } else if (l<0) { /* local variable */ - printf("%d+$L_%d($fp)\n",FUNC_LVAR,lvar_offset_label); + printf("%d+$L_%d($fp)\n",FUNC_LVAR(l),lvar_offset_label); } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("%d($fp)\n",CALLER_ARG); + printf("%d($fp)\n",CALLER_ARG(l-ARG_LVAR_OFFSET)); } else { /* callee's arguments */ - printf("%d+$L_%d($fp)\n",CALLEE_ARG,r1_offset_label); + printf("%d+$L_%d($fp)\n",CALLEE_ARG(l),r1_offset_label); } } @@ -374,15 +368,19 @@ { if (fnptr->sc==CODE) { if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_CALLER_ARG); + printf("\taddu\t%s,$fp,%d\n", + register_name(creg),CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); } else - printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_LVAR); + printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_LVAR(l)); } else if (l<0) { /* local variable */ - printf("\taddu\t%s,$fp,%d+$L_%d\n",register_name(creg),FUNC_LVAR,lvar_offset_label); + printf("\taddu\t%s,$fp,%d+$L_%d\n",register_name(creg), + FUNC_LVAR(l),lvar_offset_label); } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("\taddu\t%s,$fp,%d\n",register_name(creg),CALLER_ARG); + printf("\taddu\t%s,$fp,%d\n", + register_name(creg),CALLER_ARG(l-ARG_LVAR_OFFSET)); } else { /* callee's arguments */ - printf("\taddu\t%s,$fp,%d+$L_%d\n",register_name(creg),CALLEE_ARG,r1_offset_label); + printf("\taddu\t%s,$fp,%d+$L_%d\n", + register_name(creg),CALLEE_ARG(l),r1_offset_label); } } @@ -528,7 +526,7 @@ reg =REG_VAR_BASE-i; if (! regs[reg]) { /* 使われていないなら */ regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ - if (i>max_reg_var) max_reg_var=i; + if (i+1>max_reg_var) max_reg_var=i+1; return reg; /* その場所を表す番号を返す */ } } @@ -580,7 +578,7 @@ reg =FREG_VAR_BASE-i+FREG_OFFSET; if (! regs[reg]) { /* 使われていないなら */ regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ - if (i>max_freg_var) max_freg_var=i; + if (i+1>max_freg_var) max_freg_var=i+1; return reg; /* その場所を表す番号を返す */ } } @@ -646,13 +644,13 @@ if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ /* そのレジスタを使うことを宣言し */ regs[REG_VAR_BASE-i]=USING_REG; - if (i>max_reg_var) max_reg_var=i; + if (i+1>max_reg_var) max_reg_var=i+1; for(j=0;j<REG_VAR_BASE-REG_VAR_MIN;j++) { if (! regs[REG_VAR_BASE-j]) { /* 使われていないなら */ /* そのレジスタを使うことを宣言し */ regs[REG_VAR_BASE-j]=USING_REG; - if (j>max_reg_var) max_reg_var=j; + if (j+1>max_reg_var) max_reg_var=j+1; /* その場所を表す番号を返す */ regs[ll]=USING_REG; regv_l(ll) = REG_VAR_BASE-j; @@ -898,7 +896,7 @@ if (! regs[j]) { /* 使われていないなら */ /* そのレジスタを使うことを宣言し */ regs[j]=USING_REG; - if (i>=max_reg_var) max_reg_var=i+1; + if (i+1>=max_reg_var) max_reg_var=i+1; /* その場所を表す番号を返す */ return list3(REGISTER,j,(int)n); } @@ -925,7 +923,7 @@ j = freg_var_num(i); if (! regs[j]) { /* 使われていないなら */ regs[j]=USING_REG; /*そのレジスタを使うことを宣言し*/ - if (i>=max_freg_var) max_freg_var=i+1; + if (i+1>max_freg_var) max_freg_var=i+1; /* その場所を表す番号を返す */ return list3(FREGISTER,j,(int)n); } @@ -1682,8 +1680,13 @@ static int not_simple_p(int e3) { - return (e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS|| - (((e3/100)==LOP)&&(e3!=LREGISTER||e3!=LADD||e3!=LSUB))); + return (e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS|| + ((e3/100==LOP/100)&&(e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD|| + e3==LLSHIFT||e3==LULSHIFT||e3==LRSHIFT||e3==LURSHIFT))|| + ((e3/100==DOP/100)&&(e3==DDIV||e3==DADD||e3==DSUB||e3==DMUL|| + e3== DPOSTINC || e3==DPREINC || e3==DASSOP || + e3== DOP+LT || e3== DOP+LE || e3== DOP+GT || + e3== DOP+GE || e3== DOP+EQ || e3== DOP+NEQ))); } int @@ -1965,6 +1968,7 @@ if (complex_) { arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg); compute_complex_arg(complex_,reg_arg_list,arg); + car(complex_) = 0; // done. } } @@ -2082,10 +2086,9 @@ void -code_fix_frame_pointer(int disp_offset) { - int l = 0; +code_fix_frame_pointer(int offset) { printf("\tla $fp,"); - printf("%d+$L_%d($sp)\n",FUNC_LVAR,lvar_offset_label); + printf("%d+$L_%d($sp)\n",FUNC_LVAR(0),lvar_offset_label); } void @@ -2172,24 +2175,30 @@ } #endif -#if LONGLONG_CODE -int -code_lrindirect(int e1, int reg, int offset, int us) +static void +lload(int creg,int reg,int offset) { - char *crn; - int creg0; - - g_expr(e1); - if (!is_int_reg(creg)) error(-1); - crn=register_name(creg0=creg); - use_longlong(reg); - if (creg0!=regv_h(reg)) { + char *crn=register_name(creg); + if (creg!=regv_h(reg)) { printf("\tlw %s,%d(%s)\n",lregister_name_high(reg),offset,crn); printf("\tlw %s,%d(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); } else { printf("\tlw %s,%d(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); printf("\tlw %s,%d(%s)\n",lregister_name_high(reg),offset,crn); } +} + +#if LONGLONG_CODE +int +code_lrindirect(int e1, int reg, int offset, int us) +{ + int creg0; + + g_expr(e1); + if (!is_int_reg(creg)) error(-1); + creg0=creg; + use_longlong(reg); + lload(creg0,reg,offset); return us?ULONGLONG:LONGLONG; } #endif @@ -2534,8 +2543,10 @@ /* used regsister var */ int i; int offset=0; + int min = reg_var_num(max_reg_var); + int max = reg_var_num(0); for(i=0;i<32;i++) { - if (i==28||i==31||(reg_var_num(0)>i&&i>reg_var_num(max_reg_var))) { + if (i==28||i==31||(max>i&&i>=min)) { offset++; } } @@ -2549,8 +2560,10 @@ /* used regsister var */ int i; unsigned int mask=0; + int min = reg_var_num(max_reg_var); + int max = reg_var_num(0); for(i=0;i<32;i++) { - if (i==28||i==31||(reg_var_num(0)>i&&i>reg_var_num(max_reg_var))) { + if (i==28||i==31||(max>i&&i>=min)) { mask |= (1<<i); } } @@ -2561,19 +2574,15 @@ 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(reg_save)) { - printf("\tsw %s,$L_%d+%d($sp)\n",register_name(i), - r1_offset_label,disp); - disp -= SIZE_OF_INT; - } + for (i=reg_var_num(0);i>reg_var_num(reg_save);i--) { + 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(freg_save)) { - printf("\ts.s %s,$L_%d+%d($sp)\n",register_name(i), - r1_offset_label,disp); - disp -= SIZE_OF_FLOAT; - } + for (i=freg_var_num(0);i>freg_var_num(freg_save);i--) { + printf("\ts.s %s,$L_%d-%d($sp)\n",register_name(i), + r1_offset_label,-disp); + disp -= SIZE_OF_FLOAT; } return disp; } @@ -2582,19 +2591,15 @@ 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(reg_save)) { - printf("\tlw %s,$L_%d+%d($sp)\n",register_name(i), - r1_offset_label,disp); - disp -= SIZE_OF_INT; - } + for (i=reg_var_num(0);i>reg_var_num(reg_save);i--) { + 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(freg_save)) { - printf("\tl.s %s,$L_%d+%d($sp)\n",register_name(i), - r1_offset_label,disp); - disp -= SIZE_OF_FLOAT; - } + for (i=freg_var_num(0);i>freg_var_num(freg_save);i--) { + printf("\tl.s %s,$L_%d-%d($sp)\n",register_name(i), + r1_offset_label,-disp); + disp -= SIZE_OF_FLOAT; } return disp; } @@ -2604,8 +2609,10 @@ { int i; int offset=0; + int min = freg_var_num(max_reg_var); + int max = freg_var_num(0); for(i=0;i<32;i++) { - if (freg_var_num(0)>i&&i>freg_var_num(max_reg_var)) { + if (i==28||i==31||(max>i&&i>=min)) { offset++; } } @@ -2618,9 +2625,10 @@ { int i; unsigned int mask=0; - /* used fregsister var */ + int min = freg_var_num(max_reg_var); + int max = freg_var_num(0); for(i=0;i<32;i++) { - if (freg_var_num(0)>i&&i>freg_var_num(max_reg_var)) { + if (i==28||i==31||(max>i&&i>=min)) { mask |= (1<<i); } } @@ -2702,9 +2710,9 @@ 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("\tsw $31,$L_%d-%d($sp)\n",r1_offset_label,arg_offset); + printf("\tsw $fp,$L_%d-%d($sp)\n",r1_offset_label,arg_offset+SIZE_OF_INT); printf("\tj $L_%d\n",register_save_label=fwdlabel()); register_save_return_label = backdef(); printf("\tmove $fp,$sp\n"); @@ -2762,21 +2770,30 @@ fwddef(retcont1); } - +/* + <-------r1_offset------------------------------> + <------------lvar_offset-------> + r+ +-----------+----+---------------+----------+--- ----------+----+ - + callee arg xxx register save local caller arg xxx + ($fp) reg_save disp max_func_args*SIZE_OF_INT + lvar>0 lvar<0 lvar>0x1000 0000 + prev $sp=$fp $sp=$fp + */ + disp &= -SIZE_OF_INT; lvar_offsetv = round16(-disp) + - round16(max_func_args)+r1_offset; - r1_offsetv = lvar_offsetv + + round16((max_func_args<2?2:max_func_args)*SIZE_OF_INT); + r1_offsetv = lvar_offsetv + arg_offset + SIZE_OF_INT*2 + 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); + printf("\tlw $31,$L_%d-%d($sp)\n",r1_offset_label,arg_offset); + printf("\tlw $fp,$L_%d-%d($sp)\n",r1_offset_label,arg_offset+SIZE_OF_INT); if (max_reg_var+max_freg_var) - code_register_restore(max_reg_var,max_freg_var,r1_offset-SIZE_OF_INT*2); + code_register_restore(max_reg_var,max_freg_var,-arg_offset-SIZE_OF_INT*2); printf("\taddu $sp,$sp,%d\n",r1_offsetv); printf("\tj $31\n"); @@ -2784,23 +2801,39 @@ round16(-disp), max_reg_var+2, max_freg_var, - round16(max_func_args), + round16(max_func_args*SIZE_OF_INT), 0 ); fprintf(asi,"$L_%d=0x%x\n",mask_label,code_mask()); fprintf(asi,"$L_%d=%d\n",mask_offset_label,code_mask_offset()); fprintf(asi,"$L_%d=0x%x\n",fmask_label,code_fmask()); fprintf(asi,"$L_%d=%d\n",fmask_offset_label,code_fmask_offset()); - fprintf(asi,"$L_%d=%d\n",cprestore_label ,round16(max_func_args)); + fprintf(asi,"$L_%d=%d\n",cprestore_label ,round16(max_func_args*SIZE_OF_INT)); if (max_reg_var+max_freg_var==0) { fprintf(asi,"$L_%d=$L_%d\n", register_save_label,register_save_return_label); } else { code_label(register_save_label); - code_register_save(max_reg_var,max_freg_var,r1_offset-SIZE_OF_INT*2); + code_register_save(max_reg_var,max_freg_var,-arg_offset-SIZE_OF_INT*2); jmp(register_save_return_label); } +#if 1 + printf("#\n"); + printf("# callee arg top=\t%d\n",CALLEE_ARG(0)+r1_offsetv); + printf("# r1_offset=\t\t%d\n",r1_offsetv); + printf("# reg_save_top=\t\t%d\n",r1_offsetv); + printf("# reg_save_end=\t\t%d\n", + -max_reg_var*SIZE_OF_INT-max_freg_var*SIZE_OF_FLOAT-2*SIZE_OF_INT+ + r1_offsetv); + printf("# lvar_offset=\t\t%d\n",lvar_offsetv); + printf("# min local var=\t%d\n",FUNC_LVAR(0)+lvar_offsetv); + printf("# max local var=\t%d\n",FUNC_LVAR(disp)+lvar_offsetv); + printf("# min caller arg var=\t%d\n", + CALLER_ARG(round16(max_func_args*SIZE_OF_INT))); + printf("# max caller arg var=\t%d\n",CALLER_ARG(0)); + printf("#\n"); +#endif local_table(); printf("\t.end %s\n",name); @@ -3569,19 +3602,19 @@ code_dpreinc(int e1,int e2,int d,int reg) { char *frn; char *crn; - char *xrn; - int g,xreg; + int g,xreg,creg0; char *grn; int dir=caddr(e1); if (!d) { if (car(e2)==FREGISTER) { - crn=register_name(cadr(e2)); + creg0=cadr(e2); } else { g_expr(e2); if (!is_int_reg(creg)) error(-1); - crn=register_name(ireg); + creg0=ireg; } + crn=register_name(creg0); use_float(d,reg); @@ -3590,7 +3623,8 @@ printf("\tli.s %s,1.0\n",grn); if (car(e2)==FREGISTER) { - printf("\tmov.s %s,%s\n",crn,frn); + if (creg0!=reg) + printf("\tmov.s %s,%s\n",crn,frn); printf("\t%s %s,%s,%s\n",(dir>0)?"add.s":"sub.s",crn,frn,grn); } else { printf("\tl.s %s,0(%s)\n",frn,crn); @@ -3613,22 +3647,17 @@ } g_expr(e2); if(!is_int_reg(creg)) error(-1); + creg0=creg; emit_push(); code_save_stacks(); clear_ptr_cache(); + lload(creg0,DREGISTER_OPERAND,0); set_dreg(RET_DREGISTER,0); - xreg = emit_pop(1); - xrn = register_name(xreg); - printf("\tlw $4,%d(%s)\n",SIZE_OF_INT,xrn); - printf("\tlw $5,0(%s)\n",xrn); double_lib_c(dir>0?"dpadd":"dpsub",1.0); + if (reg!=USE_CREG) error(-1); use_float(d,reg); - if (use) { - printf("\tlw %s,%d(%s)\n",lregister_name_high(reg),SIZE_OF_INT,xrn); - printf("\tlw %s,0(%s)\n",lregister_name_low(reg),xrn); - } - printf("\tsw $2,%d(%s)\n",SIZE_OF_INT,xrn); - printf("\tsw $3,0(%s)\n",xrn); + xreg = emit_pop(1); + code_lassign(xreg,RET_DREGISTER); emit_pop_free(xreg); } } @@ -3637,18 +3666,19 @@ code_dpostinc(int e1,int e2,int d,int reg) { char *frn; char *crn; - int g,xreg; - char *grn,*xrn; + int g,xreg,creg0; + char *grn; int dir=caddr(e1); if (!d) { if (car(e2)==FREGISTER) { - crn=register_name(cadr(e2)); + creg0=cadr(e2); } else { g_expr(e2); if (!is_int_reg(creg)) error(-1); - crn=register_name(creg); + creg0=creg; } + crn=register_name(creg0); use_float(d,reg); @@ -3682,29 +3712,37 @@ } g_expr(e2); if(!is_int_reg(creg)) error(-1); + creg0=creg; emit_push(); code_save_stacks(); clear_ptr_cache(); set_dreg(RET_LREGISTER,0); - xreg = emit_pop(0); - xrn = register_name(xreg); - printf("\tlw $4,%d(%s)\n",SIZE_OF_INT,xrn); - printf("\tlw $5,0(%s)\n",xrn); + lload(creg0,DREGISTER_OPERAND,0); double_lib_c(dir>0?"dpadd":"dpsub",1.0); - printf("\tsw $2,%d(%s)\n",SIZE_OF_INT,xrn); - printf("\tsw $3,0(%s)\n",xrn); + if (use) { + if (reg!=USE_CREG) { + use_float(d,reg); + lload(xreg,reg,0); + } else { + reg = get_dregister(1); + xreg = emit_pop(0); + lload(xreg,reg,0); + code_lassign(xreg,RET_DREGISTER); + set_dreg(reg,0); + emit_pop_free(xreg); + return; + } + } + xreg = emit_pop(0); + code_lassign(xreg,RET_DREGISTER); emit_pop_free(xreg); - if (use) { - use_float(d,reg); - printf("\tlw %s,%d(%s)\n",lregister_name_high(reg),SIZE_OF_INT,xrn); - printf("\tlw %s,0(%s)\n",lregister_name_low(reg),xrn); - } } } void drexpr(int e1, int e2,int l1, int op,int cond) { + int op1; if (!cond) { switch(op) { case FOP+GT: @@ -3726,22 +3764,22 @@ } } switch(op) { - case FOP+GT: op=FOP+CMP; break; - case DOP+GT: op=DOP+CMP; break; - case FOP+GE: op=FOP+CMPGE; break; - case DOP+GE: op=DOP+CMPGE; break; - case FOP+EQ: op=FOP+CMPEQ; break; - case DOP+EQ: op=DOP+CMP; break; - case FOP+NEQ: op=FOP+CMPEQ; break; - case DOP+NEQ: op=DOP+CMP; break; + case FOP+GT: op1=FOP+CMP; break; + case DOP+GT: op1=DOP+CMP; break; + case FOP+GE: op1=FOP+CMPGE; break; + case DOP+GE: op1=DOP+CMPGE; break; + case FOP+EQ: op1=FOP+CMPEQ; break; + case DOP+EQ: op1=DOP+CMP; break; + case FOP+NEQ: op1=FOP+CMPEQ; break; + case DOP+NEQ: op1=DOP+CMP; break; default: error(-1); } - g_expr(list3(op,e2,e1)); + g_expr(list3(op1,e2,e1)); switch(op) { case DOP+GT: printf("\tbgez\t$2,$L_%d\n",l1);break; case FOP+GT: printf("\tbc1t\t$L_%d\n",l1);break; case DOP+GE: printf("\tbltz\t$2,$L_%d\n",l1);break; - case FOP+GE: printf("\tbc1t\t$2,$L_%d\n",l1);break; + case FOP+GE: printf("\tbc1t\t$L_%d\n",l1);break; case DOP+EQ: printf("\tbeq\t$2,$0,$L_%d\n",l1);break; case FOP+EQ: printf("\tbc1t\t$L_%d\n",l1);break; case DOP+NEQ: printf("\tbne\t$2,$0,$L_%d\n",l1);break; @@ -3820,6 +3858,8 @@ lmove(int to,int from) { int tmp; + if (regv_h(to)==regv_h(from)&&(regv_l(to)==regv_l(from))) + return; if (regv_h(to)==regv_l(from)&&(regv_l(to)==regv_h(from))) { tmp = get_register(); printf("\tmove %s,%s\n",register_name(tmp),lregister_name_low(from)); @@ -4665,7 +4705,6 @@ void code_lpreinc(int e1,int e2,int reg) { - char *xrn,*drn_h,*drn_l; int dreg=-1,xreg=-1; int dir=caddr(e1); if (car(e2)==LREGISTER) { @@ -4681,20 +4720,14 @@ emit_push(); if (reg==USE_CREG) { dreg=get_lregister(); if (!dreg) error(-1); - drn_h = lregister_name_high(dreg); - drn_l = lregister_name_low(dreg); set_lreg(dreg,0); // free old lreg==creg } else { - drn_h = lregister_name_high(reg); - drn_l = lregister_name_low(reg); + dreg = reg; } xreg = emit_pop(0); - xrn = register_name(xreg); - printf("\tlw %s,%d(%s)\n",drn_l,SIZE_OF_INT,xrn); - printf("\tlw %s,0(%s)\n",drn_h,xrn); + lload(xreg,dreg,0); ladd(dreg,dir); - printf("\tsw %s,%d(%s)\n",drn_l,SIZE_OF_INT,xrn); - printf("\tsw %s,0(%s)\n",drn_h,xrn); + code_lassign(xreg,dreg); emit_pop_free(xreg); if (dreg!=-1) free_register(dreg); } @@ -4702,8 +4735,6 @@ void code_lpostinc(int e1,int e2,int reg) { - char *xrn,*drn_h,*drn_l; - char *nrn_h,*nrn_l; int dreg,nreg,xreg; int dir=caddr(e1); if (car(e2)==LREGISTER) { @@ -4716,25 +4747,16 @@ if(!is_int_reg(creg)) error(-1); emit_push(); nreg=get_lregister(); if (!nreg) error(-1); - nrn_h = lregister_name_high(nreg); - nrn_l = lregister_name_low(nreg); if (reg==USE_CREG) { dreg=get_lregister(); if (!dreg) error(-1); - drn_h = lregister_name_high(dreg); - drn_l = lregister_name_low(dreg); set_lreg(dreg,0); // free old lreg==creg } else { - drn_h = lregister_name_high(reg); - drn_l = lregister_name_low(reg); dreg = reg; } xreg = emit_pop(0); - xrn = register_name(xreg); - printf("\tlw %s,%d(%s)\n",drn_l,SIZE_OF_INT,xrn); - printf("\tlw %s,0(%s)\n",drn_h,xrn); + lload(xreg,dreg,0); ladd(dreg,dir); - printf("\tsw %s,%d(%s)\n",nrn_l,SIZE_OF_INT,xrn); - printf("\tsw %s,0(%s)\n",nrn_h,xrn); + code_lassign(xreg,nreg); emit_pop_free(xreg); free_register(nreg); } @@ -4757,18 +4779,15 @@ register_name(edx)); edx = edx0; } - printf("\tlw %s,0(%s)\n",lregister_name_high(reg), - register_name(edx)); - printf("\tlw %s,%d(%s)\n",lregister_name_low(reg), - SIZE_OF_INT,register_name(edx)); - free_register(edx); + lload(edx0=edx,reg,0); + // free_register(edx); don't do this, it will free pushed register ltosop(op,reg,xreg); + use_reg(reg); edx = emit_pop(0); - printf("\tsw %s,0(%s)\n",lregister_name_high(reg), - register_name(edx)); - printf("\tsw %s,%d(%s)\n",lregister_name_low(reg), - SIZE_OF_INT,register_name(edx)); + code_lassign(edx,reg); free_register(edx); + if (edx0!=-1) + free_register(edx0); emit_lpop_free(xreg); }
--- a/mc-code-powerpc.c Tue May 18 14:20:46 2004 +0900 +++ b/mc-code-powerpc.c Wed May 19 09:56:53 2004 +0900 @@ -1648,7 +1648,7 @@ { return e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS|| e3==LLSHIFT||e3==LULSHIFT||e3==LRSHIFT||e3==LURSHIFT|| - e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD; + e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD||e3==LASSOP; } static int @@ -2123,6 +2123,19 @@ } #endif +static void +lload(int creg,int reg,int offset) +{ + char *crn = register_name(creg); + if (creg!=regv_h(reg)) { + printf("\tlwz %s,%d(%s)\n",lregister_name_high(reg),offset,crn); + printf("\tlwz %s,%d(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); + } else { + printf("\tlwz %s,%d(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); + printf("\tlwz %s,%d(%s)\n",lregister_name_high(reg),offset,crn); + } +} + #if LONGLONG_CODE int code_lrindirect(int e1, int reg, int offset, int us) @@ -2134,13 +2147,7 @@ if (!is_int_reg(creg)) error(-1); crn=register_name(creg0=creg); use_longlong(reg); - if (creg0!=regv_h(reg)) { - printf("\tlwz %s,%d(%s)\n",lregister_name_high(reg),offset,crn); - printf("\tlwz %s,%d(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); - } else { - printf("\tlwz %s,%d(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); - printf("\tlwz %s,%d(%s)\n",lregister_name_high(reg),offset,crn); - } + lload(creg0,reg,offset); return us?ULONGLONG:LONGLONG; } #endif @@ -4338,7 +4345,7 @@ void code_lpreinc(int e1,int e2,int reg) { - char *xrn,*drn_h,*drn_l; + char *drn_h,*drn_l; int dreg,xreg; int dir=caddr(e1); if (car(e2)==LREGISTER) { @@ -4357,28 +4364,24 @@ emit_push(); if (reg==USE_CREG) { dreg=get_lregister(); if (!dreg) error(-1); - drn_h = lregister_name_high(dreg); - drn_l = lregister_name_low(dreg); set_lreg(dreg,0); // free old lreg==creg } else { - drn_h = lregister_name_high(reg); - drn_l = lregister_name_low(reg); + dreg = reg; } xreg = emit_pop(0); - xrn = register_name(xreg); - printf("\tlwz %s,%d(%s)\n",drn_l,SIZE_OF_INT,xrn); - printf("\tlwz %s,0(%s)\n",drn_h,xrn); + lload(xreg,dreg,0); + drn_l = lregister_name_low(dreg); + drn_h = lregister_name_high(dreg); printf("\taddic %s,%s,%d\n",drn_l,drn_l,dir); printf("\tadd%s %s,%s\n",addze(dir),drn_h,drn_h); - printf("\tstw %s,%d(%s)\n",drn_l,SIZE_OF_INT,xrn); - printf("\tstw %s,0(%s)\n",drn_h,xrn); + code_lassign(xreg,dreg); emit_pop_free(xreg); } void code_lpostinc(int e1,int e2,int reg) { - char *xrn,*drn_h,*drn_l; + char *drn_h,*drn_l; char *nrn_h,*nrn_l; int dreg,nreg,xreg; int dir=caddr(e1); @@ -4399,21 +4402,17 @@ nrn_l = lregister_name_low(nreg); if (reg==USE_CREG) { dreg=get_lregister(); if (!dreg) error(-1); - drn_h = lregister_name_high(dreg); - drn_l = lregister_name_low(dreg); set_lreg(dreg,0); // free old lreg==creg } else { - drn_h = lregister_name_high(reg); - drn_l = lregister_name_low(reg); + dreg = reg; } + drn_l = lregister_name_low(dreg); + drn_h = lregister_name_high(dreg); xreg = emit_pop(0); - xrn = register_name(xreg); - printf("\tlwz %s,%d(%s)\n",drn_l,SIZE_OF_INT,xrn); - printf("\tlwz %s,0(%s)\n",drn_h,xrn); + lload(xreg,dreg,0); printf("\taddic %s,%s,%d\n",nrn_l,drn_l,dir); printf("\tadd%s %s,%s\n",addze(dir),nrn_h,drn_h); - printf("\tstw %s,%d(%s)\n",nrn_l,SIZE_OF_INT,xrn); - printf("\tstw %s,0(%s)\n",nrn_h,xrn); + code_lassign(xreg,nreg); emit_pop_free(xreg); free_register(nreg); } @@ -4435,18 +4434,14 @@ printf("# lassop\n\tmr %s,%s\n",register_name(edx0),register_name(edx)); edx = edx0; } - printf("\tlwz %s,0(%s)\n",lregister_name_high(reg), - register_name(edx)); - printf("\tlwz %s,%d(%s)\n",lregister_name_low(reg), - SIZE_OF_INT,register_name(edx)); - free_register(edx); + lload(edx0=edx,reg,0); ltosop(op,reg,xreg); + use_reg(reg); edx = emit_pop(0); - printf("\tstw %s,0(%s)\n",lregister_name_high(reg), - register_name(edx)); - printf("\tstw %s,%d(%s)\n",lregister_name_low(reg), - SIZE_OF_INT,register_name(edx)); - free_register(edx); + code_lassign(edx,reg); + if (edx0!=-1) + free_register(edx0); + emit_pop_free(edx); emit_lpop_free(xreg); }
--- a/mc-codegen.c Tue May 18 14:20:46 2004 +0900 +++ b/mc-codegen.c Wed May 19 09:56:53 2004 +0900 @@ -1000,7 +1000,7 @@ #if DEBUG_PARALLEL_ASSIGN printf("# remove same memory %d ty %d+%d sz %d\n",car(t0),ty,cadr(t0),sz); #endif - /* we should check size also (but currently useless */ + /* we should check size also (but currently useless) */ remove0(&target,t0); /* still we have source to avoid overwrite */ } @@ -1138,6 +1138,10 @@ e3 = cadr(e2); /* offset of the variable (distination) */ e4 = caddr(e1); /* right value (source) */ sz = cadddr(e1); /* size of struct or union */ + if (is_same_type(e2,e4)&&cadr(e2)==cadr(e4)) { + if (use) g_expr(e4); + return; + } g_expr(e4); emit_push(); g_expr(e2); @@ -1156,7 +1160,7 @@ return; } -void +static void assign_opt(int e5,int e2,int e4,int byte) { int reg; @@ -1208,6 +1212,10 @@ /* e2=e4 */ e2 = cadr(e1); e4 = caddr(e1);e5=car(e4); + if (is_same_type(e2,e4)&&cadr(e2)==cadr(e4)) { + if (use) g_expr(e4); + return; + } if (!use && ( (e5==REGISTER) || (car(e2)==REGISTER&&( @@ -1246,7 +1254,7 @@ #if FLOAT_CODE -void +static void dassign_opt(int e5,int e2,int e4,int d) { int reg; @@ -1293,6 +1301,10 @@ e2 = cadr(e1); e3 = cadr(e2); e4 = caddr(e1); e5=car(e4); + if (is_same_type(e2,e4)&&cadr(e2)==cadr(e4)) { + if (use) g_expr(e4); + return; + } if (car(e1)==DASS) d=1; else if (car(e1)==FASS) d=0; else error(-1); @@ -1375,6 +1387,10 @@ e2 = cadr(e1); e3 = cadr(e2); e4 = caddr(e1); e5=car(e4); + if (is_same_type(e2,e4)&&cadr(e2)==cadr(e4)) { + if (use) g_expr(e4); + return; + } if (!use && ( (e5==LREGISTER) || (car(e2)==LREGISTER&&(e5==LRGVAR||e5==LRLVAR||e5==LCONST))