changeset 669:1530b1a636ac

ato mouchotto...
author kono
date Wed, 02 May 2007 15:31:38 +0900
parents adbb9c25eb1a
children bce312f3c0cb
files Makefile mc-code-ia32.c test/stackframe.c
diffstat 3 files changed, 66 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Tue May 01 16:46:21 2007 +0900
+++ b/Makefile	Wed May 02 15:31:38 2007 +0900
@@ -6,7 +6,7 @@
 # LDFLAGS = -pg
 # for Linux Zaurus
 # CFLAGS = -fsigned-char -pipe -g -I. -I/home/zaurus/develop/include
-CFLAGS1 = -g -O -I.
+CFLAGS1 = -g -I.
 BASE=0
 STAGE=1
 MFLAGS=$(MFALGS) BASE=$(BASE) STAGE=$(STAGE)
--- a/mc-code-ia32.c	Tue May 01 16:46:21 2007 +0900
+++ b/mc-code-ia32.c	Wed May 02 15:31:38 2007 +0900
@@ -318,12 +318,7 @@
  */
 static int arg_offset;
 
-int disp_offset = -12;
-#define func_disp_offset (-12)
-#define code_disp_offset (-12)
-
 static int code_disp_label;
-static int func_disp_label;
 
 #ifdef __APPLE__
 static int goffset_label;
@@ -414,21 +409,50 @@
 #define round4(i)   ((i+0x3)&~0x3)
 
 
-#define arg_offset  24
-#define arg_offset1  24
+int disp_offset = -12;
+#define func_disp_offset (8)
+#define code_disp_offset (8)
+
+#define arg_offset  8
+#define arg_offset1  0
 #define ARG_LVAR_OFFSET 0x10000000
 
 #define code_disp_offset0 (0)
 
 #define CODE_LVAR(l) ((l)+code_disp_offset0)
 #define CODE_CALLER_ARG(l) ((l)+arg_offset1)
-#define FUNC_LVAR(l) ((l)+disp_offset)
+#define FUNC_LVAR(l) ((l)-func_disp_offset)
 #define CALLER_ARG(l) ((l)+arg_offset1)
 #define CALLEE_ARG(l) ((l)+arg_offset)
 static int r1_offset_label;
 static const char lpfx[] = "_";
-static int lvar_offset_label;
+// static int lvar_offset_label;
 static int max_func_args,max_func_arg_label;
+
+/*
+    function call stack frame
+                     prev esp
+                      <-------r1_offset------------------------------>
+            <-----                   ebp-->                  <----- esp
+ r+  +------------+---+---------------+----------+-------------------+    -
+      callee arg   xx   register save   local      caller arg  
+                          reg_save      disp       max_func_args*SIZE_OF_INT
+        lvar>0                         lvar<0       lvar>0x1000 0000
+
+code segment stack frame
+
+                 * gotoを呼び出した関数のr1 ! r1(goto前のr1)
+   #             *                           esp <---r1_offset---------> r1
+r+ +----------+--+----------+----------------+-----------+----------+----+
+    cousin arg xx  reg save !callee arg      !code local  caller arg  xx
+                   r20-r29     lvar>0         lvar<0      lvar>0x1000 000
+                   f20-f31  <-my_func_args--><--disp-----><-max_func_arg->
+                              *SIZE_OF_INT                  *SIZE_OF_INT
+
+  %esp should be alignment 16
+ 
+ */
+
 void
 code_offset_set()
 {
@@ -436,15 +460,16 @@
     int l;
 #endif
     int lvar_offsetv = 
-        round16(-disp+max_func_args*SIZE_OF_INT+func_disp_offset);
-    int r1_offsetv = round16(lvar_offsetv);
-    printf(".set %s%d,%d\n",lpfx,lvar_offset_label,r1_offsetv-lvar_offsetv);
+        round16(-disp);
+    int r1_offsetv = round16(lvar_offsetv+max_func_args*SIZE_OF_INT+func_disp_offset)+8;
+    //  +8 makes esp alignment 16
+//    printf(".set %s%d,%d\n",lpfx,lvar_offset_label,lvar_offsetv);
     if (r1_offsetv-lvar_offsetv > 65000) error(-1);
         // too large function arguments?
     printf(".set %s%d,%d\n",lpfx,r1_offset_label,r1_offsetv);
     if (max_func_arg_label) {
         printf(".set %s%d,%d\n",lpfx,max_func_arg_label,
-            round16(max_func_args*SIZE_OF_INT)+24);
+            round16(max_func_args*SIZE_OF_INT));
         max_func_arg_label = 0;
     }
 
@@ -479,7 +504,7 @@
         } else
             printf("%d(%%ebp)",CODE_LVAR(l));
     } else if (l<0) {  /* local variable */
-        printf("%d+_%d(%%ebp)",FUNC_LVAR(l),lvar_offset_label);
+        printf("%d(%%ebp)",FUNC_LVAR(l));
     } else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
         printf("%d(%%esp)",CALLER_ARG(l-ARG_LVAR_OFFSET));
     } else { /* callee's arguments */
@@ -1887,8 +1912,13 @@
 {
     char *crn;
   
-    g_expr(list3(BAND,list3(ADD,e1,list2(CONST,15)),list2(CONST,~15))); 
-    use_int(reg);
+    if (!is_const(e1)) {
+	g_expr(list3(BAND,list3(ADD,e1,list2(CONST,15)),list2(CONST,~15))); 
+	use_int(reg);
+    } else {
+	use_int(reg);
+	code_const(round16(cadr(e1)),reg);
+    }
     crn = register_name(reg,0);
     printf("\tsubl\t%s, %%esp\n",crn);
     if (!max_func_arg_label) max_func_arg_label = fwdlabel();
@@ -2415,7 +2445,7 @@
     printf("_%s:\n",name);
 #endif
 
-    lvar_offset_label = fwdlabel();
+//    lvar_offset_label = fwdlabel();
     r1_offset_label = fwdlabel();
     max_func_args = 0;
 
@@ -2424,8 +2454,7 @@
     printf("\tpushl %%ebx\n");
     printf("\tpushl %%esi\n");
     printf("\tpushl %%edi\n");
-    func_disp_label=fwdlabel();
-    printf("\tlea _%d(%%ebp),%%esp\n",func_disp_label); 
+    printf("\tlea -%s%d(%%ebp),%%esp\n",lpfx,r1_offset_label); 
 #ifdef __APPLE__
     printf("\tcall\t___i686.get_pc_thunk.bx\n");
     printf("_%d:\n",labelno);
@@ -2492,13 +2521,12 @@
     fwddef(retlabel);
     code_offset_set(fnptr);
 
-    printf("\tlea %d(%%ebp),%%esp\n",disp_offset);
+    printf("\tlea %d(%%ebp),%%esp\n",-12);
     printf("\tpopl %%edi\n");
     printf("\tpopl %%esi\n");
     printf("\tpopl %%ebx\n");
     printf("\tleave\n");
     printf("\tret\n");
-    printf("\t.set _%d,%d\n",func_disp_label,disp+disp_offset);
 #ifndef __APPLE__
     printf("_%d:\n",labelno);
     printf("\t.size\t%s,_%d-%s\n",name,labelno,name);
--- a/test/stackframe.c	Tue May 01 16:46:21 2007 +0900
+++ b/test/stackframe.c	Wed May 02 15:31:38 2007 +0900
@@ -15,6 +15,14 @@
 
 void *ret;
 
+int dum;
+
+void
+called(int a0,int a1,int a2)
+{
+    dum = a0+a1+a2;
+}
+
 void
 frame(int a0,int a1,int a2)
 {
@@ -25,13 +33,20 @@
     int l1 = L1;
 
     *top = L2;
-    for(p = top;p<top+0x100; ) {
+    called(A3,A1,A4);
+#define OFFSET 16
+    i = -OFFSET;
+    for(p = top-OFFSET;p<top+0x100; ) {
 	if (*p==(int)ret) {
 	    printf("%04x: ret address\n",i);
 	} else if (*p==A0) {
 	    printf("%04x: caller arg 1\n",i);
 	} else if (*p==A2) {
 	    printf("%04x: caller arg last\n",i);
+	} else if (*p==A3) {
+	    printf("%04x: callee arg 1\n",i);
+	} else if (*p==A4) {
+	    printf("%04x: callee arg last\n",i);
 	} else if (*p==L0) {
 	    printf("%04x: local var top\n",i);
 	} else if (*p==L1) {