Mercurial > hg > CbC > old > device
changeset 377:b23568be1155
ARM continue (const table)
author | kono |
---|---|
date | Tue, 13 Jul 2004 21:43:58 +0900 |
parents | d81e1be4036f |
children | b3c6c479c522 |
files | Changes mc-code-arm.c mc-parse.c test/offset.c |
diffstat | 4 files changed, 206 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Mon Jul 12 12:37:18 2004 +0900 +++ b/Changes Tue Jul 13 21:43:58 2004 +0900 @@ -5772,12 +5772,74 @@ とするのは、PowerPC では変更が大きすぎる。レジスタセーブする場所 が良くわからないし。 -もしかして、register save 領域は固定?! +もしかして、register save 領域は固定?! + Mon Jul 12 05:35:33 JST 2004 うーん、やっぱり、難しいよな... 何故か、printf が local variable を壊してしまう。 +register save 領域は固定なわけきゃないだろ。最初からやり直して、 + + function call stack frame + <-------r1_offset------------------------------> + <------------lvar_offset0------> + <--lvar_offset--> + r+ +------------+---+---------------+----------+--------------+----+ - + callee arg xx register save local caller arg xx + reg_save disp max_func_args*SIZE_OF_INT + lvar>0 lvar<0 lvar>0x1000 0000 + +ということになりました。frame の設定のところだけ無条件に32bit add +になったが仕方ないな。これだと、callee arg は不定オフセットにならざる +を得ない。reg_save が最後まで決まらないから。 + はぁ。大変なのはPowerPCだけで、MIPSとia32 は、そのまま動くというのが わかりました。 + +Mon Jul 12 12:54:14 JST 2004 + +が、結局、MIPSを $fp からの裸オフセットにするのは苦労したね。 + .frame $fp じゃなくて、 .frame $sp にすると動くのか。 +あと、goto 関連は、 + code_environment + code_fix_frame_pointer + leave +の三つを直さないとだめなのね。 + +この変更は、ARMのオフセット計算を固定オフセットで行うために +やっているんだけど、ARMのレジスタセーブを固定領域にすれば、 +あるいは、どこかに追いやれば、callee arg も含めて固定に出来 +るはず。 + + +なんか浮動小数点レジスタは f4 だけみたいね。 + + mov ip, sp + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc} + sub fp, ip, #4 + sub sp, sp, #12 + .L3: + ldmea fp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc} + .Lfe1: + +まるで、6809 の PSHS X,Y,D だね。PULS X,PC とか。 + +なんだけど、これだと、 + + <-------r1_offset------------------------------> + <------------lvar_offset0------> + <--lvar_offset--> + r+ +------------+---+---------------+----------+--------------+----+ - + callee arg xx register save local caller arg xx + reg_save disp max_func_args*SIZE_OF_INT + lvar>0 lvar<0 lvar>0x1000 0000 + +にならざるを得ない。となると、どっちかは、不定オフセットだな。 +ま、callee 側でしょう。ま、これに習うか。あるいは、ポインタ +で指してもいいんだよね。ていうか、reg_save に関わらず決まった領域 +をとっちゃえばいいんじゃない? 大した量じゃないし。浮動小数点 +レジスタも一つだしね。 + +もう少しかかりそうだね。
--- a/mc-code-arm.c Mon Jul 12 12:37:18 2004 +0900 +++ b/mc-code-arm.c Tue Jul 13 21:43:58 2004 +0900 @@ -1030,7 +1030,7 @@ void gexpr_init(void) { - gvar_ref_list(); + const_list(); while(reg_sp > 0) { error(-1); free_register(reg_stack[--reg_sp]); @@ -1135,29 +1135,55 @@ return xreg; } -static int gvar_ref_list; -static int gvar_ref_disp; +static int const_list; +static int const_list_label; +static int prev_const_list; +static int prev_const_list_label; + +/* + constant table + glist3( tag, next, value ) + GVAR nptr + CONST value + LABEL value + nth element has offset n * SIZE_OF_INT + */ + +#define new_const(e,v) (const_list = glist3(e,const_list,v)) static int -new_gvar_ref(NMTBL *nptr) -{ - return - gvar_ref_list = - glist3((int)nptr,gvar_ref_list,gvar_ref_disp+=SIZE_OF_INT); -} - -static int -search_gvar_ref(NMTBL *nptr) -{ - int p; - for(p = gvar_ref_list; - p && neqname(((NMTBL *)car(p))->nm,nptr->nm);p=cadr(p)); - if (p) return caddr(p); - return caddr(new_gvar_ref(nptr)); +search_const(int tag,int value,int *label) +{ + int p,i,j,list; + + for(j=0;j<2;j++) { + i = 0; + if(j==1) { + if (!const_list_label) const_list_label = fwdlabel(); + list = const_list; *label = const_list_label; + } else { + list = prev_const_list; *label = prev_const_list_label; + } + for(p = list; p ;p=cadr(p),i+=SIZE_OF_INT) { + if (car(p)!=tag) continue; + switch(tag) { + case GVAR: + if (neqname(((char *)caddr(p)), + ((NMTBL *)value)->nm)) continue; + return i; + case CONST: case LABEL: + if (caddr(p)!=value) continue; + return i; + default: error(-1); + } + } + } + new_const(tag,cadr(e)); + return i+SIZE_OF_INT; } static void -gvar_ref_list() +const_list() { int p,next,lb; if (control) { @@ -1165,25 +1191,44 @@ jmp(lb); printf("\t.align\t2\n"); } - gvar_ref_list = reverse0(gvar_ref_list); - fwddef(gvar_ref_label); - for(p = gvar_ref_list; p ;) { - printf("\t.word\t%s\n",((NMTBL *)car(p))->nm); - next = cadr(p); - free_glist3(p); - p = next; + const_list = reverse0(const_list); + fwddef(const_list_label); + for(p = const_list; p ; p = cadr(p)) { + switch(car(p)) { + case GVAR: printf("\t.word\t%s\n",((NMTBL *)caddr(p))->nm); break; + case CONST: printf("\t.word\t%d\n",caddr(p)); break; + case LABEL: printf("\t.word\t.L%d\n",caddr(p)); break; + default: error(-1); + } } if (lb) { fwddef(lb); } + free_glist3_a(pconst_list); + prev_const_list=const_list; + prev_const_list_label=const_list_label; + const_list = 0; +} + +#define CONST_TBL_COUNT 300 + +static void +inc_inst(int count) +{ + static int inst_count; + if ((inst_count+=count)>CONST_TBL_COUNT) { + inst_count = 0; + const_list(); + } } extern void code_ptr_cache_def(int r, NMTBL *nptr) { + int label,disp; char *rrn = register_name(r); - printf("\tldr %s, .L%d+%d\n",rrn,gvar_ref_label, - search_gvar_ref(nptr)); + disp = search_const(GVAR,(int)nptr,&label); + printf("\tldr %s, .L%d+%d\n",rrn,label,disp); } #define mask8(d,bit) (d & (255 << bit)) @@ -1239,22 +1284,47 @@ } static void +code_const(int e2,int reg) +{ + char *crn,*add,*mov; + int s,p1,p2,p3; + int label,disp; + + use_int(reg); + crn = register_name(reg); + if ((s=make_const(e2,&p1,&p2,&p3))) { + add = s>0?"add":"sub"; + mov = s>0?"mov":"mvn"; + if (p1) printf("\t%s\t%s, %s, #%d\n",mov,crn,rrn,p1); + if (p2) printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,p2); + if (p3) printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,p3); + } else { + disp = search_const(CONST,e2,&label); + printf("\tldr\t%s, .L%d+%d\n",crn,label,disp); + } +} + +static void code_add(int reg,int offset,int r) { char *crn = register_name(reg); char *rrn = register_name(r); int s,p1,p2,p3; + char *add; + int label,disp; if (offset==0) { if(r!=reg) printf("\tmov %s,%s\n",crn,rrn); + } 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); + 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); + if (p3) printf("\t%s\t%s, %s, #%d\n",add,crn,rrn,p3); } 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); + disp = search_const(CONST,offset,&label); + printf("\tldr\t%s, .L%d+%d\n",crn,label,disp); + printf("\tadd\t%s, %s, %s\n",crn,crn,rrn); } } @@ -1283,7 +1353,7 @@ } else { 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); + printf("\t%s\t%s, [%s, #0]%s\n",ld,crn,orn,cext); free_register(reg); } } @@ -3502,7 +3572,9 @@ { NMTBL *n; int init; - gvar_ref_list(); + const_list(); + free_glist3_a(pconst_list); pconst_list = 0; + init=0; /* static local variables */ for(n=local_static_list;n;n=n->next) {
--- a/mc-parse.c Mon Jul 12 12:37:18 2004 +0900 +++ b/mc-parse.c Tue Jul 13 21:43:58 2004 +0900 @@ -3853,6 +3853,24 @@ } } +extern void +free_glist3_a(int e1) +{ + int next; + while(e1) { + if (e1>gfree) continue; /* freeing local heap */ + next = cadr(e1); + if (e1==gfree) { + gfree-=3; + } else { + cadr(e1) = free_glist3_list; + free_glist3_list = e1; + } + e1 = next; + } +} + + extern int length(int list) {
--- a/test/offset.c Mon Jul 12 12:37:18 2004 +0900 +++ b/test/offset.c Tue Jul 13 21:43:58 2004 +0900 @@ -80,9 +80,27 @@ printf("%x\n", p[-(BIT12-1)]); printf("%x\n", p[-(BIT16-1)]); + p = large+BIT16; + + p[-1] = 0xaa; + p[-BIT8] = 0xbb; + p[-BIT10] = 0xcc; + p[-(BIT12-1)] = 0xdd; + p[-(BIT16-1)] = 0xee; + + printf("%x\n", p[-1]); + printf("%x\n", p[-BIT8]); + printf("%x\n", p[-BIT10]); + printf("%x\n", p[-(BIT12-1)]); + printf("%x\n", p[-(BIT16-1)]); + + for(p=local_midium;p<&local_midium[BIT12];p++) *p = p-local_midium; for(p=local_large;p<&local_large[BIT16];p++) *p = p-local_large; + for(p=midium;p<&midium[BIT12];p++) *p = p-midium; + for(p=large;p<&large[BIT16];p++) *p = p-large; + } main(int ac,char *av[])