Mercurial > hg > CbC > old > device
changeset 416:a6ed0575d731
ARM goto code, Parallel assignment
author | kono |
---|---|
date | Sun, 24 Oct 2004 21:07:46 +0900 |
parents | bdf900926f32 |
children | 98888da30b35 |
files | .gdbinit Changes mc-code-arm.c mc-code-powerpc.c mc-codegen.c |
diffstat | 5 files changed, 154 insertions(+), 67 deletions(-) [+] |
line wrap: on
line diff
--- a/.gdbinit Sat Oct 23 23:26:33 2004 +0900 +++ b/.gdbinit Sun Oct 24 21:07:46 2004 +0900 @@ -1,6 +1,6 @@ tb main -# run -s test/arg.c -run -s mc-parse.c +run -s test/arg.c +# run -s mc-parse.c # run -s mc-codegen.c # run -s nkf203/nkf.c # run -s -ob01.s mc-switch.c
--- a/Changes Sat Oct 23 23:26:33 2004 +0900 +++ b/Changes Sun Oct 24 21:07:46 2004 +0900 @@ -6174,3 +6174,65 @@ なので、RET_LREGにしないで、lmove してしまうのが良い。 align がおかしい + +Sat Oct 23 23:33:11 JST 2004 + +struct を使った interface をregister にmapするかどうか。まぁ、 +難しいけどね。 + +やっぱりarmのbitfieldを合わせるのは止めた方がいいんじゃない? +long long 以外は、型を大きくして対応できる。long long のはみ出し +は、ちょっと対処できない。 + a:8 => a0:4<<4+a1:4 + a:8 = hoge => a0:4 = hoge<<4, a1:4 = hoge; +というように分解する? + +Sun Oct 24 14:19:13 JST 2004 + +code_frame_pointer と code_environment は同じなんですけど... + +巨大な構造体を並列代入すると、 + +自分自身が重なっている + |----------| + |----------| + +では、 + |----------| + --copy-> |----------| + 他のものを代入 + <-copy-- + |----------| +ってことになる。 + +これは、ちょっと手間が大きい。 + |--|---|---| + |--|---|---| +と分割する(分割が細かくならない?) + |---|--|---| + |---|--|---| + +分割はだめだね。自分自身しか重なってないのだったらoverappable copy +する。 + |----------|----------|----------| + |----------|----------|----------| + +circular dependency はrecursive callする必要はないね。 + +なんか、構造体が一度、スタックにあげられてから戻されているみたい + +RSTRUCT って、本当にいるの? + +なんか、「まだ、emit_copy が間違っている!」 + +PowerPC は、code のレジスタに割り当てられた分のスタック上の引数 +を割り当てているな。なので、 +## code carg6(int i, int j,int k,int l,struct arg args0) +## goto carg3(args0,args0,i,j,k,l); +で、args0 のcopyが余計に出るね。 しかもずれ方が変。 + +無害ではあるんだが... + +でも、それでバグを見つけたわけか。 + +だいぶ、enbug しちゃったよ...
--- a/mc-code-arm.c Sat Oct 23 23:26:33 2004 +0900 +++ b/mc-code-arm.c Sun Oct 24 21:07:46 2004 +0900 @@ -60,10 +60,11 @@ static int output_mode = TEXT_EMIT_MODE; static int register_save_return_label; -// static int r1_offset_label; +static int r1_offset_label; static int lvar_offset_label; static int max_func_args = 0; static int arg_on_register = 0; +static int max_func_arg_label = 0; static int freg,ireg,lreg; @@ -102,10 +103,11 @@ #define PTRC_REG 3 /* mark for pointer cache */ -#define FREG_VAR_BASE 7 +#define FREG_VAR_BASE 4 #define FREG_VAR_MIN 4 -#define MIN_TMP_FREG 1 -#define MAX_TMP_FREG 4 +#define FREG_VAR_MAX 7 +#define MIN_TMP_FREG 0 +#define MAX_TMP_FREG 3 int MAX_REGISTER=17; /* ARMのレジスタを10個まで使う*/ int MAX_FREGISTER=8; @@ -117,11 +119,11 @@ #define LREG_OFFSET (REAL_MAX_REGISTER+REAL_MAX_FREGISTER) int MAX_INPUT_REGISTER_VAR = 4; -int MAX_CODE_INPUT_REGISTER_VAR = 9-MIN_TMP_REG; int MAX_INPUT_DREGISTER_VAR = 4; int MAX_INPUT_FREGISTER_VAR = 4; -int MAX_CODE_INPUT_DREGISTER_VAR = 3-MIN_TMP_FREG; -int MAX_CODE_INPUT_FREGISTER_VAR = 7-MIN_TMP_FREG; +int MAX_CODE_INPUT_REGISTER_VAR = 4; +int MAX_CODE_INPUT_DREGISTER_VAR = 6; +int MAX_CODE_INPUT_FREGISTER_VAR = 6; #define LREG_V 3 /* mark for virtual long long/double register */ #define REGS_MAX (REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_LREGISTER+LREG_V) @@ -317,23 +319,23 @@ register_save is done by callee - * gotoを呼び出した関数のr1 ! r1(goto前のr1) - # * $fp <-----------------r1_offset---------> $sp -r+ +----------+-------------+--------+-------+-----------+----------+----+ - cousin arg! callee arg !reg_save!reg_arg!code local caller arg xx - (arg4..) lvar>0 (arg0.3) lvar<0 lvar>0x1000 000 - <-----------my_func_args--><--disp-----><-max_func_arg-> + (prev $sp) + <---lvar_offset--> + # $fp <--------------------r1_offset---------> $sp +r+ +----------+-------------+--------+-------+-----------+---------------+ + cousin arg! callee arg !reg_save!reg_arg!local caller arg + (arg4..)lvar>0 (arg0.3) lvar<0 lvar>0x1000 000 + <--------------my_func_args--><--disp-----><-max_func_arg-> *SIZE_OF_INT *SIZE_OF_INT prev $sp=$fp $fp $sp - - <-------r1_offset------------------------------> - <------------lvar_offset-------> - <-arg_offset-> - r+ +-----------+----+---------------+----------+-------------+----+ - callee arg xxx register save local caller arg xxx - ($r31)($fp) reg_save disp max_func_args*SIZE_OF_INT - lvar>0 lvar<0 lvar>0x1000 0000 + (prev $sp) + <------r1_offset----------------> $sp + (prev $fp) $fp + r+ +-----------+--------------------+----------+-----------------------+ + callee arg register save local caller arg + disp max_func_args*SIZE_OF_INT + lvar<0 lvar>0x1000 0000 prev $sp=$fp $sp=$fp */ @@ -344,7 +346,6 @@ #define func_disp_offset 8 #define code_disp_offset 0 -#define jump_offset 0 #define CODE_LVAR(l) ((l)+code_disp_offset) #define CODE_CALLER_ARG(l) ((l)+arg_offset1) @@ -356,15 +357,29 @@ code_offset_set(NMTBL *fnptr) { int lvar_offsetv; - // int code_f = (fnptr->sc==CODE); + int r1_offsetv; + int code_f = (fnptr->sc==CODE); disp &= -SIZE_OF_INT; - lvar_offsetv = - -12 - max_reg_var*SIZE_OF_INT-max_freg_var*SIZE_OF_DOUBLE; + + if (code_f) { + r1_offsetv = disp-max_func_args*SIZE_OF_INT; + printf("\t.set .L%d, %d\n",r1_offset_label,r1_offsetv); + } else { + lvar_offsetv = + -12 - max_reg_var*SIZE_OF_INT-max_freg_var*SIZE_OF_DOUBLE; + printf("\t.set .L%d, %d\n",lvar_offset_label,lvar_offsetv); + } + if (max_func_arg_label) { + printf(".set L_%d,%d\n",max_func_arg_label,max_func_args*SIZE_OF_INT); + max_func_arg_label = 0; + } + + // printf(" @ args = %d, pretend = %d, frame = %d\n", // max_func_args,0,round16(-disp)); // printf(" @ frame_needed = 1, current_function_anonymous_args = 0\n"); - printf("\t.set .L%d, %d\n",lvar_offset_label,lvar_offsetv); + #if 0 printf("# vars= %d, regs= %d/%d, args= %d, extra= %d\n", @@ -627,7 +642,7 @@ get_register(void) { /* 使われていないレジスタを調べる */ int i,j,reg; - for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { + for(i=MAX_TMP_REG;i>=MIN_TMP_REG;i--) { if (regs[i]) continue; /* 使われている */ regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ return i; /* その場所を表す番号を返す */ @@ -662,7 +677,7 @@ } } /* PTR_CACHE をつぶす */ - for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { + for(i=MAX_TMP_REG;i>=MIN_TMP_REG;i--) { if (regs[i]==PTRC_REG) { clear_ptr_cache_reg(i); } else @@ -709,10 +724,11 @@ if (i!=-1) regs[i]=USING_DREG; return i; } - for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) { - if (regs[i]) continue; /* 使われている */ - regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ - return i; /* その場所を表す番号を返す */ + for(i=0;i<MAX_TMP_FREG;i++) { + reg = i+MIN_TMP_FREG+FREG_OFFSET; + if (regs[reg]) continue; /* 使われている */ + regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ + return reg; /* その場所を表す番号を返す */ } /* search register stack */ for(i=0;i<freg_sp;i++) { @@ -723,11 +739,11 @@ return reg; } } - for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) { - reg =FREG_VAR_BASE-i+FREG_OFFSET; + for(i=0;i<FREG_VAR_MAX;i++) { + reg =FREG_VAR_BASE+i+FREG_OFFSET; if (! regs[reg]) { /* 使われていないなら */ regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ - if (i+1>max_freg_var) max_freg_var=i+1; + if (i>max_freg_var) max_freg_var=i; return reg; /* その場所を表す番号を返す */ } } @@ -852,11 +868,11 @@ int j; if (is_code) { if (!(arch_mode&UseFPP)) { - if(!(i<FREG_VAR_BASE-FREG_VAR_MIN)) return 0; - i = FREG_VAR_BASE-i+FREG_OFFSET; + if(i>MAX_CODE_INPUT_DREGISTER_VAR) return 0; + i = FREG_VAR_BASE+i+FREG_OFFSET; return list3(FREGISTER,i,(int)n); } else { - return 0; + return get_input_lregister_var(i,n,is_code); } } if (d) { @@ -1126,20 +1142,20 @@ return list2(LVAR,new_lvar(SIZE_OF_INT)); } -#define freg_var_num(i) (FREG_VAR_BASE-i+FREG_OFFSET) +#define freg_var_num(i) (FREG_VAR_BASE+i+FREG_OFFSET) int get_dregister_var(NMTBL *n,int d) { int i,j; if ((arch_mode&UseFPP)) { - for(i=0;i<FREG_VAR_BASE-FREG_VAR_MIN;i++) { + for(i=0;i<FREG_VAR_MAX;i++) { j = freg_var_num(i); if (! regs[j]) { /* 使われていないなら */ regs[j]=USING_REG; /*そのレジスタを使うことを宣言し*/ if (i+1>max_freg_var) max_freg_var=i+1; /* その場所を表す番号を返す */ - return list3(d?DREGISTER:FREGISTER,j,(int)n); + return list3(FREGISTER,j,(int)n); } } } @@ -2201,7 +2217,7 @@ not_simple_p(int e3) { switch(e3) { - case FUNCTION: case CONV: case RSTRUCT: case STASS: case ALLOCA: + case FUNCTION: case CONV: case STASS: case ALLOCA: case DIV : case UDIV : case MOD : case UMOD : case LDIV: case LUDIV: case LMOD: case LUMOD: case LMUL: case LUMUL: @@ -2658,7 +2674,9 @@ crn = register_name(reg); inc_inst(2); printf("\trsb\tsp, %s, sp\n",crn); - printf("\tmov\t%s, sp\n",crn); + if (!max_func_arg_label) max_func_arg_label = fwdlabel(); + code_label_value(max_func_arg_label ,REG_ip); + printf("\tadd\t%s, sp, ip\n",crn); } void @@ -2681,7 +2699,7 @@ code_jmp(char *s) { // jump to continuation means use all register variable max_reg_var = REG_VAR_MAX-REG_VAR_MIN; - max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; + max_freg_var = FREG_VAR_MAX-FREG_VAR_MIN; inc_inst(1); printf("\tb\t%s\n",s); control=0; @@ -2691,7 +2709,7 @@ code_indirect_jmp(int e2) { // jump to continuation means use all register variable max_reg_var = REG_VAR_MAX-REG_VAR_MIN; - max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; + max_freg_var = FREG_VAR_MAX-FREG_VAR_MIN; use_int(e2); inc_inst(1); printf("\tmov\tpc, %s @ indirect jump\n",register_name(e2)); // ?! @@ -3266,11 +3284,11 @@ if (stmode!=STATIC) printf("\t.globl\t%s\n",name); printf("\t.type\t%s,function\n",name); - lvar_offset_label = fwdlabel(); + r1_offset_label = fwdlabel(); max_func_args = 0; printf("%s:\n",name); - jmp(entry_label = fwdlabel()); - register_save_return_label = backdef(); + code_label_value(r1_offset_label,REG_ip); + printf("\tadd\tsp, ip, fp\n"); } @@ -3285,10 +3303,7 @@ void code_leave(char *name) { - fwddef(entry_label); code_offset_set(fnptr); - code_add(REG_sp,disp,REG_fp); - jmp(register_save_return_label); local_table(); printf("\t.size\t%s,.L%d-%s\n",name, backdef(),name); } @@ -3360,10 +3375,6 @@ } #if R1SAVE #else - inc_inst(1); - printf("\tsub\tfp, "); -// printf("fp, #%d+.L%d\n",FUNC_LVAR(0),lvar_offset_label); - printf("fp, #%d\n",FUNC_LVAR(0)); #endif } fwddef(retlabel);
--- a/mc-code-powerpc.c Sat Oct 23 23:26:33 2004 +0900 +++ b/mc-code-powerpc.c Sun Oct 24 21:07:46 2004 +0900 @@ -1571,7 +1571,7 @@ break; default: if (length <0) { - if (length > -MAX_COPY_LEN) { + if (length >= -MAX_COPY_LEN) { for(;length<=-4;length+=4,offset-=4) emit_copy(from,to,-4,offset-4,0,det); for(;length<=-2;length+=2,offset-=2) @@ -1591,11 +1591,13 @@ } clear_ptr_cache(); code_save_stacks(); - printf("\tli r5,%d\n",length); + printf("\tli r5,%d\n",length>0?length:-length); printf("\tmr r4,%s\n",frn); printf("\tmr r3,%s\n",trn); - //if (offset) - // code_add(3,offset,3); + if (length<0 && offset) { + code_add(4,offset,4); + code_add(3,offset,3); + } /* overrap must be allowed */ printf("\tbl L_%s$stub\n",memmove); extern_define(memmove,0,FUNCTION,1); @@ -1823,7 +1825,7 @@ static int not_simple_p(int e3) { - return e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS|| + return e3==FUNCTION||e3==CONV/*||e3==RSTRUCT*/||e3==STASS|| e3==LLSHIFT||e3==LULSHIFT||e3==LRSHIFT||e3==LURSHIFT|| e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD||e3==LASSOP||e3==ALLOCA; }
--- a/mc-codegen.c Sat Oct 23 23:26:33 2004 +0900 +++ b/mc-codegen.c Sun Oct 24 21:07:46 2004 +0900 @@ -951,8 +951,15 @@ return 1; } if ((s1=overlap(t1,sz,*source))) { + if (s==s1) { +#if DEBUG_PARALLEL_ASSIGN +printf("# self dependency %d ty %d+%d sz %d\n",car(s1),ty,cadr(s1),sz); +#endif + return 1; + } /* another overlap start over */ - return circular_dependency(t,s1,target,source); + s = s1; target0 = *target; + continue; } } target0=cadr(target0); @@ -1048,13 +1055,13 @@ if (ce1==LVAR) { switch(ce2) { case RLVAR: case CRLVAR: case FRLVAR: case DRLVAR: - case SRLVAR: case SURLVAR: case CURLVAR: + case SRLVAR: case SURLVAR: case CURLVAR: case LVAR: return 1; } } else if (ce2==LVAR) { switch(ce1) { case RLVAR: case CRLVAR: case FRLVAR: case DRLVAR: - case SRLVAR: case SURLVAR: case CURLVAR: case LRLVAR: + case SRLVAR: case SURLVAR: case CURLVAR: case LRLVAR: case LVAR: return 1; } } else if (ce1==GVAR) { @@ -1105,7 +1112,9 @@ int processing = 0; int use = 0; - /* まず、サイズを計算しながら、決まった形に落す。 */ + /* e1 = list4(FUNCTION,code_segment,arglist,ftype); */ + + /* まず、サイズを計算しながら、target を決まった形に落す。 */ arg_size = 0; regs = 0; fregs = 0; @@ -1120,6 +1129,7 @@ } else if ((ty==LONGLONG||ty==ULONGLONG) && (r = get_input_lregister_var(fregs,0,1))) { target=list4(r, target,ty,e2); regs+=2; } else { + while(car(e2)==RSTRUCT) e2=cadr(e2); target=list4(list2(LVAR,0), target,ty,e2); } /* keep arg space for register variables */ @@ -1296,6 +1306,9 @@ e3 = cadr(e2); /* offset of the variable (distination) */ e4 = caddr(e1); /* right value (source) */ sz = cadddr(e1); /* size of struct or union */ + if (car(e4)==RSTRUCT) { + e4 = cadr(e4); + } if (is_same_type(e2,e4)&&cadr(e2)==cadr(e4)) { if (use) g_expr(e4); return; @@ -1306,7 +1319,6 @@ xreg = emit_pop(0); /* 一般的にはコピーのオーバラップの状況は実行時にしかわからない */ /* しかし、わかる場合もある */ - if (car(e4)==RSTRUCT) e4=cadr(e4); if (is_same_type(e2,e4)) { if(cadr(e2)<cadr(e4)) { offset=sz; sz=-sz;} det=1;