diff mc-code-ia32.c @ 313:f73b93de216a alloca

alloca done for ia32, powerpc, mips
author kono
date Tue, 15 Jun 2004 00:11:26 +0900
parents a86612cf1a19
children 84df3dd8cc3d
line wrap: on
line diff
--- a/mc-code-ia32.c	Sat Jun 12 15:58:56 2004 +0900
+++ b/mc-code-ia32.c	Tue Jun 15 00:11:26 2004 +0900
@@ -63,6 +63,7 @@
 
 static int  reg_sp;   /* REGister Stack-Pointer */
 static int reg_stack[MAX_MAX];  /* 実際のレジスタの領域 */
+int stack_depth = 0;
 
 /* floating point registers */
 
@@ -227,6 +228,7 @@
 #define __externsion__\n\
 #define __flexarr\n\
 #define wchar_t int\n\
+#define __GNUC__ 2\n\
 ";
 
 void
@@ -471,6 +473,7 @@
     if (freg_sp>0) error(-1);
     reg_sp = 0;
     freg_sp = 0;
+    stack_depth = 0;
     text_mode();
     gexpr_code_init();
     register_usage("gexpr_init");
@@ -599,6 +602,7 @@
 	if (reg_sp>=MAX_MAX) error(-1);
 	reg_stack[reg_sp++] =  -1;
 	printf("\tpushl %s\n",register_name(creg,0));
+	stack_depth += SIZE_OF_INT;
 	/* creg is used soon, don't regv[creg]=0 */
     } else {
 	reg_stack[reg_sp++] = creg;     /* push するかわりにレジスタを使う */
@@ -622,6 +626,7 @@
 }
 	printf("\tpopl %s\n",register_name(dreg,0));
 	regv[dreg]=1;
+	stack_depth -= SIZE_OF_INT;
 	return dreg;
     } else if (xreg<= -REG_LVAR_OFFSET) {
 	code_rlvar(xreg+REG_LVAR_OFFSET,dreg);
@@ -1096,6 +1101,7 @@
 	regv[xreg]=1;
     } else
 	free_register(xreg);
+    stack_depth += length*SIZE_OF_INT;
     return length/SIZE_OF_INT;
 }
 
@@ -1105,6 +1111,8 @@
     int e2,e3,e4,nargs,t,ret_type;
     NMTBL *n=0;
     int save,saved;
+    int stack_depth_save = stack_depth;
+
     ret_type = cadr(cadddr(e1));
     if (ret_type==CHAR) ret_type=INT;
 
@@ -1135,6 +1143,7 @@
 		g_expr(e4);
 		printf("\tpushl %s\n",register_name(creg,0));
 	    }
+	    stack_depth += SIZE_OF_INT;
 	} else if (t==LONGLONG||t==ULONGLONG) {
 	    if (car(e4)==LREGISTER) {
 		printf("\tpushl %s\n\tpushl %s\n",l_edx(cadr(e4)),l_eax(cadr(e4)));
@@ -1143,17 +1152,20 @@
 		printf("\tpushl %%edx\n\tpushl %%eax\n");
 	    }
 	    ++nargs;
+	    stack_depth += SIZE_OF_INT*2;
 	} else if (t==DOUBLE) {
 	    g_expr(e4);
 	    printf("\tleal\t-8(%%esp),%%esp\n\tfstpl\t(%%esp)\n");
 	    nargs += SIZE_OF_DOUBLE/SIZE_OF_INT;
 	    fregv[freg]=0;
+	    stack_depth += SIZE_OF_DOUBLE;
 	    continue;
 	} else if (t==FLOAT) {
 	    g_expr(e4);
 	    printf("\tleal\t-4(%%esp),%%esp\n\tfstps\t(%%esp)\n");
 	    nargs += SIZE_OF_FLOAT/SIZE_OF_INT;
 	    fregv[freg]=0;
+	    stack_depth += SIZE_OF_FLOAT;
 	    continue;
 	} else if (car(t)==STRUCT||car(t)==UNION) {
 	    nargs += struct_push(e4,t);
@@ -1202,10 +1214,36 @@
 	use_register(creg,REG_EAX,0);
 	fregv[freg]=0; regv[creg]=1;
     }
+    stack_depth = stack_depth_save;
     return ret_type;
 }
 
 void
+code_alloca(int e1,int reg)
+{
+    char *crn,*drn;
+    int edx;
+  
+    g_expr(list3(BAND,list3(ADD,e1,list2(CONST,15)),list2(CONST,~15))); 
+    use_int(reg);
+    if (stack_depth>0) {
+	edx = edx_setup(-1);
+	crn = register_name(reg,0);
+	drn = register_name(edx,0);
+	printf("\tmovl %%esp,%s\n",drn);
+	printf("\tsubl %s,%%esp\n",crn);
+	printf("\tmovl %%esp,%s\n",crn);
+	emit_copy(edx,creg,stack_depth,0,1,1);
+	printf("\taddl $%d,%s\n",stack_depth,register_name(creg,0));
+	edx_cleanup();
+    } else {
+	crn = register_name(reg,0);
+	printf("\tsubl %s,%%esp\n",crn);
+	printf("\tmovl %%esp,%s\n",crn);
+    }
+}
+
+void
 code_frame_pointer(int e3) {
     use_int(e3);
     printf("\tmovl %s,%%ebp\n",register_name(e3,0));
@@ -1474,9 +1512,11 @@
 oprtc(int op,int reg,int orn)
 {
     char *crn;
+    int datareg;
     use_int(reg);
     crn = register_name(reg,0);
     orn = cadr(orn);
+    datareg=(rname[reg]<MAX_DATA_REG);
 
     switch(op) {
     case LSHIFT:
@@ -1496,13 +1536,23 @@
 	printf("\tsubl $%d,%s\n",orn,crn);
 	break;
     case BAND: 
-	printf("\tandl $%d,%s\n",orn,crn);
+	if (datareg&&(orn & ~255)==~255)
+	    printf("\tandb $%d,%s\n",orn,register_name(reg,1));
+	else if (datareg&&(orn & ~65535)==~65535)
+	    printf("\tandw $%d,%s\n",orn,register_name(reg,2));
+	else
+	    printf("\tandl $%d,%s\n",orn,crn);
 	break;
     case EOR: 
 	printf("\txorl $%d,%s\n",orn,crn);
 	break;
     case BOR:
-	printf("\torl $%d,%s\n",orn,crn);
+	if (datareg&&(orn & ~255)==0)
+	    printf("\tor $%d,%s\n",orn,register_name(reg,1));
+	else if (datareg&&(orn & ~65535)==0)
+	    printf("\tor $%d,%s\n",orn,register_name(reg,2));
+	else
+	    printf("\torl $%d,%s\n",orn,crn);
 	break;
     case MUL:
     case UMUL:
@@ -2587,6 +2637,7 @@
     // e2 (operand) is on the top of the stack
     use_longlong(reg);
     opl = 0; call=0;
+    stack_depth -= SIZE_OF_INT * 2;
 
     switch(op) {
     case LLSHIFT:
@@ -2736,9 +2787,9 @@
     switch(op) {
     case LADD: opl="addl";oph="adcl"; break;
     case LSUB: opl="subl";oph="sbbl"; break;
-    case LBAND: opl=oph="andl"; break;
     case LEOR:  opl=oph="xorl"; break;
     case LBOR:  opl=oph="orl"; break;
+    case LBAND: opl=oph="andl"; break;
     default: error(-1);
     }
     printf("\t%s $%d,%s\n\t%s $%d,%s\n",opl,vl,l_eax(reg),oph,vh,l_edx(reg));
@@ -2751,6 +2802,7 @@
 
 void emit_lpush()
 {
+    stack_depth += SIZE_OF_INT * 2;
     printf("\tpushl %%edx\n\tpushl %%eax\n");
 }