# HG changeset patch # User kono # Date 1089585203 -32400 # Node ID 91849fdeea60d49af5303738c03821fdc9484b77 # Parent 9bc42f69f65315297facefb8a62a0328c85be050 PowerPC large offset. diff -r 9bc42f69f653 -r 91849fdeea60 Changes --- 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 +を壊してしまう。 diff -r 9bc42f69f653 -r 91849fdeea60 mc-code-powerpc.c --- 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