Mercurial > hg > CbC > old > device
diff mc-code-powerpc.c @ 375:91849fdeea60
PowerPC large offset.
author | kono |
---|---|
date | Mon, 12 Jul 2004 07:33:23 +0900 |
parents | 238c3704ee3d |
children | 832e1f6bba82 |
line wrap: on
line diff
--- 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",