Mercurial > hg > CbC > old > device
changeset 141:b70018bb3c0e
MIPS
author | kono |
---|---|
date | Mon, 12 May 2003 00:39:57 +0900 |
parents | aac62d1e30a6 |
children | de272ad4ddce |
files | Changes mc-code-mips.c mc-code-powerpc.c |
diffstat | 3 files changed, 355 insertions(+), 106 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Wed May 07 13:12:58 2003 +0900 +++ b/Changes Mon May 12 00:39:57 2003 +0900 @@ -2933,3 +2933,31 @@ 入混じってるな。ま、いいんだけど。 やっぱり、後者に統一。(めんどさ〜) free で d を指定するのはまずい。 + +Thu May 8 11:02:42 JST 2003 + +regs/fregs の複数は必要ないんじゃないか? 一つで良い? 外から +は見えないから、mc-code-mips だけでそうするのが良い。 + +register のやり方を工夫しないとだめか。 + +あーめんどい.... 本当に動くのか? + +double のライブラリ呼び出しで$3,$4,$5,$6 を使うわけだけど、 +ここは必ずあけておかなければいけないわけだよね。でも、実際に +は、ライブラリの呼び出し後には$3,$4 が使われてしまう。ここで、 +emit_push されると気まずいが... + +本当のfunction callと同じ扱いでもいいんだけど、それだと +ちょっときつくない? + +なんか浮動小数点レジスタ変数へのdpreinc/dpostinc を定義して +ないんじゃない? それは、まずいんじゃないの? dassop もそうか? +あれ? なんか何もしてないみたいだな。Intel 版にはレジスタ変数 +がないから、テストしなかったのか。code の引数はレジスタに割 +り当てられるから、そのあたりでテストすることは可能だろうね。 +まぁ、これ自体は難しくはないが... + +あるいは#define REG register でテストする必要があるわけね。 + +MIPSでは、$4,$5,$6,$7 は、本当に特別扱いしないとだめだね。
--- a/mc-code-mips.c Wed May 07 13:12:58 2003 +0900 +++ b/mc-code-mips.c Mon May 12 00:39:57 2003 +0900 @@ -76,6 +76,11 @@ static int dreg; /* general temporal register */ +#define dregister(i,j) (i*32+j) +#define dregister0(i) (i/32) +#define dregister1(i) (i%32) + + int mips_regs[REAL_MAX_REGISTER]; int mips_regv[REAL_MAX_REGISTER]; @@ -85,6 +90,8 @@ int mips_fregs[REAL_MAX_FREGISTER]; int mips_fregv[REAL_MAX_FREGISTER]; +#define FDREG 40 + int *fregv = mips_fregv; int *fregs = mips_fregs; @@ -279,20 +286,23 @@ } } else if (type==FLOAT) { if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) { - n->sc = DREGISTER; + n->sc = FREGISTER; n->dsp = cadr(reg); fregv[n->dsp]= 1; fregs[n->dsp]= INPUT_REG; - freg_var++; + if (freg_var<2) freg_var++; + else reg_var++; cadddr(args)=size(type); /* why we need this? */ } } else if (type==DOUBLE) { - if ((reg = get_input_dregister_var(freg_var,n,is_code0,1))) { + if ((reg = get_input_dregister_var(reg_var,n,is_code0,1))) { n->sc = DREGISTER; n->dsp = cadr(reg); - fregv[n->dsp]= 1; - fregs[n->dsp]= INPUT_REG; - freg_var++; + regv[dregister0(n->dsp)]= 1; + regv[dregister1(n->dsp)]= 1; + regs[dregister0(n->dsp)]= INPUT_REG; + regs[dregister1(n->dsp)]= INPUT_REG; + reg_var+=2; cadddr(args)=size(type); /* why we need this? */ } } @@ -342,7 +352,12 @@ int get_dregister(int d) { /* 使われていないレジスタを調べる */ - int i,reg; + int i,j,reg; + if (d) { + i = get_register(); + j = get_register(); + return dregister(i,j); + } for(i=MAX_TMP_FREG;i>MIN_TMP_FREG;i--) { if (fregs[i]) continue; /* 使われている */ fregs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ @@ -391,6 +406,13 @@ void free_dregister(int i) { /* いらなくなったレジスタを開放 */ + int j; + if (i>FDREG) { + j = dregister0(i); + regv[j]=regs[j]=0; + j = dregister1(i); + regv[j]=regs[j]=0; + } if (i<0||MAX_FREGISTER<i) error(-1); fregv[i]=fregs[i]=0; } @@ -399,11 +421,35 @@ get_input_dregister_var(int i,NMTBL *n,int is_code,int d) { if (is_code) { - if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; - i = REG_VAR_BASE-i; - return list3(DREGISTER,i,(int)n); - } else - return 0; + if (d) { + if(!(i*2<MAX_INPUT_REGISTER_VAR)) return 0; + i = REG_VAR_BASE-i*2; + return list3(DREGISTER,dregister(i,i+1),(int)n); + } else { + if(!(i<FREG_VAR_BASE-FREG_VAR_MIN)) return 0; + i = FREG_VAR_BASE-i; + return list3(FREGISTER,i,(int)n); + } + } else { + if (d) { + if (i==0) { + return list3(DREGISTER,dregister(4,5),(int)n); + } else if (i==1) { + return list3(DREGISTER,dregister(6,7),(int)n); + } + } else { + if (i==0) { + return list3(FREGISTER,12,(int)n); + } else if (i==1) { + return list3(FREGISTER,14,(int)n); + } else if (i==2) { + return list3(FREGISTER,6+FDREG,(int)n); + } else if (i==3) { + return list3(FREGISTER,7+FDREG,(int)n); + } + } + } + return 0; } int @@ -1151,6 +1197,13 @@ offset+=size_of_int; t = INT; reg += reg_offset; /* for duplicated floating point argument */ + } else if (tag==FREGISTER) { + /* fregs[reg]==INPUT_REG case should be considered */ + n->dsp = offset; + t = n->ty; + if(t==FLOAT) { offset+=size_of_float; reg_offset+=1; } + else if(t==DOUBLE) { offset+=size_of_double; reg_offset+=2; } + else error(-1); } else if (tag==DREGISTER) { /* fregs[reg]==INPUT_REG case should be considered */ n->dsp = offset; @@ -2041,35 +2094,73 @@ void code_dregister(int e2,int freg,int d) { - if (freg!=e2) - printf("\tmov.s %s,%s\n",fregister_name(freg),fregister_name(e2)); + if (freg!=e2) { + if (d) { + printf("\tmove %s,%s\n", + fregister_name0(freg)), + fregister_name0(e2)); + printf("\tmove %s,%s\n", + fregister_name1(freg), + fregister_name1(e2)); + } else { + printf("\tmov.s %s,%s\n",fregister_name(freg),fregister_name(e2)); + } + } fregv[freg]=1; } void code_dassign_gvar(int e2,int freg,int d) { NMTBL *n = (NMTBL*)cadr(e2); - printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),n->nm); + if (d) { + printf("\tsw %s,0(%s)\n",fregister_name0(freg),n->nm); + printf("\tsw %s,0(%s)\n",fregister_name1(freg),n->nm); + } else { + printf("\t%s.s %s,0(%s)\n",fregister_name(freg),n->nm); + } fregv[freg]=1; } void code_dassign_lvar(int e2,int freg,int d) { - printf("\t%s %s,",fstore(d),fregister_name(freg)); + if (d) { + printf("\tsw %s,",fregister_name0(freg)); + lvar(e2); + printf("\tsw %s,",fregister_name1(freg)); + e2 += size_of_double/2; + } else { + printf("\ts.s %s,",fregister_name(freg)); + } lvar(e2); fregv[freg]=1; } void code_dassign(int e2,int freg,int d) { - printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(e2)); + if (d) { + printf("\tsw %s,0(%s)\n",fregister_name0(freg),register_name(e2)); + printf("\tsw %s,4(%s)\n",fregister_name1(freg),register_name(e2)); + } else { + printf("\ts.s %s,0(%s)\n",fregister_name(freg),register_name(e2)); + } fregv[freg]=1; } void code_dassign_dregister(int e2,int d,int freg) { - if (e2!=freg) - printf("\tmov.s %s,%s\n",fregister_name(e2),fregister_name(freg)); + /* これってさ、code_dregister と同じ? */ + if (e2!=freg) { + if (d) { + printf("\tmove %s,%s\n", + fregister_name0(freg)), + fregister_name0(e2)); + printf("\tmove %s,%s\n", + fregister_name1(freg), + fregister_name1(e2)); + } else { + printf("\tmov.s %s,%s\n",fregister_name(e2),fregister_name(freg)); + } + } } static double d0 = 1.0; @@ -2099,16 +2190,31 @@ void code_dconst(int e2,int freg,int d) { double value = dcadr(e2); - char *frn = fregister_name(freg); - printf("\tli.s %s,%g\n",frn,value); + char *frn; + if (d) { + printf("\tli %s,%g\n",fregister_name0(freg),code_d1(value)); + printf("\tli %s,%g\n",fregister_name1(freg),code_d2(value)); + } else { + frn = fregister_name(freg); + printf("\tli.s %s,%g\n",frn,value); + } fregv[freg]=1; } void code_dneg(int freg,int d) { - char *frn = fregister_name(freg); - printf("\tfneg %s,%s\n",frn,frn); + char *frn; + if (d) { + code_save_stacks(); + printf("\tmove $4,%s\n", fregister_name0(freg)); + printf("\tmove $5,%s\n", fregister_name1(freg)); + printf("\tjal dpneg\n"); + set_freg(RET_DREGISTER,0); + } else { + frn = fregister_name(freg); + printf("\tfneg %s,%s\n",frn,frn); + } } void code_d2i(int freg,int creg) @@ -2131,7 +2237,7 @@ code_save_stacks(); set_creg(RET_REGISTER,1); printf("\tjal litodp\n"); - set_freg(RET_FREGISTER,0); + set_freg(RET_DREGISTER,0); fregs[freg]=1; regs[creg]=0; } @@ -2162,36 +2268,78 @@ regs[creg]=0; } -void code_d2f(int freg) {} -void code_f2d(int freg) {} -void code_f2i(int freg,int creg) {} -void code_f2u(int freg,int creg) {} -void code_i2f(int creg,int freg) {} -void code_u2f(int creg,int freg) {} +void code_d2f(int freg) { + code_save_stacks(); + /* setup arguments */ + printf("\tmove $4,%s\n", fregister_name0(freg)); + printf("\tmove $5,%s\n", fregister_name1(freg)); + printf("\tjal dptofp\n"); + set_freg(RET_FREGISTER,0); +} +void code_f2d(int freg) { + code_save_stacks(); + /* setup arguments */ + printf("\tmov.s f12,%s\n", fregister_name(freg)); + printf("\tjal fptodp\n"); + set_freg(RET_DREGISTER,0); +} + +void code_f2i(int freg,int creg) { +} + +void code_f2u(int freg,int creg) { +} + +void code_i2f(int creg,int freg) { +} + +void code_u2f(int creg,int freg) { +} void code_drgvar(int e2,int d,int freg) { char *nm = ((NMTBL*)cadr(e2))->nm; - printf("\t%s %s,%s\n",fload(d),fregister_name(freg),nm); + if (d) { + printf("\tlw %s,%s\n",fregister_name0(freg),nm); + printf("\tlw %s,%s\n",fregister_name1(freg),nm); + } else { + printf("\tl.s %s,%s\n",fregister_name(freg),nm); + } fregv[freg]=1; } void code_drlvar(int e2,int d,int freg) { - printf("\t%s %s,",fload(d),fregister_name(freg)); lvar(e2); + if (d) { + printf("\tlw %s,\n",fregister_name0(freg)); lvar(e2); + printf("\tlw %s,%s\n",fregister_name1(freg)); lvar(e2+size_of_double/2); + } else { + printf("\tl.s %s,",fregister_name(freg)); lvar(e2); + } fregv[freg]=1; } void code_cmp_drgvar(int e2,int d) { char *frn=fregister_name(freg); - int g=get_dregister(d); - char *grn=fregister_name(g); - char *nm = ((NMTBL*)cadr(e2))->nm; - printf("\t%s %s,%s\n",fload(1),grn,nm); - printf("\tfcmpu cr0,%s,%s\n",frn,grn); + int g,g1; + char *grn; + if (d) { + g=get_input_dregister_var(0,0,0,d); + g1=get_input_dregister_var(1,0,0,d); + code_drgvar(e2,d,g1); + if (freg!=g) { + printf("\tmove $3,%s\n", fregister_name0(freg)); + printf("\tmove $4,%s\n", fregister_name1(freg)); + } + printf("\tjal dcmp\n"); + } else { + g=get_dregister(d); + code_drgvar(e2,d,g); + printf("\tfc.eq.s %s,%s\n",frn,fregister_name(g)); + } free_dregister(g); fregv[freg]=0; } @@ -2199,64 +2347,103 @@ void code_cmp_drlvar(int e2,int d) { char *frn=fregister_name(freg); - int g=get_dregister(d); - char *grn=fregister_name(g); - - printf("\t%s %s,",fload(1),grn); lvar(e2); - printf("\tfcmpu cr0,%s,%s\n",frn,grn); + int g,g1; + char *grn; + if (d) { + g=get_input_dregister_var(0,0,0,d); + g1=get_input_dregister_var(1,0,0,d); + if (freg!=g) { + printf("\tmove $3,%s\n", fregister_name0(freg)); + printf("\tmove $4,%s\n", fregister_name1(freg)); + } + code_drlvar(e2,d,g1); + printf("\tjal dcmp\n"); + } else { + g=get_dregister(d); + code_drlvar(e2,d,g); + printf("\tc.eq.s %s,%s\n",frn,fregister_name(g)); + } free_dregister(g); fregv[freg]=0; } +static void +dtosop0(char *opn,int e1,int d,int cmp) +{ + char *frn; + char *grn; + if (d) { + g=get_input_dregister_var(0,0,0,d); + g1=get_input_dregister_var(1,0,0,d); + if (freg!=g) { + printf("\tmove $3,%s\n", fregister_name0(freg)); + printf("\tmove $4,%s\n", fregister_name1(freg)); + } + if (e1!=g1) { + printf("\tmove $5,%s\n", fregister_name0(e1)); + printf("\tmove $6,%s\n", fregister_name1(e1)); + } + printf("\tjal %s\n",opn); + set_freg(RET_DREGISTER,0); + } else { + frn=fregister_name(freg); + grn=fregister_name(e1); + if (cmp) { + printf("\t%s %s,%s\n",opn,frn,grn); + } else { + printf("\t%s %s,%s,%s\n",opn,frn,frn,grn); + } + } + free_dregister(e1); +} + void dtosop(int op,int e1) { char *opn=""; - char *frn=fregister_name(freg); - char *grn=fregister_name(e1); fregv[freg]=1; switch(op) { - case FADD: - case DADD: opn="fadd"; break; - case FSUB: - case DSUB: opn="fsub"; break; - case FDIV: - case DDIV: opn="fdiv"; break; - case FMUL: - case DMUL: opn="fmul"; break; - case FCMP: - printf("\tfcmpu cr0,%s,%s\n",frn,grn); - free_dregister(e1); - return; - case DCMP: - printf("\tfcmpu cr0,%s,%s\n",frn,grn); - free_dregister(e1); - return; + case FADD: dtosop0("fadd",e1,0,0); return; + case DADD: dtosop0("dpadd",e1,1,0); return; + case FSUB: dtosop0("fadd",e1,0,0); return; + case DSUB: dtosop0("dpsub",e1,1,0); return; + case FDIV: dtosop0("fadd",e1,0,0); return; + case DDIV: dtosop0("dpdiv",e1,1,0); return; + case FMUL: dtosop0("fadd",e1,0,0); return; + case DMUL: dtosop0("dpmul",e1,1,0); return; + case DCMPGE: + case DCMP: dtosop0("dpcmp",e1,1,1); return; case FCMPGE: - printf("\tfcmpu cr7,%s,%s\n",frn,grn); - free_dregister(e1); - return; - case DCMPGE: - printf("\tfcmpu cr7,%s,%s\n",frn,grn); - free_dregister(e1); - return; + case FCMP: dtosop0("c.eq.s",e1,0,1); return; default: error(-1); return; } - printf("\t%s %s,%s,%s\n",opn,frn,frn,grn); - free_dregister(e1); } void code_dassop(int op,int d) { /* we have lvalue in creg, applied floating value is in freg */ - char *frn=fregister_name(freg); - int xreg=emit_dpop(d); + char *frn; + int xreg; char *crn=register_name(creg); - printf("\t%s %s,0(%s)\n",fload(d),frn,crn); - dtosop(op,xreg); - printf("\t%s %s,0(%s)\n",fstore(d),frn,crn); - emit_dpop_free(xreg,d); + if (d) { + xreg=emit_dpop(d); + printf("\tlw %s,0(%s)\n",register_name0(freg),crn); + printf("\tlw %s,%d(%s)\n",register_name1(freg),size_of_int,crn); + dtosop(op,xreg); + printf("\tsw %s,0(%s)\n",register_name0(freg),crn); + printf("\tsw %s,%d(%s)\n",register_name1(freg),size_of_int,crn); + emit_dpop_free(xreg,d); + } else { + xreg=emit_dpop(d); + frn=fregister_name(freg); + crn=register_name(creg); + + printf("\tl.s %s,0(%s)\n",frn,crn); + dtosop(op,xreg); + printf("\ts.s %s,0(%s)\n",frn,crn); + emit_dpop_free(xreg,d); + } fregv[freg]=1; } @@ -2267,23 +2454,37 @@ char *crn; int g; char *grn,*drn; - int r; g_expr(e2); - crn=register_name(creg); - frn=fregister_name(freg); - drn=register_name(r); - grn=fregister_name(g=get_dregister(d)); + if (d) { + crn=register_name(creg); + frn=fregister_name(freg); - printf("\t%s %s,0(%s)\n",fload(d),frn,crn); - printf("\tlfs %s,0(%s)\n",grn,drn); - if (caddr(e1)>0) - printf("\tfadd %s,%s,%s\n",frn,frn,grn); - else - printf("\tfsub %s,%s,%s\n",frn,frn,grn); - printf("\t%s %s,0(%s)\n",fstore(d),frn,crn); - free_dregister(g); + printf("\tlw $4,0(%s)\n",crn); + printf("\tlw $5,%d(%s)\n",size_of_int,crn); + printf("\tli.d $6,1.0\n"); + if (caddr(e1)>0) + printf("\tjal dpadd\n"); + else + printf("\tjal dpsub\n"); + set_freg(RET_DREGISTER,0); + printf("\tsw $2,0(%s)\n",crn); + printf("\tsw $3,%d(%s)\n",size_of_int,crn); + } else { + crn=register_name(creg); + frn=fregister_name(freg); + grn=fregister_name(g=get_dregister(d)); + + printf("\tl.s %s,0(%s)\n",frn,crn); + printf("\tli.s %s,1.0\n",grn); + if (caddr(e1)>0) + printf("\tfadd %s,%s,%s\n",frn,frn,grn); + else + printf("\tfsub %s,%s,%s\n",frn,frn,grn); + printf("\ts.s %s,0(%s)\n",frn,crn); + free_dregister(g); + } fregv[freg]=1; } @@ -2296,18 +2497,39 @@ g_expr(e2); - crn=register_name(creg); - frn=fregister_name(freg); - grn=fregister_name(g=get_dregister(d)); + if (d) { + crn=register_name(creg); + frn=fregister_name(freg); + g = get_dregister(d); - printf("\t%s %s,0(%s)\n",fload(d),frn,crn); - printf("\tlfs %s,0(%s)\n",grn,drn); - if (caddr(e1)>0) - printf("\tfadd %s,%s,%s\n",grn,frn,grn); - else - printf("\tfsub %s,%s,%s\n",grn,frn,grn); - printf("\t%s %s,0(%s)\n",fstore(d),grn,crn); - free_dregister(g); + printf("\tlw $4,0(%s)\n",crn); + printf("\tlw $5,%d(%s)\n",size_of_int,crn); + printf("\tmove %s,$4\n",fregister_name0(g)); + printf("\tmove %s,$5\n",fregister_name0(g)); + printf("\tli.d $6,1.0\n"); + if (caddr(e1)>0) + printf("\tjal dpadd\n"); + else + printf("\tjal dpsub\n"); + set_freg(RET_DREGISTER,0); + printf("\tsw $2,0(%s)\n",crn); + printf("\tsw $3,%d(%s)\n",size_of_int,crn); + free_dregister(freg); + set_freg(g,0); + } else { + crn=register_name(creg); + frn=fregister_name(freg); + grn=fregister_name(g=get_dregister(d)); + + printf("\tl.s %s,0(%s)\n",frn,crn); + printf("\tli.s %s,1.0\n",grn); + if (caddr(e1)>0) + printf("\tfadd %s,%s,%s\n",frn,frn,grn); + else + printf("\tfsub %s,%s,%s\n",frn,frn,grn); + printf("\ts.s %s,0(%s)\n",grn,crn); + free_dregister(g); + } fregv[freg]=1; } @@ -2318,20 +2540,19 @@ switch(op) { case DOP+GE: case FOP+GE: - printf("\tcror 2,29,30\n"); - printf("\tbne\tcr0,L_%d\n",l1); + printf("\tbgez\tL_%d\n",l1); break; case DOP+GT: case FOP+GT: - printf("\tble\tcr0,L_%d\n",l1); + printf("\tbltz\tL_%d\n",l1); break; case DOP+EQ: case FOP+EQ: - printf("\tbne\tcr0,L_%d\n",l1); + printf("\tbeq\tL_%d\n",l1); break; case DOP+NEQ: case FOP+NEQ: - printf("\tbeq\tcr0,L_%d\n",l1); + printf("\tbne\tL_%d\n",l1); break; } }
--- a/mc-code-powerpc.c Wed May 07 13:12:58 2003 +0900 +++ b/mc-code-powerpc.c Mon May 12 00:39:57 2003 +0900 @@ -520,14 +520,14 @@ void register_usage(char *s) { -#if 1 +#if 0 int i; #endif if (chk) return; if (!lsrc) return; printf("# %d: %s:",lineno,s); printf(" creg=%s fgreg=%s",register_name(creg),fregister_name(freg)); -#if 1 +#if 0 printf("\n# regs:"); for(i=0;i<MAX_REGISTER;i++) { printf("%d",regv[i]); } printf(":");