changeset 660:3e1dba5758d8

*** empty log message ***
author kono
date Wed, 31 Jan 2007 16:06:04 +0900
parents 2a3b1cddd45f
children f566ac85f2e0
files mc-code-powerpc.c mc-codegen.c mc-macro.c mc-parse.c mc-tree.c mc.h
diffstat 6 files changed, 388 insertions(+), 56 deletions(-) [+]
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 {
--- a/mc-codegen.c	Wed Jan 24 14:31:50 2007 +0900
+++ b/mc-codegen.c	Wed Jan 31 16:06:04 2007 +0900
@@ -902,6 +902,7 @@
 function_type(int e1,int *dots)
 {
     int ret_type,t;
+    if (e1<0) return INT;
     ret_type = type_value(cadr(e1));
     if (ret_type==CHAR) ret_type=INT;
 
@@ -2933,15 +2934,15 @@
 	    continue;
 	} else if (BINARY_ARGS(car(e))) {
         /* biary operators */
+	    arg=p(arg,e);
 	    arg=contains_p2(arg,cadr(e),p);
-	    arg=p(arg,e);
 	    e = caddr(e);
 	    continue;
 	} else if (TERNARY_ARGS(car(e))) {
         /* tarary operators */
+	    arg=p(arg,e);
 	    arg=contains_p2(arg,cadr(e), p);
 	    arg=contains_p2(arg,caddr(e),p);
-	    arg=p(arg,e);
 	    e = cadddr(e);
 	    continue;
 	} else if (NULLARY_ARGS(car(e))) {
@@ -2977,7 +2978,7 @@
 copy_expr(int e)
 {
     int smode = mode;  
-	if (!car(e)) return 0;
+	if (!e || !car(e)) return 0;
 	if (car(e)<0) {
 	    mode = GDECL;
 	    switch (car(e)){
@@ -3003,7 +3004,7 @@
 	    return glist4(car(e),copy_expr(cadr(e)),caddr(e),cadddr(e));
 	case LVAR: case RLVAR:
 	case GVAR: case RGVAR:
-	    return (e<gfree)?glist3(car(e),cadr(e),caddr(e)):e;
+	    return (e>gfree)?glist3(car(e),cadr(e),caddr(e)):e;
 	case INDIRECT: case RINDIRECT:
 	    return glist2(car(e),copy_expr(cadr(e)));
 	}
@@ -3026,7 +3027,7 @@
 	    return e;
 	} else if (NULLARY_ARGS(car(e))) {
         /* nullary operators */
-	    if (e<gfree) { // local
+	    if (e>gfree) { // local
 		int smode = mode;
 		switch(car(e)%SOP) {
 		case GVAR: case RGVAR: case URGVAR:
@@ -3575,7 +3576,7 @@
     } else if(mode==SFDINIT) {
 // if (lsrc)printf("## %d sfdinit c0(e)=%d type=%d t=%d offset=%d\n",lineno,car(e),type,t,offset);
 	decl_str_init=insert_ascend(decl_str_init,
-		list4(offset,0,e,list2(t,type)),str_init_eq);
+		glist4(offset,0,e,glist2(t,type)),str_init_eq);
     } else {
 	error(DCERR);
 	return offset;
@@ -4046,6 +4047,7 @@
     t = caddr(type_value(type));
     if (t==0) {
 	nptr0=(NMTBL*)cadddr(type);
+	if (!nptr0->ty) { error(TYERR); return 0; }
 	t = caddr(type) = caddr(nptr0->ty);
     }
     for(;t;t = cadr(t)) {
@@ -4077,7 +4079,7 @@
     if (integral(type0)||(car(type0)!=STRUCT && car(type0)!=UNION)) {
 	e=rvalue(e); type0 = type_value(type);
     }
-    if ((car(type0)!=STRUCT && car(type0)!=UNION)) {
+    if (type<=0 || (car(type0)!=STRUCT && car(type0)!=UNION)) {
 	error(TYERR); type=INT; return e; 
     }
     /* type = list4(s,disp,fields,tag_nptr); */
--- a/mc-macro.c	Wed Jan 24 14:31:50 2007 +0900
+++ b/mc-macro.c	Wed Jan 31 16:06:04 2007 +0900
@@ -112,10 +112,10 @@
 	}
 	*t++=0;
 	// evaluate generated result again
-if (0 && lsrc) {
-    printf("### %s\n",macropp);
-    if (t[-2]!='\n') putchar('\n');
-}
+// if (0 && lsrc) {
+//     printf("### %s\n",macropp);
+//     if (t[-2]!='\n') putchar('\n');
+// }
         macrop=macro_eval(macrop,macropp,0);
 	cheap = reset_cheap(&scheap);
 	macropp = cheap->ptr;
@@ -130,10 +130,10 @@
     // genrated macro will be overwrited by cheap, but it's OK, again
     mconcat = 0;
     set_lfree(slfree);
-    if (lsrc && !asmf && nptrm->sc==FMACRO) {
-	gen_comment(macropp);
-	if (t[-2]!='\n') putchar('\n');
-    }
+//     if (lsrc && !asmf && nptrm->sc==FMACRO) {
+// 	gen_comment(macropp);
+// 	if (0 && t[-2]!='\n') putchar('\n');
+//     }
     // push previous chptr, and change it to the generate macro
     chptrsave = glist2((int)chptr,chptrsave);  // push old one into the stack
     chsave = glist2(ch,chsave);
@@ -966,7 +966,10 @@
 	    body += len;
 	    c = *body;
 	    nptrm = name_space_search(nptrm,MACRO);
-	    macro = (char *)car(nptrm->dsp);
+	    if (nptrm->dsp)
+		macro = (char *)car(nptrm->dsp);
+	    else
+		macro="";
 //	    if (check_recurse(macro,history)) goto skip;
 //		string_falg = 0;
 	    switch(nptrm->sc) {
--- a/mc-parse.c	Wed Jan 24 14:31:50 2007 +0900
+++ b/mc-parse.c	Wed Jan 31 16:06:04 2007 +0900
@@ -773,10 +773,12 @@
 set_converter(char *s)
 {
     chptr = s;
-    if (macroeq("c2cbc")) conv=&c2cbc_converter;
+    if (0) ;
+#if !UDPCL
+    else if (macroeq("c2cbc")) conv=&c2cbc_converter;
     else if (macroeq("cbc2c")) conv=&cbc2c_converter;
     else if (macroeq("c")) conv=&c_converter;
-#if UDPCL
+#else
     else if (macroeq("udpcl")) conv=&udpcl_converter;
 #endif
     else conv=&null_converter;
@@ -2009,7 +2011,7 @@
     } else {
 	if (parse && (car(parse)!=ST_DECL&&car(parse)!=ST_COMMENT))
 	    error(-1);  // What kind of error?
-	if (car(parse)==ST_COMMENT)
+	if (parse && car(parse)==ST_COMMENT)
 	    cadr(parse)=0;
 	else
 	    parse = 0;
@@ -2698,7 +2700,7 @@
 docase(void)
 {
 #if CASE_CODE
-    int l=0,clist=0,c,cst = (car(csvalue1)==CONST);
+    int l=0,clist=0,c,cst = (csvalue1 && car(csvalue1)==CONST);
     if (!inmode && !cst)
 	l = fwdlabel();
     while(sym==CASE) {
@@ -2762,7 +2764,7 @@
 #else
     /* casading branch implementation */
     int c,clist,l,slfree;
-    int cst = (car(csvalue1)==CONST);
+    int cst = (csvalue1 && car(csvalue1)==CONST);
     if (!inmode && !cst) {
 	if (retpending) { 
 	    ret(); retpending=0;
@@ -4105,6 +4107,10 @@
 
     function_type(ftype,&dots);
 
+    if (type0<=0) {
+	getsym(0);
+	return INT;
+    }
     argtypes = caddr(type0);
     if (!argtypes) dots=1;
     if ((t=type_value(cadr(type0)))>=0 && (car(t)==STRUCT||car(t)==UNION)) {
--- a/mc-tree.c	Wed Jan 24 14:31:50 2007 +0900
+++ b/mc-tree.c	Wed Jan 31 16:06:04 2007 +0900
@@ -478,6 +478,10 @@
 {
     NMTBL *nptr,*n;
 
+    if (e==0) {
+	fprintf(vout,"()");
+	return;
+    }
     switch (car(e)%SOP) {
     case LVAR:
     case RLVAR:
@@ -586,6 +590,9 @@
         print_expr(caddr(e),vout);
         fprintf(vout,")");
         break;
+    case RSTRUCT:
+        print_expr(cadr(e),vout);
+        break;
     default:
         error(-1);
     }
--- a/mc.h	Wed Jan 24 14:31:50 2007 +0900
+++ b/mc.h	Wed Jan 31 16:06:04 2007 +0900
@@ -570,9 +570,9 @@
 
 extern void print_expr(int e, FILE *vout);
 
-#if 0
+#if 1
 extern int heapsize;
-#define CHECK_HEAP(b) ({int _k=(int)(b);if(_k>heapsize||_k<0)error(-1);_k;})
+#define CHECK_HEAP(b) ({int _k=(int)(b);if(_k>heapsize||_k<=0)error(-1);_k;})
 #else
 #define CHECK_HEAP(b)  (b)
 #endif