Mercurial > hg > CbC > old > device
changeset 90:07e3113c3c13
*** empty log message ***
author | kono |
---|---|
date | Fri, 07 Mar 2003 03:09:02 +0900 |
parents | 917947ffeb7c |
children | 9b1aeb62e0b9 |
files | Changes mc-code-powerpc.c test/float.c |
diffstat | 3 files changed, 194 insertions(+), 172 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Thu Mar 06 23:47:42 2003 +0900 +++ b/Changes Fri Mar 07 03:09:02 2003 +0900 @@ -2008,3 +2008,5 @@ 全部、stub にしておいて、.set で書き換えるという手もあるけど。 (さすがに一日ではできないか...) + +なんか整数から浮動小数点への変換はじぶんでやらないとだめなのね。
--- a/mc-code-powerpc.c Thu Mar 06 23:47:42 2003 +0900 +++ b/mc-code-powerpc.c Fri Mar 07 03:09:02 2003 +0900 @@ -92,6 +92,7 @@ void local_table(void); void text_mode(void); void data_mode(char *name); +int init_ptr_cache(); char *register_name(int i,int byte); int register_var(int r); @@ -264,6 +265,7 @@ int i; for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; regv[i]=0;rname[i]=i;} free_all_register(); + init_ptr_cache(); reg_sp = 0; text_mode(); } @@ -329,6 +331,15 @@ int ptr_cache=0; int +init_ptr_cache() +{ + int i; + for(i=0;i<MAX_PTR_CACHE;i++) { + ptr_cache=glist3(0,ptr_cache,0); + } +} + +int clear_ptr_cache() { int ptcptr=ptr_cache; @@ -341,15 +352,6 @@ } } -int -init_ptr_cache() -{ - int i; - for(i=0;i<MAX_PTR_CACHE;i++) { - ptr_cache=glist3(0,ptr_cache,0); - } -} - int get_ptr_cache(char *name) @@ -407,25 +409,26 @@ void code_lvar(int e2) { - printf("\tla %d(r1),%s\n",e2,register_name(creg)); + printf("\tla %s,%d(r1),%s\n",register_name(creg),e2); } void code_register(int e2) { - printf("\tmr %s,%s\n",register_name(creg),register_name(e2)); + if (creg!=e2) + printf("\tmr %s,%s\n",register_name(creg),register_name(e2)); } void code_rlvar(int e2) { - printf("\tlwz %d(r1),%s\n",e2,register_name(creg)); + printf("\tlwz %s,%d(r1),%s\n",register_name(creg),e2); } void code_crlvar(int e2) { - printf("\tlbz %d(r1),%s\n",e2,register_name(creg)); + printf("\tlbz %s,%d(r1),%s\n",register_name(creg),e2); printf("\textsb %s,%s\n",register_name(creg),register_name(creg)); } @@ -940,6 +943,7 @@ free_register(jmp); } regv[creg]=1; + clear_ptr_cache(); } void @@ -969,41 +973,65 @@ void rindirect(int e1) /* *(p +5 ) */ { - char *op; + char *op,*crn; int e2,e3,byte; e3 = cadr(e2 = cadr(e1)); g_expr(e2); + crn=register_name(creg); switch (car(e1)) { case FRINDIRECT: case DRINDIRECT: - printf("\t%s (%s)\n",fload(car(e1)==DRINDIRECT),register_name(creg)); - break; - case CRINDIRECT: case RINDIRECT: - op = ((byte = (car(e1) == CRINDIRECT)) ? "movsbl" : "movl"); - printf("\t%s (%s),%s\n",op,register_name(creg),register_name(creg)); + printf("\t%s %s,(%s)\n",fload(car(e1)==DRINDIRECT), + register_name(freg),crn); + regv[creg]=0; regv[freg]=1; + break; + case CRINDIRECT: + printf("\tlbz %s,(%s)\n",crn,crn); + printf("\textsb %s,%s\n",crn,crn); + break; + case RINDIRECT: + printf("\tlwz %s,(%s)\n",crn,crn); + break; } } - void code_assign_gvar(int e2,int byte) { - if (byte) use_data_reg(creg,1); - printf("\t%s %s,%s\n",move(byte),register_name(creg,byte),(char *)caddr(e2)); + int r; + char *crn,*rrn; + r = get_ptr_cache((char*)caddr(e2)); + rrn=register_name(r); + crn=register_name(creg); + if (byte) { + printf("\tstb %s,(%s)\n",crn,rrn); + } else { + printf("\tstw %s,(%s)\n",crn,rrn); + } } void code_assign_lvar(int e2,int byte) { - if (byte) use_data_reg(creg,1); - printf("\t%s %s,%d(%%ebp)\n",move(byte),register_name(creg,byte),e2); + char *crn; + crn=register_name(creg); + if (byte) { + printf("\tstb %s,%d(r1)\n",crn,e2); + } else { + printf("\tstw %s,%d(r1)\n",crn,e2); + } } void code_assign_register(int e2,int byte) { - printf("\tmovl %s,%s\n",register_name(creg),register_name(e2,0)); + printf("\tmr %s,%s\n",register_name(e2),register_name(creg)); } void code_assign(int e2,int byte) { - printf("\t%s %s,(%s)\n",move(byte),register_name(creg,byte),register_name(e2,0)); + char *drn=register_name(dreg); + if (byte) { + printf("\tstb %s,(%s)\n",crn,drn); + } else { + printf("\tstw %s,(%s)\n",crn,drn); + } } @@ -1014,23 +1042,29 @@ creg = reg = e2; tosop(op,xreg); creg = xreg; - printf("\tmovl %s,%s\n",register_name(reg,0),register_name(creg)); + printf("\tmr %s,%s\n",register_name(creg),register_name(reg)); } void code_assop(int op,int byte) { - char *xrn; + char *xrn,*crn,*drn; int xreg; - int edx = edx_setup(); + int edx = get_register(); if(!edx) error(-1); xrn = register_name(xreg = emit_pop(0),0); /* pop e3 value */ regv[xreg]=regs[xreg]=1; printf("\tmovl %s,%s # assop \n",register_name(creg),register_name(edx,0)); regv[edx]=1; ld_indexx(byte,0,edx); tosop(op,xreg); - printf("\t%s %s,(%s)\n",byte ? "movb" : "movl",register_name(creg,byte),register_name(edx,0)); - edx_cleanup(); + crn = register_name(creg); + drn = register_name(edx); + if (byte) { + printf("\tstb %s,(%s)\n",crn,drn); + } else { + printf("\tstw %s,(%s)\n",crn,drn); + } + free_register(edx); emit_pop_free(xreg); } @@ -1044,116 +1078,72 @@ switch(op) { case LSHIFT: case ULSHIFT: - shift("sall",oreg); + shift("slw",oreg); return; case RSHIFT: - shift("sarl",oreg); + shift("srw",oreg); return; case URSHIFT: - shift("shrl",oreg); + shift("sraw",oreg); return; } - if(oreg==-1) { - printf("\tpopl %s\n",register_name(dreg,0)); - oreg = dreg; - regv[dreg]=1; - } - regv[oreg]=1; regs[oreg]=1; orn = register_name(oreg,0); crn = register_name(creg); switch(op) { case ADD: - printf("\taddl %s,%s\n",orn,crn); + printf("\tadd %s,%s,%s\n",crn,orn,crn); break; case SUB: - printf("\tsubl %s,%s\n",orn,crn); + printf("\tsub %s,%s,%s\n",crn,orn,crn); break; case BAND: - printf("\tandl %s,%s\n",orn,crn); + printf("\tand %s,%s,%s\n",crn,orn,crn); break; case EOR: - printf("\txorl %s,%s\n",orn,crn); + printf("\txor %s,%s,%s\n",crn,orn,crn); break; case BOR: - printf("\torl %s,%s\n",orn,crn); + printf("\torl %s,%s,%s\n",crn,orn,crn); break; case MUL: case UMUL: - printf("\t%s %s,%s\n","imull",orn,crn); + printf("\t%mullw %s,%s,%s\n",crn,orn,crn); break; case DIV: + printf("\t%divw %s,%s,%s\n",crn,orn,crn); + break; case UDIV: - use_register(creg,REG_EAX,1); - edx_setup(); - orn = register_name(oreg,0); - if (op==DIV) - printf("\tcltd\n\tdivl %s\n",orn); - else - printf("\txor %%edx,%%edx\n\tidivl %s\n",orn); - edx_cleanup(); + printf("\t%divwu %s,%s,%s\n",crn,orn,crn); break; case MOD: + dx=get_register(); + drn = register_name(drn); + printf("\t%divwu %s,%s,%s\n",drn,orn,crn); + printf("\t%mullw %s,%s,%s\n",drn,drn,crn); + printf("\t%subf %s,%s,%s\n",drn,drn,orn); + free_register(creg); + creg=dx; + break; case UMOD: - use_register(creg,REG_EAX,1); - edx_setup(); - orn = register_name(oreg,0); - if (op==DIV) - printf("\tcltd\n\tdivl %s\n",orn); - else - printf("\txor %%edx,%%edx\n\tidivl %s\n",orn); - dx = virtual(REG_EDX); - if (dx!=creg) { - rname[dx]=rname[creg]; - rname[creg]=REG_EDX; - } - edx_cleanup(); + dx=get_register(); + drn = register_name(drn); + printf("\t%divwu %s,%s,%s\n",drn,orn,crn); + printf("\t%mullw %s,%s,%s\n",drn,drn,crn); + printf("\t%subf %s,%s,%s\n",drn,drn,orn); + free_register(creg); + creg=dx; break; } - if (oreg!=dreg&&oreg>=0) - free_register(oreg); -} - -static int edx_stack=0; - -int -edx_setup() -{ - int edx_save; - /* make real EDX register empty */ - if (free_register_count()<1) { - for(edx_save = 0;edx_save==dreg||edx_save==creg;edx_save++); - printf("\tpushl %s\n",register_name(edx_save,0)); - edx_stack = list3(edx_save,edx_stack,0); - } else { - edx_save = get_register(); - edx_stack = list3(edx_save,edx_stack,1); - } - regv[edx_save]=0; - use_register(edx_save,REG_EDX,0); - return edx_save; + if(oreg!=cre) free_register(oreg); } void -edx_cleanup() -{ - if (caddr(edx_stack)==0) { - printf("\tpopl %s\n",register_name(car(edx_stack),0)); - } else - free_register(car(edx_stack)); - edx_stack = cadr(edx_stack); -} - -void shift(char *op, int reg) { - if (reg>=0) { - use_register(reg,REG_ECX,1); - } else { - use_register(dreg,REG_ECX,0); - printf("\tpopl %%ecx\n"); - } - printf("\t%s %%cl,%s\n",op,register_name(creg)); + char *crn = register_name(creg)); + char *rrn = register_name(reg)); + printf("\t%s %s,%s,%s\n",op,crn,rrn,crn); } void @@ -1161,11 +1151,13 @@ { char *op; - op = byte ? "movsbl" : "movl"; - if (n) - printf("\t%s %d(%s),%s\n",op,n,register_name(xreg,0),register_name(creg,byte)); - else - printf("\t%s (%s),%s\n",op,register_name(xreg,0),register_name(creg,byte)); + if (byte) { + printf("\tlbz %s,%d(%s),%s\n",register_name(creg),n, + register_name(xreg)); + printf("\textsb %s,%s\n",crn,crn); + } else + printf("\tlwz %s,%d(%s),%s\n",register_name(creg),n, + register_name(xreg)); } void @@ -1173,8 +1165,7 @@ { /* used in dosiwtch() */ if(chk) return; - use_register(creg,csreg,0); - printf("\tcmpl $%d,%s\n",e,register_name(creg)); + printf("\tcmpw cr0,%s,%d\n",register_name(csreg),e); } void @@ -1196,8 +1187,8 @@ void rexpr(int e1, int l1, char *s) { - g_expr(list3(SUB,cadr(e1),caddr(e1))); - printf("\tj%s\t_%d\n",s,l1); + g_expr(list3(CMP,cadr(e1),caddr(e1))); + printf("\tb%s cr0,_%d\n",s,l1); } @@ -1205,7 +1196,7 @@ jcond(int l, char cond) { if (chk) return; - printf("\tj%s\t_%d\n",cond?"ne":"e",l); + printf("\tb%s cr0,_%d\n",cond?"ne":"eq",l); } void @@ -1213,14 +1204,7 @@ { control=0; if (chk) return; - printf("\tjmp\t_%d\n",l); - /* align? */ - /* - this is not allowed because of ? operator - regv[creg]=regv[dreg]=0; - use_register(creg,REG_EAX,0); - use_register(dreg,REG_EBX,0); - */ + printf("\tb\t_%d\n",l); } void @@ -1321,7 +1305,7 @@ void code_set_fixed_creg(int mode) { - use_register(creg,REG_EAX,mode); + creg=11; } void @@ -1491,38 +1475,30 @@ char * fstore(int d) { - return use? - (d?"fstl":"fsts"): - (d?"fstpl":"fstps") - ; -} - -char * -fstore_u(int d) -{ - return d?"fstpl":"fstps"; + return (d?"stfd":"stfs"); } char * fload(int d) { - return d?"fldl":"flds"; + return d?"lfd":"lfs"; } - void code_dassign_gvar(int e2,int d) { - printf("\t%s %s\n",fstore(d),(char *)caddr(e2)) ; + int r; + r = get_ptr_cache((char*)caddr(e1)); + printf("\t%s %s,(%s)\n",fstore(d),register_name(freg),register_name(r)); } void code_dassign_lvar(int e2,int d) { - printf("\t%s %d(%%ebp)\n",fstore(d),e2); + printf("\t%s %s,%d(r1)\n",fstore(d),register_name(creg),e2); } void code_dassign(int e2,int d) { - printf("\t%s (%s)\n",fstore(d),register_name(e2,0)); + printf("\t%s %s,(%s)\n",fstore(d),register_name(creg),register_name(e2)); } static double d0 = 1.0; @@ -1545,6 +1521,9 @@ { int lb; double d = dcadr(e2); + int r; + char *rrn; + rrn = register_name((r=get_register())); if (d==0.0) { printf("\tfldz\n"); return; @@ -1561,58 +1540,90 @@ } else { text_mode(); } - printf("\tfldl _%d\n",lb); + printf("\taddis %s,r31,ha16(_%d-%s)\n",rrn,lb,code_base); + printf("\tla %s,lo16(_%d-%s)(%s)\n",rrn,lb,code_base,rrn); + printf("\tlfd %s,%(s)\n",register_name(freg),rrn); + free_register(r); } void code_dneg() { - printf("\tfchs\n"); + char *frn = register_name(freg); + printf("\tfneg %s,%s\n",freg); } void code_d2i() { - /* fuck you! */ - printf("\tlea -%d(%%esp),%%esp\n",size_of_int*2); - printf("\tfnstcw (%%esp)\n"); - printf("\tmovl (%%esp), %s\n",register_name(creg)); - printf("\tmovb $12, 1(%%esp)\n"); - printf("\tfldcw (%%esp)\n"); - printf("\tmovl %s, (%%ebp)\n",register_name(creg)); - printf("\tfistpl %d(%%esp)\n",size_of_int); - printf("\tfldcw (%%esp)\n"); - printf("\tpopl %s\n",register_name(creg)); - printf("\tpopl %s\n",register_name(creg)); + char *frn = register_name(freg); + disp-=size_of_double; + printf("\tfctiwz %s,%s\n",); + printf("\tstfd %s,%d(r1)\n",disp); + printf("\tlwz %s,%d(r1)\n",crn,disp+size_of_double-size_of_int); + fregs[freg]=0; + regs[creg]=1; } void code_i2d() { - printf("\tpushl %s\n",register_name(creg)); - printf("\tfildl (%%esp)\n"); - printf("\tlea %d(%%esp),%%esp\n",size_of_int); + char *frn = register_name(freg); + char *crn = register_name(creg); + int dreg = get_register(); + char *drn = register_name(dreg); + disp-=size_of_double; + + printf("\tlis %s,0x4330\n",drn); + printf("\txoris %s,%s,0x8000\n",crn,crn); + printf("\tstw %s,%d(r1)\n",crn,disp+size_of_int); + printf("\tstw %s,%d(r1)\n",drn,disp); + printf("\tlfd %s,%d(r1)\n",frn,disp); + free_register(dreg); + fregs[freg]=1; + regs[creg]=0; } void code_d2u() { - /* fuck you! */ - printf("\tlea -%d(%%esp),%%esp\n",size_of_int*3); - printf("\tfnstcw (%%esp)\n"); - printf("\tmovl (%%esp), %s\n",register_name(creg)); - printf("\tmovb $12, 1(%%esp)\n"); - printf("\tfldcw (%%esp)\n"); - printf("\tmovl %s, (%%ebp)\n",register_name(creg)); - printf("\tfistpll %d(%%esp)\n",size_of_int); - printf("\tfldcw (%%esp)\n"); - printf("\tmovl %d(%%esp),%s\n",size_of_int,register_name(creg)); - printf("\tlea %d(%%esp),%%esp\n",size_of_int*3); + bl _u2w + addis r9,r31,ha16(_d-L1$pb) + la r9,lo16(_d-L1$pb)(r9) + lfd f13,0(r9) + addis r11,r31,ha16(LC1-L1$pb) + lfd f0,lo16(LC1-L1$pb)(r11) + fcmpu cr0,f13,f0 + cror 2,1,2 + beq- cr0,L2 + fctiwz f0,f13 + stfd f0,72(r1) + lwz r0,76(r1) + b L3 +L2: + lfd f0,0(r9) + addis r9,r31,ha16(LC1-L1$pb) + lfd f13,lo16(LC1-L1$pb)(r9) + fsub f0,f0,f13 + fctiwz f0,f0 + stfd f0,80(r1) + lwz r0,84(r1) + xoris r0,r0,0x8000 +L3: + stw r0,0(r29) + + code_d2i(); } void code_u2d() { - printf("\tpushl %s\n",register_name(creg)); - printf("\tpushl %s\n",register_name(creg)); - printf("\tmovl $0, %d(%%esp)\n",size_of_int); - printf("\tfildll (%%esp)\n"); - printf("\tlea %d(%%esp),%%esp\n",size_of_int*2); + code_i2d(); + lwz r0,0(r29) + stw r0,68(r1) + lis r0,0x4330 + stw r0,64(r1) + lfd f13,64(r1) + addis r9,r31,ha16(LC0-L1$pb) + lfd f0,lo16(LC0-L1$pb)(r9) + fsub f13,f13,f0 + addis r9,r31,ha16(_d1-L1$pb) + stfd f13,lo16(_d1-L1$pb)(r9) } void code_drgvar(int e2,int d)