changeset 83:f3f75911d62c

*** empty log message ***
author kono
date Wed, 05 Mar 2003 03:41:08 +0900
parents 25654dc29ecc
children 1a723130a2c7
files mc-code-ia32.c mc-code.h mc-codegen.c mc-codegen.h mc-parse.c mc.h
diffstat 6 files changed, 199 insertions(+), 94 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-ia32.c	Wed Mar 05 00:39:39 2003 +0900
+++ b/mc-code-ia32.c	Wed Mar 05 03:41:08 2003 +0900
@@ -43,16 +43,12 @@
 int size_of_double = 8;
 int size_of_longlong = 8;
 int endian = 0;
-int MAX_REGISTER=6;         /* intel386のレジスタを4つまで使う*/
+int MAX_REGISTER=6;         /* intel386のレジスタを6つまで使う*/
 int REAL_MAX_REGISTER=8;    /* intel386のレジスタが8つということ*/
 int MAX_DATA_REG=4;    
 int MAX_POINTER=3;    
 int MAX_REGISTGER_VAR=2;    
-
-EXTERN int  creg;     /* current register */
-EXTERN int  dreg;     /* temporary register */
-EXTERN int  freg;     /* current floating point register */
-EXTERN int  reg_sp;   /* REGister Stack-Pointer */
+int MAX_FREGISTER=1;
 
 
 #define REG_EAX   0
@@ -71,17 +67,6 @@
 static char *reg_name_l[4];
 static char *reg_name_w[4];
 
-extern int  creg;     /* current register */
-extern int  dreg;     /* temporary register */
-extern int  reg_sp;   /* REGister Stack-Pointer */
-
-#define MAX_MAX 10
-int rname[MAX_MAX];
-int regs[MAX_MAX];       /* 使われているレジスタを示すフラグ */
-int reg_stack[MAX_MAX];  /* 実際のレジスタの領域 */
-int regv[MAX_MAX];       /* 値が入っているかどうか */
-
-
 void use_register(int virt, int real, int move);
 void code_preinc(int e1,int e2) ;
 void code_cmp_register(int e2) ;
@@ -167,13 +152,10 @@
     }
 }
 
-extern int creg_regvar;
-
 void
 gexpr_code_init(void){
     use_register(creg,REG_EAX,0);
     regv[dreg]=0;
-    creg_regvar = -1;
 }
 
 int
@@ -250,6 +232,7 @@
     int new_reg;
     new_reg = get_register();
     if(new_reg<0) {                     /* もうレジスタがない */
+	if (reg_sp>=MAX_MAX) error(-1);
 	reg_stack[reg_sp++] =  -1;
 	printf("\tpushl %s\n",register_name(creg,0));
 	/* creg is used soon, don't regv[creg]=0 */
@@ -734,13 +717,13 @@
 	} else if (t==DOUBLE) {
 	    g_expr(e4);
 	    printf("\tleal\t-8(%%esp),%%esp\n\tfstpl\t(%%esp)\n");
-	    regv[freg]=0;
+	    fregv[freg]=0;
 	    nargs += size_of_double/size_of_int;
 	    continue;
 	} else if (t==FLOAT) {
 	    g_expr(e4);
 	    printf("\tleal\t-4(%%esp),%%esp\n\tfstps\t(%%esp)\n");
-	    regv[freg]=0;
+	    fregv[freg]=0;
 	    nargs += size_of_float/size_of_int;
 	    continue;
 	} else if (car(t)==STRUCT||car(t)==UNION) {
@@ -781,7 +764,7 @@
     }
     regv[save]=0;
     regv[creg]=1;
-    regv[freg]=1; /* return type はどこ? fnptr にはあるけど... */
+    fregv[freg]=1; /* return type はどこ? fnptr にはあるけど... */
 }
 
 void
@@ -1174,7 +1157,7 @@
     fwddef(retlabel);
     /* use_register(creg,REG_EAX,0); too late */
     /* if(disp) printf("\taddl $%d,%%esp\n",-disp);  */
-    disp&= -size_of_int;
+    disp &= -size_of_int;
 
     printf("\tlea %d(%%ebp),%%esp\n",disp_offset);
     printf("\tpopl %%edi\n");
@@ -1363,6 +1346,15 @@
 char *
 fstore(int d)
 {
+    return use?
+	(d?"fstl":"fsts"):
+	(d?"fstpl":"fstps")
+    ;
+}
+
+char *
+fstore_u(int d)
+{
     return d?"fstpl":"fstps";
 }
 
@@ -1490,6 +1482,42 @@
     }
 }
 
+void
+code_dassop(int op,int d) {
+    /* we have lvalue in creg, applied floating value is in %st(0) */
+    printf("\t%s (%s)\n",fload(d),register_name(creg,0));
+    dtosop(op,0);
+    printf("\t%s (%s)\n",fstore(d),register_name(creg,0));
+}
+
+void
+code_dpreinc(int e1,int e2,int d) {
+    g_expr(e2);
+    printf("\t%s (%s)\n",fload(d),register_name(creg,0));
+    printf("\tfld1\n");
+    if (e2>0)
+	printf("\tfaddp %%st,%%st(1)\n");
+    else
+	printf("\tfsubrp %%st,%%st(1)\n");
+    printf("\t%s (%s)\n",fstore(d),register_name(creg,0));
+}
+
+void
+code_dpostinc(int e1,int e2,int d) {
+    g_expr(e2);
+    printf("\t%s (%s)\n",fload(d),register_name(creg,0));
+    if (use)
+	/* dup */;
+    printf("\tfld1\n");
+    if (e2>0)
+	printf("\tfaddp %%st,%%st(1)\n");
+    else
+	printf("\tfsubrp %%st,%%st(1)\n");
+    printf("\t%s (%s)\n",fstore_u(d),register_name(creg,0));
+    if (use)
+	/* pop */;
+}
+
 int dpop_register()
 { 
     return 1;
--- a/mc-code.h	Wed Mar 05 00:39:39 2003 +0900
+++ b/mc-code.h	Wed Mar 05 03:41:08 2003 +0900
@@ -2,6 +2,15 @@
      mc-code-*.c have to provied these
  */
 
+extern int size_of_int;
+extern int size_of_float;
+extern int size_of_double;
+extern int size_of_longlong;
+extern int endian;
+extern int MAX_REGISTER; 
+extern int MAX_REGISTGER_VAR;
+extern int MAX_FREGISTER;
+
 extern char *register_name(int i,int byte);
 extern void gexpr_code_init(void);
 extern int register_var(int r);
@@ -87,3 +96,6 @@
 extern void code_i2d();
 extern void code_d2i();
 
+extern void code_dpreinc(int e1,int e2,int d);
+extern void code_dpostinc(int e1,int e2,int d);
+extern void code_dassop(int op,int d);
--- a/mc-codegen.c	Wed Mar 05 00:39:39 2003 +0900
+++ b/mc-codegen.c	Wed Mar 05 03:41:08 2003 +0900
@@ -10,7 +10,23 @@
 int  dreg;     /* temporary register */
 int  reg_sp;   /* REGister Stack-Pointer */
 
+int rname[MAX_MAX];
+int regs[MAX_MAX];       /* 使われているレジスタを示すフラグ */
+int reg_stack[MAX_MAX];  /* 実際のレジスタの領域 */
+int regv[MAX_MAX];       /* 値が入っているかどうか */
+
+/* floating point registers */
+
 int  freg;     /* current floating point register */
+int  greg;     /* current floating point register */
+int  freg_sp;  /* floating point REGister Stack-Pointer */
+
+int frname[MAX_MAX];
+int fregs[MAX_MAX];      /* 使われているレジスタを示すフラグ */
+int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */
+int fregv[MAX_MAX];      /* 値が入っているかどうか */
+
+int use;       /* generated value will be used */
 
 /*
     creg   currrent virtual register
@@ -23,6 +39,9 @@
     regv[]        value in virtual register flag
 
     reg_name[rname[creg]]
+
+    freg    current floating point register
+    fregv   calue in floating point register
  */
 
 void remove0(int *parent,int e) ;
@@ -33,6 +52,7 @@
 void sassign(int e1);
 void assign(int e1);
 void assop(int e1);
+void g_expr0(int e1);
 
 int 
 get_register(void)
@@ -119,24 +139,6 @@
     arg_register0(fnptr->dsp);
 }
 
-
-int creg_regvar = -1;
-static int creg_regvar_back;
-static int creg_back;
-
-void
-creg_destroy() {
-    creg_back = creg; creg_regvar_back = creg_regvar;
-    if (creg_regvar>=0)
-	creg = creg_regvar;
-    creg_regvar=-1;
-}
-
-void
-creg_un_destroy() {
-    creg = creg_back; creg_regvar = creg_regvar_back;
-}
-
 void
 register_usage(char *s)
 {
@@ -219,17 +221,18 @@
 }
 
 void
-gexpr(int e1)
+gexpr(int e1,int use0)
 {
     if (chk) return;
     gexpr_init();
+    use = use0;
 #if 0
     if(lineno==2862) {
-        g_expr(e1); /*break here*/
+        g_expr0(e1); /*break here*/
         return;
     } 
 #endif
-    g_expr(e1);
+    g_expr0(e1);
 }
 
 int
@@ -239,9 +242,25 @@
 }
 
 void
+g_expr_u(int e1)
+{
+    int suse = use; use=0;
+    g_expr0(e1);
+    use=suse;
+}
+
+void
 g_expr(int e1)
 {
-    int e2,e3/*,e4*/;
+    int suse = use; use=1;
+    g_expr0(e1);
+    use=suse;
+}
+
+void
+g_expr0(int e1)
+{
+    int e2,e3;
     NMTBL *n;
 
     e2 = cadr(e1);
@@ -279,19 +298,19 @@
 	return;
     case FRLVAR:
 	code_drlvar(lvar(e2),0);
-	regv[freg]=1;
+	fregv[freg]=1;
 	return;
     case FRGVAR:
 	code_drgvar(e1,0);
-	regv[freg]=1;
+	fregv[freg]=1;
 	return;
     case DRLVAR:
 	code_drlvar(lvar(e2),1);
-	regv[freg]=1;
+	fregv[freg]=1;
 	return;
     case DRGVAR:
 	code_drgvar(e1,1);
-	regv[freg]=1;
+	fregv[freg]=1;
 	return;
     case FNAME:
 	code_fname(((NMTBL *)(e2))->nm);
@@ -303,7 +322,7 @@
 	return;
     case DCONST:
 	code_dconst(e1);
-	regv[freg]=1;
+	fregv[freg]=1;
 	return;
     case STRING:
 	string(e1);
@@ -317,37 +336,37 @@
 	jump(e2,caddr(e1));
 	return;
     case INDIRECT:
-	g_expr(e2);
+	g_expr0(e2);
 	return;
     case RINDIRECT:  case CRINDIRECT:
     case DRINDIRECT: case FRINDIRECT:
 	rindirect(e1);
 	return;
     case ADDRESS:
-	g_expr(e2);
+	g_expr0(e2);
 	return;
     case MINUS:  /* レジスタに対し、neglを実行すれば実現可能 */
-	g_expr(e2);
+	g_expr0(e2);
 	code_neg();
 	return;
     case DMINUS: 
-	g_expr(e2);
+	g_expr0(e2);
 	code_dneg();
 	return;
     case I2D: 
-	g_expr(e2);
+	g_expr0(e2);
 	code_i2d();
 	return;
     case D2I: 
-	g_expr(e2);
+	g_expr0(e2);
 	code_d2i();
 	return;
     case BNOT:   /* ~ */
-	g_expr(e2);
+	g_expr0(e2);
 	code_not();
 	return;
     case LNOT:   /* !  */
-	g_expr(e2);
+	g_expr0(e2);
 	code_lnot();
 	return;
     case PREINC:
@@ -356,6 +375,18 @@
     case POSTINC:
 	code_postinc(e1,e2);
 	return;
+    case DPREINC:
+	code_dpreinc(e1,e2,1);
+	return;
+    case DPOSTINC:
+	code_dpostinc(e1,e2,1);
+	return;
+    case FPREINC:
+	code_dpreinc(e1,e2,0);
+	return;
+    case FPOSTINC:
+	code_dpostinc(e1,e2,0);
+	return;
     case CPOSTINC:
 	/*   char *p; *p++ */
 	code_cpostinc(e1,e2);
@@ -385,13 +416,13 @@
 	e2=fwdlabel();
 	b_expr(cadr(e1),0,e2,0);
 	code_set_fixed_creg(0);
-	g_expr(caddr(e1));
+	g_expr0(caddr(e1));
 	/* e4 = rname[creg]; this is a bad idea */
 	code_set_fixed_creg(1);
 	jmp(e3=fwdlabel());
 	fwddef(e2);
 	code_set_fixed_creg(0);
-	g_expr(cadddr(e1));
+	g_expr0(cadddr(e1));
 	code_set_fixed_creg(1);
 	fwddef(e3);
 	return;
@@ -411,11 +442,11 @@
 	dassop(e1);
 	return;
     case RSTRUCT:
-	g_expr(e2);
+	g_expr0(e2);
 	return;
     case COMMA:
-	g_expr(e2);
-	g_expr(caddr(e1));
+	g_expr_u(e2);
+	g_expr0(caddr(e1));
 	return;
     case RETURN:
 	n = (NMTBL *)e2;
@@ -546,10 +577,9 @@
 	if((dcadr(e2)!=0.0)^cond) jmp(l1);
 	return;
     default:
-	/* type ? */
 	if(err) {
 	    error(-1); return; /* recursive g_expr/b_expr */
-	}
+	} /* type ? */
 	g_expr(e1);
 	code_cmp_register(creg);
 	jcond(l1,cond);
@@ -611,11 +641,11 @@
     if (sz==size_of_int && (e1=get_register())!=-1) {
 	*use=list3(t,*use,e1);
 	e1=list2(REGISTER,e1);
-	g_expr(assign_expr0(e1,s,ty,ty));
+	g_expr_u(assign_expr0(e1,s,ty,ty));
 	*target = append4(*target,t,ty,e1);
     } else {
 	disp-=sz;
-	g_expr(assign_expr0((e1=list2(LVAR,disp)),s,ty,ty));
+	g_expr_u(assign_expr0((e1=list2(LVAR,disp)),s,ty,ty));
 	*target = append4(*target,t,ty,e1);
     }
 }
@@ -667,7 +697,7 @@
 #if DEBUG_PARALLEL_ASSIGN
 printf("# normal assign %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz);
 #endif
-		g_expr(assign_expr0(t,s,ty,ty));
+		g_expr_u(assign_expr0(t,s,ty,ty));
 		remove_target(target,t,use); remove0(source,s);
 	    } else {
 		if(circular_dependency(t,s1,target,source)) {
@@ -791,7 +821,7 @@
 	}
 	if (!is_simple(car(s0))) {
 	    disp-=sz;
-	    g_expr(assign_expr0((e4=list2(LVAR,disp)),s0,ty,ty));
+	    g_expr_u(assign_expr0((e4=list2(LVAR,disp)),s0,ty,ty));
 	    cadddr(e2)=e4;
 	    s0=e4;
         } else if (is_same_type(t0,s0)) {
@@ -884,7 +914,7 @@
     g_expr(e2);
     dtosop(car(e1),(e2=dpop_register()));
     emit_dpop_free(e2);
-    regv[freg]=1;
+    fregv[freg]=1;
     return;
 }
 
@@ -1014,11 +1044,21 @@
 void
 dassop(int e1)
 {
-}
+    int e2,e3,op,d;
 
-void
-fassop(int e1)
-{
+    /*   e2 op= e3 */
+    d = (car(e1) == DASSOP);
+    e2 = cadr(e1);
+    if (car(e2)==INDIRECT) e2=cadr(e2);
+    e3 = caddr(e1);
+    op = cadddr(e1);
+
+    g_expr(e3);
+    emit_dpush();
+    g_expr(e2);
+    code_dassop(op,d);
+    regv[creg]=1;
+    return;
 }
 
 int
--- a/mc-codegen.h	Wed Mar 05 00:39:39 2003 +0900
+++ b/mc-codegen.h	Wed Mar 05 03:41:08 2003 +0900
@@ -1,19 +1,31 @@
+
+/* max stack in an expression (for each int, float ) */
+#define MAX_MAX 10
 
 extern int  creg;     /* current register */
 extern int  dreg;     /* temporary register */
 extern int  reg_sp;   /* REGister Stack-Pointer */
 
-extern int rname[];
-extern int regs[];       /* 使われているレジスタを示すフラグ */
-extern int reg_stack[];  /* 実際のレジスタの領域 */
-extern int regv[];       /* 値が入っているかどうか */
-extern int MAX_REGISTER;
+extern int rname[MAX_MAX];
+extern int regs[MAX_MAX];       /* 使われているレジスタを示すフラグ */
+extern int reg_stack[MAX_MAX];  /* 実際のレジスタの領域 */
+extern int regv[MAX_MAX];       /* 値が入っているかどうか */
+
+/* floating point registers */
 
-extern int creg_regvar;
+extern int  freg;     /* current floating point register */
+extern int  greg;     /* current floating point register */
+extern int  freg_sp;  /* floating point REGister Stack-Pointer */
+
+extern int frname[MAX_MAX];
+extern int fregs[MAX_MAX];      /* 使われているレジスタを示すフラグ */
+extern int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */
+extern int fregv[MAX_MAX];      /* 値が入っているかどうか */
+
+extern int use;                 /* generated value will be used */
 
 /* function provided by mc-codegen.c */
 
-
 extern void def_label(int cslabel, int dlabel);
 extern int backdef(void);
 extern int csvalue();
@@ -47,7 +59,7 @@
 extern void gen_comment(char *s);
 extern void gen_gdecl(char *n, int gpc);
 extern void gen_source(char *s);
-extern void gexpr(int e1);
+extern void gexpr(int e1,int use);
 extern void gexpr_init(void);
 extern void jcond(int l, char cond);
 extern void jmp(int l);
--- a/mc-parse.c	Wed Mar 05 00:39:39 2003 +0900
+++ b/mc-parse.c	Wed Mar 05 03:41:08 2003 +0900
@@ -850,7 +850,7 @@
     if (!init_vars) return;
     init_vars = reverse0(init_vars);
     while(init_vars) {
-	gexpr(car(init_vars));
+	gexpr(car(init_vars),0);
 	init_vars = cadr(init_vars);
     }
 }
@@ -1287,7 +1287,7 @@
 	    statement();
 	} else {	
 	    slfree=lfree;
-	    gexpr(expr(0));
+	    gexpr(expr(0),0);
 	    lfree=slfree;
 	    conv->sm_();
 	    checksym(SM);
@@ -1400,7 +1400,7 @@
     checksym(LPAR);
     slfree=lfree;
     if(sym!=SM) {	
-	gexpr(expr(0));
+	gexpr(expr(0),0);
 	checksym(SM);
 	conv->for1_();
     } else {
@@ -1432,7 +1432,7 @@
 	statement();
 	checkret();
 	fwddef(clabel);
-	gexpr(e);
+	gexpr(e,0);
 	lfree=slfree;
     }
     conv->for_end_();
@@ -1457,7 +1457,7 @@
     checksym(LPAR);
     slfree=lfree;
     svalue=csvalue1;      /* save parents switch value */
-    gexpr(expr(0));
+    gexpr(expr(0),1);
     csvalue1=csvalue() ;
     lfree=slfree;
     checksym(RPAR);
@@ -1547,20 +1547,21 @@
 	if ((car(type)==STRUCT || car(type)==UNION)&&
 		size(type)==cadr(struct_return)) {
 	    if(car(e)==RSTRUCT && car(cadr(e))==FUNCTION) {
+                /* pass the return pointer to the called function */
 		replace_return_struct(cadr(e),
 		    rvalue_t(car(struct_return),caddr(struct_return)));
-		gexpr(cadr(e));
+		gexpr(cadr(e),0);
 	    } else {
 		e = rvalue(e);
 		type = caddr(struct_return);
 		e1 = rvalue_t(cadr(struct_return),INT); /* size */
-		gexpr(list4(SASS,rvalue(car(struct_return)),e,e1));
+		gexpr(list4(SASS,rvalue(car(struct_return)),e,e1),0);
 	    }
 	} else {
 	    error(TYERR); /* should check compatible */
 	}
     } else {
-	gexpr(expr(0));
+	gexpr(expr(0),1);
     }
     lfree=slfree;
     conv->return_end_();
@@ -1616,7 +1617,7 @@
 	    nptr0=(NMTBL *)cadr(e2);
 	    nptr0->sc = CODE;
 	}
-	gexpr(list3(CODE,e1,env));
+	gexpr(list3(CODE,e1,env),0);
 	control=0;
 	conv->sm_();
 	checksym(SM);
@@ -1976,6 +1977,10 @@
 	}
 	if(integral(type))
 	    return(list3(PREINC,e,op==INC?1:-1));
+	if(type==FLOAT)
+	    return(list3(FPREINC,e,op==INC?1:-1));
+	if(type==DOUBLE)
+	    return(list3(DPREINC,e,op==INC?1:-1));
 	if(car(type)!=POINTER) 
 	    error(TYERR);
 	return(list3(PREINC,e,
@@ -2043,7 +2048,7 @@
 		if(sym==INC||sym==DEC) {	
 		    getsym();
 		    if(type==CHAR) type=INT;
-		    else if(!scalar(type))
+		    else if(!scalar(type)&&type!=FLOAT&&type!=DOUBLE)
 			error(TYERR);
 		}
 	    }
@@ -2064,6 +2069,10 @@
 	}
 	if(integral(type))
 	    return(list3(POSTINC,e,op==INC?1:-1));
+	if(type==FLOAT)
+	    return(list3(FPOSTINC,e,op==INC?1:-1));
+	if(type==DOUBLE)
+	    return(list3(DPOSTINC,e,op==INC?1:-1));
 	if(car(type)!=POINTER) 
 	    error(TYERR);
 	return (list3(POSTINC,e,
--- a/mc.h	Wed Mar 05 00:39:39 2003 +0900
+++ b/mc.h	Wed Mar 05 03:41:08 2003 +0900
@@ -178,10 +178,14 @@
 
 #define I2D	97
 #define D2I	98
+#define FPOSTINC	99
+#define DPOSTINC	100
+#define FPREINC	101
+#define DPREINC	102
 
 #define US	1
 #define AS	200
-#define DOP	300
+#define DOP	400
 
 #define FILERR	1
 #define DCERR	2