Mercurial > hg > CbC > old > device
changeset 378:b3c6c479c522
ARM continue...
author | kono |
---|---|
date | Wed, 14 Jul 2004 14:37:37 +0900 |
parents | b23568be1155 |
children | c7abd48191b3 |
files | Changes mc-code-arm.c mc-code-mips.c stdio.h |
diffstat | 4 files changed, 206 insertions(+), 346 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Tue Jul 13 21:43:58 2004 +0900 +++ b/Changes Wed Jul 14 14:37:37 2004 +0900 @@ -5843,3 +5843,17 @@ レジスタも一つだしね。 もう少しかかりそうだね。 + +Wed Jul 14 12:45:01 JST 2004 + +やっぱり浮動小数点ありとなしを一緒に実装するのはめんどい。 + +あれ、? mc-code-mips.c の + rexpr_bool(int e1, int reg) + { + int e2,reg0; + int op = car(e1); + return 0; + +ってなんだ? せっかく作ったのに? +
--- a/mc-code-arm.c Tue Jul 13 21:43:58 2004 +0900 +++ b/mc-code-arm.c Wed Jul 14 14:37:37 2004 +0900 @@ -177,7 +177,7 @@ char *lh(i) { return lregister_name_high(i); } #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_float_reg(i) (arch_mode==Linux_Zaurus?(REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER):is_int_reg(i)) #define is_longlong_reg(i) (LREG_OFFSET<=i&&i<LREG_OFFSET+REAL_MAX_LREGISTER+LREG_V) #define is_double_reg(i) (arch_mode==GameBoyAdvance?is_longlong_reg(i):is_float_reg(i)) @@ -397,19 +397,19 @@ } static void -lvar(int l) +lvar(int l,char *cext) { if (fnptr->sc==CODE) { if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("[sp, #%d]\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); + printf("[sp, #%d]%s\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),cext); } else - printf("[fp, #%d]\n",CODE_LVAR(l)); + printf("[fp, #%d]%s\n",CODE_LVAR(l),cext); } else if (l<0) { /* local variable */ - printf("[fp, #%d+.L%d]\n",FUNC_LVAR(l),lvar_offset_label); + printf("[fp, #%d+.L%d]%s\n",FUNC_LVAR(l),lvar_offset_label,cext); } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("[sp, #%d]\n",CALLER_ARG(l-ARG_LVAR_OFFSET)); + printf("[sp, #%d]%s\n",CALLER_ARG(l-ARG_LVAR_OFFSET),cext); } else { /* callee's arguments */ - printf("[fp, #%d+.L%d]\n",CALLEE_ARG(l),r1_offset_label); + printf("[fp, #%d+.L%d]%s\n",CALLEE_ARG(l),r1_offset_label,cext); } } @@ -1234,7 +1234,7 @@ #define mask8(d,bit) (d & (255 << bit)) static int -make_const(int c,int *p1,int *p2,int *p3) +make_const(int c,int *p1,int *p2,int *p3,int mode) { int sign,im,jm,km; int min_stage = 4; @@ -1243,7 +1243,7 @@ int i,j,k; for(sign=1;sign>=-1;sign-=2) { int d; - if (sign==1) { d = c; } else { d = -c; } + if (sign==1) { d = c; } else { d = mode==CMP?-c:~c; } if (min_stage==1) break; for(i=24;i>=0;i-=2) { jm = km = 0; @@ -1283,6 +1283,15 @@ } else return 0; } +static int +is_stage1_const(int c,int mode) +{ + int sign,p1,p2,p3; + sign = make_const(c,&p1,&p2,&p3,mode); + return (*p1&&!*p2&&!*p3)?sign:0; +} + + static void code_const(int e2,int reg) { @@ -1292,7 +1301,7 @@ use_int(reg); crn = register_name(reg); - if ((s=make_const(e2,&p1,&p2,&p3))) { + if ((s=make_const(e2,&p1,&p2,&p3,0))) { add = s>0?"add":"sub"; mov = s>0?"mov":"mvn"; if (p1) printf("\t%s\t%s, %s, #%d\n",mov,crn,rrn,p1); @@ -1316,7 +1325,7 @@ if(r!=reg) printf("\tmov %s,%s\n",crn,rrn); } - if ((s=make_const(offset,&p1,&p2,&p3))) { + if ((s=make_const(offset,&p1,&p2,&p3,0))) { add = s>0?"add":"sub"; if (p1) printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,p1); if (p2) printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,p2); @@ -1408,43 +1417,32 @@ use_int(reg); lvar_intro(e2); printf("\tldr\t%s, ",register_name(reg)); - lvar(e2); + lvar(e2,""); } extern void code_i2c(int reg) { - int reg1; - use_int(reg); - reg1 = get_register(); - printf("sll %s,%s,24\n",register_name(reg1),register_name(reg)); - printf("sra %s,%s,24\n",register_name(reg),register_name(reg1)); - free_register(reg1); } extern void code_i2s(int reg) { - int reg1; - use_int(reg); - reg1 = get_register(); - printf("sll %s,%s,16\n",register_name(reg1),register_name(reg)); - printf("sra %s,%s,16\n",register_name(reg),register_name(reg1)); - free_register(reg1); } extern void code_u2uc(int reg) { use_int(reg); - printf("andi %s,%s,0xff\n",register_name(reg),register_name(reg)); + printf("and\t%s, %s, #255\n",register_name(reg),register_name(reg)); } extern void code_u2us(int reg) { use_int(reg); - printf("andi %s,%s,0xffff\n",register_name(reg),register_name(reg)); + printf("bic %s, %s, #16711680\n",register_name(reg),register_name(reg)); + printf("bic %s, %s, #-16777216\n",register_name(reg),register_name(reg)); } void @@ -1452,7 +1450,7 @@ use_int(reg); lvar_intro(e2); printf("\t%s %s,",cload(sz,sign),register_name(reg)); - lvar(e2); + lvar(e2,sz==1?" @ zero_extendqisi2":""); cext(sign,sz,reg); } @@ -1462,35 +1460,20 @@ use_int(reg); r = get_ptr_cache(n); if(r!=reg) - printf("\tmove %s,%s\n",register_name(reg),register_name(r)); + printf("\tmov %s,%s\n",register_name(reg),register_name(r)); return; } void code_label_value(int label,int reg) { + int lb,disp; use_int(reg); - printf("\tldr %s,.L%d\n",register_name(reg), - make_const_ptr(label)); + disp = search_const(LABEL,label,&lb); + printf("\tldr\t%s, .L%d+%d\n",crn,lb,disp); return; } void -code_const(int e2,int reg) { - char *crn,*add; - int p1,p2,p3; - use_int(reg); - crn = register_name(reg); - if ((s=make_const(e2,&p1,&p2,&p3))) { - add = s>0?"add":"sub"; - if (p1) printf("\tmov\t%s, %s, #%d\n",crn,rrn,offset); - if (p2) printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,offset); - if (p3) printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,offset); - } else { - printf("\tldr\t%s, .L%d\n",crn,new_const_ref(r,e2)); - } -} - -void code_neg(int creg) { use_int(creg); printf("\trsb\t%s, %s, #0\n", register_name(creg), register_name(creg)); @@ -1573,10 +1556,13 @@ void code_return(int creg) { + int label,disp; char *crn; use_int(creg); crn = register_name(creg); - printf("\tla %s,$L_%d\n",crn,retcont); + + disp = search_const(LABEL,retcont,&label); + printf("\tldr\t%s, .L%d+%d\n",crn,label,disp); } #define R1SAVE 0 @@ -1589,8 +1575,7 @@ printf("\tldr\t%s,[fp, #0]\n",register_name(creg)); #else use_int(creg); - printf("\taddu %s,",register_name(creg)); - printf("$fp,%d+$L_%d\n",FUNC_LVAR(0),lvar_offset_label); + printf("\tmov\t%s,fp\n",register_name(creg)); #endif } @@ -1624,37 +1609,37 @@ char * code_gt(int cond) { - return (cond?"ne":"eq"); + return (cond?"le":"gt"); } char * code_ugt(int cond) { - return code_gt(cond); + return (cond?"ls":"hi"); } char * code_ge(int cond) { - return code_gt(!cond); + return (cond?"lt":"ge"); } char * code_uge(int cond) { - return code_gt(!cond); + return (cond?"lo":"hs"); } char * code_eq(int cond) { - return cond?"":0; + return (cond?"ne":"eq"); } void code_cmp_crgvar(int e1,int reg,int sz,int label,int cond) { use_int(reg); - code_ld(cload(sz,0),reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1))); + code_ld(cload(sz,0),reg,cadr(e1),xreg,get_ptr_cache((NMTBL*)caddr(e1)), + sz==1?" @ zero_extendqisi2":""); cext(0,sz,r); cmpreg = reg; - // printf("\tcmpwi cr0,%s,0\n",crn); jcond(label,cond); } @@ -1666,7 +1651,7 @@ crn = register_name(reg); lvar_intro(e2); printf("\t%s %s,",cload(sz,0),crn); - lvar(e2); + lvar(e2,sz==1?" @ zero_extendqisi2":""); cext(0,sz,reg); code_cmp_register(reg,label,cond); } @@ -1675,7 +1660,7 @@ void code_cmp_rgvar(int e1,int reg,int label,int cond) { use_int(reg); - code_ld("lw",reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1))); + code_ld("ldr",reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1)),""); code_cmp_register(reg,label,cond); } @@ -1686,8 +1671,8 @@ use_int(reg); crn = register_name(reg); lvar_intro(e2); - printf("\tlw %s,",crn); - lvar(e2); + printf("\tldr %s,",crn); + lvar(e2,""); code_cmp_register(reg,label,cond); } @@ -1695,7 +1680,6 @@ void code_cmp_register(int e2,int label,int cond) { use_int(e2); - cmpreg = e2; // used by jcond, beq $reg,$0,L_xx jcond(label,cond); } @@ -1704,7 +1688,7 @@ code_string(int e1,int creg) { char *s,*crn; - int lb; + int lb,disp,label; use_int(creg); crn = register_name(creg); @@ -1713,7 +1697,9 @@ lb = emit_string_label(); ascii(s); text_mode(2); - printf("\tla %s,$L_%d\n",crn,lb); + + disp = search_const(LABEL,lb,&label); + printf("\tldr\t%s, .L%d+%d\n",crn,label,disp); } #define MAX_COPY_LEN 20 @@ -1738,16 +1724,16 @@ switch (length) { case 0: break; case 1: case -1: - printf("\tlb %s,%d(%s)\n",drn,offset,frn); - printf("\tsb %s,%d(%s)\n",drn,offset,trn); + printf("\tldrb\t%s, [%s,#%d]\n",drn,frn,offset); + printf("\tstrb\t%s, [%s,#%d]\n",drn,frn,offset); break; case 2: case -2: - printf("\tlh %s,%d(%s)\n",drn,offset,frn); - printf("\tsh %s,%d(%s)\n",drn,offset,trn); + printf("\tldrh\t%s, [%s,#%d]\n",drn,frn,offset); + printf("\tstrh\t%s, [%s,#%d]\n",drn,frn,offset); break; case 4: case -4: - printf("\tlw %s,%d(%s)\n",drn,offset,frn); - printf("\tsw %s,%d(%s)\n",drn,offset,trn); + printf("\tldr\t%s, [%s,#%d]\n",drn,frn,offset); + printf("\tstr\t%s, [%s,#%d]\n",drn,frn,offset); break; default: if (length <0) { @@ -1771,11 +1757,11 @@ } clear_ptr_cache(); code_save_stacks(); - printf("\tli $6,%d\n",length); - printf("\tmove $5,%s\n",frn); - printf("\tmove $4,%s\n",trn); + code_code_register(from,0); + code_code_register(to,1); + code_const(length,2); /* overrap must be allowed */ - printf("\tjal %s\n",memmove); + printf("\tbl %s\n",memmove); extern_define(memmove,0,FUNCTION,1); fix=0; set_ireg(RET_REGISTER,0); @@ -1815,8 +1801,8 @@ srn = register_name(sreg); code_lvar(cadr(arg),dreg); for(count=0;count<length;count+=SIZE_OF_INT) { - printf("\tlw %s,%d(%s)\n",srn,count,crn); - printf("\tsw %s,%d(%s)\n",srn,count,drn); + printf("\tldr %s, [%s, #%d]\n",srn,crn,count); + printf("\tstr %s, [%s, #%d]\n",srn,crn,count); } free_register(sreg); free_register(dreg); @@ -1839,7 +1825,7 @@ if (ireg && reg!=ireg ) { free_register(ireg); if (mode) { - printf("\tmove %s,%s\n",register_name(reg),register_name(ireg)); + printf("\tmov %s,%s\n",register_name(reg),register_name(ireg)); } } free_register(creg); @@ -1856,7 +1842,9 @@ if (freg && reg!=freg) { free_register(freg); if (mode) { - printf("\tmov.s %s,%s\n",fregister_name(reg),fregister_name(freg)); + printf("\t%s %s,%s\n", + arch_mode==Linux_Zaurus?"mvfd":mov", + fregister_name(reg),fregister_name(freg)); } } // if (creg!=ireg) free_register(creg); @@ -1871,9 +1859,9 @@ if (reg!=creg) { if (lreg && reg!=lreg) { if (mode) { - printf("\tmove %s,%s\n", + printf("\tmov %s,%s\n", lregister_name_low(reg),lregister_name_low(lreg)); - printf("\tmove %s,%s\n", + printf("\tmov %s,%s\n", lregister_name_high(reg),lregister_name_high(lreg)); } free_register(lreg); @@ -2136,7 +2124,7 @@ break; case FRLVAR: lvar_intro(cadr(e2)); - printf("\tlw %s,",frn); lvar(cadr(e2)); + printf("\tlw %s,",frn); lvar(cadr(e2),""); default: g_expr(e2); case FREGISTER: @@ -2234,24 +2222,12 @@ static void code_call(int e2,NMTBL *fn,int jmp) { - // char *jrn; - if (fnptr->sc==CODE) { - if (car(e2) == FNAME) { - printf("\tla\t$25,%s\n",fn->nm); - } else { - // jrn = register_name(cadr(jmp)); - // printf("\tmove\t$25,%s\n",jrn); - } - printf("\tjalr\t$25\n"); - printf("\tlw\t$gp,$L_%d($sp)\n",cprestore_label); + if (car(e2) == FNAME) { + printf("\tbl\t%s\n",fn->nm); } else { - if (car(e2) == FNAME) { - printf("\tjal\t%s\n",fn->nm); - } else { - // jrn = register_name(cadr(jmp)); - // printf("\tmove $25,%s\n",jrn); - printf("\tjal\t$31,$25\n"); - } + printf("\tmov\tlr, pc\n"); + printf("\tmov\tpc, %s\n",register_name(jmp)); + printf("\tldmea\tfp, {fp, sp, pc}\n"); } } @@ -2288,7 +2264,7 @@ fn=(NMTBL *)cadr(e2); } else { if (car(e2)==INDIRECT) e2=cadr(e2); // (*func)(i) case - jmp = list2(REGISTER,25); + jmp = get_register_var(0); if (!simple_arg(e2)) { e3=get_register_var(0); g_expr_u(assign_expr0(e3,e2,INT,INT)); @@ -2458,8 +2434,8 @@ g = get_register(); crn = register_name(reg); grn = register_name(g); - printf("\tsubu $sp,$sp,%s\n",crn); - printf("\taddu %s,$sp,$L_%d\n",crn,cprestore_label); + printf("\trsb\tsp, %s, sp,%s\n",crn); + printf("\tmov\t%s, sp\n",crn); free_register(g); } @@ -2467,17 +2443,15 @@ code_frame_pointer(int e3) { use_int(e3); #if R1SAVE - printf("\tmove $fp,%s\n",register_name(e3)); + printf("\tmov fp, %s\n",register_name(e3)); #else - printf("\tmove $fp,%s\n",register_name(e3)); + printf("\tmov fp, %s\n",register_name(e3)); #endif } void code_fix_frame_pointer(int offset) { - printf("\tla $fp,"); - printf("%d+$L_%d($sp)\n",FUNC_LVAR(0),lvar_offset_label); } void @@ -2485,8 +2459,7 @@ // jump to continuation means use all register variable max_reg_var = REG_VAR_BASE-REG_VAR_MIN; max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; - printf("\tla $25,%s\n",s); - printf("\tj\t$25\n"); + printf("\tb\t%s\n",s); control=0; } @@ -2496,21 +2469,19 @@ max_reg_var = REG_VAR_BASE-REG_VAR_MIN; max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; use_int(e2); - printf("\tmove $25,%s\n",register_name(e2)); - printf("\tj\t$25\n"); + printf("\tmov\tpc, %s\n",s); // ?! control=0; } void code_rindirect(int e1, int reg,int offset, int sign,int sz) { - char *crn,*rrn; + int lreg; g_expr(e1); if (!is_int_reg(creg)) error(-1); - crn=register_name(creg); + lreg = creg; use_int(reg); - rrn=register_name(reg); - printf("\t%s %s,%d(%s)\n",cload(sz,sign),rrn,offset,crn); + code_ld(cload(sz,sign),reg,offset,lreg,sz==1?" @ zero_extendqisi2":""); cext(sign,sz,reg); } @@ -2518,20 +2489,22 @@ int code_drindirect(int e1, int reg,int offset, int d) { - char *crn; - if (d) { - code_lrindirect(e1,reg,offset,1); - use_float(d,reg); - // regs[reg==USE_CREG?lreg:reg]=USING_DREG; - return DOUBLE; + int xreg; + if(arch_mode==GameBoyAdvance) { + if (d) { + code_lrindirect(e1,reg,offset,1); + return DOUBLE; + } else { + code_rindirect(e1,reg,offset,0,0); + return FLOAT; + } } g_expr(e1); if (!is_int_reg(creg)) error(-1); - crn=register_name(creg); + xreg = creg; use_float(d,reg); - printf("\tl.s %s,%d(%s)\n", - fregister_name(reg),offset,crn); - return FLOAT; + code_ldf(d?"ldfd":"ldfs,reg,offset,xreg,""); + return d?DOUBLE:FLOAT; } #endif @@ -2543,19 +2516,19 @@ char *crn=register_name(creg); #if ENDIAN==0 if (creg!=regv_l(reg)) { - printf("\tlw %s,%d(%s)\n",lregister_name_low(reg),offset,crn); - printf("\tlw %s,%d(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn); + printf("\tldr\t%s, [%s, #%d]\n",lregister_name_low(reg),crn,offset); + printf("\tldr\t%s, [%s, #%d]\n",lregister_name_high(reg),crn,offset+SIZE_OF_INT); } else { - printf("\tlw %s,%d(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn); - printf("\tlw %s,%d(%s)\n",lregister_name_low(reg),offset,crn); + printf("\tldr\t%s, [%s, #%d]\n",lregister_name_high(reg),crn,offset+SIZE_OF_INT); + printf("\tldr\t%s, [%s, #%d]\n",lregister_name_low(reg),crn,offset); } #else if (creg!=regv_l(reg)) { - 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); + printf("\tldr\t%s, [%s, #%d]\n",lregister_name_low(reg),crn,offset+SIZE_OF_INT); + printf("\tldr\t%s, [%s, #%d]\n",lregister_name_high(reg),crn,offset); } else { - 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); + printf("\tldr\t%s, [%s, #%d]\n",lregister_name_high(reg),crn,offset); + printf("\tldr\t%s, [%s, #%d]\n",lregister_name_low(reg),crn,offset+SIZE_OF_INT); } #endif } @@ -2591,11 +2564,11 @@ crn_h = lregister_name_high(creg); crn_l = lregister_name_low(creg); #if ENDIAN==0 - printf("\tsw %s,0(%s)\n",crn_l,drn); - printf("\tsw %s,%d(%s)\n",crn_h,SIZE_OF_INT,drn); + printf("\tstr\t%s, [%s, #0]\n",crn_l,drn); + printf("\tstr\t%s, [%s, #%d]\n",crn_h,drn,SIZE_OF_INT); #else - printf("\tsw %s,0(%s)\n",crn_h,drn); - printf("\tsw %s,%d(%s)\n",crn_l,SIZE_OF_INT,drn); + printf("\tstr\t%s, [%s, #0]\n",crn_h,drn); + printf("\tstr\t%s, [%s, #%d]\n",crn_l,drn,SIZE_OF_INT); #endif } @@ -2613,12 +2586,21 @@ } #endif +static char * +cstore(int sz) +{ + swithc(sz) { + case 1: return "strb"; + case SIZE_OF_SHORT: return "strh"; + default: return "str"; + } +} void code_assign_gvar(int e2,int creg,int byte) { use_int(creg); code_ldf(cstore(byte),register_name(creg),cadr(e2), - get_ptr_cache((NMTBL*)caddr(e2))); + get_ptr_cache((NMTBL*)caddr(e2)),byte==SIZE_OF_SHORT?" @ movhi"); } void @@ -2627,21 +2609,15 @@ use_int(creg); crn=register_name(creg); lvar_intro(e2); - if (byte==1) { - printf("\tsb %s,",crn); - } else if (byte==SIZE_OF_SHORT) { - printf("\tsh %s,",crn); - } else { - printf("\tsw %s,",crn); - } - lvar(e2); + printf("\t%s\t%s,",cstore(byte),crn); + lvar(e2,""); } void code_assign_register(int e2,int byte,int creg) { use_int(creg); if (e2!=creg) - printf("\tmove %s,%s\n",register_name(e2),register_name(creg)); + printf("\tmov %s,%s\n",register_name(e2),register_name(creg)); } void @@ -2653,13 +2629,7 @@ use_int(creg); crn=register_name(creg); - if (byte==1) { - printf("\tsb %s,0(%s)\n",crn,drn); - } else if (byte==SIZE_OF_SHORT) { - printf("\tsh %s,0(%s)\n",crn,drn); - } else { - printf("\tsw %s,0(%s)\n",crn,drn); - } + printf("\t%s\t%s, [%s, #0]",cstore(byte),crn,drn); } @@ -2685,13 +2655,7 @@ tosop(op,ireg,xreg); crn = register_name(ireg); drn = register_name(creg); - if (byte==1) { - printf("\tsb %s,0(%s)\n",crn,drn); - } else if (byte==SIZE_OF_SHORT) { - printf("\tsh %s,0(%s)\n",crn,drn); - } else { - printf("\tsw %s,0(%s)\n",crn,drn); - } + printf("\t%s\t%s, [%s, #0]",cstore(byte),crn,drn); free_register(edx); emit_pop_free(xreg); #else @@ -2700,13 +2664,7 @@ tosop(op,creg,xreg); crn = register_name(creg); drn = register_name(edx); - if (byte==1) { - printf("\tsb %s,0(%s)\n",crn,drn); - } else if (byte==SIZE_OF_SHORT) { - printf("\tsh %s,0(%s)\n",crn,drn); - } else { - printf("\tsw %s,0(%s)\n",crn,drn); - } + printf("\t%s\t%s, [%s, #0]",cstore(byte),crn,drn); free_register(edx); emit_pop_free(xreg); #endif @@ -2733,7 +2691,7 @@ switch(op) { case LSHIFT: case ULSHIFT: - shift("sll",creg,oreg); + shift("asl",creg,oreg); if(ox!=-1) free_register(ox); return; case RSHIFT: @@ -2741,7 +2699,7 @@ if(ox!=-1) free_register(ox); return; case URSHIFT: - shift("srl",creg,oreg); + shift("asr",creg,oreg); if(ox!=-1) free_register(ox); return; } @@ -2749,49 +2707,32 @@ crn = register_name(creg); switch(op) { case ADD: - printf("\taddu %s,%s,%s\n",crn,crn,orn); + printf("\tadd %s,%s,%s\n",crn,crn,orn); break; case SUB: - printf("\tsubu %s,%s,%s\n",crn,crn,orn); - break; - case CMPGE: - printf("\tslt %s,%s,%s\n",crn,crn,orn); - cmpreg = creg; + printf("\tsub %s,%s,%s\n",crn,crn,orn); break; case CMP: - printf("\tslt %s,%s,%s\n",crn,orn,crn); - cmpreg = creg; - break; - case UCMPGE: - printf("\tsltu %s,%s,%s\n",crn,crn,orn); - cmpreg = creg; - break; - case UCMP: - printf("\tsltu %s,%s,%s\n",crn,orn,crn); - cmpreg = creg; - break; - case CMPEQ: - printf("\tbeq %s,%s",crn,orn); // beq $2,$3,L1 - break; - case CMPNEQ: - printf("\tbne %s,%s",crn,orn); // beq $2,$3,L1 + printf("\tcmp %s,%s\n",crn,orn); break; case BAND: printf("\tand %s,%s,%s\n",crn,crn,orn); break; case EOR: - printf("\txor %s,%s,%s\n",crn,crn,orn); + printf("\teor %s,%s,%s\n",crn,crn,orn); break; case BOR: - printf("\tor %s,%s,%s\n",crn,crn,orn); + printf("\torr %s,%s,%s\n",crn,crn,orn); break; case MUL: - printf("\tmult %s,%s,%s\n",crn,crn,orn); - break; case UMUL: - printf("\tmultu %s,%s,%s\n",crn,crn,orn); + printf("\tmul %s,%s,%s\n",crn,crn,orn); break; case DIV: case UDIV: case MOD: case UMOD: + bl __modsi3 + bl __udivsi3 + bl __umodsi3 + printf("\t%s $0,%s,%s\n",(op==UDIV||op==UMOD)?"divu":"div",crn,orn); printf("\t%s %s\n",(op==MOD||op==UMOD)?"mfhi":"mflo",crn); printf("\t.set noreorder\n"); @@ -2812,10 +2753,20 @@ { if (car(v)!=CONST) return 0; v = cadr(v); - if (op==MUL||op==UMUL) return ilog(v) ; - if (op==DIV||op==UDIV) return ilog(v) ; - if (!(op==LSHIFT|| op==ULSHIFT|| op==RSHIFT|| op==URSHIFT|| op==ADD|| op==SUB|| op==CMP|| op==BOR)) return 0; - return (-32766<v&&v<32767); + switch(op) { + case MUL: case UMUL: case DIV: case UDIV: + return ilog(v); + case ADD: case SUB; + return 1; + case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT: + return 0<v&&v<=32; + case CMP: + return is_stage1_const(v,CMP); + case EOR: case BOR: case BAND: + return is_stage1_const(v,0); + default: + return 0; + } } void @@ -2827,38 +2778,32 @@ v = cadr(v); switch(op) { + case MUL: case UMUL: + v=ilog(v); case LSHIFT: case ULSHIFT: - printf("\tsll %s,%s,%d\n",crn,crn,v); + printf("\tmov\t%s, %s, asl #%d\n",crn,crn,v); return; + case DIV: + v=ilog(v); case RSHIFT: - printf("\tsra %s,%s,%d\n",crn,crn,v); + printf("\tmov\t%s, %s, asr #%d\n",crn,crn,v); return; + case UDIV: + v=ilog(v); case URSHIFT: - printf("\tsrl %s,%s,%d\n",crn,crn,v); + printf("\tmov\t%s, %s, lsr #%d\n",crn,crn,v); return; case ADD: - printf("\taddu %s,%s,%d\n",crn,crn,v); + code_add(creg,v,creg); break; case SUB: - printf("\taddu %s,%s,-%d\n",crn,crn,v); - break; - case CMP: - printf("\tslt %s,%s,%d\n",crn,crn,v); - cmpreg = creg; - break; - case BOR: - printf("\tori %s,%s,%d\n",crn,crn,v); + code_add(creg,-v,creg); break; - case MUL: case UMUL: - printf("\tsll %s,%s,%d\n",crn,crn,ilog(v)); - break; - case UDIV: - printf("\tsrl %s,%s,%d\n",crn,crn,ilog(v)); - break; - case DIV: - printf("\tsra %s,%s,%d\n",crn,crn,ilog(v)); - break; + case CMP: printf("\tcmp\t%s,%d\n",crn,v); break; + case BOR: printf("\torr\t%s, %s, #%d\n",crn,crn,v); break; + case EOR: printf("\teor\t%s, %s, #%d\n",crn,crn,v); break; + case BAND: printf("\tand\t%s, %s, #%d\n",crn,crn,v); break; default: error(-1); } @@ -2871,17 +2816,14 @@ char *rrn = register_name(reg); use_int(creg); crn = register_name(creg); - printf("\t%s %s,%s,%s\n",op,crn,crn,rrn); + printf("\tmov %s, %s, %s %s\n",crn,crn,op,rrn); } void ld_indexx(int byte, int n, int xreg,int creg, int sign) { - char *crn; use_int(creg); - crn = register_name(creg); - printf("\t%s %s,%d(%s)\n",cload(byte,sign),register_name(creg),n, - register_name(xreg)); + code_ld(cload(byte,sign),creg,n,xreg,byte==1?" @ zero_extendqisi2":""); } int @@ -2894,37 +2836,25 @@ code_cmpdimm(int e, int csreg,int label,int cond) { /* used in dosiwtch() */ - int reg=-1; + int sign,reg=-1; char *rn,*crn; if(chk) return; crn = register_name(csreg); - if (e<-32767||32766<e) { + if (!(sign=is_stage1_const(e,CMP))) { rn = register_name(reg= get_register()); code_const(list2(CONST,e),reg); - switch(cond) { - case 1: - printf("\tbne\t%s,%s,$L_%d\n",crn,rn,label); break; - case 0: - printf("\tbeq\t%s,%s,$L_%d\n",crn,rn,label); break; - case LT: - use_reg(csreg); - printf("\tslt\t%s,%s,%s\n",rn,crn,rn); - printf("\tbne\t%s,$0,$L_%d\n",rn,label); break; - default: error(-1); - } - free_register(reg); + printf("\tcmp\t%s, %s\n",crn,rn); + } else { + printf("\t%s\t%s, #%d\n",sign?"cmp":"cmn",crn,e); } switch(cond) { case 1: - printf("\tbne\t%s,%d,$L_%d\n",crn,e,label); break; + printf("\tbne\t.L%d\n",label); break; case 0: - printf("\tbeq\t%s,%d,$L_%d\n",crn,e,label); break; + printf("\tbeq\t.L%d\n",label); break; case LT: - use_reg(csreg); - rn = register_name(reg= get_register()); - printf("\tslt\t%s,%s,%d\n",rn,crn,e); - printf("\tbne\t%s,$0,$L_%d\n",rn,label); break; + printf("\tblt\t.L%d\n",label); break; default: error(-1); } if (reg!=-1) free_register(reg); @@ -2933,11 +2863,10 @@ void code_opening(char *filename) { - static int count=0; /* this is called once per file */ - printf("\t.file %d \"%s\"\n",count++,filename); + printf("@ Generated by mc for ARM/elf\n"); + printf("\t.file \"%s\"\n",filename); printf(".text\n"); - } // should have pcond_const @@ -3076,39 +3005,6 @@ } static int -code_mask_offset() -{ - /* 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||(max>i&&i>=min)) { - offset++; - } - } - if (offset>2) offset-=1; - return -offset*SIZE_OF_INT; -} - -static unsigned int -code_mask() -{ - /* 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||(max>i&&i>=min)) { - mask |= (1<<i); - } - } - return mask; -} - -static int code_register_save(int reg_save,int freg_save,int disp) { int i; @@ -3142,36 +3038,6 @@ return disp; } -static int -code_fmask_offset() -{ - 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 (i==28||i==31||(max>i&&i>=min)) { - offset++; - } - } - if (offset>2) offset-=1; - return -offset*SIZE_OF_FLOAT; -} - -static unsigned int -code_fmask() -{ - int i; - unsigned int mask=0; - int min = freg_var_num(max_reg_var); - int max = freg_var_num(0); - for(i=0;i<32;i++) { - if (i==28||i==31||(max>i&&i>=min)) { - mask |= (1<<i); - } - } - return mask; -} void code_enter(char *name) @@ -3692,7 +3558,7 @@ use_float(d,freg); lvar_intro(e2); printf("\ts.s %s,",fregister_name(freg)); - lvar(e2); + lvar(e2,""); } void @@ -3989,7 +3855,7 @@ } use_float(d,freg); lvar_intro(e2); - printf("\tl.s %s,",fregister_name(freg)); lvar(e2); + printf("\tl.s %s,",fregister_name(freg)); lvar(e2,""); } void @@ -4607,11 +4473,11 @@ crn_l = lregister_name_low(creg); lvar_intro(e2); #if ENDIAN==0 - printf("\tsw %s,",crn_l);lvar(e2); - printf("\tsw %s,",crn_h);lvar(e2+SIZE_OF_INT); + printf("\tsw %s,",crn_l);lvar(e2,""); + printf("\tsw %s,",crn_h);lvar(e2+SIZE_OF_INT,""); #else - printf("\tsw %s,",crn_h);lvar(e2); - printf("\tsw %s,",crn_l);lvar(e2+SIZE_OF_INT); + printf("\tsw %s,",crn_h);lvar(e2,""); + printf("\tsw %s,",crn_l);lvar(e2+SIZE_OF_INT,""); #endif } @@ -4700,8 +4566,8 @@ crn_h = lregister_name_high(creg); crn_l = lregister_name_low(creg); lvar_intro(e1); - printf("\tlw %s,",crn_l); lvar(e1); - printf("\tlw %s,",crn_h); lvar(e1+SIZE_OF_INT); + printf("\tlw %s,",crn_l); lvar(e1,""); + printf("\tlw %s,",crn_h); lvar(e1+SIZE_OF_INT,""); }
--- a/mc-code-mips.c Tue Jul 13 21:43:58 2004 +0900 +++ b/mc-code-mips.c Wed Jul 14 14:37:37 2004 +0900 @@ -2442,13 +2442,7 @@ use_int(creg); crn=register_name(creg); lvar_intro(e2); - if (byte==1) { - printf("\tsb %s,",crn); - } else if (byte==SIZE_OF_SHORT) { - printf("\tsh %s,",crn); - } else { - printf("\tsw %s,",crn); - } + printf("\t%s %s,",cstore(byte),crn); lvar(e2); } @@ -2468,13 +2462,7 @@ use_int(creg); crn=register_name(creg); - if (byte==1) { - printf("\tsb %s,0(%s)\n",crn,drn); - } else if (byte==SIZE_OF_SHORT) { - printf("\tsh %s,0(%s)\n",crn,drn); - } else { - printf("\tsw %s,0(%s)\n",crn,drn); - } + printf("\t%s %s,0(%s)\n",cstore(byte),crn,drn); } @@ -2500,13 +2488,7 @@ tosop(op,ireg,xreg); crn = register_name(ireg); drn = register_name(creg); - if (byte==1) { - printf("\tsb %s,0(%s)\n",crn,drn); - } else if (byte==SIZE_OF_SHORT) { - printf("\tsh %s,0(%s)\n",crn,drn); - } else { - printf("\tsw %s,0(%s)\n",crn,drn); - } + printf("\t%s %s,0(%s)\n",cstore(byte),crn,drn); free_register(edx); emit_pop_free(xreg); #else @@ -2515,13 +2497,7 @@ tosop(op,creg,xreg); crn = register_name(creg); drn = register_name(edx); - if (byte==1) { - printf("\tsb %s,0(%s)\n",crn,drn); - } else if (byte==SIZE_OF_SHORT) { - printf("\tsh %s,0(%s)\n",crn,drn); - } else { - printf("\tsw %s,0(%s)\n",crn,drn); - } + printf("\t%s %s,0(%s)\n",cstore(byte),crn,drn); free_register(edx); emit_pop_free(xreg); #endif
--- a/stdio.h Tue Jul 13 21:43:58 2004 +0900 +++ b/stdio.h Wed Jul 14 14:37:37 2004 +0900 @@ -1,3 +1,4 @@ +#define __micro_c__ 1 #ifndef __micro_c__ #include "/usr/include/stdio.h" long long strtoll(const char *, char **, int); @@ -5,7 +6,10 @@ void * realloc(void *ptr, size_t size); #else +typedef int size_t; + long long strtoll(const char *, char **, int); +void * realloc(void *ptr, size_t size); #ifdef __APPLE__