Mercurial > hg > CbC > old > device
changeset 374:9bc42f69f653 lvar-offset-before
arm continue...
author | kono |
---|---|
date | Sun, 11 Jul 2004 20:59:52 +0900 |
parents | a9bc85fe6702 |
children | 91849fdeea60 |
files | Changes mc-code-arm.c mc-code-mips.c |
diffstat | 3 files changed, 147 insertions(+), 77 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Sun Jul 11 13:31:52 2004 +0900 +++ b/Changes Sun Jul 11 20:59:52 2004 +0900 @@ -5708,9 +5708,56 @@ で1000命令毎には出力する必要がある。しかも、既に出力されてい るものは、前のを使う必要がある。なるほどね。っていうことは、 テーブルにそういうフラグをつけないとだめか。(それぐらい -アセンブラでやってよ〜) +アセンブラでやってよ〜) + +すべてのprintfにcounter をつければ良いわけだけど、いくつかは +問題があるだろうな。ちょっと量多いしね。 ARMには short ってないのか。short を多用しているプログラムは だめなのね。 (でも、どっちかって言うとテスト環境を作る方が難しそう) + +slとかipとか思い入れがありそうなレジスタの名前も大した意味がある +わけではないらしい。 + +ARMって、なんかsigned char とunsinged char の区別がないな。 + +lvar offset が、ちょっとめんどくさいかな。 +constant が決まってないから、せっかく作ったcode_add +が使えない。いや、決まるのかな? + +Sun Jul 11 20:37:20 JST 2004 + +やっぱり、local variable のオフセットがその場で定数でないのは +まずい。 + + 負の値 + fp <-------| + +------+------------------+ + <----lvar_offset---> + +なのがまずいんだよね。 + + 負の値 + fp-------> | + +------+------------------+ + <----lvar_offset---> + +にすれば良いだけだよね。なんけど、def で pre decrement しているが +まずい。が、<0 でないとまずいので、単純な post decrement でもだめ。 + +でも、これ修正量が多いよね。 + + 負の値 + fp-------> sp-----> + +------+------------------+ + callee <----lvar_offset---> caller + arg arg + <------> pre known offset + ----> + +と、直せば良い。 + +ん、だが.... +
--- a/mc-code-arm.c Sun Jul 11 13:31:52 2004 +0900 +++ b/mc-code-arm.c Sun Jul 11 20:59:52 2004 +0900 @@ -83,12 +83,12 @@ static int lreg_sp; /* longlong REGister Stack-Pointer */ static int lreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ -#define REG_fp 11 -#define REG_sp 15 -#define REG_VAR_BASE 10 -#define REG_VAR_MIN 8 -#define MIN_TMP_REG 0 -#define MAX_TMP_REG 7 +#define REG_fp 13 +#define REG_sp 14 +#define REG_VAR_BASE 11 +#define REG_VAR_MIN 4 +#define MIN_TMP_REG 12 /* only one tmp register? */ +#define MAX_TMP_REG 12 #define PTRC_REG 3 /* mark for pointer cache */ @@ -107,7 +107,7 @@ #define LREG_OFFSET (REAL_MAX_REGISTER+REAL_MAX_FREGISTER) int MAX_INPUT_REGISTER_VAR = 4; -int MAX_CODE_INPUT_REGISTER_VAR = 7-MIN_TMP_REG; +int MAX_CODE_INPUT_REGISTER_VAR = 9-MIN_TMP_REG; int MAX_INPUT_DREGISTER_VAR = 0; int MAX_INPUT_FREGISTER_VAR = 0; int MAX_CODE_INPUT_DREGISTER_VAR = 3-MIN_TMP_FREG; @@ -162,7 +162,7 @@ static char *reg_name[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "sl", "fp", "ip", "lr", "pc", "sp", + "r8", "r9", "sl", "lr", "ip", "fp", "sp", "pc", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7"; }; @@ -418,16 +418,14 @@ { if (fnptr->sc==CODE) { if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("\tadd\t%s, sp, #%d\n", - register_name(creg),CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); + code_add(creg,CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),REG_sp); } else - printf("\tadd\t%s, fp,#%d\n",register_name(creg),CODE_LVAR(l)); + code_add(creg,CODE_LVAR(l),REG_fp); } else if (l<0) { /* local variable */ printf("\tsub\t%s, fp, #%d+$L_%d\n",register_name(creg), FUNC_LVAR(l),lvar_offset_label); } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("\tadd\t%s, $sp, #%d\n", - register_name(creg),CALLER_ARG(l-ARG_LVAR_OFFSET)); + code_add(creg,CALLER_ARG(l-ARG_LVAR_OFFSET),REG_sp); } else { /* callee's arguments */ printf("\tsub\t%s, fp, #%d+$L_%d\n", register_name(creg),CALLEE_ARG(l),r1_offset_label); @@ -1032,6 +1030,7 @@ void gexpr_init(void) { + gvar_ref_list(); while(reg_sp > 0) { error(-1); free_register(reg_stack[--reg_sp]); @@ -1189,8 +1188,8 @@ #define mask8(d,bit) (d & (255 << bit)) -static void -make_const(int c) +static int +make_const(int c,int *p1,int *p2,int *p3) { int sign,im,jm,km; int min_stage = 4; @@ -1233,8 +1232,10 @@ } } } - if (min_stage<=3) { emit(sign,im,jm,km); } - else { print "emit const c\n"; } + if (min_stage<=3) { + *p1 = im; *p2= jm; *p3 = km; + return sign; + } else return 0; } static void @@ -1242,51 +1243,64 @@ { char *crn = register_name(reg); char *rrn = register_name(r); + int s,p1,p2,p3; if (offset==0) { if(r!=reg) printf("\tmov %s,%s\n",crn,rrn); - } else if (offset > 0) { - if (offset> - printf("\tadd %s, %s, #%d\n",crn,rrn,offset); + if ((s=make_const(offset,&p1,&p2,&p3))) { + add = s>0?"add":"sub"; + if (p1) printf("\t%s\t%s, %s, #%d\n",add,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,offset)); + printf("\tadd\t%s, %s, %s\n",add,crn,crn,rrn); } } static void -code_ld(char *ld,int reg,int offset,int r) +code_ld(char *ld,int reg,int offset,int r,char *cext) { char *crn = register_name(reg); char *rrn = register_name(r); - printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn); + if (-1024<offset&&offset<1024) { + printf("\t%s\t%s, [%s, #%d]%s\n",ld,crn,rrn,offset,cext); + } else { + code_add(reg,offset,r); + printf("\t%s\t%s, [%s, #0]%s\n",ldcrn,crn,cext); + } } static void -code_ldf(char *ld,char *crn,int offset,int r) +code_ldf(char *ld,char *crn,int offset,int r,char *cext) { char *rrn = register_name(r); - printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn); -} - - -static char *cload(int sz,int sign) { - if (sign) { - return sz==1?"lb":sz==SIZE_OF_SHORT?"lh":"lw"; + char *orn; + int reg; + if (-1024<offset&&offset<1024) { + printf("\t%s\t%s, [%s, #%d]%s\n",ld,crn,rrn,offset,cext); } else { - return sz==1?"lbu":sz==SIZE_OF_SHORT?"lhu":"lw"; - } -} - -static char *cstore(int sz) { return sz==1?"sb":sz==SIZE_OF_SHORT?"sh":"sw"; } - -#define cext(sign,sz,reg) /* do nothing */ - + orn = register_name(reg=get_register()); + code_add(reg,offset,r); + printf("\t%s\t%s, [%s, #%d]%s\n",ld,crn,orn,offset,cext); + free_register(reg); + } +} + + +#define cload(sz,sign) \ + (sz==1?"ldrb":sz==SIZE_OF_SHORT?(sign?"ldrsh":"ldrh"):"ldr") + +#define cstore(sz) (sz==1?"strb":sz==SIZE_OF_SHORT?"strh":"str") + +#define cext(sign,sz,reg) void code_label(int labelno) { clear_ptr_cache(); - printf("$L_%d:\n",labelno); + printf(".L%d:\n",labelno); } void @@ -1299,13 +1313,14 @@ void code_rgvar(int e1,int reg) { 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)),""); } void code_crgvar(int e1,int reg,int sign,int sz){ use_int(reg); - code_ld(cload(sz,sign),reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1))); + code_ld(cload(sz,sign),reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1)) + sz==1?" @ zero_extendqisi2":""); cext(sign,sz,reg); } @@ -1314,7 +1329,7 @@ code_register(int e2,int reg) { use_int(reg); if (reg!=e2) - printf("\tmove %s,%s\n",register_name(reg),register_name(e2)); + printf("\tmov %s,%s\n",register_name(reg),register_name(e2)); } @@ -1322,7 +1337,7 @@ code_rlvar(int e2,int reg) { use_int(reg); lvar_intro(e2); - printf("\tlw %s,",register_name(reg)); + printf("\tldr\t%s, ",register_name(reg)); lvar(e2); } @@ -1384,59 +1399,65 @@ void code_label_value(int label,int reg) { use_int(reg); - printf("\tla %s,$L_%d\n",register_name(reg),label); + printf("\tldr %s,.L%d\n",register_name(reg), + make_const_ptr(label)); return; } void code_const(int e2,int reg) { - char *crn; + char *crn,*add; + int p1,p2,p3; use_int(reg); crn = register_name(reg); - printf("\tli %s,%d\n",crn,e2); + 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("\tsubu %s,$0,%s\n", register_name(creg), register_name(creg)); + printf("\trsb\t%s, %s, #0\n", register_name(creg), register_name(creg)); } void code_not(int creg) { use_int(creg); - printf("\tnor %s,%s,%s\n", + printf("\tmvn\t%s, %s, %s\n", register_name(creg), register_name(creg),register_name(creg)); } void code_lnot(int creg) { - int dreg = get_register(); use_int(creg); - printf("\txori %s,%s,0x0\n", - register_name(dreg),register_name(creg)); - printf("\tsltu %s,%s,1\n", - register_name(creg),register_name(dreg)); - free_register(dreg); + printf("\tcmp\t%s, #0\n", register_name(creg)); + printf("\tmovne\t%s, #0\n", register_name(creg)); + printf("\tmoveq\t%s, #1\n", register_name(creg)); } void code_preinc(int e1,int e2,int dir,int sign,int sz,int reg) { char *xrn,*drn; + int xreg; if (car(e2)==REGISTER) { use_int(reg); - printf("\taddu %s,%s,%d\n", - register_name(cadr(e2)),register_name(cadr(e2)), dir); + code_add(dir,cadr(e2)); if (cadr(reg)!=e2) - printf("\tmove %s,%s\n",register_name(reg),register_name(cadr(e2))); + code_register(cadr(e2),reg); return; } g_expr(e2); if (!is_int_reg(creg)) error(-1); - xrn = register_name(creg); + xrn = register_name(xreg = creg); if (reg==USE_CREG) { reg=get_register(); if (!reg) error(-1); drn = register_name(reg); @@ -1444,27 +1465,25 @@ } else { drn = register_name(reg); } - printf("\t%s %s,0(%s)\n",cload(sz,sign),drn,xrn); - if (use) cext(sign,sz,reg); - printf("\taddi %s,%s,%d\n",drn,drn,dir); - printf("\t%s %s,0(%s)\n",cstore(sz),drn,xrn); + code_ld(cload(sz,sign),reg,0,xreg,sz==1?" @ zero_extendqisi2":""); + code_add(reg,dir,reg); + code_ldf(cstore(sz),reg,0,xreg,sz==SIZE_OF_SHORT?" @ movhi":""); } void code_postinc(int e1,int e2,int dir,int sign,int sz,int reg) { char *xrn,*crn,*nrn; - int nreg; + int nreg,xreg; if (car(e2)==REGISTER) { use_int(reg); - printf("\tmove %s,%s\n",register_name(reg),register_name(cadr(e2))); - printf("\taddu %s,%s,%d\n", - register_name(cadr(e2)),register_name(cadr(e2)),dir); + code_register(cadr(e2),reg); + code_add(dir,reg); return; } g_expr(e2); if (!is_int_reg(creg)) error(-1); - crn = register_name(creg); + crn = register_name(xreg=creg); nreg=get_register(); if (!nreg) error(-1); nrn = register_name(nreg); if (reg==USE_CREG) { @@ -1474,10 +1493,10 @@ } else { xrn = register_name(reg); } - printf("\t%s %s,0(%s)\n",cload(sz,sign),xrn,crn); - if (use) cext(sign,sz,reg); - printf("\taddi %s,%s,%d\n",nrn,xrn,dir); - printf("\t%s %s,0(%s)\n",cstore(sz),nrn,crn); + code_ld(cload(sz,sign),reg,0,xreg,sz==1?" @ zero_extendqisi2":""); + code_add(nreg,dir,reg); + code_ldf(cstore(sz),nreg,0,xreg,sz==SIZE_OF_SHORT?" @ movhi":""); + free_register(nreg); } @@ -1497,7 +1516,7 @@ /* save frame pointer */ #if R1SAVE use_int(creg); - printf("\tlw %s,0($fp)\n",register_name(creg)); + printf("\tldr\t%s,[fp, #0]\n",register_name(creg)); #else use_int(creg); printf("\taddu %s,",register_name(creg)); @@ -1512,6 +1531,7 @@ char *xrn; int e2,e3; if (rexpr_bool(e1, reg)) return; +#if 0 b_expr(e1,1,e2=fwdlabel(),1); /* including > < ... */ if (use) { use_int(reg); @@ -1524,6 +1544,12 @@ } else { fwddef(e2); } +#else + b_expr(e1,1,0,1); /* including > < ... */ + use_int(reg); + printf("\tmovne\t%s, #0\n", register_name(reg)); + printf("\tmoveq\t%s, #1\n", register_name(reg)); +#endif } char * @@ -2384,9 +2410,6 @@ printf("%d+$L_%d($sp)\n",FUNC_LVAR(0),lvar_offset_label); } -// MIPS $25 (=$jp) contains calling function address. -// It is used in cpload $25 to get global address table $gp. - void code_jmp(char *s) { // jump to continuation means use all register variable
--- a/mc-code-mips.c Sun Jul 11 13:31:52 2004 +0900 +++ b/mc-code-mips.c Sun Jul 11 20:59:52 2004 +0900 @@ -1332,7 +1332,7 @@ use_int(reg); printf("\taddu %s,%s,%d\n", register_name(cadr(e2)),register_name(cadr(e2)), dir); - if (cadr(reg)!=e2) + if (cadr(e2)!=reg) printf("\tmove %s,%s\n",register_name(reg),register_name(cadr(e2))); return; }