Mercurial > hg > CbC > old > device
diff mc-code-powerpc.c @ 660:3e1dba5758d8
*** empty log message ***
author | kono |
---|---|
date | Wed, 31 Jan 2007 16:06:04 +0900 |
parents | cddab906095e |
children | c9df4e08da9b |
line wrap: on
line diff
--- a/mc-code-powerpc.c Wed Jan 24 14:31:50 2007 +0900 +++ b/mc-code-powerpc.c Wed Jan 31 16:06:04 2007 +0900 @@ -153,6 +153,7 @@ static int max_reg_var, max_freg_var; +#ifdef __APPLE__ static char *reg_name[] = { "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9", "r10","r11","r12","r13","r14","r15","r16","r17","r18","r19", @@ -163,6 +164,19 @@ "f20","f21","f22","f23","f24","f25","f26","f27","f28","f29", "f30","f31" }; +#else +// PS3 (PowerPC Fedora Core) +static char *reg_name[] = { + "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", + "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" +}; +#endif #define round4(i) ((i+(SIZE_OF_INT-1))&~(SIZE_OF_INT-1)) @@ -373,6 +387,8 @@ static int large_offset_reg; +#ifdef __APPLE__ + static void lvar(int l) { @@ -448,12 +464,95 @@ } else { /* callee's arguments */ if (LARGE_OFFSET(CALLEE_ARG(l))) { rn=register_name(large_offset_reg=get_register()); - printf("\taddis %s,r30,lo16(%d+L_%d)\n", + printf("\taddis %s,r30,ha16(%d+L_%d)\n", rn,CALLEE_ARG(l),lvar_offset_label); } } } +#else /* PS3 */ + +static void +lvar(int l) +{ + char *rn; + if (!large_offset_reg) { + if (is_code(fnptr)) { + if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ + printf("%d@l(1)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); + } else + printf("%d@l(30)\n",CODE_LVAR(l)); + } else if (l<0) { /* local variable */ + printf("%d@l(30)\n",FUNC_LVAR(l)); + } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ + printf("%d@l(1)\n",CALLER_ARG(l-ARG_LVAR_OFFSET)); + } else { /* callee's arguments */ + printf("%d+L_%d@l(30)\n",CALLEE_ARG(l),lvar_offset_label); + } + } else { + rn = register_name(large_offset_reg); + if (is_code(fnptr)) { + if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ + printf("%d@l(%s)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),rn); + } else + printf("%d@l(%s)\n",CODE_LVAR(l),rn); + } else if (l<0) { /* local variable */ + printf("%d@l(%s)\n",FUNC_LVAR(l),rn); + } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ + printf("%d@l(%s)\n",CALLER_ARG(l-ARG_LVAR_OFFSET),rn); + } else { /* callee's arguments */ + printf("%d+L_%d@l(%s)\n",CALLEE_ARG(l),lvar_offset_label,rn); + } + free_register(large_offset_reg); + } +} + +/* if size of local variables / input variables is more then 64k, + lo16 does not work. We have to use ha16 also. But we can't know + the exact size in one path compile. We may safely use lvar16ha + if disp or max_func_args > 32k. Of course this is redundant for + smaller offset. But who cares who use very large local variables? + */ + +#define LARGE_OFFSET(l) (l<-32000||l>32000) + +static void +lvar_intro(int l) +{ + char *rn; + large_offset_reg=0; + if (is_code(fnptr)) { + if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ + if (LARGE_OFFSET(CODE_CALLER_ARG(l-ARG_LVAR_OFFSET))) { + rn=register_name(large_offset_reg=get_register()); + printf("\tla %s,1,%d@ha\n",rn, + CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); + } + } else { + if (LARGE_OFFSET(CODE_LVAR(l))) { + rn=register_name(large_offset_reg=get_register()); + printf("\tla %s,30,%d@ha\n",rn,CODE_LVAR(l)); + } + } + } else if (l<0) { /* local variable */ + if (LARGE_OFFSET(FUNC_LVAR(l))) { + rn=register_name(large_offset_reg=get_register()); + printf("\tla %s,30,%d@ha\n",rn,FUNC_LVAR(l)); + } + } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ + if (LARGE_OFFSET(CALLER_ARG(l-ARG_LVAR_OFFSET))) { + rn=register_name(large_offset_reg=get_register()); + printf("\tla %s,1,%d@ha\n",rn,CALLER_ARG(l-ARG_LVAR_OFFSET)); + } + } else { /* callee's arguments */ + if (LARGE_OFFSET(CALLEE_ARG(l))) { + rn=register_name(large_offset_reg=get_register()); + printf("\tla %s,30,%d+L_%d@ha\n", + rn,CALLEE_ARG(l),lvar_offset_label); + } + } +} +#endif void code_lvar(int e2,int reg) { @@ -1140,12 +1239,15 @@ return xreg; } +#ifdef __APPLE__ static int code_base; +#endif extern void code_ptr_cache_def(int r,NMTBL *nptr) { char *rrn = register_name(r); +#ifdef __APPLE__ if (nptr->sc==STATIC && !(is_code(nptr)||is_function(nptr))) { printf("\taddis %s,r31,ha16(_%s-L_%d)\n", rrn,nptr->nm,code_base); @@ -1157,6 +1259,12 @@ printf("\tlwz %s,lo16(L_%s$non_lazy_ptr-L_%d)(%s)\n", rrn,nptr->nm,code_base,rrn); } +#else + printf("\tlis %s,%s@ha\n", + rrn,nptr->nm); + printf("\tla %s,%s@l(%s)\n", + rrn,nptr->nm,rrn); +#endif } static char *cload(int sz) { return sz==1?"lbz":sz==SIZE_OF_SHORT?"lhz":"lwz"; } @@ -1184,7 +1292,11 @@ code_label(int labelno) { clear_ptr_cache(); +#ifdef __APPLE__ printf("L_%d:\n",labelno); +#else + printf(".LC%d:\n",labelno); +#endif } static void @@ -1196,8 +1308,13 @@ if(r!=reg) printf("\tmr %s,%s\n",crn,rrn); } else if (LARGE_OFFSET(offset)) { +#ifdef __APPLE__ printf("\tla %s,lo16(%d)(%s)\n",crn,offset,rrn); printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); +#else + printf("\tla %s,%d@l(%s)\n",crn,offset,rrn); + printf("\taddis %s,%s,%d@ha\n",crn,crn,offset); +#endif } else printf("\taddi %s,%s,%d\n",crn,rrn,offset); } @@ -1208,8 +1325,13 @@ char *crn = register_name(reg); char *rrn = register_name(r); if (LARGE_OFFSET(offset)) { +#ifdef __APPLE__ printf("\taddis %s,%s,ha16(%d)\n",crn,rrn,offset); printf("\t%s %s,lo16(%d)(%s)\n",ld,crn,offset,crn); +#else + printf("\taddis %s,%s,%d@ha\n",crn,rrn,offset); + printf("\t%s %s,%d@l(%s)\n",ld,crn,offset,crn); +#endif } else printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn); } @@ -1222,8 +1344,13 @@ char *lrn; if (offset<-32768||32767<offset) { lrn = register_name(reg = get_register()); +#ifdef __APPLE__ printf("\taddis %s,%s,ha16(%d)\n",lrn,rrn,offset); printf("\t%s %s,lo16(%d)(%s)\n",ld,crn,offset,lrn); +#else + printf("\taddis %s,%s,%d@ha\n",lrn,rrn,offset); + printf("\t%s %s,%d@l(%s)\n",ld,crn,offset,lrn); +#endif free_register(reg); } else printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn); @@ -1318,8 +1445,13 @@ char *crn; use_int(reg); crn = register_name(reg); +#ifdef __APPLE___ printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",crn,label,code_base); printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",crn,label,code_base,crn); +#else + printf("\tlis %s,.LC%d@ha\n",crn,label); + printf("\tla %s,.LC%d@l(%s)\n",crn,label,crn); +#endif return; } @@ -1329,6 +1461,7 @@ use_int(reg); crn = register_name(reg); // printf("## 0x%08x\n",e2); +#ifdef __APPLE__ if (-32768<e2&&e2<32768) printf("\tli %s,%d\n",crn,e2); else if ((e2&0xffff)==0) @@ -1337,6 +1470,16 @@ printf("\tlis %s,ha16(%d)\n",crn,e2); printf("\taddi %s,%s,lo16(%d)\n",crn,crn,e2); } +#else + if (-32768<e2&&e2<32768) + printf("\tli %s,%d\n",crn,e2); + else if ((e2&0xffff)==0) + printf("\tlis %s,%d@ha\n",crn,e2); + else { + printf("\tlis %s,%d@ha\n",crn,e2); + printf("\taddi %s,%s,%d@l\n",crn,crn,e2); + } +#endif } void @@ -1357,8 +1500,13 @@ void code_lnot(int creg) { use_int(creg); +#ifdef __APPLE__ printf("\tsubfic r0,%s,0\n", register_name(creg)); printf("\tadde %s,r0,%s\n", register_name(creg),register_name(creg)); +#else + printf("\tsubfic 0,%s,0\n", register_name(creg)); + printf("\tadde %s,0,%s\n", register_name(creg),register_name(creg)); +#endif } void @@ -1425,9 +1573,7 @@ code_return(int creg) { char *crn; use_int(creg); - crn = register_name(creg); - printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",crn,retcont,code_base); - printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",crn,retcont,code_base,crn); + code_label_value(retcont,creg); } #define R1SAVE 0 @@ -1437,9 +1583,9 @@ /* save frame pointer */ use_int(creg); #if R1SAVE - printf("\tlwz %s,0(r1)\n",register_name(creg)); + printf("\tlwz %s,0(%s)\n",register_name(creg),register_name(1)); #else - printf("\tmr %s,r30\n",register_name(creg)); + printf("\tmr %s,%s\n",register_name(creg),register_name(30)); // int l = 0; // printf("\tla %s,",register_name(creg)); // printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); @@ -1513,7 +1659,11 @@ code_ld(cload(sz),reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1))); cext(0,sz,reg); inc_cmpflag(); +#ifdef __APPLE__ printf("\tcmpwi cr%d,%s,0\n",cmpflag,register_name(reg)); +#else + printf("\tcmpwi %d,%s,0\n",cmpflag,register_name(reg)); +#endif jcond(label,cond); } @@ -1555,7 +1705,11 @@ code_cmp_register(int e2,int label,int cond) { use_int(e2); inc_cmpflag(); +#ifdef __APPLE__ printf("\tcmpwi cr%d,%s,0\n",cmpflag,register_name(e2)); +#else + printf("\tcmpwi %d,%s,0\n",cmpflag,register_name(e2)); +#endif jcond(label,cond); } @@ -1564,7 +1718,6 @@ code_string(int e1,int creg) { int lb; - char *crn; NMTBL *n = (NMTBL *)cadr(e1); if ((lb=attr_value(n,LABEL))) { // already defined @@ -1572,7 +1725,6 @@ } use_int(creg); - crn = register_name(creg); lb = emit_string_label(); ascii(n->nm); if (output_mode==TEXT_EMIT_MODE) { @@ -1580,8 +1732,7 @@ } else { text_mode(0); } - printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",crn,lb,code_base); - printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",crn,lb,code_base,crn); + code_label_value(lb,creg); set_attr(n,LABEL,lb); } @@ -1648,10 +1799,17 @@ l = list3(4,l,from); parallel_rassign(l); +#ifdef __APPLE__ printf("\tli r5,%d\n",length>0?length:-length); /* offset should be ignored */ /* overrap must be allowed */ printf("\tbl L_%s$stub\n",memmove); +#else + printf("\tli 5,%d\n",length>0?length:-length); + /* offset should be ignored */ + /* overrap must be allowed */ + printf("\tbl %s\n",memmove); +#endif extern_define(memmove,0,FUNCTION,1); set_ireg(RET_REGISTER,0); //if (creg!=to) { @@ -1779,9 +1937,9 @@ if (!is_longlong_reg(reg)) { error(-1); return; } if (mode) { if (regv_l(reg)!=3) - printf("\tmr r3,%s\n", lregister_name_high(reg)); + printf("\tmr %s,%s\n", register_name(3),lregister_name_high(reg)); if (regv_l(reg)!=4) - printf("\tmr r4,%s\n", lregister_name_low(reg)); + printf("\tmr %s,%s\n", register_name(4),lregister_name_low(reg)); } } @@ -1792,9 +1950,9 @@ if (!is_longlong_reg(reg)) { error(-1); return; } if (mode) { if (regv_l(reg)!=5) - printf("\tmr r5,%s\n", lregister_name_high(reg)); + printf("\tmr %s,%s\n", register_name(5),lregister_name_high(reg)); if (regv_l(reg)!=6) - printf("\tmr r6,%s\n", lregister_name_low(reg)); + printf("\tmr %s,%s\n", register_name(6),lregister_name_low(reg)); } } @@ -2248,7 +2406,11 @@ } clear_ptr_cache(); if (car(e2) == FNAME) { +#ifdef __APPLE__ printf("\tbl\tL_%s$stub\n",fn->nm); +#else + printf("\tbl\t%s\n",fn->nm); +#endif } else { jrn = register_name(cadr(jmp)); printf("\tmtctr %s\n",jrn); @@ -2288,13 +2450,18 @@ crn = register_name(reg); grn = register_name(g); // printf("\trlwinm r0,%s,0,0,27\n",crn); - printf("\tlwz %s,0(r1)\n",grn); + printf("\tlwz %s,0(%s)\n",grn,register_name(1)); printf("\tneg %s,%s\n",crn,crn); - printf("\tstwux %s,r1,%s\n",grn,crn); + printf("\tstwux %s,%s,%s\n",grn,register_name(1),crn); // printf("\tstw %s,0(r1)\n",grn); if (!max_func_arg_label) max_func_arg_label = fwdlabel(); +#ifdef __APPLE__ printf("\taddis r1,r1,ha16(L_%d)\n",max_func_arg_label); printf("\taddi %s,r1,lo16(L_%d)\n",crn,max_func_arg_label); +#else + printf("\taddis 1,1,.LC%d@ha\n",max_func_arg_label); + printf("\taddi %s,1,.LC%d@l\n",crn,max_func_arg_label); +#endif free_register(g); } @@ -2302,9 +2469,9 @@ code_frame_pointer(int e3) { use_int(e3); #if R1SAVE - printf("\tmr r1,%s\n",register_name(e3)); + printf("\tmr %s,%s\n",register_name(1),register_name(e3)); #else - printf("\tmr r30,%s\n",register_name(e3)); + printf("\tmr %s,%s\n",register_name(30),register_name(e3)); #endif } @@ -2326,7 +2493,11 @@ code_jmp(char *s) { max_reg_var = REG_VAR_BASE-REG_VAR_MIN; max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; +#ifdef __APPLE__ printf("\tb L_%s$stub\n",s); +#else + printf("\tb %s\n",s); +#endif control=0; } @@ -2341,6 +2512,22 @@ control=0; } +static void +code_add_op(char *op, char *crn, int offset, char *rrn) +{ +#ifdef __APPLE__ + 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); +#else + if (LARGE_OFFSET(offset)) { + printf("\taddis %s,%s,%d@ha\n",crn,crn,offset); + } + printf("\t%s %s,%d@l(%s)\n",cload(sz),rrn,offset,crn); +#endif +} + void code_rindirect(int e1, int reg,int offset, int sign,int sz) { @@ -2350,10 +2537,7 @@ crn=register_name(creg); use_int(reg); rrn=register_name(reg); - 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); + code_add_op(cload(sz),rrn,offset,crn); cext(sign,sz,reg); } @@ -2366,21 +2550,20 @@ if (!is_int_reg(creg)) error(-1); crn=register_name(creg); use_float(d,reg); - 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); + code_add_op(fload(d),fregister_name(reg),offset,crn); return d?DOUBLE:FLOAT; } #endif #if LONGLONG_CODE + + static void lload(int creg,int reg,int offset) { char *crn = register_name(creg); +#ifdef __APPLE__ if (LARGE_OFFSET(offset)) { printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); } @@ -2401,6 +2584,29 @@ printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset,crn); } #endif +#else + if (LARGE_OFFSET(offset)) { + printf("\taddis %s,%s,%d@ha\n",crn,crn,offset); + } +#if ENDIAN_L==0 + if (creg!=regv_l(reg)) { + printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset,crn); + printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn); + } else { + printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn); + printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset,crn); + } +#else + if (creg!=regv_h(reg)) { + printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset,crn); + printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); + } else { + printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); + printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset,crn); + } +#endif + +#endif } int @@ -2431,7 +2637,7 @@ use_int(creg); crn=register_name(creg); lvar_intro(e2); - printf("\t%s %s,",cstore(byte),crn); + printf("\t%s %s,",cstore(byte),crn); lvar(e2); } @@ -2613,31 +2819,59 @@ printf("\tsrwi %s,%s,%d\n",crn,crn,v); return; case ADD: +#ifdef __APPLE__ printf("\taddi %s,%s,lo16(%d)\n",crn,crn,v); +#else + printf("\taddi %s,%s,%d@l\n",crn,crn,v); +#endif break; case SUB: +#ifdef __APPLE__ printf("\taddi %s,%s,lo16(-%d)\n",crn,crn,v); +#else + printf("\taddi %s,%s,-%d@l\n",crn,crn,v); +#endif break; case CMP: inc_cmpflag(); +#ifdef __APPLE__ printf("\tcmpwi cr%d,%s,lo16(%d)\n",cmpflag,crn,v); +#else + printf("\tcmpwi %d,%s,%d@l\n",cmpflag,crn,v); +#endif break; case UCMP: inc_cmpflag(); +#ifdef __APPLE__ printf("\tcmplwi cr%d,%s,lo16(%d)\n",cmpflag,crn,v); +#else + printf("\tcmplwi %d,%s,%d@l\n",cmpflag,crn,v); +#endif break; case EOR: +#ifdef __APPLE__ printf("\txori %s,%s,lo16(%d)\n",crn,crn,v); +#else + printf("\txori %s,%s,%d@l\n",crn,crn,v); +#endif break; case BOR: +#ifdef __APPLE__ printf("\tori %s,%s,lo16(%d)\n",crn,crn,v); +#else + printf("\tori %s,%s,%d@l\n",crn,crn,v); +#endif break; case MUL: case UMUL: if ((l=ilog(v))) { printf("\tslwi %s,%s,%d\n",crn,crn,l); } else +#ifdef __APPLE__ printf("\tmulli %s,%s,lo16(%d)\n",crn,crn,v); +#else + printf("\tmulli %s,%s,%d@l\n",crn,crn,v); +#endif break; default: error(-1); @@ -2678,14 +2912,22 @@ /* used in dosiwtch() */ inc_cmpflag(); if (-32767<e&&e<32767) { +#ifdef __APPLE__ printf("\tcmpwi cr%d,%s,%d\n",cmpflag,register_name(csreg),e); +#else + printf("\tcmpwi %d,%s,%d\n",cmpflag,register_name(csreg),e); +#endif jcond(label,cond); } else { regsv = regs[csreg]; regs[csreg]=USING_REG; reg = get_register(); regs[csreg]= regsv; code_const(e,reg); +#ifdef __APPLE__ printf("\tcmpw cr%d,%s,%s\n",cmpflag,register_name(csreg),register_name(reg)); +#else + printf("\tcmpw %d,%s,%s\n",cmpflag,register_name(csreg),register_name(reg)); +#endif jcond(label,cond); free_register(reg); } @@ -2772,16 +3014,28 @@ jcond(int l, char cond) { if (cond==LT) { +#ifdef __APPLE__ printf("\tb%s cr%d,L_%d\n",code_ge(0),cmpflag,l); +#else + printf("\tb%s %d,L_%d\n",code_ge(0),cmpflag,l); +#endif } else if (cond==1||cond==0) { +#ifdef __APPLE__ printf("\tb%s cr%d,L_%d\n",cond?"ne":"eq",cmpflag,l); +#else + printf("\tb%s %d,.LC%d\n",cond?"ne":"eq",cmpflag,l); +#endif } else error(-1); } void jmp(int l) { +#ifdef __APPLE__ printf("\tb\tL_%d\n",l); +#else + printf("\tb\t.LC%d\n",l); +#endif } extern void @@ -2793,6 +3047,7 @@ void code_enter(char *name) { +#ifdef __APPLE__ if (output_mode!=TEXT_EMIT_MODE) text_mode(0); else @@ -2815,6 +3070,27 @@ printf("\tmflr r31\n"); max_func_args = 0; clear_ptr_cache(); +#else + if (output_mode!=TEXT_EMIT_MODE) + text_mode(0); + else + printf("\t.align 2\n"); + if (stmode!=STATIC) + printf(".globl %s\n",name); +#ifdef DOT_SIZE + printf("\t.type\t%s,@function\n",name); +#endif + printf("%s:\n",name); + code_disp_label=fwdlabel(); +#if 0 + printf("\tla r1,lo16(L_%d)(r30)\n",code_disp_label); +#else + printf("\tla r1,.LC%d@l(r30)\n",code_disp_label); + printf("\taddis r1,r1,.LC%d@ha\n",code_disp_label); +#endif + max_func_args = 0; + clear_ptr_cache(); +#endif } @@ -2832,12 +3108,19 @@ int r1_offsetv; disp&= -SIZE_OF_INT; r1_offsetv = -disp+max_func_args*SIZE_OF_INT -code_disp_offset0 +8+32+48; - +#ifdef __APPLE__ printf(".set L_%d,%d\n",code_disp_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; } +#else + printf(".set .LC%d,%d\n",code_disp_label,-r1_offsetv); + if (max_func_arg_label) { + printf(".set .LC%d,%d\n",max_func_arg_label,max_func_args*SIZE_OF_INT+24); + max_func_arg_label = 0; + } +#endif local_table(); // free_all_register(); } @@ -2845,6 +3128,7 @@ void enter(char *name) { +#ifdef __APPLE__ if (output_mode!=TEXT_EMIT_MODE) text_mode(0); else @@ -2873,6 +3157,34 @@ printf("\tstwux r1,r1,r31\n"); #endif printf("\tmflr r31\n"); +#else + if (output_mode!=TEXT_EMIT_MODE) + text_mode(0); + else + printf("\t.align 2\n"); + if (stmode!=STATIC) + printf(".globl _%s\n",name); +/* + printf("\t.type\t%s,@function\n",name); + */ + printf("%s:\n",name); + code_setup=fwdlabel(); + printf("\tmflr 0\n"); + printf("\tbl .LC%d\n",code_setup); + 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"); +#else + printf("\taddi 30,1,-L_%d@l\n",lvar_offset_label); + printf("\tlis 31,-L_%d@ha\n",r1_offset_label); + printf("\taddi 31,31,-L_%d@l\n",r1_offset_label); + printf("\tstwux 1,1,31\n"); +#endif + printf("\tmflr 31\n"); +#endif max_func_args = 0; clear_ptr_cache(); } @@ -2898,7 +3210,11 @@ void code_label_call(int l) { +#ifdef __APPLE__ printf("\tbl\tL_%d\n",l); +#else + printf("\tbl\t.LC%d\n",l); +#endif } void @@ -3508,8 +3824,7 @@ } else { text_mode(0); } - printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",rrn,lb,code_base); - printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",rrn,lb,code_base,rrn); + code_label_value(lb,rrn); if (d) { printf("\tlfd %s,0(%s)\n",frn,rrn); } else { @@ -3567,8 +3882,7 @@ } else { text_mode(0); } - printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",rrn,lb,code_base); - printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",rrn,lb,code_base,rrn); + code_label_value(lb,rrn); if (d) { printf("\tlfd %s,0(%s)\n",frn,rrn); } else {