changeset 418:c73f013d07d7 arm-complete

ARM complete. PowerPC, MIPS, IA32 checked. emit_copy register save.
author kono
date Mon, 25 Oct 2004 19:16:17 +0900
parents 98888da30b35
children 5fafb50df9d4
files Changes mc-code-arm.c mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c test/arg.c
diffstat 6 files changed, 59 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Mon Oct 25 01:16:28 2004 +0900
+++ b/Changes	Mon Oct 25 19:16:17 2004 +0900
@@ -6251,3 +6251,15 @@
 うーん... 一応、直ったけど...
 
 他のがどんどん動かなくなる...
+
+Mon Oct 25 03:13:48 JST 2004
+
+codegen で、jump しているのだけど、そこでは、offset -1 で、
+局所変数となる。局所変数をそのままcode_segment の引数に
+しているらしい。
+
+code_segment側でも、同じoffsetで処理するが、ARMの場合は、
+offset 0- -xx までは、register save が入る。それを書き潰し
+してしまうらしい。goto 時に。で、戻ったときにerrorとなる。
+register は全部、save するので、差はわかっているので、それを
+足せば良いだけだけどね。(これ、前もやったな...)
--- a/mc-code-arm.c	Mon Oct 25 01:16:28 2004 +0900
+++ b/mc-code-arm.c	Mon Oct 25 19:16:17 2004 +0900
@@ -345,7 +345,7 @@
 #define disp_offset  0
 
 #define func_disp_offset 8
-#define code_disp_offset 0
+#define code_disp_offset (-64)
 
 #define CODE_LVAR(l) ((l)+code_disp_offset)
 #define CODE_CALLER_ARG(l) ((l)+arg_offset1)
@@ -363,7 +363,7 @@
     disp &= -SIZE_OF_INT;
 
     if (code_f) {
-	r1_offsetv = disp-max_func_args*SIZE_OF_INT;
+	r1_offsetv = disp-max_func_args*SIZE_OF_INT+code_disp_offset;
 	printf("\t.set .L%d, %d\n",r1_offset_label,r1_offsetv);
     } else {
 	lvar_offsetv = 
@@ -371,7 +371,7 @@
 	printf("\t.set .L%d, %d\n",lvar_offset_label,lvar_offsetv);
     }
     if (max_func_arg_label) {
-        printf(".set L_%d,%d\n",max_func_arg_label,max_func_args*SIZE_OF_INT);
+	printf("\t.set .L%d, %d\n",max_func_arg_label,max_func_args*SIZE_OF_INT);
         max_func_arg_label = 0;
     }
 
@@ -1149,7 +1149,7 @@
 {
     int i,j;
     if ((arch_mode&UseFPP)) {
-	for(i=0;i<FREG_VAR_MAX;i++) {
+	for(i=0;i<FREG_VAR_MAX-FREG_VAR_BASE;i++) {
 	    j = freg_var_num(i);
 	    if (! regs[j]) {       /* 使われていないなら */
 		regs[j]=USING_REG; /*そのレジスタを使うことを宣言し*/
@@ -1897,7 +1897,7 @@
     char *drn;
     int fix = 0;
     char *memmove = "memmove";
-    int dreg = get_register(); if (!dreg) error(-1);
+    int dreg = REG_ip; 
 
     drn	 = register_name(dreg);
     use_int(from);
@@ -1946,7 +1946,7 @@
 	clear_ptr_cache();
 	code_save_stacks();
 	parallel_rassign(list3(1,list3(2,0,from),to));
-	code_const(length,3);
+	code_const(length>0?length:-length,3);
         /* overrap must be allowed */
 	inc_inst(1);
 	// offset have to be ignored */
@@ -1968,7 +1968,7 @@
 	    free_register(creg); creg=to; ireg=to;
 	}
     }
-    free_register(dreg);
+    // free_register(dreg);
 }
 
 int
@@ -2568,6 +2568,8 @@
 	    arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0);
 	    struct_push(e4,t,arg);
 	    car(e3)=0;  // done
+	    if (car(arg)==REGISTER)
+		use_input_reg(cadr(arg),1);
 	}
     } else {
 	//  last complex argument can use input register
@@ -2576,6 +2578,8 @@
 	    reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg);
 	    if (car(arg)!=LVAR) use_input_reg(cadr(arg),1);
 	    car(complex_) = 0; // done.
+	    if (car(arg)==REGISTER)
+		use_input_reg(cadr(arg),1);
 	}
     }
 
@@ -3283,7 +3287,7 @@
     else
 	printf("\t.align 3\n");
     if (stmode!=STATIC)
-    printf("\t.globl\t%s\n",name);
+	printf("\t.globl\t%s\n",name);
     printf("\t.type\t%s,function\n",name);
     r1_offset_label = fwdlabel();
     max_func_args = 0;
@@ -3510,8 +3514,8 @@
 void
 emit_global(char *name,int t)
 {
+    data_mode(name);
     printf("\t.globl\t%s\n",name);
-    data_mode(name);
     align(t);
     printf("%s:\n",name); 
 }
--- a/mc-code-ia32.c	Mon Oct 25 01:16:28 2004 +0900
+++ b/mc-code-ia32.c	Mon Oct 25 19:16:17 2004 +0900
@@ -1070,7 +1070,6 @@
 void 
 emit_copy(int from,int  to,int length,int offset,int value,int det)
 {
-    int fix = 0;
     /* length <0 means upward direction copy */
     use_int(from);
     use_int(to);
@@ -1114,21 +1113,32 @@
                 emit_copy(from,to,length,offset,0,det);
             break;
         }
-	use_register(from,REG_ESI,1);
-	use_register(to,  REG_EDI,1);
-	use_register(dreg,REG_ECX,0);
+	printf("\tpushl %%esi\n");
+	printf("\tpushl %%edi\n");
+	printf("\tpushl %%ecx\n");
+	printf("\tpushl %s\n",register_name(from,0));
+	printf("\tpushl %s\n",register_name(to,0));
+	printf("\tpushl %s\n",register_name(dreg,0));
+	printf("\tpopl %%ecx\n");
+	printf("\tpopl %%edi\n");
+	printf("\tpopl %%esi\n");
 	if (length<0) {
 	    printf("\tmovl $%d,%%ecx\n",-length/4);
-	    printf("\taddl $%d,%%esi\n",-length);
-	    printf("\taddl $%d,%%edi\n",-length);
+	    printf("\taddl $%d,%%esi\n",-length-4);
+	    printf("\taddl $%d,%%edi\n",-length-4);
 	    printf("\tstd\n\trep\n\tmovsl\n");
+	    printf("\tpopl %%ecx\n");
+	    printf("\tpopl %%edi\n");
+	    printf("\tpopl %%esi\n");
 	    if(length%4) {
 		emit_copy(from,to,length,offset+length/SIZE_OF_INT,0,det);
 	    }
 	} else {
 	    printf("\tmovl $%d,%%ecx\n",length/4);
-	    fix = (length/4)*4;
 	    printf("\tcld\n\trep\n\tmovsl\n");
+	    printf("\tpopl %%ecx\n");
+	    printf("\tpopl %%edi\n");
+	    printf("\tpopl %%esi\n");
 	    if(length%4) {
 		emit_copy(from,to,length,offset+length/SIZE_OF_INT,0,det);
 	    }
@@ -1138,7 +1148,6 @@
     /* creg must point top of the destination data */
     /* this code is necessary for the value of assignment or function call */
     /* otherwise we don't need this */
-	if (fix) printf("\tsubl $%d,%s\n",fix,register_name(to,0));
 	if(creg!=to) {
 	    if (to==dreg) 
 		printf("\tmovl %s,%s\n",register_name(to,0),register_name(creg,0));
@@ -1810,6 +1819,7 @@
 void
 code_enter(char *name)
 {
+    text_mode();
     printf("\t.align 4\n");
     if (stmode!=STATIC)
 	printf(".globl %s\n",name);
@@ -1831,7 +1841,7 @@
 code_leave(char *name)
 {
     disp &= -SIZE_OF_INT;
-    printf("\t.set _%d,%d\n",code_disp_label,disp+code_disp_offset);
+    printf("\t.set _%d,%d\n",code_disp_label,disp+code_disp_offset-8);
     printf("_%d:\n",labelno);
     printf("\t.size\t%s,_%d-%s\n",name,labelno,name);
     local_table();
@@ -1842,6 +1852,7 @@
 void
 enter(char *name)
 {
+    text_mode();
     printf("\t.align 2\n");
     if (stmode!=STATIC)
 	printf(".globl %s\n",name);
@@ -1994,8 +2005,8 @@
 extern void
 emit_global(char *name,int t)
 {
+    data_mode(name);
     printf(".globl\t%s\n",name);
-    data_mode(name);
     align(t);
     printf("%s:\n",name); 
 }
--- a/mc-code-mips.c	Mon Oct 25 01:16:28 2004 +0900
+++ b/mc-code-mips.c	Mon Oct 25 19:16:17 2004 +0900
@@ -1582,11 +1582,9 @@
 	}
 	clear_ptr_cache();
 	code_save_stacks();
-	printf("\tli $6,%d\n",length);
+	printf("\tli $6,%d\n",length>0?length:-length);
 	printf("\tmove $5,%s\n",frn);
-	//if (offset) 
-	//    printf("\taddu $4,%s,%d\n",trn,offset);
-	//else
+	// offset should not be used
 	printf("\tmove $4,%s\n",trn);
         /* overrap must be allowed */
 	printf("\tjal %s\n",memmove);
@@ -2176,6 +2174,8 @@
 	    arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0);
 	    struct_push(e4,t,arg);
 	    car(e3)=0;  // done
+	    if (car(arg)==REGISTER)
+		use_input_reg(cadr(arg),1);
 	}
     } else {
 	//  last complex argument can use input register
@@ -2183,6 +2183,8 @@
 	    arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg);
 	    reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg);
 	    car(complex_) = 0; // done.
+	    if (car(arg)==REGISTER)
+		use_input_reg(cadr(arg),1);
 	}
     }
 
@@ -2991,7 +2993,7 @@
     else
 	printf("\t.align 3\n");
     if (stmode!=STATIC)
-    printf("\t.globl\t%s\n",name);
+	printf("\t.globl\t%s\n",name);
 #ifdef DOT_SIZE
     printf("\t.type\t%s,@function\n",name);
 #endif
@@ -3259,8 +3261,8 @@
 extern void
 emit_global(char *name,int t)
 {
+    data_mode(name);
     printf(".globl\t%s\n",name);
-    data_mode(name);
     align(t);
     printf("%s:\n",name); 
 }
--- a/mc-code-powerpc.c	Mon Oct 25 01:16:28 2004 +0900
+++ b/mc-code-powerpc.c	Mon Oct 25 19:16:17 2004 +0900
@@ -3012,8 +3012,8 @@
 extern void
 emit_global(char *name,int t)
 {
+    data_mode(name);
     printf(".globl\t_%s\n",name);
-    data_mode(name);
     align(t);
     printf("_%s:\n",name); 
 }
--- a/test/arg.c	Mon Oct 25 01:16:28 2004 +0900
+++ b/test/arg.c	Mon Oct 25 19:16:17 2004 +0900
@@ -39,6 +39,10 @@
 {
     printf("args3: %d %d %d %d %d : %x %x %x %x\n",
 	args0.a0,args0.a1,args0.a2,args0.a3,args0.a4,i,j,k,l);
+    printf("args3: args0 %d %d %d %d %d : args1 %d %d %d %d %d : %x %x %x %x\n",
+	args0.a0,args0.a1,args0.a2,args0.a3,args0.a4,
+	args1.a0,args1.a1,args1.a2,args1.a3,args1.a4,
+	i,j,k,l);
     if (args0.a0==args1.a0) exit(0);
     goto carg4(args0,args1,j,k,l,i);
 }