Mercurial > hg > CbC > old > device
changeset 375:91849fdeea60
PowerPC large offset.
author | kono |
---|---|
date | Mon, 12 Jul 2004 07:33:23 +0900 |
parents | 9bc42f69f653 |
children | d81e1be4036f |
files | Changes mc-code-powerpc.c mc-codegen.c test/basic.c test/offset.c |
diffstat | 5 files changed, 161 insertions(+), 73 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Sun Jul 11 20:59:52 2004 +0900 +++ b/Changes Mon Jul 12 07:33:23 2004 +0900 @@ -5761,3 +5761,20 @@ ん、だが.... + <------r1_offset------------------------------> + <-lvar_offset-------> + r+ +------------+---+-------+------------------+--------------+----+ - + callee arg xx local register save caller arg xx + disp reg_save max_func_args*SIZE_OF_INT + lvar>0 lvar<0 lvar>0x1000 0000 + r30 r1 + +とするのは、PowerPC では変更が大きすぎる。レジスタセーブする場所 +が良くわからないし。 + +もしかして、register save 領域は固定?! + +Mon Jul 12 05:35:33 JST 2004 + +うーん、やっぱり、難しいよな... 何故か、printf が local variable +を壊してしまう。
--- a/mc-code-powerpc.c Sun Jul 11 20:59:52 2004 +0900 +++ b/mc-code-powerpc.c Mon Jul 12 07:33:23 2004 +0900 @@ -263,8 +263,9 @@ f24-f31 saved register variable function call stack frame - <------r1_offset------------------------------> - <------------lvar_offset-------> + <-------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 @@ -299,14 +300,16 @@ int l; #endif int lvar_offsetv = -disp+max_func_args*SIZE_OF_INT+func_disp_offset; - int r1_offsetv = -disp+max_func_args*SIZE_OF_INT-reg_save+r1_offset; - printf(".set L_%d,%d\n",lvar_offset_label,lvar_offsetv); + // int r1_offsetv = -disp+max_func_args*SIZE_OF_INT-reg_save+r1_offset; + int r1_offsetv = lvar_offsetv-reg_save+12; + printf(".set L_%d,%d\n",lvar_offset_label,r1_offsetv-lvar_offsetv); printf(".set L_%d,%d\n",r1_offset_label,r1_offsetv); if (max_func_arg_label) { printf(".set L_%d,%d\n",max_func_arg_label,max_func_args*SIZE_OF_INT+24); max_func_arg_label = 0; } +printf("# reg_save %d\n",reg_save); #if 0 printf("# function %s\n",fnptr->nm); l = ARG_LVAR_OFFSET; @@ -327,21 +330,40 @@ #endif } +static int large_offset_reg; static void -lvar8(int l) +lvar(int l) { - if (fnptr->sc==CODE) { - if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("lo16(%d)(r1)\n",CODE_CALLER_ARG); - } else - printf("lo16(%d)(r30)\n",CODE_LVAR); - } else if (l<0) { /* local variable */ - printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); - } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("lo16(%d)(r1)\n",CALLER_ARG); - } else { /* callee's arguments */ - printf("lo16(%d+L_%d)(r30)\n",CALLEE_ARG,r1_offset_label); + char *rn; + if (!large_offset_reg) { + if (fnptr->sc==CODE) { + if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ + printf("lo16(%d)(r1)\n",CODE_CALLER_ARG); + } else + printf("lo16(%d)(r30)\n",CODE_LVAR); + } else if (l<0) { /* local variable */ + printf("lo16(%d)(r30)\n",FUNC_LVAR); + } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ + printf("lo16(%d)(r1)\n",CALLER_ARG); + } else { /* callee's arguments */ + printf("lo16(%d+L_%d)(r30)\n",CALLEE_ARG,lvar_offset_label); + } + } else { + rn = register_name(large_offset_reg); + if (fnptr->sc==CODE) { + if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ + printf("lo16(%d)(%s)\n",CODE_CALLER_ARG,rn); + } else + printf("lo16(%d)(%s)\n",CODE_LVAR,rn); + } else if (l<0) { /* local variable */ + printf("lo16(%d)(%s)\n",FUNC_LVAR,rn); + } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ + printf("lo16(%d)(%s)\n",CALLER_ARG,rn); + } else { /* callee's arguments */ + printf("lo16(%d+L_%d)(%s)\n",CALLEE_ARG,lvar_offset_label,rn); + } + free_register(large_offset_reg); } } @@ -352,49 +374,44 @@ smaller offset. But who cares who use very large local variables? */ -#define LARGE_LVAR (disp<-32765||max_func_args>32765) - -static void -lvar16ha(int l) -{ - if (fnptr->sc==CODE) { - if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("la r0,ha16(%d)(r1)\n",CODE_CALLER_ARG); - } else - printf("la r0,ha16(%d)(r30)\n",CODE_LVAR); - } else if (l<0) { /* local variable */ - printf("la r0,ha16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); - } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - if (CALLER_ARG>32765) - printf("la r0,ha16(%d)(r1)\n",CALLER_ARG); - } else { /* callee's arguments */ - printf("la r0,ha16(%d+L_%d)(r30)\n",CALLEE_ARG,r1_offset_label); - } -} +#define LARGE_OFFSET(l) (l<-32000||l>32000) static void -lvar16lo(int l) +lvar_intro(int l) { + char *rn; + large_offset_reg=0; if (fnptr->sc==CODE) { - if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("lo16(%d)(r0)\n",CODE_CALLER_ARG); - } else - printf("lo16(%d)(r0)\n",CODE_LVAR); + if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ + if (LARGE_OFFSET(CODE_CALLER_ARG)) { + rn=register_name(large_offset_reg=get_register()); + printf("\taddis %s,r1,ha16(%d)\n",rn,CODE_CALLER_ARG); + } + } else { + if (LARGE_OFFSET(CODE_LVAR)) { + rn=register_name(large_offset_reg=get_register()); + printf("\taddis %s,r30,ha16(%d)\n",rn,CODE_LVAR); + } + } } else if (l<0) { /* local variable */ - printf("lo16(%d+L_%d)(r0)\n",FUNC_LVAR,lvar_offset_label); + if (LARGE_OFFSET(FUNC_LVAR)) { + rn=register_name(large_offset_reg=get_register()); + printf("\taddis %s,r30,ha16(%d)\n",rn,FUNC_LVAR); + } } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - if (CALLER_ARG>32765) - printf("lo16(%d)(r0)\n",CALLER_ARG); - else - printf("lo16(%d)(r1)\n",CALLER_ARG); + if (LARGE_OFFSET(CALLER_ARG)) { + rn=register_name(large_offset_reg=get_register()); + printf("\taddis %s,r1,ha16(%d)\n",rn,CALLER_ARG); + } } else { /* callee's arguments */ - printf("lo16(%d+L_%d)(r0)\n",CALLEE_ARG,r1_offset_label); + if (LARGE_OFFSET(CALLEE_ARG)) { + rn=register_name(large_offset_reg=get_register()); + printf("\taddis %s,r30,lo16(%d+L_%d)\n", + rn,CALLEE_ARG,lvar_offset_label); + } } } -#define lvar_intro(i) if (LARGE_LVAR) lvar16ha(i) - -#define lvar(i) if (LARGE_LVAR) lvar16lo(i); else lvar8(i) void code_lvar(int e2,int reg) { @@ -1116,7 +1133,7 @@ if (offset==0) { if(r!=reg) printf("\tmr %s,%s\n",crn,rrn); - } else if (offset<-32768||32767<offset) { + } else if (LARGE_OFFSET(offset)) { printf("\tla %s,ha16(%d)(%s)\n",crn,offset,rrn); printf("\taddi %s,%s,lo16(%d)\n",crn,crn,offset); } else @@ -1128,7 +1145,7 @@ { char *crn = register_name(reg); char *rrn = register_name(r); - if (offset<-32768||32767<offset) { + if (LARGE_OFFSET(offset)) { printf("\tla %s,ha16(%d)(%s)\n",crn,offset,rrn); printf("\t%s %s,%s,lo16(%d)\n",ld,crn,crn,offset); } else @@ -2239,7 +2256,7 @@ code_fix_frame_pointer(int disp_offset) { int l = 0; printf("\tla r30,"); - printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); + printf("lo16(%d)(r30)\n",FUNC_LVAR); } void @@ -2270,7 +2287,10 @@ crn=register_name(creg); use_int(reg); rrn=register_name(reg); - printf("\t%s %s,%d(%s)\n",cload(sz),rrn,offset,crn); + if (LARGE_OFFSET(offset)) { + printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); + } + printf("\t%s %s,lo16(%d)(%s)\n",cload(sz),rrn,offset,crn); cext(sign,sz,reg); } @@ -2283,8 +2303,12 @@ if (!is_int_reg(creg)) error(-1); crn=register_name(creg); use_float(d,reg); - printf("\t%s %s,%d(%s)\n",fload(d), + if (LARGE_OFFSET(offset)) { + printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); + } + printf("\t%s %s,lo16(%d)(%s)\n",fload(d), fregister_name(reg),offset,crn); + return d?DOUBLE:FLOAT; } #endif @@ -2293,12 +2317,15 @@ lload(int creg,int reg,int offset) { char *crn = register_name(creg); + if (LARGE_OFFSET(offset)) { + printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); + } if (creg!=regv_h(reg)) { - printf("\tlwz %s,%d(%s)\n",lregister_name_high(reg),offset,crn); - printf("\tlwz %s,%d(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); + printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset,crn); + printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); } else { - printf("\tlwz %s,%d(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); - printf("\tlwz %s,%d(%s)\n",lregister_name_high(reg),offset,crn); + printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); + printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset,crn); } } @@ -2762,8 +2789,16 @@ fwddef(code_base); r1_offset_label = fwdlabel(); lvar_offset_label = fwdlabel(); +#if 0 + printf("\taddi r30,r1,lo16(-L_%d)\n",lvar_offset_label); printf("\tstwu r1,lo16(-L_%d)(r1)\n",r1_offset_label); - printf("\tmr r30,r1\n"); + // printf("\tmr r30,r1\n"); +#else + printf("\taddi r30,r1,lo16(-L_%d)\n",lvar_offset_label); + printf("\tlis r31,ha16(-L_%d)\n",r1_offset_label); + printf("\taddi r31,r31,lo16(-L_%d)\n",r1_offset_label); + printf("\tstwux r1,r1,r31\n"); +#endif printf("\tmflr r31\n"); max_func_args = 0; } @@ -3384,10 +3419,10 @@ " mflr r10", " mtlr r0", " xoris r3,r3,0x8000", -" stw r3,-28(r30)", +" stw r3,-28(r1)", " lis r0,0x4330", -" stw r0,-32(r30)", -" lfd f0,-32(r30)", +" stw r0,-32(r1)", +" lfd f0,-32(r1)", " addis r9,r10,ha16(__i2dLC0-__i2dL1$pb)", " lfd f1,lo16(__i2dLC0-__i2dL1$pb)(r9)", " fsub f1,f0,f1", @@ -3427,16 +3462,16 @@ " cror 2,1,2", " beq- cr0,__d2uL2", " fctiwz f0,f1", -" stfd f0,-32(r30)", -" lwz r3,-28(r30)", +" stfd f0,-32(r1)", +" lwz r3,-28(r1)", " blr", "__d2uL2:", " addis r9,r10,ha16(__d2uLC0-__d2uL1$pb)", " lfd f0,lo16(__d2uLC0-__d2uL1$pb)(r9)", " fsub f0,f1,f0", " fctiwz f0,f0", -" stfd f0,-24(r30)", -" lwz r3,-20(r30)", +" stfd f0,-24(r1)", +" lwz r3,-20(r1)", " xoris r3,r3,0x8000", " blr", 0 @@ -3469,10 +3504,10 @@ "__u2dL2$pb:", " mflr r10", " mtlr r0", -" stw r3,-28(r30)", +" stw r3,-28(r1)", " lis r0,0x4330", -" stw r0,-32(r30)", -" lfd f0,-32(r30)", +" stw r0,-32(r1)", +" lfd f0,-32(r1)", " addis r9,r10,ha16(__u2dLC1-__u2dL2$pb)", " lfd f1,lo16(__u2dLC1-__u2dL2$pb)(r9)", " fsub f1,f0,f1",
--- a/mc-codegen.c Sun Jul 11 20:59:52 2004 +0900 +++ b/mc-codegen.c Mon Jul 12 07:33:23 2004 +0900 @@ -3601,7 +3601,7 @@ extern int new_lvar0(int sz) { - return disp -= sz; + return disp-=sz; } extern int
--- a/test/basic.c Sun Jul 11 20:59:52 2004 +0900 +++ b/test/basic.c Mon Jul 12 07:33:23 2004 +0900 @@ -1,3 +1,5 @@ +#define ARG_ADDRESS 0 + double ggg = 0.134; float fff = 0.0; @@ -62,6 +64,9 @@ int a0,int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8,int a9,int a10,int a11,int a12,int a13,int a14,int a15,int a16,int a17,int a18,int a19,int a20,int a21,int a22,int a23,int a24,int a25,int a26,int a27,int a28,int a29,int a30,int a31,int a32,int a33,int a34,int a35,int a36,int a37,int a38,int a39,int a40,int a41,int a42,int a43,int a44,int a45,int a46,int a47,int a48,int a49 ) { +#if ARG_ADDRESS + printf("i50: a0 %x a49 %x\n",&a0,&a49); +#endif printf("i50: %d\n", a0+a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15+a16+a17+a18+a19+a20+a21+a22+a23+a24+a25+a26+a27+a28+a29+a30+a31+a32+a33+a34+a35+a36+a37+a38+a39+a40+a41+a42+a43+a44+a45+a46+a47+a48+a49 ); @@ -111,6 +116,10 @@ void tmp1 () { +#if ARG_ADDRESS + int a0; + printf("tmp1: a0 %x\n",&a0); +#endif printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d \n", 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49
--- a/test/offset.c Sun Jul 11 20:59:52 2004 +0900 +++ b/test/offset.c Mon Jul 12 07:33:23 2004 +0900 @@ -7,12 +7,25 @@ int midium[BIT12]; int large[BIT16]; -main() + +main0(int ac,char *av[]) { int *p; int local_midium[BIT12]; int local_large[BIT16]; +#if 0 + printf("int ac =\t%x\n",&ac); + printf("int midium[0] =\t%x\n",&midium[0]); + printf("int midium[BIT12] =\t%x\n",&midium[BIT12]); + printf("int large[0] =\t%x\n",&large[0]); + printf("int large[BIT16] =\t%x\n",&large[BIT16]); + printf("int local_midium[0] =\t%x\n",&local_midium[0]); + printf("int local_midium[BIT12] =\t%x\n",&local_midium[BIT12]); + printf("int local_large[0] =\t%x\n",&local_large[0]); + printf("int local_large[BIT16] =\t%x\n",&local_large[BIT16]); +#endif + midium[0]=0x55; large[0]=0x55; local_midium[0]=0x55; @@ -64,7 +77,21 @@ 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]); + 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; } + +main(int ac,char *av[]) +{ + int i=-1,j=-2,k=-3; + + main0(ac,av); + + printf("%d %d %d %d\n",ac,i,j,k); + return 0; +} +