Mercurial > hg > CbC > old > device
changeset 149:0f36fdbcba9b
mips no compile error
author | kono |
---|---|
date | Mon, 14 Jul 2003 07:56:26 +0900 |
parents | e0eba2993c37 |
children | f8271009a314 |
files | mc-code-mips.c |
diffstat | 1 files changed, 392 insertions(+), 348 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-code-mips.c Sun Jul 13 23:59:26 2003 +0900 +++ b/mc-code-mips.c Mon Jul 14 07:56:26 2003 +0900 @@ -11,7 +11,6 @@ #define RODATA_EMIT_MODE 2 static void data_mode(char *name); -static void init_ptr_cache(); static void ld_indexx(int byte, int n, int xreg); static void local_table(void); static void shift(char *op, int reg); @@ -28,7 +27,7 @@ static int reg_save; static int freg_save; -static int freg,ireg; +static int freg,ireg,dreg; /* mips requires two registers for compare */ static int cmpreg = -1; @@ -59,6 +58,11 @@ #define MIN_TMP_REG 4 #define MAX_TMP_REG 11 +#define DREG_VAR_BASE 29 +#define DREG_VAR_MIN 18 +#define MIN_TMP_DREG 4 +#define MAX_TMP_DREG 11 + #define PTRC_REG 3 #define FREG_VAR_BASE 31 @@ -89,15 +93,15 @@ #define CREG_REGISTER MAX_TMP_REG #define FREG_FREGISTER (MAX_TMP_FREG+FREG_OFFSET) -#define DREG_DREGISTER (2+DFREG_OFFSET) +#define DREG_DREGISTER (2+DREG_OFFSET) -int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REL_MAX_DREGISTER]; -int powerpc_regv[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REL_MAX_DREGISTER]; +int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_DREGISTER]; +int powerpc_regv[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_DREGISTER]; -unsigned char dreg_pair0[REL_MAX_DREGISTER] = { +unsigned char dreg_pair0[REAL_MAX_DREGISTER] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 }; -unsigned char dreg_pair1[REL_MAX_DREGISTER] = { +unsigned char dreg_pair1[REAL_MAX_DREGISTER] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 }; @@ -121,19 +125,34 @@ #define register_name(i) reg_name0(i) #define fregister_name(i) reg_name0(i) +#define dregister_name0(i) reg_name1(i,dreg_pair0) +#define dregister_name1(i) reg_name1(i,dreg_pair1) -static +static char * reg_name0(int i) { if (i<=REAL_MAX_REGISTER+REAL_MAX_FREGISTER) return reg_name[i]; - else + else { error(-1); + return reg_name[0]; + } } +static char * +reg_name1(int i,unsigned char *d) +{ + if (i<=REAL_MAX_REGISTER+REAL_MAX_FREGISTER) { + error(-1); + return reg_name[0]; + } else + return reg_name[d[i-DREG_OFFSET]]; +} + + #define is_int_reg(i) (0<=i&&i<REAL_MAX_REGISTER) #define is_float_reg(i) (REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER) -#define is_double_reg(i) (REAL_MAX_REGISTER+REAL_MAX_FREGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER+REL_MAX_DREGISTER) +#define is_double_reg(i) (REAL_MAX_REGISTER+REAL_MAX_FREGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER+REAL_MAX_DREGISTER) int use_int(int i) { @@ -154,7 +173,9 @@ return i; } -static char * fload(int d); +static int code_d1(double d); +static int code_d2(double d); + static void code_save_stacks(); static void code_save_input_registers(); static void set_creg(int,int); @@ -377,7 +398,7 @@ code_dassign_lvar( (dreg_stack[i]=new_lvar(size_of_double)),reg,1); dreg_stack[i]= dreg_stack[i]-REG_LVAR_OFFSET; - free_dregister(reg); + free_register(reg); return get_register(); /* 今度は必ずある */ } } @@ -402,6 +423,7 @@ static int get_dregister1() { + int i; for(i=MAX_TMP_DREG;i>MIN_TMP_DREG;i--) { if (regs[i]) continue; /* 使われている */ if (regs[dreg_pair0[i-DREG_OFFSET]]) continue; @@ -417,7 +439,7 @@ static int get_dregister0() { - int i0,i1,reg,i; + int reg,i; /* とりあえず、空き int register pair を探す */ if ((i=get_dregister1())!=-1) { return i; @@ -480,8 +502,7 @@ int get_dregister(int d) -{ /* 使われていないレジスタを調べる */ - int i,reg; +{ if (d) { return get_dregister0(); } else { @@ -717,13 +738,13 @@ int i,j; if (d) { for(i=0;i<DREG_VAR_BASE-DREG_VAR_MIN;i++) { - if (! regs[j=(DREG_VAR_BASE-i+DREG_OFFSET])) { /* 使われていないなら */ + if (! regs[j=(DREG_VAR_BASE-i+DREG_OFFSET)]) { /* 使われていないなら */ if (regs[dreg_pair0[j]] || regs[dreg_pair1[j]]) continue; regs[DREG_VAR_BASE-i+DREG_OFFSET]=USING_REG; /*そのレジスタを使うことを宣言し*/ regv[DREG_VAR_BASE-i+DREG_OFFSET]=0; regs[dreg_pair0[j]] = regs[dreg_pair1[j]] = USING_REG; regv[dreg_pair0[j]] = regv[dreg_pair1[j]] = 0; - if (dreg_pair1[j]>max_reg_var) max_reg_var=dreg_pair[j]; + if (dreg_pair1[j]>max_reg_var) max_reg_var=dreg_pair1[j]; /* その場所を表す番号を返す */ return list3(DREGISTER,DREG_VAR_BASE-i+DREG_OFFSET,(int)n); } @@ -772,7 +793,6 @@ void code_label(int labelno) { - clear_ptr_cache(); printf("L_%d:\n",labelno); } @@ -1112,7 +1132,7 @@ void code_cmp_rlvar(int e2) { if (cmpreg==-1) cmpreg = get_register(); - code_rlvar(e1,cmpreg); + code_rlvar(e2,cmpreg); regv[cmpreg]=1; } @@ -1224,6 +1244,7 @@ } break; } + if (value) { /* creg must point top of the destination data */ /* this code is necessary for the value of assignment or function call */ /* otherwise we don't need this */ @@ -1299,22 +1320,30 @@ } } +static void +move_dreg(int reg,int dreg) +{ + if (reg!=dreg) { + printf("\tmove %s,%s\n",dregister_name0(reg), + dregister_name0(dreg)); + printf("\tmove %s,%s\n",dregister_name1(reg), + dregister_name1(dreg)); + } +} + void set_dreg(int reg,int mode) { if (!is_double_reg(reg)) error(-1); if (reg!=creg) { - if (reg!=dreg && mode) { - printf("\tmove %s,%s\n",register_name(dreg_pair0(reg)), - register_name(dreg_pari0(dreg))); - printf("\tmove %s,%s\n",register_name(dreg_pari1(reg)), - register_name(dreg_pari1(dreg))); + if (mode) { + move_dreg(reg,dreg); } free_register(creg); creg = dreg = reg; regs[dreg]=1; - regs[dreg_pair0(dreg)]=1; - regs[dreg_pair1(dreg)]=1; + regs[dreg_pair0[dreg]]=1; + regs[dreg_pair1[dreg]]=1; } } @@ -1521,7 +1550,6 @@ for(;arg_assign;arg_assign=cadr(arg_assign)) { g_expr_u(car(arg_assign)); } - clear_ptr_cache(); if (car(e2) == FNAME) { printf("\tbl\tL_%s$stub\n",fn->nm); } else { @@ -1599,10 +1627,18 @@ g_expr(e2); crn=register_name(creg); switch (car(e1)) { - case FRINDIRECT: case DRINDIRECT: - printf("\t%s %s,%d(%s)\n",fload(car(e1)==DRINDIRECT), - fregister_name(freg),offset,crn); + case FRINDIRECT: + printf("\tl.s %s,%d(%s)\n", fregister_name(freg),offset,crn); regv[creg]=0; regv[freg]=1; + creg = freg; + return FLOAT; + case DRINDIRECT: + printf("\tlw %s,%d(%s)\n", + dregister_name0(dreg),offset,crn); + printf("\tlw %s,%d(%s)\n", + dregister_name1(dreg),offset+size_of_int,crn); + regv[creg]=0; regv[dreg]=1; + creg = dreg; return DOUBLE; case CRINDIRECT: printf("\tlb %s,%d(%s)\n",crn,offset,crn); @@ -1699,7 +1735,7 @@ tosop(int op,int oreg) { int dx; - char *orn,*crn,*drn; + char *orn,*crn; if(oreg==-1) { error(-1); @@ -1755,7 +1791,7 @@ case DIV: printf("\tdivw %s,%s,%s\n",crn,crn,orn); break; - case DIV: case UDIV: case MOD: case UMOD: + case UDIV: case MOD: case UMOD: printf("\t%s $0,%s,%s\n",(op==UDIV||op==UMOD)?"divu":"div",crn,orn); printf("\t%s %s\n",(op==MOD||op==UMOD)?"mflo":"mfhi",crn); printf("\t.set noreorder\n"); @@ -2191,6 +2227,7 @@ } } +void global_table(void) { NMTBL *n; @@ -2269,60 +2306,93 @@ void code_cmp_dregister(int e2,int d) { - char *frn,*rrn,*grn; - int greg,r; - grn = register_name(greg = get_dregister(d)); - frn = register_name(e2); - float_zero_lib_used=1; - r = get_ptr_cache(&float_zero); - rrn = register_name(r); - printf("\tlfs %s,0(%s)\n",grn,rrn); - printf("\tfcmpu cr0,%s,%s\n",grn,frn); - free_register(greg); - return; + char *frn,*grn; + int greg; + + if (d) { + printf("\tli.d $6,%g\n",0.0); + code_save_stacks(); + move_dreg(4+DREG_OFFSET,freg); + printf("\tjal dpcmp\n"); + set_dreg(RET_DREGISTER,0); + return; + } else { + grn = register_name(greg = get_dregister(d)); + frn = register_name(e2); + printf("\tli.s %s,%g\n",grn,0.0); + printf("\tc.eq.s %s,%s\n",grn,frn); + free_register(greg); + return; + } } void code_dregister(int e2,int freg,int d) { if (freg!=e2) { - if (is_int_reg(e2)) error(-1); - printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2)); + if (d) { + if (!is_double_reg(e2)) error(-1); + move_dreg(freg,e2); + } else { + if (!is_float_reg(e2)) error(-1); + printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2)); + } } regv[freg]=1; } void code_dassign_gvar(int e2,int freg,int d) { - int r; - r = get_ptr_cache((NMTBL*)cadr(e2)); - if (!is_float_reg(freg)) error(-1); - printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(r)); + NMTBL *n = (NMTBL*)cadr(e2); + if (d) { + if (!is_double_reg(freg)) error(-1); + printf("\tsw %s,0(%s)\n",dregister_name0(freg),n->nm); + printf("\tsw %s,0(%s)\n",dregister_name1(freg),n->nm); + } else { + printf("\ts.s %s,0(%s)\n",fregister_name(freg),n->nm); + } regv[freg]=1; } void code_dassign_lvar(int e2,int freg,int d) { - lvar_intro(e2); - if (!is_float_reg(freg)) error(-1); - printf("\t%s %s,",fstore(d),fregister_name(freg)); + if (d) { + if (!is_double_reg(freg)) error(-1); + printf("\tsw %s,",dregister_name0(freg)); + lvar(e2); + printf("\tsw %s,",dregister_name1(freg)); + e2 += size_of_double/2; + } else { + printf("\ts.s %s,",fregister_name(freg)); + } lvar(e2); regv[freg]=1; } void code_dassign(int e2,int freg,int d) { - if (!is_float_reg(freg)) error(-1); - printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(e2)); + if (d) { + if (!is_double_reg(freg)) error(-1); + printf("\tsw %s,0(%s)\n",dregister_name0(freg),register_name(e2)); + printf("\tsw %s,4(%s)\n",dregister_name1(freg),register_name(e2)); + } else { + printf("\ts.s %s,0(%s)\n",fregister_name(freg),register_name(e2)); + } regv[freg]=1; } void code_dassign_dregister(int e2,int d,int freg) { + /* これってさ、code_dregister と同じ? */ if (e2!=freg) { - if (is_int_reg(freg)) error(-1); - printf("\tfmr %s,%s\n",fregister_name(e2),fregister_name(freg)); + if (d) { + if (!is_double_reg(freg)) error(-1); + move_dreg(freg,e2); + } else { + printf("\tmov.s %s,%s\n",fregister_name(e2),fregister_name(freg)); + } } + } static double d0 = 1.0; @@ -2352,298 +2422,241 @@ void code_dconst(int e2,int freg,int d) { - int lb; double value = dcadr(e2); - int r; - char *rrn,*frn; - frn = fregister_name(freg); - if (value==0.0) { - float_zero_lib_used=1; - r = get_ptr_cache(&float_zero); - rrn = register_name(r); - printf("\tlfs %s,0(%s)\n",frn,rrn); - return; - } - if (value==1.0) { - float_one_lib_used=1; - r = get_ptr_cache(&float_one); - rrn = register_name(r); - printf("\tlfs %s,0(%s)\n",frn,rrn); - return; + char *frn; + if (d) { + printf("\tli.d %s,%g\n",dregister_name0(freg),value); + } else { + frn = fregister_name(freg); + printf("\tli.s %s,%g\n",frn,value); } - rrn = register_name((r=get_register())); - printf(" \t.data\n\t.align 3\n"); - lb=fwdlabel(); - printf("L_%d:\n",lb); - if (d) { - printf("\t.long\t0x%x,0x%x\n",code_d2(value),code_d1(value)); - } else { - printf("\t.long\t0x%x\n",code_f(value)); - } - if (output_mode==TEXT_EMIT_MODE) { - printf(".text\n"); - } else { - text_mode(); - } - printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",rrn,lb,code_base); - printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",rrn,lb,code_base,rrn); - if (d) { - printf("\tlfd %s,0(%s)\n",frn,rrn); - } else { - printf("\tlfs %s,0(%s)\n",frn,rrn); - } - free_register(r); regv[freg]=1; } void code_dneg(int freg,int d) { - char *frn = fregister_name(freg); - if (is_int_reg(freg)) error(-1); - printf("\tfneg %s,%s\n",frn,frn); + char *frn; + if (d) { + code_save_stacks(); + move_dreg(4+DREG_OFFSET,freg); + printf("\tjal dpneg\n"); + set_dreg(RET_DREGISTER,0); + } else { + frn = fregister_name(freg); + printf("\tfneg %s,%s\n",frn,frn); + } } void code_d2i(int freg0) { - char *frn; - char *crn; - int e2 = new_lvar(size_of_double); - - freg0 = use_double(freg0); - frn = fregister_name(freg0); - creg = use_int(creg); - crn = register_name(creg); - - freg = freg0; - free_lvar(e2); - printf("\tfctiwz %s,%s\n",frn,frn); - lvar_intro(e2); - printf("\tstfd %s,",frn); lvar(e2); - lvar_intro(e2+size_of_double-size_of_int); - printf("\tlwz %s,",crn); lvar(e2+size_of_double-size_of_int); + code_save_stacks(); + set_dreg(RET_DREGISTER,1); + printf("\tjal dptoli\n"); + set_creg(RET_REGISTER,0); + regv[freg]=0; regv[creg]=1; } -static int i2d_lib_used=0; -static char *i2d_lib[] = { -".data", -/* ".literal8", */ -" .align 3", -"__i2dLC0:", -" .long 1127219200", -" .long -2147483648", -".text", -" .align 2", -"i2d_:", -" mflr r0", -" bcl 20,31,__i2dL1$pb", -"__i2dL1$pb:", -" mflr r10", -" mtlr r0", -" xoris r3,r3,0x8000", -" stw r3,-28(r30)", -" lis r0,0x4330", -" stw r0,-32(r30)", -" lfd f0,-32(r30)", -" addis r9,r10,ha16(__i2dLC0-__i2dL1$pb)", -" lfd f1,lo16(__i2dLC0-__i2dL1$pb)(r9)", -" fsub f1,f0,f1", -" blr", -0 -}; - void code_i2d(int creg0) { - i2d_lib_used = 1; - clear_ptr_cache(); code_save_stacks(); set_creg(RET_REGISTER,1); - printf("\tbl i2d_\n"); - set_freg(RET_FREGISTER,0); + printf("\tjal litodp\n"); + set_freg(RET_DREGISTER,0); regv[freg]=1; + regv[creg]=0; } -static int d2u_lib_used=0; -static char *d2u_lib[] = { -/* ".literal8", */ -" .align 3", -"__d2uLC0:", -" .long 1105199104", -" .long 0", -".text", -" .align 2", -"d2u_:", -" mflr r0", -" bcl 20,31,__d2uL1$pb", -"__d2uL1$pb:", -" mflr r10", -" mtlr r0", -" addis r9,r10,ha16(__d2uLC0-__d2uL1$pb)", -" lfd f0,lo16(__d2uLC0-__d2uL1$pb)(r9)", -" fcmpu cr0,f1,f0", -" cror 2,1,2", -" beq- cr0,__d2uL2", -" fctiwz f0,f1", -" stfd f0,-32(r30)", -" lwz r3,-28(r30)", -" blr", -"__d2uL2:", -" addis r9,r10,ha16(__d2uLC0-__d2uL1$pb)", -" lfd f0,lo16(__d2uLC0-__d2uL1$pb)(r9)", -" fsub f0,f1,f0", -" fctiwz f0,f0", -" stfd f0,-24(r30)", -" lwz r3,-20(r30)", -" xoris r3,r3,0x8000", -" blr", -0 -}; - void code_d2u(int freg0) { code_save_stacks(); - clear_ptr_cache(); - d2u_lib_used=1; - set_freg(RET_FREGISTER,1); - printf("\tbl d2u_\n"); + set_dreg(RET_DREGISTER,1); + printf("\tjal dptoul\n"); set_creg(RET_REGISTER,0); regv[freg]=1; } -static int u2d_lib_used=0; -static char *u2d_lib[] = { -".data", -/* ".literal8", */ -" .align 3", -"__u2dLC1:", -" .long 1127219200", -" .long 0", -".text", -" .align 2", -"u2d_:", -" mflr r0", -" bcl 20,31,__u2dL2$pb", -"__u2dL2$pb:", -" mflr r10", -" mtlr r0", -" stw r3,-28(r30)", -" lis r0,0x4330", -" stw r0,-32(r30)", -" lfd f0,-32(r30)", -" addis r9,r10,ha16(__u2dLC1-__u2dL2$pb)", -" lfd f1,lo16(__u2dLC1-__u2dL2$pb)(r9)", -" fsub f1,f0,f1", -" blr", -0 -}; - void code_u2d(int creg0) { code_save_stacks(); - clear_ptr_cache(); - u2d_lib_used = 1; set_creg(RET_REGISTER,1); - printf("\tbl u2d_\n"); - set_freg(FREG_FREGISTER,0); + printf("\tjal ultodp\n"); + set_dreg(RET_DREGISTER,0); regv[freg]=1; } -void code_d2f(int freg) { } -void code_f2d(int freg) { } -void code_f2i(int freg) { code_d2i(freg); } -void code_f2u(int freg) { code_d2u(freg); } -void code_i2f(int creg) { code_i2d(creg); } -void code_u2f(int creg) { code_u2d(creg); } +void code_d2f(int freg) { + code_save_stacks(); + set_dreg(RET_DREGISTER,1); + printf("\tjal dptofp\n"); + set_freg(RET_FREGISTER,0); +} + +void code_f2d(int freg) { + code_save_stacks(); + set_freg(RET_FREGISTER,1); + printf("\tjal fptodp\n"); + set_dreg(RET_DREGISTER,0); +} + +void code_f2i(int freg) { + printf("\ttrunc.w.s %s,%s,%s\n",register_name(freg), + register_name(freg),register_name(ireg)); + creg = ireg; +} + +void code_f2u(int freg) { + printf("\ttrunc.w.s %s,%s,%s\n",register_name(freg), + register_name(freg),register_name(ireg)); + creg = ireg; +} + +void code_i2f(int creg0) { + printf("\tcvt.s.w %s,%s\n",register_name(freg),register_name(freg)); + creg = freg; +} + +void code_u2f(int creg0) { + printf("\tcvt.s.w %s,%s\n",register_name(freg),register_name(freg)); + creg = freg; +} void code_drgvar(int e2,int d,int freg) { - int r; - r = get_ptr_cache((NMTBL*)cadr(e2)); - printf("\t%s %s,0(%s)\n",fload(d),fregister_name(freg),register_name(r)); + char *nm = ((NMTBL*)cadr(e2))->nm; + if (d) { + printf("\tlw %s,%s\n",dregister_name0(freg),nm); + printf("\tlw %s,%s\n",dregister_name1(freg),nm); + } else { + printf("\tl.s %s,%s\n",fregister_name(freg),nm); + } regv[freg]=1; } void code_drlvar(int e2,int d,int freg) { - lvar_intro(e2); - printf("\t%s %s,",fload(d),fregister_name(freg)); lvar(e2); + if (d) { + printf("\tlw %s,\n",dregister_name0(freg)); lvar(e2); + printf("\tlw %s,\n",dregister_name1(freg)); lvar(e2+size_of_double/2); + } else { + printf("\tl.s %s,",fregister_name(freg)); lvar(e2); + } regv[freg]=1; } void code_cmp_drgvar(int e2,int d) { - int r; - char *frn=fregister_name(freg); - int g=get_dregister(d); - char *grn=fregister_name(g); - r = get_ptr_cache((NMTBL*)cadr(e2)); - printf("\t%s %s,0(%s)\n",fload(1),grn,register_name(r)); - printf("\tfcmpu cr0,%s,%s\n",frn,grn); - free_register(g); - regv[freg]=0; + char *frn; + int g; + if (d) { + code_save_stacks(); + set_dreg(RET_DREGISTER,1); + code_drgvar(e2,d,RET_DREGISTER+2); + printf("\tjal dcmp\n"); + regv[dreg]=0; + } else { + frn=fregister_name(freg); + g=get_dregister(d); + code_drgvar(e2,d,g); + printf("\tfc.eq.s %s,%s\n",frn,fregister_name(g)); + free_register(g); + regv[freg]=0; + } } void code_cmp_drlvar(int e2,int d) { char *frn=fregister_name(freg); - int g=get_dregister(d); - char *grn=fregister_name(g); + int g; + if (d) { + code_save_stacks(); + set_dreg(RET_DREGISTER,1); + code_drgvar(e2,d,RET_DREGISTER+2); + printf("\tjal dcmp\n"); + regv[dreg]=0; + } else { + g=get_dregister(d); + code_drlvar(e2,d,g); + printf("\tc.eq.s %s,%s\n",frn,fregister_name(g)); + free_register(g); + regv[freg]=0; + } +} - lvar_intro(e2); - printf("\t%s %s,",fload(1),grn); lvar(e2); - printf("\tfcmpu cr0,%s,%s\n",frn,grn); - free_register(g); - regv[freg]=0; +static void +dtosop0(char *opn,int e1,int d,int cmp) +{ + char *frn; + char *grn; + if (d) { + code_save_stacks(); + set_dreg(RET_DREGISTER,1); + move_dreg(RET_DREGISTER+2,e1); + printf("\tjal %s\n",opn); + } 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_register(e1); } + void dtosop(int op,int e1) { - char *opn=""; - char *frn=fregister_name(freg); - char *grn=fregister_name(e1); regv[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: - case DCMP: - printf("\tfcmpu cr0,%s,%s\n",frn,grn); - free_register(e1); - return; - case FCMPGE: + 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: - printf("\tfcmpu cr7,%s,%s\n",frn,grn); - free_register(e1); - return; + case DCMP: dtosop0("dpcmp",e1,1,1); return; + case FCMPGE: dtosop0("c.le.s",e1,0,1); return; + case FCMP: dtosop0("c.eq.s",e1,0,1); return; default: - error(-1); return; + error(-1); return; } - printf("\t%s %s,%s,%s\n",opn,frn,frn,grn); - regv[freg]=1; - free_register(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); - if (!is_float_reg(freg)) error(-1); - 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); - regv[freg]=1; + if (d) { + xreg=emit_dpop(d); + printf("\tlw %s,0(%s)\n",dregister_name0(freg),crn); + printf("\tlw %s,%d(%s)\n",dregister_name1(freg),size_of_int,crn); + dtosop(op,xreg); + printf("\tsw %s,0(%s)\n",dregister_name0(freg),crn); + printf("\tsw %s,%d(%s)\n",dregister_name1(freg),size_of_int,crn); + emit_dpop_free(xreg,d); + creg = dreg; + } 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); + creg = freg; + } + regv[creg]=1; } @@ -2652,33 +2665,42 @@ char *frn; char *crn; int g; - char *grn,*drn; - int r; - r = get_ptr_cache(&float_one); - float_one_lib_used=1; + char *grn; - if (car(e2)==DREGISTER||car(e2)==FREGISTER) { - error(-1); /* unspported now */ - } 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); - if (!is_float_reg(freg)) error(-1); - printf("\t%s %s,0(%s)\n",fstore(d),frn,crn); - free_register(g); - regv[freg]=1; - regv[ireg]=0; - creg = freg; + code_save_stacks(); + set_dreg(RET_DREGISTER,0); + 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"); + printf("\tsw $2,0(%s)\n",crn); + printf("\tsw $3,%d(%s)\n",size_of_int,crn); + creg = dreg; + } 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_register(g); + creg = freg; + } + regv[creg]=1; } void @@ -2686,57 +2708,76 @@ char *frn; char *crn; int g; - char *grn,*drn; - int r; - r = get_ptr_cache(&float_one); - float_one_lib_used=1; + char *grn; - if (car(e2)==DREGISTER||car(e2)==FREGISTER) { - error(-1); /* unspported now */ - } 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); + g = get_dregister(d); + set_dreg(RET_DREGISTER,0); + printf("\tlw $4,0(%s)\n",crn); + printf("\tlw $5,%d(%s)\n",size_of_int,crn); + move_dreg(g,4+DREG_OFFSET); + printf("\tli.d $6,1.0\n"); + if (caddr(e1)>0) + printf("\tjal dpadd\n"); + else + printf("\tjal dpsub\n"); + set_dreg(RET_DREGISTER,0); + printf("\tsw $2,0(%s)\n",crn); + printf("\tsw $3,%d(%s)\n",size_of_int,crn); + free_register(freg); + set_dreg(g,0); + creg = g; + } else { + crn=register_name(creg); + frn=fregister_name(freg); + grn=fregister_name(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); - if (!is_float_reg(freg)) error(-1); - printf("\t%s %s,0(%s)\n",fstore(d),grn,crn); - free_register(g); - regv[freg]=1; - regv[ireg]=0; - creg = freg; + 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_register(g); + creg = freg; + } + regv[creg]=1; + } void drexpr(int e1, int e2,int l1, int op) { - g_expr(list3(((op==DOP+GE)?DCMPGE:DCMP),e1,e2)); + g_expr(list3(((op==FOP+EQ||op==FOP+NEQ)?DCMP:FCMPGE),e1,e2)); switch(op) { - case DOP+GE: - case FOP+GE: - printf("\tcror 2,29,30\n"); - printf("\tbne\tcr0,L_%d\n",l1); - break; - case DOP+GT: - case FOP+GT: - printf("\tble\tcr0,L_%d\n",l1); - break; - case DOP+EQ: - case FOP+EQ: - printf("\tbne\tcr0,L_%d\n",l1); - break; - case DOP+NEQ: - case FOP+NEQ: - printf("\tbeq\tcr0,L_%d\n",l1); - break; + case DOP+GE: + printf("\tbgez\tL_%d\n",l1); + break; + case DOP+GT: + printf("\tbltz\tL_%d\n",l1); + break; + case DOP+EQ: + printf("\tbeq\tL_%d\n",l1); + break; + case DOP+NEQ: + printf("\tbne\tL_%d\n",l1); + break; + case FOP+GE: + printf("\tbc1tl\tL_%d\n",l1); + break; + case FOP+GT: + printf("\tbc1tl\tL_%d\n",l1); + break; + case FOP+EQ: + printf("\tbc1f\tL_%d\n",l1); + break; + case FOP+NEQ: + printf("\tbc1f\tL_%d\n",l1); + break; } } @@ -2746,7 +2787,7 @@ xreg=pop_fregister(); if (xreg<= -REG_LVAR_OFFSET) { reg = get_dregister(d); - code_drlvar(REG_LVAR_OFFSET+xreg,1,reg); + code_drlvar(REG_LVAR_OFFSET+xreg,d,reg); free_lvar(REG_LVAR_OFFSET+xreg); regv[reg]=1; xreg=reg; } @@ -2762,7 +2803,7 @@ { int new_reg; if (freg_sp>MAX_MAX) error(-1); - new_reg = get_dregister(1); + new_reg = get_dregister(d); freg_stack[freg_sp++] = freg; /* push するかわりにレジスタを使う */ creg = freg = new_reg; regv[freg]=1; @@ -2779,10 +2820,17 @@ reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; } } + for(i=0;i<dreg_sp;i++) { + if ((reg=dreg_stack[i])>=0) { + code_dassign_lvar( + (dreg_stack[i]=new_lvar(size_of_double)),reg,1); + dreg_stack[i]= dreg_stack[i]-REG_LVAR_OFFSET; + } + } for(i=0;i<freg_sp;i++) { if ((reg=freg_stack[i])>=0) { code_dassign_lvar( - (freg_stack[i]=new_lvar(size_of_double)),reg,1); + (freg_stack[i]=new_lvar(size_of_float)),reg,0); freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET; } } @@ -2799,13 +2847,9 @@ void code_closing() { - if (d2u_lib_used) emit_lib(d2u_lib); - if (u2d_lib_used) emit_lib(u2d_lib); - if (float_one_lib_used) emit_lib(float_one_lib); - if (float_zero_lib_used) emit_lib(float_zero_lib); - if (i2d_lib_used) emit_lib(i2d_lib); global_table(); /* printf("\t.ident \"Micro-C compiled\"\n"); */ + fclose(asi); } /* end */