From 089dea355a28da44376ce4f5195baa4b4e0b217d Mon Sep 17 00:00:00 2001
From: jiang <30155751@qq.com>
Date: Sat, 3 May 2014 23:51:09 +0800
Subject: [PATCH] tcc on i386 are still having problems at work.Thank Roy
 report again. Struck on several variables can be connected to commit in the
 register. I am worried whether tcc can run the os. Since my machine is ubuntu
 64 bits I can test my machine.

---
 arm-gen.c    | 10 +++++++++-
 c67-gen.c    | 11 ++++++++++-
 i386-gen.c   | 10 +++++-----
 tcc.h        |  2 --
 tccgen.c     | 37 ++++++++-----------------------------
 x86_64-gen.c |  2 +-
 6 files changed, 33 insertions(+), 39 deletions(-)

diff --git a/arm-gen.c b/arm-gen.c
index 6da17068..567c8682 100644
--- a/arm-gen.c
+++ b/arm-gen.c
@@ -61,7 +61,7 @@
 #define RC_IRET    RC_R0  /* function return: integer register */
 #define RC_LRET    RC_R1  /* function return: second integer register */
 #define RC_FRET    RC_F0  /* function return: float register */
-
+#define RC_MASK    (RC_INT|RC_FLOAT)
 /* pretty names for the registers */
 enum {
     TREG_R0 = 0,
@@ -540,6 +540,14 @@ void load(int r, SValue *sv)
   v = fr & VT_VALMASK;
   if (fr & VT_LVAL) {
     uint32_t base = 0xB; // fp
+    if(fr & VT_TMP){
+			int size, align;
+			if((ft & VT_BTYPE) == VT_FUNC)
+				size = PTR_SIZE;
+			else
+				size = type_size(&sv->type, &align);
+			loc_stack(size, 0);
+		}
     if(v == VT_LLOCAL) {
       v1.type.t = VT_PTR;
       v1.r = VT_LOCAL | VT_LVAL;
diff --git a/c67-gen.c b/c67-gen.c
index 209fa7f9..07ae259d 100644
--- a/c67-gen.c
+++ b/c67-gen.c
@@ -58,7 +58,7 @@
 #define RC_IRET    RC_C67_A4	/* function return: integer register */
 #define RC_LRET    RC_C67_A5	/* function return: second integer register */
 #define RC_FRET    RC_C67_A4	/* function return: float register */
-
+#define RC_MASK    (RC_INT|RC_FLOAT)
 /* pretty names for the registers */
 enum {
     TREG_EAX = 0,		// really A2
@@ -1571,12 +1571,21 @@ void load(int r, SValue * sv)
 
     v = fr & VT_VALMASK;
     if (fr & VT_LVAL) {
+        if(fr & VT_TMP){
+			int size, align;
+			if((ft & VT_BTYPE) == VT_FUNC)
+				size = PTR_SIZE;
+			else
+				size = type_size(&sv->type, &align);
+			loc_stack(size, 0);
+		}
 	if (v == VT_LLOCAL) {
 	    v1.type.t = VT_INT;
 	    v1.r = VT_LOCAL | VT_LVAL;
 	    v1.c.ul = fc;
 	    load(r, &v1);
 	    fr = r;
+        fc = 0;
 	} else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
 	    tcc_error("long double not supported");
 	} else if ((ft & VT_TYPE) == VT_BYTE) {
diff --git a/i386-gen.c b/i386-gen.c
index 018307a2..cfa9cc6f 100644
--- a/i386-gen.c
+++ b/i386-gen.c
@@ -21,7 +21,7 @@
 #ifdef TARGET_DEFS_ONLY
 
 /* number of available registers */
-#define NB_REGS         4
+#define NB_REGS         8
 #define NB_ASM_REGS     8
 
 /* a register can belong to several classes. The classes must be
@@ -41,7 +41,6 @@
 #define RC_LRET    RC_EDX /* function return: second integer register */
 #define RC_FRET    RC_ST0 /* function return: float register */
 #define RC_MASK    (RC_INT|RC_INT2|RC_FLOAT)
-
 /* pretty names for the registers */
 enum {
     TREG_EAX = 0,
@@ -104,8 +103,8 @@ ST_DATA const int reg_classes[NB_REGS] = {
     RC_INT|RC_INT2|RC_EBX,
     0,
     /* st0 */ RC_FLOAT | RC_ST0,
-    RC_RSI|RC_INT2,
-    RC_RDI|RC_INT2,
+    RC_ESI|RC_INT2,
+    RC_EDI|RC_INT2,
 };
 
 static unsigned long func_sub_sp_offset;
@@ -241,7 +240,7 @@ ST_FUNC void load(int r, SValue *sv)
         if(fr & VT_TMP){
 			int size, align;
 			if((ft & VT_BTYPE) == VT_FUNC)
-				size = 4;
+				size = PTR_SIZE;
 			else
 				size = type_size(&sv->type, &align);
 			loc_stack(size, 0);
@@ -254,6 +253,7 @@ ST_FUNC void load(int r, SValue *sv)
             if (!(reg_classes[fr] & RC_INT))
                 fr = get_reg(RC_INT);
             load(fr, &v1);
+            fc = 0;
         }
         if ((ft & VT_BTYPE) == VT_FLOAT) {
             o(0xd9); /* flds */
diff --git a/tcc.h b/tcc.h
index f56273fb..1cead42a 100644
--- a/tcc.h
+++ b/tcc.h
@@ -1350,8 +1350,6 @@ ST_FUNC void gen_le16(int c);
 ST_FUNC void gen_le32(int c);
 ST_FUNC void gen_addr32(int r, Sym *sym, int c);
 ST_FUNC void gen_addrpc32(int r, Sym *sym, int c);
-ST_FUNC void struct_copy(SValue *d, SValue *s, SValue *c);
-ST_FUNC void gen_putz(SValue *d, int size);
 #endif
 
 #ifdef CONFIG_TCC_BCHECK
diff --git a/tccgen.c b/tccgen.c
index d5045728..c2481b0c 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -873,7 +873,7 @@ ST_FUNC int gv(int rc)
 #endif
 
 		r = vtop->r & VT_VALMASK;
-		if((rc & ~RC_MASK) && (rc != RC_ST0))
+		if(rc & ~RC_MASK)
 			rc2 = ex_rc;
 		else
 			rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
@@ -2624,20 +2624,19 @@ ST_FUNC void vstore(void)
 				vtop -=2;
 			}else{
 				size = type_size(&vtop->type, &align);
-#ifndef TCC_TARGET_X86_64
                 /* destination */
                 vswap();
                 vtop->type.t = VT_PTR;
                 gaddrof();
 
                 /* address of memcpy() */
-#   ifdef TCC_ARM_EABI
+#ifdef TCC_ARM_EABI
                 if(!(align & 7))
                     vpush_global_sym(&func_old_type, TOK_memcpy8);
                 else if(!(align & 3))
                     vpush_global_sym(&func_old_type, TOK_memcpy4);
                 else
-#   endif
+#endif
                 vpush_global_sym(&func_old_type, TOK_memcpy);
 
                 vswap();
@@ -2646,22 +2645,8 @@ ST_FUNC void vstore(void)
                 vtop->type.t = VT_PTR;
                 gaddrof();
                 /* type size */
-                vpushs(size);
+                vpushi(size);
                 gfunc_call(3);
-#else
-                /* destination */
-				vswap();
-				vtop->type.t = VT_PTR;
-				gaddrof();
-				/* source */
-				vpushv(vtop - 1);
-				vtop->type.t = VT_PTR;
-				gaddrof();
-				/* size */
-				vpushs(size);
-				struct_copy(&vtop[-2], &vtop[-1], &vtop[0]);
-				vtop -=3;
-#endif
 			}
         } else {
             vswap();
@@ -5354,22 +5339,16 @@ static void init_putz(CType *t, Section *sec, unsigned long c, int size)
     if (sec) {
         /* nothing to do because globals are already set to zero */
     } else {
-#ifndef TCC_TARGET_X86_64
         vpush_global_sym(&func_old_type, TOK_memset);
         vseti(VT_LOCAL, c);
-#   ifdef TCC_TARGET_ARM
+#ifdef TCC_TARGET_ARM
         vpushs(size);
         vpushi(0);
-#   else
-        vpushi(0);
-        vpushs(size);
-#   endif
-        gfunc_call(3);
 #else
-        vseti(VT_LOCAL, c);
-		gen_putz(vtop, size);
-		vtop--;
+        vpushi(0);
+        vpushs(size);
 #endif
+        gfunc_call(3);
     }
 }
 
diff --git a/x86_64-gen.c b/x86_64-gen.c
index 7a79278b..2b52bb1e 100644
--- a/x86_64-gen.c
+++ b/x86_64-gen.c
@@ -408,7 +408,7 @@ void load(int r, SValue *sv)
         if(fr & VT_TMP){
 			int size, align;
 			if((ft & VT_BTYPE) == VT_FUNC)
-				size = 8;
+				size = PTR_SIZE;
 			else
 				size = type_size(&sv->type, &align);
 			loc_stack(size, 0);