changeset 536:a349f9c2aef5 inline-test-passed

MIPS set_ireg/lreg interferance
author kono
date Sat, 31 Dec 2005 14:26:40 +0900
parents c17f1ef0d2be
children a6c9ffbf3f08
files Changes mc-code-arm.c mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-codegen.c mc-parse.c
diffstat 7 files changed, 86 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Sat Dec 31 03:14:03 2005 +0900
+++ b/Changes	Sat Dec 31 14:26:40 2005 +0900
@@ -7700,3 +7700,31 @@
 
 ia32 は  inline のregister_varをfreeしたことがなかったみたいだね。
 
+Sat Dec 31 10:34:44 JST 2005
+
+code_return_struct で、一時構造体がinlineの場合にうまく
+とられない。
+
+.data
+.globl foo
+        .comm foo,4
+        .comm ebp,4
+.text
+        .set ebx_offset,16
+.globl check
+check:
+        pushl %eax
+        pushl %ebx
+        movl ebp,%ebx
+        movl ebx_offset(%ebx),%eax
+        cmpl %eax,foo
+        jne bad
+        popl %ebx
+        popl %eax
+        ret
+bad:
+        popl %ebx
+        popl %eax
+        ret
+
+とかで stack のぶっこわしを検出できます。
--- a/mc-code-arm.c	Sat Dec 31 03:14:03 2005 +0900
+++ b/mc-code-arm.c	Sat Dec 31 14:26:40 2005 +0900
@@ -2059,6 +2059,7 @@
 	    }
 	}
 	free_register(creg);
+	if (creg==lreg) lreg=0;
 	regs[reg]=USING_REG;
     }
     creg = ireg = reg;
--- a/mc-code-ia32.c	Sat Dec 31 03:14:03 2005 +0900
+++ b/mc-code-ia32.c	Sat Dec 31 14:26:40 2005 +0900
@@ -28,7 +28,7 @@
 #define    ENDIAN_L  0
 #define    ENDIAN_D  0
 
-#define SAVE_STACKS 1
+
 
 #define TEXT_EMIT_MODE 0
 #define DATA_EMIT_MODE 1
@@ -611,14 +611,15 @@
 int
 get_register_var(NMTBL *nptr)
 {
-    int i;
+    int i,j;
     if (reg_var<2) {
 	for(i=REG_ESI;i<REG_EBP;i++) {
-	    if (! regs[i]) {    /* 使われていないなら */
-		regs[i]=REG_VAR;      /* そのレジスタを使うことを宣言し */
-		regv[i]=0;
+	    j = virtual(i);
+	    if (! regs[j]) {    /* 使われていないなら */
+		regs[j]=REG_VAR;      /* そのレジスタを使うことを宣言し */
+		regv[j]=0;
 		regvar[reg_var++]=i;
-		return list3(REGISTER,i,(int)nptr); /* その場所を表す番号を返す */
+		return list3(REGISTER,j,(int)nptr); /* その場所を表す番号を返す */
 	    }
 	}
     }
@@ -1246,12 +1247,12 @@
     ret_type = cadr(cadddr(e1));
     if (ret_type==CHAR) ret_type=INT;
 
-#ifdef SAVE_STACKS
+
     code_save_stacks();
 #if FLOAT_CODE
     code_save_fstacks();
 #endif
-#endif
+
     if (free_register_count(0)<1) {
         for(save = 0;save==dreg||save==creg;save++);
 	printf("\tpushl %s\n",register_name(save,0));
--- a/mc-code-mips.c	Sat Dec 31 03:14:03 2005 +0900
+++ b/mc-code-mips.c	Sat Dec 31 14:26:40 2005 +0900
@@ -1662,6 +1662,7 @@
 	    }
 	}
 	free_register(creg);
+	if (creg==lreg) lreg = 0;
 	regs[reg]=USING_REG;
     }
     creg = ireg = reg;
--- a/mc-code-powerpc.c	Sat Dec 31 03:14:03 2005 +0900
+++ b/mc-code-powerpc.c	Sat Dec 31 14:26:40 2005 +0900
@@ -675,6 +675,8 @@
 cleanup_lregister0()
 {
     int i;
+    // we should not have this, but powerpc's function
+    // lost some input register variables.
 #if 1
     for(i=LREG_OFFSET+1;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) {
 	if (regs[i]) {
@@ -1664,6 +1666,7 @@
 	    }
 	}
 	free_register(creg);
+	if (creg==lreg) lreg = 0;
 	regs[reg]=USING_REG;
     }
     creg = ireg = reg;
--- a/mc-codegen.c	Sat Dec 31 03:14:03 2005 +0900
+++ b/mc-codegen.c	Sat Dec 31 14:26:40 2005 +0900
@@ -3135,7 +3135,7 @@
 	str_ret.dsp = 0; str_ret.ty = 0;
 	type=list2(POINTER,t);
 	/* fix all argument's offset */
-	sz = size(type);
+	sz = inmode?1:size(type);
 	for(t=fnptr->dsp;t;t=cadr(t)) {
 	    n=(NMTBL *)caddr(t);
 	    n->dsp += sz;
@@ -3145,7 +3145,9 @@
 	else {
 	    args = 0;
 	    def(&str_ret,0);
-	    struct_return = list3(list3(LVAR,str_ret.dsp,0),sz,type);
+	    struct_return = inmode
+		?list3(list3(IVAR,str_ret.dsp,0),sz,type)
+		:list3(list3(LVAR,str_ret.dsp,0),sz,type);
 	    caddr(fnptr->ty) = glist2(POINTER,caddr(fnptr->ty));
 	}
 	type = type_save;
--- a/mc-parse.c	Sat Dec 31 03:14:03 2005 +0900
+++ b/mc-parse.c	Sat Dec 31 14:26:40 2005 +0900
@@ -1833,6 +1833,7 @@
 
 	nargs=list4(car(args),nargs,(int)n1,cadddr(args));
     }
+    // fdecl_struct(fnptr->ty);  already done by fdecl before
     fnptr->dsp=reverse0(nargs);
     
     retcont = 0;
@@ -3446,10 +3447,42 @@
 
 /* function call */
 
+static NMTBL *
+make_tmp_struct()
+{
+    int sz;
+    /* checks type */
+    /* make temporary struct for return value */
+    /* but it is better to see we can reuse old one */
+    if (tmp_struct && !inmode) {
+	sz = size(tmp_struct->ty);
+	if (sz>=size(type)) {
+	    /* reuse it */
+	} else if (tmp_struct->dsp-sz==disp) {
+	    /* extendable */
+	    disp -= tmp_struct->dsp-sz;
+	    tmp_struct->dsp = disp;
+	} else {
+	    tmp_struct = def(0,0);
+	}
+    } else if (tmp_struct && inmode) {
+	if (size(type)>size(tmp_struct->ty)) {
+	    tmp_struct->ty = type;
+	}
+    } else {
+	tmp_struct = def(0,0);
+	if (inmode) {
+	    set_attr(tmp_struct,HAS_ADDRESS,1);
+	    parse = list4(ST_DECL,parse,(int)tmp_struct,0);
+	}
+    }
+    return tmp_struct;
+}
+
 static int
 expr15(int e1)
 {
-    int t,arglist,e,sz,argtypes,at,ftype;
+    int t,arglist,e,argtypes,at,ftype;
     int type0 = type_value(type);
     int dots;
 
@@ -3514,23 +3547,12 @@
     if(type0==CHAR||type0==SHORT) type=set_type_with_attr(INT,type);
     else if(type0==UCHAR||type0==USHORT) type=set_type_with_attr(UNSIGNED,type);
     else if(type0>0 && (car(type0)==STRUCT||car(type0)==UNION)) {
-	/* make temporary struct for return value */
-	/* but it is better to see we can reuse old one */
-	if (tmp_struct) {
-	    sz = size(tmp_struct->ty);
-	    if (sz>=size(type)) {
-		/* reuse it */
-	    } else if (tmp_struct->dsp-sz==disp) {
-		/* extendable */
-		disp -= tmp_struct->dsp-sz;
-		tmp_struct->dsp = disp;
-	    } else {
-		tmp_struct = def(0,0);
-	    }
-	} else {
-	    tmp_struct = def(0,0);
-	}
-	e = list3(LVAR,tmp_struct->dsp,0);
+
+	/* temporal struct is required */
+
+	NMTBL *tmp = make_tmp_struct();
+
+	e = list3(inmode?IVAR:LVAR,tmp->dsp,(int)tmp);
 
 	/* pass the pointer as an argument */
 	/* this is recognized by called function declaration */