changeset 38:d48d952da354

struct copy continue
author kono
date Tue, 11 Feb 2003 11:26:51 +0900
parents 412ad2e6c2a2
children c63c4fdeb9a7
files .gdbinit mc-nop-386.c mc-parse.c
diffstat 3 files changed, 38 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Mon Feb 10 22:29:12 2003 +0900
+++ b/.gdbinit	Tue Feb 11 11:26:51 2003 +0900
@@ -1,6 +1,6 @@
 tb main
-b error
-b errmsg
+# b error
+# b errmsg
 define regs 
 call fprintf(stderr,"eax=%08x ebx=%08x ecx=%08x edx=%08x\nesi=%08x edi=%08x ebp=%08x esp=%08x eip=%08x\n",$eax,$ebx,$ecx,$edx,$esi,$edi,$ebp,$esp,$eip)
 end
--- a/mc-nop-386.c	Mon Feb 10 22:29:12 2003 +0900
+++ b/mc-nop-386.c	Tue Feb 11 11:26:51 2003 +0900
@@ -55,7 +55,7 @@
 static void tosop(int op);
 static void div_cleanup(char *orn);
 static void use_register(int virt, int real, int move);
-static void emit_copy(char *from,char *to,int length,int offset);
+static void emit_copy(int from,int to,int length,int offset);
 
 extern int error(int n);
 extern int fwdlabel(void);
@@ -177,6 +177,10 @@
 char *
 register_name(int i,int byte)
 {
+    if (i<0) {
+	error(REG_ERR);
+	return "%eax";
+    }
     if (byte && rname[i] <= REG_EDX) {
 	return reg_name_l[rname[i]];
     } else {
@@ -740,22 +744,22 @@
 #define MAX_COPY_LEN 20
 
 void 
-emit_copy(char *from,char *to,int length,int offset)
+emit_copy(int from,int  to,int length,int offset)
 {
     if (length<0) return;
     switch (length) {
     case 0:	break;
     case 1:
-	printf("\tmovb %d(%s),%s\n",offset,from, reg_name_l[rname[dreg]] );
-	printf("\tmovb %s,%d(%s)\n",reg_name_l[rname[dreg]] ,offset,to);
+	printf("\tmovb %d(%s),%s\n",offset,register_name(from,0), reg_name_l[rname[dreg]] );
+	printf("\tmovb %s,%d(%s)\n",reg_name_l[rname[dreg]] ,offset,register_name(to,0));
 	break;
     case 2:
-	printf("\tmovw %d(%s),%s\n",offset,from, reg_name_w[rname[dreg]] );
-	printf("\tmovw %s,%d(%s)\n",reg_name_w[rname[dreg]] ,offset,to);
+	printf("\tmovw %d(%s),%s\n",offset,register_name(from,0), reg_name_w[rname[dreg]] );
+	printf("\tmovw %s,%d(%s)\n",reg_name_w[rname[dreg]] ,offset,register_name(to,0));
 	break;
     case 4:
-	printf("\tmovl %d(%s),%s\n",offset,from, register_name(dreg,0));
-	printf("\tmovl %s,%d(%s)\n",register_name(dreg,0), offset,to);
+	printf("\tmovl %d(%s),%s\n",offset,register_name(from,0), register_name(dreg,0));
+	printf("\tmovl %s,%d(%s)\n",register_name(dreg,0), offset,register_name(to,0));
 	break;
     default:
 	if (length <=MAX_COPY_LEN) {
@@ -767,16 +771,13 @@
 		emit_copy(from,to,length,offset);
 	    return;
 	}
-	printf("\txchg %%edi,%s\n",from);
-	printf("\txchg %%esi,%s\n",to);
-	printf("\txchg %%ecx,%s\n",register_name(dreg,0));
+	use_register(from,REG_EDI,1);
+	use_register(to,  REG_ESI,1);
+	use_register(dreg,REG_ECX,1);
 	printf("\tmovl $%d,%%ecx\n",length/4);
 	printf("\tcld\n\trep\n\tmovsl\n");
-	printf("\txchg %%ecx,%s\n",register_name(dreg,0));
-	printf("\txchg %%esi,%s\n",to);
-	printf("\txchg %%edi,%s\n",from);
 	if(length%4) {
-	    emit_copy("%esi","%edi",length,offset+length/4);
+	    emit_copy(from,to,length,offset+length/4);
 	}
     }
 }
@@ -784,28 +785,29 @@
 int
 struct_push(int e4,int t) 
 {
-    int length;
+    int length,xreg,save;
     g_expr(e4);
     length=size(t); 
     if(length%size_of_int) {
 	length += size_of_int - (length%size_of_int);
     }
+    /* I think, after g_expr, at least two registers are free */
     printf("\tsubl $%d,%%esp\n",length);
-    if (length<=MAX_COPY_LEN)
-	emit_copy(register_name(creg,0),"%esp",length,0);
-    else {
-	printf("\tpushl %%edi\n");
-	printf("\tpushl %%esi\n");
-	printf("\tpushl %%ecx\n");
-	printf("\tleal 12(%%esp),%%edi\n");
-	if (rname[creg]!=REG_ESI)
-		printf("\tmovl %s,%%esi\n",register_name(creg,0));
-	printf("\tmovl $%d,%%ecx\n",length/size_of_int);
-	printf("\tcld\n\trep\n\tmovsl\n");
-	printf("\tpopl %%ecx\n");
-	printf("\tpopl %%esi\n");
-	printf("\tpopl %%edi\n");
+    if (register_full()) {
+	/* this is wrong assumption */
+	save = 1;
+	printf("\tpushl %s\n",register_name(lreg,0));
+	xreg = lreg;
+    } else {
+	save=0;
+	xreg = get_register();
     }
+    printf("\tmovl %%esp,%s\n",register_name(xreg,0));
+    emit_copy(creg,xreg,length,0);
+    if (save) {
+	printf("\tpopl %s\n",register_name(lreg,0));
+    } else
+	free_register(xreg);
     return length/size_of_int;
 }
 
@@ -1107,8 +1109,7 @@
 void
 sassign(int e1)
 {
-    int e2,e3,e4,sz;
-    char *xrn;
+    int e2,e3,e4,sz,xreg;
 
     /* structure assignment */
     e2 = cadr(e1);  /* pointer variable to the struct */
@@ -1118,8 +1119,8 @@
     g_expr(e4);
     emit_push();
     g_expr(e2);
-    xrn = register_name(emit_pop(0),0);
-    emit_copy(xrn,register_name(creg,0),sz,0);
+    xreg = emit_pop(0);
+    emit_copy(xreg,creg,sz,0);
     return;
 }
 
--- a/mc-parse.c	Mon Feb 10 22:29:12 2003 +0900
+++ b/mc-parse.c	Tue Feb 11 11:26:51 2003 +0900
@@ -1959,15 +1959,7 @@
 	    return list2(ADDRESS,e);
 	} else if(t==STRUCT || t==UNION) { 
 	    t = cadr(type); /* size */
-	    switch(car(e)) {
-	    case GVAR:
-		return(list3(RSTRUCT,list3(RGVAR,cadr(e),caddr(e)),t));
-	    case LVAR:
-		return(list3(RSTRUCT,list2(RLVAR,cadr(e)),t));
-	    case INDIRECT:
-		return(list3(RSTRUCT,list2(RINDIRECT,cadr(e)),t));
-	    default: return list3(RSTRUCT,e,t);
-	    }
+	    return list3(RSTRUCT,e,t);
 	} else if(t!=POINTER) error(TYERR);
     }
     switch(car(e)) {