changeset 783:feeb9b9f8236

i64 code segement goto statement
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 20 Nov 2010 13:49:56 +0900
parents 003067098032
children 3bc6c34bfa2e
files mc-code-i64.c mc-codegen.c
diffstat 2 files changed, 30 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-i64.c	Sat Nov 20 10:55:31 2010 +0900
+++ b/mc-code-i64.c	Sat Nov 20 13:49:56 2010 +0900
@@ -376,6 +376,7 @@
 #define REG_EAX   8
 #define REG_R10   9
 #define REG_EBX   11
+#define REG_R14   14
 #define REG_R15   15
 #define REG_XMM0  16
 #define is_int_reg(reg) (1<=reg&&reg<=MAX_REGISTER)
@@ -527,10 +528,13 @@
 #define arg_offset1  (0)
 #define ARG_LVAR_OFFSET 0x10000000
 
-#define code_disp_offset0 (0)              // should be zero
-// disp_offset
+#define code_disp_offset0 (-func_disp_offset)   
 int disp_offset = code_disp_offset0;
 
+/*
+     FUNC_LVAR == CODE_LVAR is necessary in jump from function
+       func_disp_offset === code_disp_offset0
+ */
 #define CODE_LVAR(l) ((l)+code_disp_offset0)
 #define CODE_CALLER_ARG(l) ((l)+arg_offset1)
 #define FUNC_LVAR(l) ((l)-func_disp_offset)
@@ -601,7 +605,7 @@
     if (code_f) {
 	data_mode(0);
 	code_label(code_disp_label);
-	emit_longlong(round16(r1_offsetv));
+	emit_longlong(llist2(LCONST,round16(r1_offsetv)));
         code_disp_label = 0;
     } else {
 	//  +8 makes esp alignment 16
@@ -612,7 +616,7 @@
     if (max_func_arg_label) {
 	data_mode(0);
 	code_label(max_func_arg_label);
-	emit_longlong(round16(max_func_args*SIZE_OF_INT));
+	emit_longlong(llist2(LCONST,round16(max_func_args*SIZE_OF_INT)));
         max_func_arg_label = 0;
     }
 
@@ -3001,16 +3005,16 @@
     fwddef(retcont);
     if (ty==FLOAT||ty==DOUBLE) {
 	set_freg(RET_DREGISTER,0);
-	printf("\tmovs%s %s,%s\n",ty==FLOAT?"s":"d",fregister_name(REG_XMM0),register_name(creg,0));
-	printf("\tmovq %s,%%rbp\n",register_name(REG_EDI,0));
+	printf("\tmovs%s %s,%s\n",ty==FLOAT?"s":"d",fregister_name(REG_XMM0),fregister_name(creg));
+	printf("\tmovq %s,%%rbp\n",register_name(REG_R15,0));
     } else if (ty>0&&( car(ty)==STRUCT || car(ty)==UNION)) {
 	set_ireg(RET_REGISTER,0);
 	printf("\tlea %d(%%rbp),%s\n",disp-SIZE_OF_LONGLONG, register_name(creg,0));
-	printf("\tmovq %s,%%rbp\n",register_name(REG_ESI,0));
+	printf("\tmovq %s,%%rbp\n",register_name(REG_R15,0));
     } else if (ty!=VOID) {
 	set_ireg(RET_REGISTER,0);
-	printf("\tmovq %s,%s\n",register_name(REG_EDI,0),register_name(creg,0));
-	printf("\tmovq %s,%%rbp\n",register_name(REG_ESI,0));
+	printf("\tmovq %s,%s\n",register_name(REG_R15,0),register_name(creg,0));
+	printf("\tmovq %s,%%rbp\n",register_name(REG_R14,0));
     }
 }
 
@@ -5162,13 +5166,13 @@
 {
     if(type0==CHAR||type0==UCHAR) {
         if (n->dsp==0) {
-            n->dsp = args;
+            n->dsp = is_code?-args-size_of_longlong:args;
             if (endian) n->dsp += size_of_longlong-1;
         }
         args += size_of_longlong;
     } else if(type0==SHORT||type0==USHORT) {
         if (n->dsp==0) {
-            n->dsp = args;
+            n->dsp = is_code?-args-size_of_longlong:args;
             if (endian) n->dsp += size_of_longlong-size_of_short;
         }
         args += size_of_longlong;
@@ -5176,12 +5180,13 @@
         /* alignment in struct in argument */
         /* should be GCD of member alignment */
         /* __attribute(alignment(16)) is ignored in argments */
-        n->dsp = args;
-        args += align(sz,size_of_longlong);
+        int asz =  align(sz,size_of_longlong);
+        n->dsp = is_code?-args-asz:args;
+        args += asz;
     } else {
         /* if (n->dsp==0) (argument list in ADECL is useless, type
            list can be found in type ) */
-        n->dsp = args;
+        n->dsp = is_code?-args-size_of_longlong:args;
         args += align(sz,size_of_longlong);
     }
     return args;
--- a/mc-codegen.c	Sat Nov 20 10:55:31 2010 +0900
+++ b/mc-codegen.c	Sat Nov 20 13:49:56 2010 +0900
@@ -1613,7 +1613,7 @@
 		caddr(e2) = int_unsigned;
 		caddddr(e2) = list3(
 			cadddr(e2)=list3n(LVAR,cadr(s0),0),
-				0, size_of_int);
+				0, int_size);
 #if DEBUG_PARALLEL_ASSIGN
 if (lsrc)printf("## div 0 source %d ty %d+%d sz %d\n",car(s0),ty,cadr(s0),int_size);
 #endif
@@ -1625,7 +1625,7 @@
 		    case 2:
 		    case 3: caddr(e2) = USHORT; r = size_of_short; break;
 		    case 4: if (lp64) { caddr(e2) = UNSIGNED; r = size_of_int; break; }
-		    default: caddr(e2) = int_unsigned; r = size_of_int;
+		    default: caddr(e2) = int_unsigned; r = int_size;
 		    }
 		    if (e4==int_size) e3=cadr(e2);
 		    car(e2) =  list3n(LVAR,cadr(t0)+e4,0);
@@ -3572,19 +3572,20 @@
 
 // standard 32bit alignment 
 
-// for code
+
+// for function
 extern int
-code_arg_alignment1(int offset,NMTBL *n, int type0,int sz, int is_code)
+code_arg_alignment0(int offset,NMTBL *n, int type0,int sz, int is_code)
 {
     if(type0==CHAR||type0==UCHAR) {
         if (n->dsp==0) {
-            n->dsp = -offset;
+            n->dsp = is_code? -offset-size_of_int:offset;
             if (endian) n->dsp += size_of_int-1;
         }
         offset += size_of_int;
     } else if(type0==SHORT||type0==USHORT) {
         if (n->dsp==0) {
-            n->dsp = -offset;
+            n->dsp = is_code? -offset-size_of_int: offset;
             if (endian) n->dsp += size_of_int-size_of_short;
         }
         offset += size_of_int;
@@ -3592,45 +3593,13 @@
         /* alignment in struct in argument */
         /* should be GCD of member alignment */
         /* __attribute(alignment(16)) is ignored in argments */
-        n->dsp = -offset;
-        offset += align(sz,size_of_int);
+        int asz = align(sz,size_of_int);
+        n->dsp = is_code? -offset-asz:offset;
+        offset += asz;
     } else {
         /* if (n->dsp==0) (argument list in ADECL is useless, type
            list can be found in type ) */
-        n->dsp = -offset;
-        offset += sz; 
-    }
-    return offset;
-}
-
-// for function
-extern int
-code_arg_alignment0(int offset,NMTBL *n, int type0,int sz, int is_code)
-{
-    if (is_code) return code_arg_alignment1(offset,n,type0,sz,is_code);
-
-    if(type0==CHAR||type0==UCHAR) {
-        if (n->dsp==0) {
-            n->dsp = offset;
-            if (endian) n->dsp += size_of_int-1;
-        }
-        offset += size_of_int;
-    } else if(type0==SHORT||type0==USHORT) {
-        if (n->dsp==0) {
-            n->dsp = offset;
-            if (endian) n->dsp += size_of_int-size_of_short;
-        }
-        offset += size_of_int;
-    } else if(type0>0&&(car(type0)==UNION||car(type0)==STRUCT)) {
-        /* alignment in struct in argument */
-        /* should be GCD of member alignment */
-        /* __attribute(alignment(16)) is ignored in argments */
-        n->dsp = offset;
-        offset += align(sz,size_of_int);
-    } else {
-        /* if (n->dsp==0) (argument list in ADECL is useless, type
-           list can be found in type ) */
-        n->dsp = offset;
+	n->dsp = is_code? -offset-size_of_int: offset;
         offset += sz; 
     }
     return offset;