diff mc-code-powerpc.c @ 280:affb054fe920

lrexpr fix. rexpr in MIPS fix.
author kono
date Sun, 23 May 2004 15:27:25 +0900 (2004-05-23)
parents 87b9cfc86a10
children 230a3b98b843
line wrap: on
line diff
--- a/mc-code-powerpc.c	Sat May 22 13:00:03 2004 +0900
+++ b/mc-code-powerpc.c	Sun May 23 15:27:25 2004 +0900
@@ -1338,6 +1338,14 @@
     return (cond?"eq":"ne");
 }
 
+static int cmpflag = 0;
+
+static void
+inc_cmpflag()
+{
+    cmpflag = (cmpflag+1)%7;
+}
+
 void
 code_cmp_crgvar(int e1,int reg,int sz) {
     int r;
@@ -1347,7 +1355,7 @@
     r = get_ptr_cache((NMTBL*)cadr(e1));
     printf("\t%s %s,0(%s)\n",cload(sz),crn,register_name(r));
     cext(0,sz,r);
-    printf("\tcmpwi cr0,%s,0\n",crn);
+    printf("\tcmpwi cr%d,%s,0\n",cmpflag,crn);
 }
 
 
@@ -1391,7 +1399,7 @@
 void
 code_cmp_register(int e2) {
     use_int(e2);
-    printf("\tcmpwi cr0,%s,0\n",register_name(e2));
+    printf("\tcmpwi cr%d,%s,0\n",cmpflag,register_name(e2));
 }
 
 
@@ -2301,7 +2309,6 @@
     emit_pop_free(xreg);
 }
 
-
 void
 tosop(int op,int creg,int oreg)
 {
@@ -2344,7 +2351,10 @@
 	printf("\tsub %s,%s,%s\n",crn,crn,orn);
 	break;
     case CMP:
-	printf("\tcmpw cr0,%s,%s\n",crn,orn);
+	printf("\tcmpw cr%d,%s,%s\n",cmpflag,crn,orn);
+	break;
+    case UCMP:
+	printf("\tcmplw cr%d,%s,%s\n",cmpflag,crn,orn);
 	break;
     case BAND: 
 	printf("\tand %s,%s,%s\n",crn,crn,orn);
@@ -2423,7 +2433,7 @@
 	printf("\taddi %s,%s,lo16(-%d)\n",crn,crn,v);
 	break;
     case CMP:
-	printf("\tcmpwi cr0,%s,lo16(%d)\n",crn,v);
+	printf("\tcmpwi cr%d,%s,lo16(%d)\n",cmpflag,crn,v);
 	break;
     case EOR: 
 	printf("\txori %s,%s,lo16(%d)\n",crn,crn,v);
@@ -2474,7 +2484,7 @@
 {
     /* used in dosiwtch() */
     if(chk) return;
-    printf("\tcmpwi cr0,%s,%d\n",register_name(csreg),e);
+    printf("\tcmpwi cr%d,%s,%d\n",cmpflag,register_name(csreg),e);
 }
 
 void
@@ -2487,10 +2497,24 @@
 }
 
 void
-rexpr(int e1, int l1, char *s,int t)
+rexpr(int e1, int l1, int cond,int t)
 {       
-    g_expr(list3(CMP,cadr(e1),caddr(e1)));
-    printf("\tb%s cr0,L_%d\n",s,l1);
+    char *s;
+    switch(car(e1)) {
+    case GT:  s=code_gt(cond);  break;
+    case UGT: s=code_ugt(cond); break;
+    case GE:  s=code_ge(cond);  break;
+    case UGE: s=code_uge(cond); break;
+    case LT:  s=code_ge(!cond); break;
+    case ULT: s=code_uge(!cond);break;
+    case LE:  s=code_gt(!cond); break;
+    case ULE: s=code_ugt(!cond);break;
+    case EQ:  s=code_eq(cond);  break;
+    case NEQ: s=code_eq(!cond); break;
+    default: error(-1);
+    }
+    g_expr(list3((t==INT?CMP:UCMP),cadr(e1),caddr(e1)));
+    printf("\tb%s cr%d,L_%d\n",s,cmpflag,l1);
 }
 
 
@@ -2498,7 +2522,7 @@
 jcond(int l, char cond)
 {       
     if (chk) return;
-    printf("\tb%s cr0,L_%d\n",cond?"ne":"eq",l);
+    printf("\tb%s cr%d,L_%d\n",cond?"ne":"eq",cmpflag,l);
 }
 
 void
@@ -2990,7 +3014,7 @@
     r = get_ptr_cache(&float_zero);
     rrn = register_name(r);
     printf("\tlfs %s,0(%s)\n",grn,rrn);
-    printf("\tfcmpu cr0,%s,%s\n",grn,frn);
+    printf("\tfcmpu cr%d,%s,%s\n",cmpflag,grn,frn);
     free_register(greg);
     return;
 }
@@ -3310,7 +3334,7 @@
 
     r = get_ptr_cache((NMTBL*)cadr(e2));
     printf("\t%s %s,0(%s)\n",fload(1),grn,register_name(r));
-    printf("\tfcmpu cr0,%s,%s\n",frn,grn);
+    printf("\tfcmpu cr%d,%s,%s\n",cmpflag,frn,grn);
     free_register(g);
 }
 
@@ -3326,7 +3350,7 @@
 
     lvar_intro(e2);
     printf("\t%s %s,",fload(1),grn); lvar(e2);
-    printf("\tfcmpu cr0,%s,%s\n",frn,grn);
+    printf("\tfcmpu cr%d,%s,%s\n",cmpflag,frn,grn);
     free_register(g);
 }
 
@@ -3584,9 +3608,21 @@
 }
 
 static void
-pcond(char *s,int l1)
+pcond(char *s,int cmpflag,int l1)
+{
+    printf("\tb%s cr%d,L_%d\n",s,cmpflag,l1);
+}
+
+static int
+lcmp(int op,int cond)
 {
-    printf("\tb%s cr0,L_%d\n",s,l1);
+    if (op==LOP+UGT||op==LOP+UGE) {
+        return UCMP;
+    } else if (op==LOP+LE||op==LOP+GE) {
+        return CMP;
+    } else {
+        return CMP;
+    }
 }
 
 void
@@ -3594,57 +3630,55 @@
 {
     int reg;
     int e3;
+    int l2;
+    int op1,cr0,cr1;
+
     g_expr(e1);
     emit_lpush();
     g_expr(e2);
     e3 = emit_lpop();
     if (!is_longlong_reg(creg)) error(-1);
     reg = lreg;
-
-    tosop(CMP,regv_h(reg),regv_h(e3));
+    op1 = lcmp(op,cond);
+    tosop(op1,regv_h(e3),regv_h(reg));
+    cr0 = cmpflag;
+    inc_cmpflag();
+    cr1 = cmpflag;
+    tosop(op1,regv_l(e3),regv_l(reg));
+
+    l2 = fwdlabel();
+    // cond==0 jump on false condtion   ( if(x) => rexpr(..  cond=0 ...) )
     switch(op) {
     case LOP+GT:
-    	pcond(code_gt(cond),l1); break;
     case LOP+GE:
-    	pcond(code_ge(cond),l1); break;
+	pcond(code_gt(1),cr0,cond?l1:l2);
+	pcond(code_eq(0),cr0,cond?l2:l1);
+	break;
+    case LOP+UGT:
+    case LOP+UGE:
+	pcond(code_ugt(1),cr0,cond?l1:l2);
+	pcond(code_eq(0), cr0,cond?l2:l1);
+	break;
     case LOP+EQ:
-    	pcond(code_eq(cond),l1); break;
+	pcond(code_eq(0),cr0,(cond?l2:l1));
+	pcond(code_eq(cond),cr1,l1);
+	break;
     case LOP+NEQ:
-    	pcond(code_eq(!cond),l1); break;
-    case LOP+LT:
-    	pcond(code_ge(!cond),l1); break;
-    case LOP+LE:
-    	pcond(code_gt(!cond),l1); break;
-    case LOP+UGT:
-    	pcond(code_ugt(cond),l1); break;
-    case LOP+UGE:
-    	pcond(code_uge(cond),l1); break;
+	pcond(code_eq(0),cr0,(cond?l1:l2));
+	pcond(code_eq(!cond),cr1,l1);
+	break;
     default:
 	error(-1);
     }
-    tosop(CMP,regv_l(reg),regv_l(e3));
     switch(op) {
-    case LOP+GT:
-    	pcond(code_gt(cond),l1); break;
-    case LOP+GE:
-    	pcond(code_ge(cond),l1); break;
-    case LOP+EQ:
-    	pcond(code_eq(cond),l1); break;
-    case LOP+NEQ:
-    	pcond(code_eq(!cond),l1); break;
-    case LOP+LT:
-    	pcond(code_ge(!cond),l1); break;
-    case LOP+LE:
-    	pcond(code_gt(!cond),l1); break;
-    case LOP+UGT:
-    	pcond(code_ugt(cond),l1); break;
-    case LOP+UGE:
-    	pcond(code_uge(cond),l1); break;
-    default:
-	error(-1);
-    }
-    emit_lpop_free(e3);
-}
+    case LOP+GT:  pcond(code_gt(cond),  cr1,l1); break;
+    case LOP+GE:  pcond(code_ge(cond),  cr1,l1); break;
+    case LOP+UGT: pcond(code_ugt(cond), cr1,l1); break;  
+    case LOP+UGE: pcond(code_uge(cond), cr1,l1); break;  
+    }  
+    fwddef(l2);  
+    emit_lpop_free(e3); 
+} 
 
 int
 emit_lpop()
@@ -3677,7 +3711,7 @@
 		lregister_name_low(reg),
 		lregister_name_low(reg),
 		lregister_name_high(reg));
-    printf("\tcmpwi cr0,%s,0\n",lregister_name_low(reg));
+    printf("\tcmpwi cr%d,%s,0\n",cmpflag,lregister_name_low(reg));
 }
 
 void