changeset 219:6190d24e178c use_xxx_fix_before

long long code generation level 4
author kono
date Sun, 25 Apr 2004 18:32:30 +0900
parents 2d64e82437d2
children 97246ddfe8ab
files Changes mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-parse.c mc.h
diffstat 8 files changed, 150 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Sat Apr 24 21:56:53 2004 +0900
+++ b/Changes	Sun Apr 25 18:32:30 2004 +0900
@@ -3973,3 +3973,17 @@
 long long op int, unsigned long long op int/unsigned
 
 ってのがあるのか.... うーん...
+
+Sun Apr 25 17:20:40 JST 2004
+
+実装しないのにテストルーチン入れるなよ。。。 register lassop
+
+compiler を書くには...
+   (1) parser を書く
+   (2) code 生成部を書く
+   (3) compiler のcompile エラーを取る
+   (4) compiler のコード生成をデバッグする
+   (5) 生成したコードがアセンブラを通るかどうかを直す
+   (6) 生成したコードが正しいかどうかを調べる 
+で、(4) までできました。
+
--- a/mc-code-ia32.c	Sat Apr 24 21:56:53 2004 +0900
+++ b/mc-code-ia32.c	Sun Apr 25 18:32:30 2004 +0900
@@ -1940,6 +1940,11 @@
 }
 
 void
+code_register_dassop(int reg,int op,int d) {
+    error(-1);
+}
+
+void
 code_dpreinc(int e1,int e2,int d,int freg) {
     g_expr(e2);
     printf("\t%s (%s)\n",fload(d),register_name(creg,0));
@@ -2295,6 +2300,10 @@
 
 }
 
+void
+code_register_lassop(int reg,int op) {
+}
+
 
 #endif
 
--- a/mc-code-mips.c	Sat Apr 24 21:56:53 2004 +0900
+++ b/mc-code-mips.c	Sun Apr 25 18:32:30 2004 +0900
@@ -2555,6 +2555,11 @@
     }
 }
 
+void
+code_register_dassop(int reg,int op,int d) {
+    error(-1);
+}   
+
 
 void
 code_dpreinc(int e1,int e2,int d,int reg) {
@@ -2964,6 +2969,11 @@
 
 }
 
+void
+code_register_lassop(int reg,int op) {
+}
+
+
 
 #endif
 
--- a/mc-code-powerpc.c	Sat Apr 24 21:56:53 2004 +0900
+++ b/mc-code-powerpc.c	Sun Apr 25 18:32:30 2004 +0900
@@ -449,7 +449,7 @@
 int 
 get_register(void)
 {    /* 使われていないレジスタを調べる */
-    int i,reg;
+    int i,j,reg;
     for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) {
 	if (regs[i]) continue;  /* 使われている */
 	regs[i]=USING_REG;      /* そのレジスタを使うことを宣言し */
@@ -468,8 +468,8 @@
     for(i=0;i<reg_sp;i++) {
 	if ((reg=reg_stack[i])>=0) {
             code_assign_lvar(
-                (reg_stack[i]=new_lvar(size_of_int)),reg,0); 
-            reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET;
+                (j=new_lvar(size_of_int)),reg,0); 
+            reg_stack[i]= j-REG_LVAR_OFFSET;
 	    return reg;
 	}
     }
@@ -477,9 +477,9 @@
     /* search register stack */
     for(i=0;i<lreg_sp;i++) {
 	if ((reg=lreg_stack[i])>=0) {
-            code_assign_lvar(
-                (lreg_stack[i]=new_lvar(size_of_longlong)),reg,0); 
-            lreg_stack[i]= lreg_stack[i]-REG_LVAR_OFFSET;
+            code_lassign_lvar(
+                (j=new_lvar(size_of_longlong)),reg); 
+            lreg_stack[i]= j-REG_LVAR_OFFSET;
 	    free_register(reg);
 	    return get_register();
 	}
@@ -1446,7 +1446,7 @@
 	if (creg!=ireg) free_register(creg);
 	free_register(creg);
     }
-    creg = freg = reg;
+    creg = lreg = reg;
 }
 
 void
@@ -1608,7 +1608,7 @@
 	    nargs ++ ; reg_arg++;
 	    continue;
 	} else if (t==LONGLONG||t==ULONGLONG) {
-	    if (reg_arg>=MAX_INPUT_REGISTER_VAR) { 
+	    if (reg_arg+1>=MAX_INPUT_REGISTER_VAR) { 
 		arg = list2(LVAR,caller_arg_offset_v(nargs));
 	    } else if (!simple_args(e3) && cadr(e3)) {
 		arg = get_register_var(0); 
@@ -2966,6 +2966,20 @@
     emit_dpop_free(xreg,d);
 }
 
+void
+code_register_dassop(int reg,int op,int d) {
+    int  xreg=emit_dpop(d);
+    set_freg(reg,0);
+    dtosop(op,xreg);
+    if (creg==reg) {
+	printf("\tfmr %s,%s\n",fregister_name(xreg),fregister_name(freg));
+	free_register(freg);
+	freg = creg = xreg;
+    } else {
+	printf("\tfmr %s,%s\n",fregister_name(reg),fregister_name(freg));
+	emit_dpop_free(xreg,d);
+    }
+}   
 
 void
 code_dpreinc(int e1,int e2,int d,int reg) {
@@ -3097,6 +3111,12 @@
 
 
 /* 64bit int part */
+static void
+lmove(int to,int from)
+{
+    printf("\tmr %s,%s\n",lregister_name_high(to),lregister_name_high(from));
+    printf("\tmr %s,%s\n",lregister_name_low(to),lregister_name_low(from));
+}
 
 static void
 cond(char *s,int l1)
@@ -3185,10 +3205,7 @@
 code_lregister(int e2,int reg)
 {
     if (creg!=e2) {
-	printf("\tmr %s,%s\n",lregister_name_low(creg),
-		lregister_name_low(e2));
-	printf("\tmr %s,%s\n",lregister_name_high(creg),
-		lregister_name_high(e2));
+	lmove(creg,e2);
     }
 }
 
@@ -3249,9 +3266,8 @@
 void
 code_lassign_lregister(int e2,int reg)
 {
-    if (e2!=creg) {
-        printf("\tmr %s,%s\n",lregister_name_high(e2),lregister_name_high(creg));
-        printf("\tmr %s,%s\n",lregister_name_low(e2),lregister_name_low(creg));
+    if (e2!=reg) {
+	lmove(e2,reg);
     }
 }
 
@@ -3354,6 +3370,7 @@
 "      lwz     r3,-48(r1)",
 "      lwz     r4,-44(r1)",
 "      blr",
+0
 };
 
 static int asld_lib_used=0;
@@ -3385,6 +3402,7 @@
 "      lwz     r3,-48(r1)",
 "      lwz     r4,-44(r1)",
 "      blr",
+0
 };
 
 static int asrd_lib_used=0;
@@ -3415,6 +3433,7 @@
 "      lwz     r3,-48(r1)",
 "      lwz     r4,-44(r1)",
 "      blr",
+0
 };
 
 static void
@@ -3552,31 +3571,31 @@
     crn_h = lregister_name_high(creg);
     crn_l = lregister_name_low(creg);
     switch(op) {
-    case ADD:
+    case LADD:
 	printf("\taddc %s,%s,%s\n",crn_l,crn_l,orn_l);
 	printf("\tadde %s,%s,%s\n",crn_h,crn_h,orn_h);
 	break;
-    case SUB:
+    case LSUB:
 	printf("\tsubfc %s,%s,%s\n",crn_l,crn_l,orn_l);
 	printf("\tsubfe %s,%s,%s\n",crn_h,crn_h,orn_h);
 	break;
     case LCMP:
 	error(-1);
 	break;
-    case BAND: 
+    case LBAND: 
 	printf("\tand %s,%s,%s\n",crn_l,crn_l,orn_l);
 	printf("\tand %s,%s,%s\n",crn_h,crn_h,orn_h);
 	break;
-    case EOR: 
+    case LEOR: 
 	printf("\txor %s,%s,%s\n",crn_l,crn_l,orn_l);
 	printf("\txor %s,%s,%s\n",crn_h,crn_h,orn_h);
 	break;
-    case BOR:
+    case LBOR:
 	printf("\tor %s,%s,%s\n",crn_l,crn_l,orn_l);
 	printf("\tor %s,%s,%s\n",crn_h,crn_h,orn_h);
 	break;
-    case MUL:
-    case UMUL:
+    case LMUL:
+    case LUMUL:
 	dx=get_lregister();
 	drn_l = lregister_name_low(dx);
 	drn_h = lregister_name_high(dx);
@@ -3597,16 +3616,16 @@
 	printf("\tadd %s,%s,%s\n",crn_l,drn_h,crn_h);
 	printf("\tmr %s,%s\n",crn_l,drn_l);
 	break;
-    case DIV:
+    case LDIV:
 	code_ldiv_lib(oreg); // ___divdi3$stub
 	break;
-    case UDIV:
+    case LUDIV:
 	code_ludiv_lib(oreg); // ___udivdi3$stub
 	break;
-    case MOD:
+    case LMOD:
 	code_lmod_lib(oreg); // ___moddi3$stub
 	break;
-    case UMOD:
+    case LUMOD:
 	code_lumod_lib(oreg); // ___umoddi3$stub
 	break;
     default:
@@ -3633,10 +3652,10 @@
     case RSHIFT:
     case URSHIFT:
 	return  (0<v&&v<31);
-    case ADD:
-    case SUB:
+    case LADD:
+    case LSUB:
 	return 1;
-    case BOR:
+    case LBOR:
 	return  (v>0);
     default:
 	return 0;
@@ -3656,8 +3675,8 @@
     else if (car(e)==CONST) v = caddr(e);
 
     switch(op) {
-    case LSHIFT:
-    case ULSHIFT:
+    case LLSHIFT:
+    case LULSHIFT:
 	greg = get_register();
 	grn = register_name(greg);
 	printf("\tsrwi %s,%s,%d\n",grn,crn_h,32-v);
@@ -3666,7 +3685,7 @@
 	printf("\tslwi %s,%s,%d\n",crn_h,crn_h,v);
 	free_register(greg);
 	return;
-    case RSHIFT:
+    case LRSHIFT:
 	greg = get_register();
 	grn = register_name(greg);
 	printf("\tsrwi %s,%s,%d\n",grn,crn_l,v);
@@ -3675,7 +3694,7 @@
 	printf("\tmr %s,%s\n",crn_l,grn);
 	free_register(greg);
 	return;
-    case URSHIFT:
+    case LURSHIFT:
 	greg = get_register();
 	grn = register_name(greg);
 	printf("\tslwi %s,%s,%d\n",grn,crn_l,32-v);
@@ -3685,15 +3704,15 @@
 	free_register(greg);
 	return;
 	return;
-    case ADD:
+    case LADD:
 	printf("\taddi %s,%s,lo16(%d)\n",crn_l,crn_l,v);
 	printf("\taddze %s,%s\n",crn_h,crn_h);
 	break;
-    case SUB:
+    case LSUB:
 	printf("\tsubi %s,%s,lo16(%d)\n",crn_l,crn_l,v);
 	printf("\taddme %s,%s\n",crn_h,crn_h);
 	break;
-    case BOR:
+    case LBOR:
 	printf("\tori %s,%s,lo16(%d)\n",crn_l,crn_l,v);
 	break;
     default:
@@ -3721,15 +3740,15 @@
 }
 
 void
-code_i2ll(int creg)
+code_i2ll(int reg)
 {
     char *crn,*crn_h,*crn_l;
     int creg0;
-    crn = register_name(creg);
+    crn = register_name(reg);
     creg = use_longlong(creg0=creg);
     crn_h = lregister_name_high(creg);
     crn_l = lregister_name_low(creg);
-    if (creg0!=regv_l(creg))
+    if (creg0!=regv_l(reg))
 	printf("\tmr %s,%s\n",crn_l,crn);
     printf("\tsrawi %s,%s,31\n",crn_h,crn_l);
 }
@@ -3741,15 +3760,15 @@
 }
 
 void
-code_u2ll(int creg)
+code_u2ll(int reg)
 {
     int creg0;
     char *crn,*crn_h,*crn_l;
-    crn = register_name(creg);
+    crn = register_name(reg);
     creg = use_longlong(creg0=creg);
     crn_h = lregister_name_high(creg);
     crn_l = lregister_name_low(creg);
-    if (creg0!=regv_l(creg))
+    if (creg0!=regv_l(reg))
 	printf("\tmr %s,%s\n",crn_l,crn);
     printf("\tli %s,0\n",crn_h);
 }
@@ -3761,12 +3780,13 @@
 }
 
 void
-code_ll2i(int creg)
+code_ll2i(int reg)
 {
-    int creg0;
-    char *crn_l = lregister_name_low(creg);
-    creg = use_int(creg0=creg);
-    if (creg!=regv_l(creg0))
+    char *crn_l;
+    if (!is_longlong_reg(reg)) { error(-1); return; }
+    crn_l = lregister_name_low(reg);
+    creg = use_int(creg);
+    if (creg!=regv_l(reg))
 	printf("\tmr %s,%s\n",register_name(creg),crn_l);
 }
 
@@ -3867,10 +3887,7 @@
         printf("\taddei %s,%s,0\n", 
                 lregister_name_high(cadr(e2)),lregister_name_high(cadr(e2)));
         if (cadr(reg)!=cadr(e2)) {
-            printf("\tmr %s,%s\n",lregister_name_low(cadr(reg)),
-		lregister_name_low(cadr(e2)));
-            printf("\tmr %s,%s\n",lregister_name_high(cadr(reg)),
-		lregister_name_high(cadr(e2)));
+	    lmove(cadr(reg),cadr(e2));
 	}
         return;
     } 
@@ -3896,10 +3913,7 @@
     int dreg,nreg;
     int dir=caddr(e1);
     if (car(e2)==LREGISTER) {
-	printf("\tmr %s,%s\n",lregister_name_low(cadr(reg)),
-	    lregister_name_low(cadr(e2)));
-	printf("\tmr %s,%s\n",lregister_name_high(cadr(reg)),
-	    lregister_name_high(cadr(e2)));
+	lmove(cadr(reg),cadr(e2));
         printf("\taddci %s,%s,%d\n", 
                 lregister_name_low(cadr(e2)),lregister_name_low(cadr(e2)), dir);
         printf("\taddei %s,%s,0\n", 
@@ -3952,6 +3966,21 @@
     emit_lpop_free(xreg);
 }
 
+void
+code_register_lassop(int reg,int op) {
+    int  xreg=emit_lpop();
+    set_lreg(reg,0);
+    ltosop(op,xreg);
+    if (creg==reg) {
+	free_register(lreg);
+	lmove(xreg,lreg);
+	lreg = creg = xreg;
+    } else {
+	lmove(reg,lreg);
+	emit_lpop_free(xreg);
+    }
+}   
+
 
 #endif
 
--- a/mc-code.h	Sat Apr 24 21:56:53 2004 +0900
+++ b/mc-code.h	Sun Apr 25 18:32:30 2004 +0900
@@ -145,6 +145,7 @@
 extern void code_dpreinc(int e1,int e2,int d,int reg);
 extern void code_dpostinc(int e1,int e2,int d,int reg);
 extern void code_dassop(int op,int d);
+extern void code_register_dassop(int reg,int op,int d);
 
 #endif
 
@@ -196,6 +197,7 @@
 extern void code_lpreinc(int e1,int e2,int reg);
 extern void code_lpostinc(int e1,int e2,int reg);
 extern void code_lassop(int op);
+extern void code_register_lassop(int reg,int op);
 
 #endif
 
--- a/mc-codegen.c	Sat Apr 24 21:56:53 2004 +0900
+++ b/mc-codegen.c	Sun Apr 25 18:32:30 2004 +0900
@@ -143,6 +143,12 @@
 	code_dregister(e2,creg,0);
 	return FLOAT;
 #endif
+#if LONGLONG_CODE
+    case LREGISTER:
+	creg=use_longlong(creg);
+	code_lregister(e2,creg);
+	return LONGLONG;
+#endif
     case RLVAR:
 	creg=use_int(creg);
 	code_rlvar(e2,creg);
@@ -363,11 +369,19 @@
     case LPREINC:   /* ++d */
 	creg=use_longlong(creg);
 	code_lpreinc(e1,e2,creg);
-	return DOUBLE;
+	return LONGLONG;
     case LPOSTINC:  /* d++ */
 	creg=use_longlong(creg);
 	code_lpostinc(e1,e2,creg);
-	return DOUBLE;
+	return LONGLONG;
+    case LUPREINC:   /* ++d */
+	creg=use_longlong(creg);
+	code_lpreinc(e1,e2,creg);
+	return ULONGLONG;
+    case LUPOSTINC:  /* d++ */
+	creg=use_longlong(creg);
+	code_lpostinc(e1,e2,creg);
+	return ULONGLONG;
 #endif
     case MUL: case UMUL:
     case DIV: case UDIV:	   
@@ -999,7 +1013,8 @@
          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
+         ce1==REGISTER|| ce1==DREGISTER || ce1==FREGISTER ||
+         ce1==LREGISTER
     );
 }
 
@@ -1475,11 +1490,11 @@
             return;
     }
     g_expr(e2);
-    emit_lpush();
+    emit_push();
     g_expr(e4);
-    e2 = emit_lpop();
+    e2 = emit_pop(0);
     code_lassign(e2,creg);
-    emit_lpop_free(e2);
+    emit_pop_free(e2);
     return;
 }
 
@@ -1538,8 +1553,7 @@
     emit_dpush(d);
     g_expr(e2);
     if (car(e2)==DREGISTER||car(e2)==FREGISTER) {
-	/* code_register_dassop(cadr(e2),op,d); */
-	error(-1); /* unsupported now */
+	code_register_dassop(cadr(e2),op,d);
 	return;
     }
     code_dassop(op,d);
@@ -1566,8 +1580,7 @@
     emit_lpush();
     g_expr(e2);
     if (car(e2)==LREGISTER) {
-	/* code_register_lassop(cadr(e2),op); */
-	error(-1); /* unsupported now */
+	code_register_lassop(cadr(e2),op);
 	return;
     }
     code_lassop(op);
--- a/mc-parse.c	Sat Apr 24 21:56:53 2004 +0900
+++ b/mc-parse.c	Sun Apr 25 18:32:30 2004 +0900
@@ -809,6 +809,7 @@
 	if(t==REGISTER) return size_of_int;
 	if(t==DREGISTER) return size_of_double;
 	if(t==FREGISTER) return size_of_float;
+	if(t==LREGISTER) return size_of_longlong;
 	if(scalar(t)) return size_of_int;
 	if(t==FLOAT) return size_of_float;
 	if(t==DOUBLE) return size_of_double;
@@ -2237,7 +2238,7 @@
 	    return(list4(LASSOP,e1,e2,op+LOP));
 	} else if (t==ULONGLONG) {
 	    e2=ulonglong_value(e2,type); type=t;
-	    return(list4(LASSOP,e1,e2,op+LOP+US));
+	    return(list4(LASSOP,e1,e2,op+LOP+((op==MUL+AS||op==DIV+AS)?US:0)));
 	}
 #endif
 	if(!integral(type)) error(TYERR);
@@ -2744,6 +2745,7 @@
 	    type=nptr->ty;
 	    getsym(0);
 	    break;
+	case LREGISTER:
 	case DREGISTER:
 	case FREGISTER:
 	case REGISTER:
@@ -3257,6 +3259,7 @@
     }
     if((op==MUL||op==DIV)&&car(e2)==LCONST&&lcadr(e2)==1) return e1;
     if(op==BOR||op==EOR||op==BAND) return(list3(op+LOP,e1,e2));
+    /* there is no UADD, USUB (should be? */
     if(op==LSHIFT||op==RSHIFT) return(list3(op+(t1==ULONGLONG?US:0)+LOP,e1,e2));
     return(list3(type==ULONGLONG?op+US+LOP:op,e1,e2));
 }
@@ -3272,16 +3275,14 @@
     if(t1>0&&car(t1)==POINTER) { e2= int_value(e2,t2); t2=INT; }
     else if(t2>0&&car(t2)==POINTER) { e1= int_value(e1,t1); t1=INT; }
 #if FLOAT_CODE
-    if(t1==DOUBLE||t2==DOUBLE)
+    else if(t1==DOUBLE||t2==DOUBLE)
 	return dbinop(op,e1,e2,t1,t2);
-    if(t1==FLOAT||t2==FLOAT)
+    else if(t1==FLOAT||t2==FLOAT)
 	return fbinop(op,e1,e2,t1,t2);
 #endif
 #if LONGLONG_CODE
-    if(t1==LONGLONG||t2==LONGLONG)
+    else if((t1==LONGLONG||t2==LONGLONG)||(t1==ULONGLONG||t2==ULONGLONG))
 	return lbinop(op,e1,e2,t1,t2);
-    if(t1==ULONGLONG||t2==ULONGLONG)
-	return lbinop(op+((op==BOR||op==EOR||op==BAND||op==EQ||op==NEQ)?0:US),e1,e2,t1,t2);
 #endif
     if(car(e1)==CONST&&car(e2)==CONST) {
 	e1=cadr(e1);
--- a/mc.h	Sat Apr 24 21:56:53 2004 +0900
+++ b/mc.h	Sun Apr 25 18:32:30 2004 +0900
@@ -144,7 +144,7 @@
 #define STRING	8
 #define FNAME	9
 
-#define NULLARY_ARGS(i) (i==REGISTER||i==DREGISTER||i==FREGISTER||(GVAR<=(i%SOP)&&(i%SOP)<=FNAME))
+#define NULLARY_ARGS(i) (i==REGISTER||i==DREGISTER||i==FREGISTER||i==LREGISTER||(GVAR<=(i%SOP)&&(i%SOP)<=FNAME))
 
 /* unary  argments */