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 {