Mercurial > hg > CbC > old > device
changeset 211:dbad3172fa14
*** empty log message ***
author | kono |
---|---|
date | Fri, 23 Apr 2004 03:27:01 +0900 |
parents | f21651f85344 |
children | 32f54ab63b35 |
files | mc-code-powerpc.c |
diffstat | 1 files changed, 431 insertions(+), 113 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-code-powerpc.c Thu Apr 22 12:55:46 2004 +0900 +++ b/mc-code-powerpc.c Fri Apr 23 03:27:01 2004 +0900 @@ -93,8 +93,8 @@ REAL_MAX_LREGISTER]; static int regv_h0[REAL_MAX_LREGISTER]; static int regv_l0[REAL_MAX_LREGISTER]; -#define regv_h(i) regv_h0[i-LREG_OFFSET] -#define regv_l(i) regv_l0[i-LREG_OFFSET] +#define regv_h(i) regv_h0[(i)-LREG_OFFSET] +#define regv_l(i) regv_l0[(i)-LREG_OFFSET] static int *regs = powerpc_regs; @@ -636,7 +636,8 @@ free_register(xreg); } -void +void + free_register(int i) { /* いらなくなったレジスタを開放 */ // printf("# free_register %d\n",i); regs[i]=0; @@ -796,7 +797,8 @@ printf("\n"); } -void +void + gexpr_init(void) { while(reg_sp > 0) { @@ -814,7 +816,8 @@ } -void +void + emit_init(void) { free_all_register(); @@ -857,7 +860,8 @@ return list2(LVAR,new_lvar(size_of_double)); } -void +void + emit_push() { int new_reg; @@ -1280,7 +1284,8 @@ #define MAX_COPY_LEN 20 -void +void + emit_copy(int from,int to,int length,int offset,int value,int det) { char *frn = register_name(from); @@ -1816,17 +1821,8 @@ void code_assign_gvar(int e2,int creg,int byte) { int r; - char *crn,*rrn; r = get_ptr_cache((NMTBL*)cadr(e2)); - rrn=register_name(r); - crn=register_name(creg); - if (byte==1) { - printf("\tstb %s,0(%s)\n",crn,rrn); - } else if (byte==size_of_short) { - printf("\tsth %s,0(%s)\n",crn,rrn); - } else { - printf("\tstw %s,0(%s)\n",crn,rrn); - } + code_assign(r,byte,creg); } void @@ -1988,7 +1984,8 @@ return (-127<v&&v<128); } -void +void + oprtc(int op,int v) { char *crn = register_name(creg); @@ -2308,7 +2305,8 @@ */ } -void +void + align(int t) { if (t!=CHAR) { @@ -2596,7 +2594,8 @@ } } -void code_dassign_gvar(int e2,int freg,int d) +void +code_dassign_gvar(int e2,int freg,int d) { int r; r = get_ptr_cache((NMTBL*)cadr(e2)); @@ -2604,7 +2603,8 @@ printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(r)); } -void code_dassign_lvar(int e2,int freg,int d) +void +code_dassign_lvar(int e2,int freg,int d) { lvar_intro(e2); if (!is_float_reg(freg)) error(-1); @@ -2612,7 +2612,8 @@ lvar(e2); } -void code_dassign(int e2,int freg,int d) +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)); @@ -2650,7 +2651,8 @@ return *j; } -void +void + code_dconst(int e2,int freg,int d) { int lb; @@ -2697,14 +2699,16 @@ } -void code_dneg(int freg,int d) +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); } -void code_d2i(int freg0) +void +code_d2i(int freg0) { char *frn; char *crn; @@ -2752,7 +2756,8 @@ 0 }; -void code_i2d(int creg0) +void +code_i2d(int creg0) { i2d_lib_used = 1; clear_ptr_cache(); @@ -2798,7 +2803,8 @@ 0 }; -void code_d2u(int freg0) +void +code_d2u(int freg0) { code_save_stacks(); clear_ptr_cache(); @@ -2835,7 +2841,8 @@ 0 }; -void code_u2d(int creg0) +void +code_u2d(int creg0) { code_save_stacks(); clear_ptr_cache(); @@ -2845,14 +2852,21 @@ set_freg(FREG_FREGISTER,0); } -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_drgvar(int e2,int d,int freg) +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_drgvar(int e2,int d,int freg) { int r; r = get_ptr_cache((NMTBL*)cadr(e2)); @@ -2860,13 +2874,15 @@ } -void code_drlvar(int e2,int d,int freg) +void +code_drlvar(int e2,int d,int freg) { lvar_intro(e2); printf("\t%s %s,",fload(d),fregister_name(freg)); lvar(e2); } -void code_cmp_drgvar(int e2,int d) +void +code_cmp_drgvar(int e2,int d) { int r; char *frn=fregister_name(freg); @@ -2878,7 +2894,8 @@ free_register(g); } -void code_cmp_drlvar(int e2,int d) +void +code_cmp_drlvar(int e2,int d) { char *frn=fregister_name(freg); int g=get_dregister(d); @@ -2890,7 +2907,8 @@ free_register(g); } -void dtosop(int op,int e1) +void +dtosop(int op,int e1) { char *opn=""; char *frn=fregister_name(freg); @@ -3045,12 +3063,14 @@ return xreg; } -void emit_dpop_free(int e1,int d) +void +emit_dpop_free(int e1,int d) { free_register(e1); } -void emit_dpush(int d) +void +emit_dpush(int d) { int new_reg; if (freg_sp>MAX_MAX) error(-1); @@ -3066,7 +3086,7 @@ /* 64bit int part */ -static +static void cond(char *s,int l1) { printf("\tb%s cr0,L_%d\n",s,l1); @@ -3082,8 +3102,8 @@ g_expr(e2); e3 = emit_lpop(); - creg = regv_h[creg_save = creg]; - tosop(CMP,regv_h[e3]); + creg = regv_h(creg_save = creg); + tosop(CMP,regv_h(e3)); switch(op) { case LOP+GT: cond(code_gt(1),l1); break; @@ -3104,8 +3124,8 @@ default: error(-1); } - creg = regv_l[creg_save]; - tosop(CMP,regv_l[e3]); + creg = regv_l(creg_save); + tosop(CMP,regv_l(e3)); switch(op) { case LOP+GT: cond(code_gt(1),l1); break; @@ -3129,12 +3149,14 @@ emit_lpop_free(e3); } -int lpop_register() +int +lpop_register() { return lreg_stack[--lreg_sp]; } -int emit_lpop() +int +emit_lpop() { int xreg,reg; xreg=lpop_register(); @@ -3147,44 +3169,78 @@ return xreg; } -void code_lregister(int e2,int reg) +void +code_lregister(int e2,int reg) { - -} - -void code_cmp_lregister(int reg) -{ - + if (creg!=e2) { + printf("\tmr %s,%s\n",lregister_name_low(creg), + lregister_name_low(e2)); + printf("\tmr %s,%s\n",lregister_name_high(creg), + lregister_name_high(e2)); + } } -void code_cmp_lrgvar(int e1,int e2) +void +code_cmp_lregister(int reg) { - + printf("\tor %s,%s,%s\n", + lregister_name_low(reg), + lregister_name_low(reg), + lregister_name_high(reg)); + printf("\tcmpwi cr0,%s,0\n",lregister_name_low(reg)); } -void code_cmp_lrlvar(int e1,int e2) +void +code_cmp_lrgvar(int e1,int creg) { - + code_lrgvar(e1,creg); + code_cmp_lregister(creg); +} + +void +code_cmp_lrlvar(int e1,int creg) +{ + code_lrlvar(e1,creg); + code_cmp_lregister(creg); } -void code_lassign(int e1,int e2) +void +code_lassign(int e2,int creg) { - + char *drn = register_name(e2); + char *crn_h = lregister_name_high(creg); + char *crn_l = lregister_name_low(creg); + + printf("\tstw %s,0(%s)\n",crn_h,drn); + printf("\tstw %s,%d(%s)\n",crn_l,size_of_int,drn); } -void code_lassign_gvar(int e1,int e2) +void +code_lassign_gvar(int e2,int creg) { - + int r; + if (!is_longlong_reg(creg)) error(-1); + r = get_ptr_cache((NMTBL*)cadr(e2)); + code_lassign(r,creg); } -void code_lassign_lvar(int e1,int e2) +void +code_lassign_lvar(int e2,int creg) { - + char *crn_h = lregister_name_high(creg); + char *crn_l = lregister_name_low(creg); + lvar_intro(e2); + printf("\tstw %s,",crn_h);lvar(e2); + printf("\tstw %s,",crn_l);lvar(e2+size_of_int); } -void code_lassign_lregister(int e2,int reg) +void +code_lassign_lregister(int e2,int reg) { - + if (e2!=creg) { + printf("\tmr %s,%s\n",lregister_name_high(e2),lregister_name_high(creg)); + printf("\tmr %s,%s\n",lregister_name_low(e2),lregister_name_low(creg)); + } } static long long ll0 = 1LL; @@ -3203,128 +3259,308 @@ return (i[1] == 1)?j[0]:j[1]; } -void code_lconst(int e1,int e2) +void +code_lconst(int e1,int creg) +{ + code_const(code_l1(lcadr(e1)),regv_l(creg)); + code_const(code_l2(lcadr(e1)),regv_h(creg)); +} + +void +code_lneg(int creg) { - + printf("\tsubfic %s,%s,0\n", + lregister_name_low(creg),lregister_name_low(creg)); + printf("\tsubfze %s,%s,0\n", + lregister_name_high(creg),lregister_name_high(creg)); } -void code_lneg(int e1,int e2) +void +code_lrgvar(int e1,int e2) +{ + int r; + char *crn_h = lregister_name_high(creg); + char *crn_l = lregister_name_low(creg); + if (!is_longlong_reg(creg)) error(-1); + r = get_ptr_cache((NMTBL*)cadr(e1)); + printf("\tlwz %s,0(%s)\n",crn_h,register_name(r)); + printf("\tlwz %s,%d(%s)\n",crn_l,size_of_int,register_name(r)); +} + +void +code_lrlvar(int e1,int creg) { - + char *crn_h = lregister_name_high(creg); + char *crn_l = lregister_name_low(creg); + lvar_intro(e1); + printf("\tlwz %s,",crn_h); lvar(e1); + printf("\tlwz %s,",crn_l); lvar(e1+size_of_int); } -void code_lrgvar(int e1,int e2) -{ - +static int asld_lib_used=0; +static char *asld_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_asld_lib(int creg0) +{ + code_save_stacks(); + clear_ptr_cache(); + asld_lib_used = 1; + printf("\tbl asld_\n"); } -void code_lrlvar(int e1,int e2) -{ - -} - -void ltosop(int e1,int e2) +void +ltosop(int op,int oreg) { - + int dx; + char *orn_h,*crn_h,*drn_h; + char *orn_l,*crn_l,*drn_l; + + if(oreg==-1) { + error(-1); + } else if (oreg<= -REG_LVAR_OFFSET) { + dx = get_lregister(); if (dx<0) error(-1); + code_rlvar(oreg+REG_LVAR_OFFSET,dx); + oreg = dx; + } + + switch(op) { + case LLSHIFT: + case LULSHIFT: + code_asld_lib(oreg); + return; + case LRSHIFT: + shift("sraw",oreg); + return; + case LURSHIFT: + shift("srw",oreg); + return; + } + orn_h = lregister_name_high(oreg); + orn_l = lregister_name_low(oreg); + crn_h = lregister_name_high(creg); + crn_l = lregister_name_low(creg); + switch(op) { + case ADD: + printf("\taddc %s,%s,%s\n",crn_l,crn_l,orn_l); + printf("\tadde %s,%s,%s\n",crn_h,crn_h,orn_h); + break; + case SUB: + printf("\tsubfc %s,%s,%s\n",crn_l,crn_l,orn_l); + printf("\tsubfe %s,%s,%s\n",crn_h,crn_h,orn_h); + break; + case LCMP: + error(-1); + break; + case BAND: + printf("\tand %s,%s,%s\n",crn_l,crn_l,orn_l); + printf("\tand %s,%s,%s\n",crn_h,crn_h,orn_h); + break; + case EOR: + printf("\txor %s,%s,%s\n",crn_l,crn_l,orn_l); + printf("\txor %s,%s,%s\n",crn_h,crn_h,orn_h); + break; + case BOR: + printf("\tor %s,%s,%s\n",crn_l,crn_l,orn_l); + printf("\tor %s,%s,%s\n",crn_h,crn_h,orn_h); + break; + case MUL: + case UMUL: + dx=get_lregister(); + drn_l = lregister_name_low(dx); + drn_h = lregister_name_high(dx); + /* + drn_l = l32( crn_l * orn_l); + drn_h = h32( crn_l * orn_l); + orn_l = l32( crn_h * orn_l); + drn_h = drn_h + orn_l; + crn_l = l32( crn_l * orn_h); + crn_h = drn_h + crn_l; + crn_l = drn_l; + */ + printf("\tmullw %s,%s,%s\n",drn_l,crn_l,orn_l); + printf("\tmulhwu %s,%s,%s\n",drn_h,crn_l,orn_l); + printf("\tmullw %s,%s,%s\n",orn_l,crn_h,orn_l); + printf("\tadd %s,%s,%s\n",drn_h,drn_h,orn_l); + printf("\tmullw %s,%s,%s\n",crn_l,orn_h,crn_l); + printf("\tadd %s,%s,%s\n",crn_l,drn_h,crn_h); + printf("\tmr %s,%s\n",crn_l,drn_l); + break; + case DIV: + printf("\tdivw %s,%s,%s\n",crn,crn,orn); + break; + case UDIV: + printf("\tdivwu %s,%s,%s\n",crn,crn,orn); + break; + case MOD: + dx=get_register(); + drn = register_name(dx); + printf("\tdivw %s,%s,%s\n",drn,crn,orn); + printf("\tmullw %s,%s,%s\n",drn,drn,orn); + printf("\tsubf %s,%s,%s\n",crn,drn,crn); + free_register(dx); + break; + case UMOD: + dx=get_register(); + drn = register_name(dx); + printf("\tdivwu %s,%s,%s\n",drn,crn,orn); + printf("\tmullw %s,%s,%s\n",drn,drn,orn); + printf("\tsubf %s,%s,%s\n",crn,drn,crn); + free_register(dx); + break; + default: + error(-1); + } + if(oreg!=creg) free_register(oreg); } -void emit_lpop_free(int e1) +void +emit_lpop_free(int xreg) { - + if (xreg>=0) + free_register(xreg); } -void emit_lpush() +void +emit_lpush() +{ + int new_reg; + if (!is_longlong(creg)) error(-1); + if (lreg_sp>MAX_MAX) error(-1); + new_reg = get_lregister(); + lreg_stack[lreg_sp++] = creg; /* push するかわりにレジスタを使う */ + lreg = creg = new_reg; +} + +void +code_i2ll(int creg) { } -void code_i2ll(int creg) +void +code_i2ull(int creg) { } -void code_i2ull(int creg) +void +code_u2ll(int creg) { } -void code_u2ll(int creg) +void +code_u2ull(int creg) { } -void code_u2ull(int creg) -{ - -} - -void code_ll2i(int creg) +void +code_ll2i(int creg) { } -void code_ll2u(int creg) +void +code_ll2u(int creg) { } -void code_ull2i(int creg) +void +code_ull2i(int creg) { } -void code_ull2u(int creg) +void +code_ull2u(int creg) { } #if FLOAT_CODE -void code_d2ll(int creg) +void +code_d2ll(int creg) { } -void code_d2ull(int creg) +void +code_d2ull(int creg) { } -void code_f2ll(int creg) +void +code_f2ll(int creg) { } -void code_f2ull(int creg) +void +code_f2ull(int creg) { } -void code_ll2d(int creg) +void +code_ll2d(int creg) { } -void code_ll2f(int creg) +void +code_ll2f(int creg) { } -void code_ull2d(int creg) +void +code_ull2d(int creg) { } -void code_ull2f(int creg) +void +code_ull2f(int creg) { } -void code_ull2ll(int creg) +void +code_ull2ll(int creg) { } -void code_ull2ull(int creg) +void +code_ull2ull(int creg) { } @@ -3332,19 +3568,101 @@ #endif -void code_lpreinc(int e1,int e2,int reg) +void +code_lpreinc(int e1,int e2,int reg) { - + char *xrn,*drn_h,*drn_l; + int i,dreg; + int dir=caddr(e1); + if (car(e2)==LREGISTER) { + printf("\taddci %s,%s,%d\n", + lregister_name_low(cadr(e2)),lregister_name_low(cadr(e2)), dir); + printf("\taddei %s,%s,0\n", + lregister_name_high(cadr(e2)),lregister_name_high(cadr(e2))); + if (cadr(reg)!=cadr(e2)) { + printf("\tmr %s,%s\n",lregister_name_low(cadr(reg)), + lregister_name_low(cadr(e2))); + printf("\tmr %s,%s\n",lregister_name_high(cadr(reg)), + lregister_name_high(cadr(e2))); + } + return; + } + g_expr(e2); + xrn = register_name(creg); + dreg=get_lregister(); if (!dreg) error(-1); + drn_h = lregister_name_high(dreg); + drn_l = lregister_name_low(dreg); + printf("\tlzw %s,%d(%s)\n",drn_l,size_of_int,xrn); + printf("\tlzw %s,0(%s)\n",drn_h,xrn); + printf("\taddci %s,%s,%d\n",drn_l,drn_l,dir); + printf("\taddei %s,%s,0\n",drn_h,drn_h,dir); + printf("\tstw %s,%d(%s)\n",drn_l,size_of_int,xrn); + printf("\tstw %s,0(%s)\n",drn_h,xrn); + set_lreg(dreg); } -void code_lpostinc(int e1,int e2,int reg) +void +code_lpostinc(int e1,int e2,int reg) { - + char *xrn,*drn_h,*drn_l; + char *nrn_h,*nrn_l; + int i,dreg,nreg; + int dir=caddr(e1); + if (car(e2)==LREGISTER) { + printf("\tmr %s,%s\n",lregister_name_low(cadr(reg)), + lregister_name_low(cadr(e2))); + printf("\tmr %s,%s\n",lregister_name_high(cadr(reg)), + lregister_name_high(cadr(e2))); + printf("\taddci %s,%s,%d\n", + lregister_name_low(cadr(e2)),lregister_name_low(cadr(e2)), dir); + printf("\taddei %s,%s,0\n", + lregister_name_high(cadr(e2)),lregister_name_high(cadr(e2))); + return; + } + g_expr(e2); + xrn = register_name(creg); + dreg=get_lregister(); if (!dreg) error(-1); + nreg=get_lregister(); if (!dreg) error(-1); + drn_h = lregister_name_high(dreg); + drn_l = lregister_name_low(dreg); + nrn_h = lregister_name_high(nreg); + nrn_l = lregister_name_low(nreg); + printf("\tlzw %s,%d(%s)\n",drn_l,size_of_int,xrn); + printf("\tlzw %s,0(%s)\n",drn_h,xrn); + printf("\taddci %s,%s,%d\n",nrn_l,drn_l,dir); + printf("\taddei %s,%s,0\n",nrn_h,drn_h,dir); + printf("\tstw %s,%d(%s)\n",nrn_l,size_of_int,xrn); + printf("\tstw %s,0(%s)\n",nrn_h,xrn); + free_register(nreg); + set_lreg(dreg); } -void code_lassop(int op) +void +code_lassop(int op) { - + int xreg; + int edx,edx0=-1; + xreg = emit_lpop(0); /* pop e3 value */ + if (!is_int_reg(creg)) error(-1); + edx = creg; + creg = use_longlong(creg); + if (regv_l(creg)==edx || regv_h(creg)==edx) { + edx0 = get_register(); if(!edx0) error(-1); + printf("# lassop\n\tmr %s,%s\n",register_name(edx0),register_name(edx)); + edx = edx0; + } + use_reg(edx); + printf("\tlwz %s,0(%s)\n",lregister_name_high(creg), + register_name(edx)); + printf("\tlwz %s,%d(%s)\n",lregister_name_low(creg), + size_of_int,register_name(edx)); + ltosop(op,xreg); + printf("\tstw %s,0(%s)\n",lregister_name_high(creg), + register_name(edx)); + printf("\tstw %s,%d(%s)\n",lregister_name_low(creg), + size_of_int,register_name(edx)); + free_register(edx); + emit_lpop_free(xreg); }