diff mc-codegen.c @ 195:c193120ee2a6

*** empty log message ***
author kono
date Sun, 04 Apr 2004 21:17:10 +0900
parents 114e9d64b5cc
children 5f70abd9453d
line wrap: on
line diff
--- a/mc-codegen.c	Sat Jan 10 17:13:49 2004 +0900
+++ b/mc-codegen.c	Sun Apr 04 21:17:10 2004 +0900
@@ -25,6 +25,22 @@
 static int g_expr0(int e1);
 static int register_to_lvar(int e);
 
+#if FLOAT_CODE
+
+/* floating point */
+
+static void dassop(int e1);
+static void dmachinop(int e1,int d);
+static void dassign(int e1);
+
+#endif
+#if LONGLONG_CODE
+static void lassop(int e1);
+static void lmachinop(int e1);
+static void lassign(int e1);
+#endif
+
+
 void
 codegen_init()
 {
@@ -117,6 +133,7 @@
 	creg=use_int(creg);
 	code_register(e2,creg);
 	return INT;
+#if FLOAT_CODE
     case DREGISTER:
 	creg=use_double(creg);
 	code_dregister(e2,creg,1);
@@ -125,6 +142,7 @@
 	creg=use_float(creg);
 	code_dregister(e2,creg,0);
 	return FLOAT;
+#endif
     case RLVAR:
 	creg=use_int(creg);
 	code_rlvar(e2,creg);
@@ -145,6 +163,7 @@
 	creg=use_int(creg);
 	code_crlvar(e2,creg,0,size_of_short);
 	return UCHAR;
+#if FLOAT_CODE
     case FRLVAR:
 	creg=use_float(creg);
 	code_drlvar(e2,0,creg);
@@ -161,6 +180,7 @@
 	creg=use_double(creg);
 	code_drgvar(e1,1,creg);
 	return DOUBLE;
+#endif
     case FNAME:
 	creg=use_int(creg);
 	code_fname((NMTBL *)(e2),creg);
@@ -169,6 +189,7 @@
 	creg=use_int(creg);
 	code_const(e2,creg);
 	return INT;
+#if FLOAT_CODE
     case DCONST:
 	creg=use_double(creg);
 	code_dconst(e1,creg,1);
@@ -177,6 +198,7 @@
 	creg=use_float(creg);
 	code_dconst(e1,creg,0);
 	return FLOAT;
+#endif
     case STRING:
 	creg=use_int(creg);
 	code_string(e1,creg);
@@ -191,7 +213,9 @@
 	return g_expr0(e2);
     case RINDIRECT:  case CRINDIRECT: case CURINDIRECT:
     case SRINDIRECT: case SURINDIRECT:
+#if FLOAT_CODE
     case DRINDIRECT: case FRINDIRECT:
+#endif
 	return rindirect(e1);
     case ADDRESS:
 	if (car(e2)==REGISTER||car(e2)==DREGISTER||car(e2)==FREGISTER)
@@ -201,15 +225,18 @@
     case MINUS:  /* レジスタに対し、neglを実行すれば実現可能 */
 	g_expr0(e2); code_neg(creg);
 	return INT;
+#if FLOAT_CODE
     case DMINUS: 
 	g_expr0(e2); code_dneg(creg,1);
 	return DOUBLE;
     case FMINUS: 
 	g_expr0(e2); code_dneg(creg,0);
 	return FLOAT;
+#endif
     case CONV: 
 	g_expr0(e2); 
 	switch(caddr(e1)) {
+#if FLOAT_CODE
 	case I2D: code_i2d(creg); return DOUBLE;
 	case D2I: code_d2i(creg); return INT;
 	case U2D: code_u2d(creg); return DOUBLE;
@@ -220,6 +247,30 @@
 	case D2U: code_d2u(creg); return UNSIGNED;
 	case D2F: code_d2f(creg); return FLOAT;
 	case F2D: code_f2d(creg); return DOUBLE;
+#endif
+#if LONGLONG_CODE
+	case  I2LL: code_i2ll(creg); return LONGLONG;
+	case  I2ULL: code_i2ull(creg); return ULONGLONG;
+	case  U2LL: code_u2ll(creg); return LONGLONG;
+	case  U2ULL: code_u2ull(creg); return ULONGLONG;
+	case  LL2I: code_ll2i(creg); return INT;
+	case  LL2U: code_ll2u(creg); return UNSIGNED;
+	case  ULL2I: code_ull2i(creg); return INT;
+	case  ULL2U: code_ull2u(creg); return UNSIGNED;
+#if FLOAT_CODE
+	case  D2LL: code_d2ll(creg); return LONGLONG;
+	case  D2ULL: code_d2ull(creg); return ULONGLONG;
+	case  F2LL: code_f2ll(creg); return LONGLONG;
+	case  F2ULL: code_f2ull(creg); return ULONGLONG;
+	case  LL2D: code_ll2d(creg); return DOUBLE;
+	case  LL2F: code_ll2f(creg); return FLOAT;
+	case  ULL2D: code_ull2d(creg); return DOUBLE;
+	case  ULL2F: code_ull2f(creg); return FLOAT;
+	case  ULL2LL: code_ull2ll(creg); return LONGLONG;
+	case  ULL2ULL: code_ull2ull(creg); return ULONGLONG;
+#endif
+#endif
+
 	default:
 	    error(-1); return INT;
 	}
@@ -245,6 +296,7 @@
 	creg=use_int(creg);
 	code_postinc(e1,e2,caddr(e1),0,cadddr(e1),creg);
 	return INT;
+#if FLOAT_CODE
     case DPREINC:   /* ++d */
 	creg=use_double(creg);
 	code_dpreinc(e1,e2,1,creg);
@@ -261,6 +313,17 @@
 	creg=use_float(creg);
 	code_dpostinc(e1,e2,0,creg);
 	return FLOAT;
+#endif
+#if LONGLONG_CODE
+    case LPREINC:   /* ++d */
+	creg=use_longlong(creg);
+	code_lpreinc(e1,e2,creg);
+	return DOUBLE;
+    case LPOSTINC:  /* d++ */
+	creg=use_longlong(creg);
+	code_lpostinc(e1,e2,creg);
+	return DOUBLE;
+#endif
     case MUL: case UMUL:
     case DIV: case UDIV:	   
     case MOD: case UMOD:
@@ -269,6 +332,7 @@
 	creg=use_int(creg);
 	machinop(e1);
 	return INT;
+#if FLOAT_CODE
     case DMUL: case DDIV:
     case DADD: case DSUB:
     case DCMP: case DCMPGE:
@@ -281,10 +345,22 @@
 	creg=use_float(creg);
 	dmachinop(e1,0);
 	return FLOAT;
-    case COND:        /* a?0:1 should consider non-brach instruction */
     case DCOND:
     case FCOND:
-        d = (car(e1)==COND?INT:car(e1)==DCOND?DOUBLE:FLOAT);
+#endif
+#if LONGLONG_CODE
+    case LMUL: case LUMUL:
+    case LDIV: case LUDIV:	   
+    case LMOD: case LUMOD:
+    case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT:
+    case LADD: case LSUB: case LBAND: case LEOR: case LBOR: case LCMP:
+	creg=use_longlong(creg);
+	lmachinop(e1);
+	return INT;
+#endif
+    case COND:        /* a?0:1 should consider non-brach instruction */
+        d = (car(e1)==LCOND?LONGLONG:
+		car(e1)==COND?INT:car(e1)==DCOND?DOUBLE:FLOAT);
 	e2=fwdlabel();
 	b_expr(cadr(e1),0,e2,0);
         g_expr0(caddr(e1));
@@ -301,15 +377,25 @@
     case ASS: case CASS: case SASS:
 	assign(e1);
 	return INT;
-    case FASS: case DASS: case LASS: 
-	dassign(e1);
-	return DOUBLE;
     case ASSOP: case CASSOP: case CUASSOP:
 	assop(e1);
 	return INT;
+#if FLOAT_CODE
+    case FASS: case DASS: 
+	dassign(e1);
+	return DOUBLE;
     case DASSOP: case FASSOP:
 	dassop(e1);
 	return DOUBLE;
+#endif
+#if LONGLONG_CODE
+    case LASS: 
+	lassign(e1);
+	return LONGLONG;
+    case LASSOP: case LUASSOP:
+	lassop(e1);
+	return LONGLONG ;
+#endif
     case RSTRUCT:
 	g_expr0(e2);
 	return RSTRUCT;
@@ -344,22 +430,33 @@
 int
 rop_dual(op)
 {
-    if (op==GT) return LT;
-    if (op==UGT) return ULT;
-    if (op==GE) return LE;
-    if (op==UGE) return ULE;
-    if (op==LT) return GT;
-    if (op==ULT) return UGT;
-    if (op==LE) return GE;
-    if (op==ULE) return UGE;
-    if (op==DOP+GT) return DOP+LT;
-    if (op==DOP+GE) return DOP+LE;
-    if (op==DOP+LT) return DOP+GT;
-    if (op==DOP+LE) return DOP+GE;
-    if (op==FOP+GT) return FOP+LT;
-    if (op==FOP+GE) return FOP+LE;
-    if (op==FOP+LT) return FOP+GT;
-    if (op==FOP+LE) return FOP+GE;
+    switch(op) {
+    case GT: return LT;
+    case UGT: return ULT;
+    case GE: return LE;
+    case UGE: return ULE;
+    case LT: return GT;
+    case ULT: return UGT;
+    case LE: return GE;
+    case ULE: return UGE;
+    case DOP+GT: return DOP+LT;
+    case DOP+GE: return DOP+LE;
+    case DOP+LT: return DOP+GT;
+    case DOP+LE: return DOP+GE;
+    case FOP+GT: return FOP+LT;
+    case FOP+GE: return FOP+LE;
+    case FOP+LT: return FOP+GT;
+    case FOP+LE: return FOP+GE;
+
+    case LOP+GT: return LOP+LT;
+    case LOP+GE: return LOP+LE;
+    case LOP+LT: return LOP+GT;
+    case LOP+LE: return LOP+GE;
+    case LOP+UGT: return FOP+ULT;
+    case LOP+UGE: return FOP+ULE;
+    case LOP+ULT: return FOP+UGT;
+    case LOP+ULE: return FOP+UGE;
+    }
     return op;
 }
 
@@ -416,7 +513,7 @@
     case NEQ:
 	rexpr(e1,l1,code_eq(!cond),INT);
 	return;
-
+#if FLOAT_CODE
     case DOP+GT:
     case DOP+GE:
     case DOP+EQ:
@@ -439,7 +536,21 @@
     case DOP+LE:
 	drexpr(caddr(e1),cadr(e1),l1,DOP+GE);
 	return;
-
+#endif
+#if LONGLONG_CODE
+    case LOP+GT:
+    case LOP+GE:
+    case LOP+EQ:
+    case LOP+NEQ:
+	lrexpr(cadr(e1),caddr(e1),l1,car(e1));
+	return;
+    case LOP+LT:
+	lrexpr(caddr(e1),cadr(e1),l1,LOP+GT);
+	return;
+    case LOP+LE:
+	lrexpr(caddr(e1),cadr(e1),l1,LOP+GE);
+	return;
+#endif
     case LAND:
 	b_expr(e2,0,cond?(l2=fwdlabel()):l1,0);
 	b_expr(caddr(e1),cond,l1,0);
@@ -480,6 +591,7 @@
 	code_cmp_rlvar(e2);
 	jcond(l1,cond);
 	return;
+#if FLOATC_DOE
     case DRLVAR:
 	creg=use_double(creg);
 	code_cmp_drlvar(e2,1);
@@ -500,11 +612,6 @@
 	code_cmp_drgvar(e2,0);
 	jcond(l1,cond);
 	return;
-    case REGISTER:
-	creg=use_int(creg);
-	code_cmp_register(e2);
-	jcond(l1,cond);
-	return;
     case FREGISTER:
 	creg=use_float(creg);
 	code_cmp_dregister(e2,0);
@@ -515,22 +622,55 @@
 	code_cmp_dregister(e2,1);
 	jcond(l1,cond);
 	return;
-    case CONST:
-	if(control&&((cond&&e2)||(!cond&&!e2))) jmp(l1);
-	return;
     case DCONST:
     case FCONST:
 	if(control&&((dcadr(e2)!=0.0)^cond)) jmp(l1);
 	return;
+#endif
+#if LONGLONG_DOE
+    case LRLVAR:
+	creg=use_longlong(creg);
+	code_cmp_lrlvar(e2,1);
+	jcond(l1,cond);
+	return;
+    case LRGVAR:
+	creg=use_longlong(creg);
+	code_cmp_lrgvar(e2,1);
+	jcond(l1,cond);
+	return;
+    case LREGISTER:
+	creg=use_longlong(creg);
+	code_cmp_lregister(e2,1);
+	jcond(l1,cond);
+	return;
+    case LCONST:
+	if(control&&((lcadr(e2)!=0)^cond)) jmp(l1);
+	return;
+#endif
+    case REGISTER:
+	creg=use_int(creg);
+	code_cmp_register(e2);
+	jcond(l1,cond);
+	return;
+    case CONST:
+	if(control&&((cond&&e2)||(!cond&&!e2))) jmp(l1);
+	return;
     default:
 	if(err) {
 	    error(-1); return; /* recursive g_expr/b_expr */
 	}
 	t=g_expr(e1);
-	if(t==FLOAT)
+	if (0) ;
+#if FLOAT_CODE
+	else if(t==FLOAT)
 	    code_cmp_dregister(creg,0);
 	else if(t==DOUBLE)
 	    code_cmp_dregister(creg,1);
+#endif
+#if LONGLONG_CODE
+	else if(t==LONGLONG||t==ULONGLONG)
+	    code_cmp_lregister(creg);
+#endif
 	else
 	    code_cmp_register(creg);
 	jcond(l1,cond);
@@ -576,11 +716,14 @@
     } else if (tag==FREGISTER) {
 	n->dsp = new_lvar(size_of_float);
         t = DOUBLE;
+    } else if (tag==LREGISTER) {
+	n->dsp = new_lvar(size_of_longlong);
+        t = LONGLONG;
     } else error(-1);
     n->sc  = LVAR;
     lvar = list2(LVAR,n->dsp);
     g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),t,t));
-    if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER) {
+    if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER||tag==LREGISTER) {
 	free_register(reg);
     return g_expr0(lvar);
 #endif
@@ -644,6 +787,7 @@
 	*use=list3(t,*use,e1);
 	g_expr_u(assign_expr0(e1,s,ty,ty));
 	*target = append4(*target,t,ty,e1);
+#if FLOAT_CODE
     } else if (sz==size_of_double && (e1=get_dregister(1))!=-1) {
 	e1=list3(DREGISTER,e1,0);
 	*use=list3(t,*use,e1);
@@ -654,6 +798,7 @@
 	*use=list3(t,*use,e1);
 	g_expr_u(assign_expr0(e1,s,ty,ty));
 	*target = append4(*target,t,ty,e1);
+#endif
     } else {
 	g_expr_u(assign_expr0((e1=list2(LVAR,new_lvar(sz))),s,ty,ty));
 	*target = append4(*target,t,ty,e1);
@@ -757,9 +902,9 @@
 {
     return (
 	e1==CONST || e1==FNAME || e1==LVAR || e1==REGISTER ||e1==DREGISTER ||
-	e1==FREGISTER ||
+	e1==FREGISTER || e1==LREGISTER ||
 	e1==GVAR || e1==RGVAR || e1==RLVAR || e1==CRLVAR || e1==CRGVAR ||
-	e1==DRLVAR || e1==FRLVAR ||
+	e1==DRLVAR || e1==FRLVAR || e1==LRLVAR ||
 	e1==CURLVAR || e1==SURLVAR || e1==CURGVAR || e1==SURGVAR
     );
 }
@@ -774,10 +919,12 @@
       || (ce1==LVAR && (ce2==SRLVAR||ce2==SURLVAR||ce2==CURLVAR))
       || (ce2==LVAR && (ce1==RLVAR||ce1==CRLVAR||ce1==FRLVAR||ce1==DRLVAR))
       || (ce2==LVAR && (ce1==SRLVAR||ce1==SURLVAR||ce1==CURLVAR))
+      || (ce2==LVAR && (ce1==LRLVAR))
       || (ce1==GVAR && (ce2==RGVAR||ce2==CRGVAR||ce2==FRGVAR||ce2==DRGVAR))
       || (ce1==GVAR && (ce2==SRGVAR||ce2==SURGVAR||ce2==CURGVAR))
       || (ce2==GVAR && (ce1==RGVAR||ce1==CRGVAR||ce1==FRGVAR||ce1==DRGVAR))
       || (ce2==GVAR && (ce1==SRGVAR||ce1==SURGVAR||ce1==CURGVAR))
+      || (ce2==GVAR && (ce1==LRGVAR))
     );
 }
 
@@ -786,8 +933,9 @@
 {
     int ce1=car(e1);
     return (   
-         ce1==LVAR ||ce1==RLVAR||ce1==CRLVAR || ce1==DRLVAR ||
-         ce1==GVAR ||ce1==RGVAR||ce1==CRGVAR || ce1==DRGVAR ||
+         ce1==LVAR ||ce1==RLVAR||ce1==CRLVAR || ce1==DRLVAR || ce1==LRLVAR ||
+         ce1==GVAR ||ce1==RGVAR||ce1==CRGVAR || ce1==DRGVAR || ce1==LRGVAR ||
+	 ce1==FRLVAR || ce1==FRGVAR ||
          ce1==CURGVAR ||ce1==SURGVAR||ce1==SRGVAR ||
          ce1==REGISTER|| ce1==DREGISTER || ce1==FREGISTER
     );
@@ -889,7 +1037,7 @@
     parallel_assign(&target,&source,&processing,&use);
     while (use) {
 	reg = car(caddr(use));
-	if (reg==REGISTER||reg==FREGISTER||reg==DREGISTER)
+	if (reg==REGISTER||reg==FREGISTER||reg==DREGISTER||reg==LREGISTER)
 	    free_register(cadr(caddr(use)));
 	else if (car(caddr(use))==LVAR)
 	    free_lvar(cadr(caddr(use)));
@@ -943,6 +1091,7 @@
     return;
 }
 
+#if FLOAT_CODE
 void
 dmachinop(int e1,int d)
 {
@@ -958,6 +1107,25 @@
     emit_dpop_free(e2,d);
     return;
 }
+#endif
+
+#if LONGLONG_CODE
+void
+lmachinop(int e1)
+{
+    int e2,e3,op;
+
+    e2 = cadr(e1);
+    op = car(e1);
+    e3 = caddr(e1);
+    g_expr(e3);
+    emit_lpush();
+    g_expr(e2);
+    ltosop(car(e1),(e2=emit_lpop()));
+    emit_lpop_free(e2);
+    return;
+}
+#endif
 
 void
 sassign(int e1)
@@ -1077,6 +1245,8 @@
     return;
 }
 
+#if FLOAT_CODE
+
 void
 dassign_opt(int e5,int e2,int e4,int d)
 {
@@ -1163,6 +1333,91 @@
     return;
 }
 
+#endif
+
+#if LONGLONG_CODE
+
+void
+lassign_opt(int e5,int e2,int e4)
+{
+    int reg;
+    /*    e2=e4 */
+    if (e5==LREGISTER) {
+	reg = cadr(e4);
+	switch(car(e2)) {
+	case GVAR:      /*   i=3 */
+		code_lassign_gvar(e2,reg);
+		return;
+	case LVAR:
+		code_lassign_lvar(cadr(e2),reg);
+		return;
+	case LREGISTER:
+		if (reg!=cadr(e2))
+		    code_lassign_lregister(cadr(e2),reg);
+		return;
+	default:
+	    error(-1);
+	}
+    }
+    /* e2 is register now */
+    if (car(e2)!=LREGISTER) error(-1);
+    reg = cadr(e2);
+    switch(e5) {
+    case LRGVAR: code_lrgvar(e4,reg); return;
+    case LRLVAR: code_lrlvar(cadr(e4),reg); return;
+    case LCONST: code_lconst(e4,reg); return;
+    default:
+	    error(-1);
+    }
+}
+
+void
+lassign(int e1)
+{
+    int e2,e3,e4,e5;
+
+    /*    e2=e4 */
+    e2 = cadr(e1);
+    e3 = cadr(e2);
+    e4 = caddr(e1); e5=car(e4);
+    if (!use && (
+	    (e5==LREGISTER) ||
+	    (car(e2)==LREGISTER&&(e5==LRGVAR||e5==LRLVAR||e5==LCONST))
+	)) {
+	creg = use_longlong(creg);
+	lassign_opt(e5,e2,e4);
+	return;
+    }
+    switch(car(e2)) {
+    case GVAR:
+            g_expr(e4);
+	    creg = use_longlong(creg);
+	    code_lassign_gvar(e2,creg);
+            return;
+    case LVAR:
+            g_expr(e4);
+	    creg = use_longlong(creg);
+	    code_lassign_lvar(cadr(e2),creg);
+            return;
+    case LREGISTER:
+            g_expr(e4);
+	    if (creg!=cadr(e2)) {
+		creg = use_longlong(creg);
+		code_lassign_lregister(cadr(e2),creg);
+	    }
+            return;
+    }
+    g_expr(e2);
+    emit_lpush();
+    g_expr(e4);
+    e2 = emit_lpop();
+    code_lassign(e2,creg);
+    emit_lpop_free(e2);
+    return;
+}
+
+#endif
+
 void
 assop(int e1)
 {
@@ -1197,6 +1452,8 @@
     return;
 }
 
+#if FLOAT_CODE
+
 void
 dassop(int e1)
 {
@@ -1222,6 +1479,36 @@
     return;
 }
 
+#endif 
+
+#if LONGLONG_CODE
+
+void
+lassop(int e1)
+{
+    int e2,e3,op;
+
+    /*   e2 op= e3 */
+    e2 = cadr(e1);
+    if (car(e2)==INDIRECT) e2=cadr(e2);
+    e3 = caddr(e1);
+    op = cadddr(e1);
+
+    creg = use_longlong(creg);
+    g_expr(e3);
+    emit_lpush();
+    g_expr(e2);
+    if (car(e2)==LREGISTER) {
+	/* code_register_lassop(cadr(e2),op); */
+	error(-1); /* unsupported now */
+	return;
+    }
+    code_lassop(op);
+    return;
+}
+
+#endif 
+
 void 
 cmpdimm(int e, int csreg)
 {