changeset 50:1ec39b34ed98

goto
author kono
date Sun, 16 Feb 2003 06:34:12 +0900
parents 884c74e6a2f7
children c2ef3a2fbe88
files mc-nop-386.c mc-parse.c mc-tree.c
diffstat 3 files changed, 108 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
--- a/mc-nop-386.c	Sun Feb 16 02:47:10 2003 +0900
+++ b/mc-nop-386.c	Sun Feb 16 06:34:12 2003 +0900
@@ -9,15 +9,15 @@
 extern void closing(void);
 extern void cmpdimm(int e, int csreg);
 extern void code_enter(char *name) ;
-extern void code_enter1(int disp0,int args);
+extern void code_enter1(int args);
 extern void code_init(void);
-extern void code_leave(char *name,int disp) ;
-extern void leave(int control,char *name,int disp0) ;
+extern void code_leave(char *name) ;
+extern void leave(int control,char *name) ;
 extern void def_label(int cslabel, int dlabel) ;
 extern void emit_data(int e, int t, NMTBL *n);
 extern void emit_init(void);
 extern void enter(char *name) ;
-extern void enter1(int disp) ;
+extern void enter1() ;
 extern void g_expr(int e1);
 extern void gen_comment(char *s);
 extern void gen_gdecl(char *n, int gpc) ;
@@ -29,9 +29,12 @@
 extern void ret(void);
 extern int assign_expr0(int e,int e1,int type,int type1);
 extern int integral(int t);
+extern void tree_print_t(int e,int t);
+extern int rvalue_t(int e,int t);
 
 static int edx_setup() ;
 static int	lvar(int l);
+static int      cvar(int l);
 static void	jump(int e1, int env);
 static void    data_mode(char *name);
 static void    text_mode(void);
@@ -82,16 +85,20 @@
 static int func_disp_label;
 
 /*
-         local1 <----24 local variable
-        %esi        -20  <- disp_offset
-        %edi        -16
-        %edx        -12
-        %ecx         -8
+                                           -16  local2
+                                           -12  local1
+                                            -8  arg1
+                                            -4  arg2
+                                             0  arg3
+                                             0  (%edi)
+         local1 <----14 local variable       0  (%esi)
+        %edi        -12  <- disp_offset          %ebp
+        %esi         -8
         %ebx         -4
         %ebp = %esp   0
         %eip          4   <- arg_offset
           arg1        8
-            see enter/enter1/leave
+            see enter/enter1/leave           see code_enter
  */
 int arg_offset = 8;
 int code_arg_offset = -4;
@@ -109,6 +116,7 @@
 static int  creg;     /* current register */
 static int  dreg;     /* temporary register */
 static int  reg_sp;   /* REGister Stack-Pointer */
+static int  vdisp;
 
 
 #define REG_EAX   0
@@ -966,6 +974,7 @@
 	t=caddr(e3);
 	n=(NMTBL *)(e5=(cadr(e4 = car(e3))));
 	switch(car(e4)) {
+/*
 	case FNAME:
 	    printf("\tlea %s,%s\n",n->nm,register_name(creg,0));
 	    printf("\tpushl %s\n",register_name(creg,0));
@@ -974,6 +983,7 @@
 	    g_expr(e5);
 	    printf("\tpushl %s\n",register_name(creg,0));
 	    break;
+  */
 	default:
 	    if(scalar(t)) {
 		g_expr(e4);
@@ -1022,14 +1032,6 @@
 /* source         list3(expr,cdr,ty) expr=listn(tag,...) */
 /* source (after) list3(list2(tag,disp),cdr,ty) */
 
-void
-disp_source(int e3) {
-    printf("# jump arg list\n");
-    for (; e3; e3 = cadr(e3)) {	
-	printf("#    %d, expr %d, size %d\n",car(e3),caddr(e3),cadddr(e3));
-    }
-}
-
 int
 overrap(int t,int source)
 {
@@ -1065,8 +1067,8 @@
 		    g_expr(assign_expr0(e1,s,ty,ty));
 		    return list2(assign_expr0(t,e1,ty,ty),e1);
 		} else {
-		    disp+=sz;
-		    g_expr(assign_expr0((e1=list2(LVAR,disp)),s,ty,ty));
+		    disp-=sz;
+		    g_expr(assign_expr0((e1=list2(LVAR,cvar(disp))),s,ty,ty));
 		    return list2(assign_expr0(t,e1,ty,ty),-1);
 		}
 	    }
@@ -1116,43 +1118,48 @@
 {
     return (
 	e1==CONST || e1==FNAME || e1==LVAR || e1==REGISTER ||
-	e1==GVAR
+	e1==GVAR || RGVAR || RLVAR || CRLVAR || CRGVAR
     );
 }
 
 int
 is_same(int e1,int e2)
 {
-    if(car(e1)==car(e2)) {
+    if(   (car(e1)==LVAR && (car(e2)==RLVAR||car(e2)==CRLVAR))
+       || (car(e1)==GVAR && (car(e2)==RGVAR||car(e2)==CRGVAR)))
 	return cadr(e1)==cadr(e2);
-    }
     return 0;
 }
 
 void
 jump(int e1, int env)
 {
-    int e2,e3,e4,sz,arg_size,ty,max_regs,regs;
+    int e2,e3,e4,ce2,ce3,sz,arg_size,ty,max_regs,regs;
     NMTBL *code0;
     int target = 0;
     int source = 0;
     int processing = 0;
+    int sdisp = disp;
 
     /* まず、サイズを計算しながら、決まった形に落す。 */
-    arg_size = 0; regs = 0; max_regs = MAX_REGISTER_VAR;
-    for (e3 = caddr(e1); e3; e3 = cadr(e3)) {	
+    arg_size = 0; regs = 0; max_regs = MAX_REGISTER_VAR-1;
+    for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {	
 	e2 = car(e3); sz = size(ty=caddr(e3)); 
 	if (regs <= max_regs&&integral(ty)) {
-	    target=list3(list2(REGISTER,(regs++)+REG_ESI),target,ty);
+	    target=list3(list2(REGISTER,virtual((regs++)+REG_ESI)),target,ty);
 	} else {
+	    target=list3(list2(LVAR,cvar(arg_size)),target,ty);
 	    arg_size += sz;
-	    target=list3(list2(LVAR,arg_size-MAX_REGISTER_VAR),target,ty);
 	}
 	source = list3(e2,source,ty);
     }
 
     /* disp を飛び先似合わせて修正 */
-    if (arg_size>disp) disp = arg_size;
+    if (fnptr->sc==CODE) {
+	if (-arg_size<disp) disp = -arg_size;
+    } else {
+	if (disp_offset-arg_size<disp) disp = disp_offset-arg_size;
+    }
 
     /*  複雑な式を前もって計算しておく     */
     /*  必要なら局所変数を用いる。         */
@@ -1160,12 +1167,13 @@
     /*  ついでに、同じものがあれば、除く */
 
     for (e3 = source,e2 = target; e3; e3 = cadr(e3),e2 = cadr(e2)) {	
-	if (!is_simple(car(car(e3)))) {
-	    disp+=size(ty=caddr(e3));
-	    g_expr(assign_expr0((e4=list2(LVAR,disp)),car(e3),ty,ty));
+	ce3=car(e3);ce2=car(e2);
+	if (!is_simple(car(ce3))) {
+	    disp-=size(ty=caddr(e3));
+	    g_expr(assign_expr0((e4=list2(LVAR,cvar(disp))),ce3,ty,ty));
 	    car(e3)=e4;
-	} else if (is_same(car(e2),car(e3))) {
-	    remove0(&source,e3);remove0(&target,e2);
+	} else if (is_same(ce2,ce3)) {
+	    remove0(&source,ce3);remove0(&target,ce2);
 	}
     }
 
@@ -1180,15 +1188,31 @@
 	g_expr(e2);
 	emit_push();
     }
+    if (env) {
+	g_expr(env);
+	emit_push();
+    }
 
     /* 並列代入を実行 */
 
     parallel_assign(&source,&target,&processing);
 
-    if (!env && arg_size>disp) {
+    if (env) {
+	/* change the frame pointer */
+	e3 = emit_pop(0);
+	printf("\tmovl %s,%%ebp\n",register_name(e3,0));
+	emit_pop_free(e3);
+    } else if (fnptr->sc==FUNCTION) {
+	printf("\tlea %d(%%ebp),%%ebp\n",disp_offset);
+    } 
+
 	/* shrink stack if necessary */
-	printf("\tleal %d(%%ebp),%%esp\n",arg_size);
-    } 
+    /*
+    if (!env && -arg_size<disp) {
+	printf("\tleal %d(%%ebp),%%esp\n",-arg_size);
+    }  Why we need this?
+     */
+
     if (car(e2) == FNAME) {	
 	printf("\tjmp %s\n",code0->nm);
     } else {
@@ -1196,7 +1220,8 @@
 	printf("\tjmp *%s\n",register_name(e2,0));
 	emit_pop_free(e2);
     }
-    free_all_register();
+    if (vdisp<disp) vdisp=disp;
+    disp=sdisp;
 }
 
 #if 0
@@ -1749,22 +1774,23 @@
 }
 
 void
-code_enter1(int disp0,int args)
+code_enter1(int args)
 {
     code_disp_label=fwdlabel();
-    printf("\tsubl $_%d,%%esp\n",code_disp_label);
+    vdisp = disp;
+    printf("\tlea _%d(%%ebp),%%esp\n",code_disp_label);
     /*
     if(disp0) {
-	printf("\tsubl $%d,%%esp\n",-disp0);
+	printf("\tsubl $%d,%%esp\n",disp0);
     }
      */
 printf("## args %d disp %d code_arg_offset=%d code_disp_offset=%d\n",args,disp,code_arg_offset,code_disp_offset); 
 }
 
 void
-code_leave(char *name,int disp0)
+code_leave(char *name)
 {
-    printf("\t.set _%d,%d\n",code_disp_label,-disp0);
+    printf("\t.set _%d,%d\n",code_disp_label,cvar(vdisp));
     printf("_%d:\n",labelno);
     printf("\t.size\t%s,_%d-%s\n",name,labelno,name);
     local_table();
@@ -1774,6 +1800,7 @@
 void
 enter(char *name)
 {
+    vdisp = disp;
     printf("\t.align 2\n");
     if (stmode!=STATIC)
 	printf(".globl %s\n",name);
@@ -1788,15 +1815,16 @@
 }
 
 void
-enter1(int disp)
+enter1()
 {
+    vdisp = disp;
     func_disp_label=fwdlabel();
-    printf("\tsubl $_%d,%%esp\n",func_disp_label); 
+    printf("\tlea _%d(%%ebp),%%esp\n",func_disp_label); 
     /* if(disp) printf("\tsubl $%d,%%esp\n",-disp); */
 }
 
 void
-leave(int control, char *name,int disp)
+leave(int control, char *name)
 {
     if (control)
 	use_register(creg,REG_EAX,1);
@@ -1810,14 +1838,14 @@
     }
     fwddef(retlabel);
     /* use_register(creg,REG_EAX,0); too late */
-    /* if(disp) printf("\taddl $%d,%%esp\n",-disp);  */
+    /* if(disp) printf("\taddl $%d,%%esp\n",-vdisp);  */
     printf("\tlea %d(%%ebp),%%esp\n",disp_offset);
     printf("\tpopl %%edi\n");
     printf("\tpopl %%esi\n");
     printf("\tpopl %%ebx\n");
     printf("\tleave\n");
     printf("\tret\n");
-    printf("\t.set _%d,%d\n",func_disp_label,-disp);
+    printf("\t.set _%d,%d\n",func_disp_label,lvar(vdisp));
     printf("_%d:\n",labelno);
     printf("\t.size\t%s,_%d-%s\n",name,labelno,name);
     local_table();
@@ -1970,17 +1998,19 @@
 int
 lvar(int l)
 {
-    if (l<0) {
-	if (fnptr->sc==CODE)
-	    return l+code_disp_offset;
-	else
-	    return l+disp_offset;
+    if (fnptr->sc==CODE) {
+	return (l<0)?  l+code_disp_offset: -l+code_arg_offset;
+    } else if (l<0) {
+	return l+disp_offset;
     } else {
-	if (fnptr->sc==CODE)
-	    return -l+code_arg_offset;
-	else
-	    return l+arg_offset;
+	return l+arg_offset;
     }
 }
 
+int
+cvar(int l)
+{
+    return (fnptr->sc==CODE)?l:l+disp_offset;
+}
+
 /* end */
--- a/mc-parse.c	Sun Feb 16 02:47:10 2003 +0900
+++ b/mc-parse.c	Sun Feb 16 06:34:12 2003 +0900
@@ -75,7 +75,7 @@
 static void reverse(int t1);
 int reverse0(int t1);
 static int rvalue(int e);
-static int rvalue_t(int e,int type);
+extern int rvalue_t(int e,int type);
 int scalar(int t);
 static int sdecl(int s);
 static int skipspc(void);
@@ -103,8 +103,8 @@
 extern void gen_gdecl(char *n, int gpc);
 extern void emit_init(void);
 extern void enter(char *name);
-extern void enter1(int disp);
-extern void leave(int control, char *name,int disp);
+extern void enter1();
+extern void leave(int control, char *name);
 extern void ret(void);
 extern void jmp(int l);
 extern void gexpr(int e1);
@@ -124,8 +124,8 @@
 extern void gen_source(char *s);
 extern void code_init(void);
 extern void code_enter(char *name) ;
-extern void code_leave(char *name,int disp) ;
-extern void code_enter1(int disp0,int args);
+extern void code_leave(char *name) ;
+extern void code_enter1(int args);
 extern int csvalue();
 extern int assign_expr(int e1,int e2,int t,int type);
 extern int assign_expr0(int e1,int e2,int t,int type);
@@ -976,8 +976,6 @@
 void
 code_decl(NMTBL *n)
 {
-    int odisp;
-
     if (n->sc==EMPTY) n->sc = CODE;
     code_enter(n->nm);
     fnptr=n;
@@ -996,20 +994,19 @@
     stmode=0;
     mode=STAT;
     init_vars=0;
-    odisp=disp;
     while (typeid(getsym()) || sym==STATIC || sym==EXTRN || sym==TYPEDEF) {	
 	mode=LDECL;
 	decl();
 	mode=STAT;
     }
     control=1;
-    code_enter1(disp-odisp,args);
+    code_enter1(args);
     emit_init_vars();
     while(sym!=RC) statement();
     if(control)
 	error(STERR);
     control=0;
-    code_leave(n->nm,disp-odisp);
+    code_leave(n->nm);
 }
 
 static NMTBL *tmp_struct;
@@ -1044,11 +1041,11 @@
 	mode=STAT;
     }
     control=1;
-    enter1(disp);
+    enter1();
     emit_init_vars();
     while(sym!=RC) statement();
 
-    leave(control,n->nm,disp);
+    leave(control,n->nm);
     retpending = 0;
     control=0;
 }
@@ -1517,7 +1514,7 @@
 assign_expr0(int e1,int e2,int t,int type) {
     int stype;
     stype=type;
-    e1=assign_expr(e1,e2,t,type);
+    e1=assign_expr(e1,rvalue_t(e2,type),t,type);
     type=stype;
     return e1;
 }
--- a/mc-tree.c	Sun Feb 16 02:47:10 2003 +0900
+++ b/mc-tree.c	Sun Feb 16 06:34:12 2003 +0900
@@ -5,6 +5,7 @@
 #include "mc.h"
 extern void tree_print(int e);
 extern void tree_parse(int e);
+extern void tree_print_t(int e,int t);
 
 typedef
 struct tree_node {
@@ -133,6 +134,16 @@
 };
 
 void
+tree_print_t(int e,int t)
+{
+    printf("# type: ");
+    tree_print(t);
+    printf("expr: ");
+    tree_print(e);
+    printf("\n");
+}
+
+void
 tree_print(int e)
 {
     printf("* generate code on type:\n* ");