changeset 733:116d4701d097

i64 continue
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 04 Nov 2010 23:18:42 +0900
parents 7a4f389b5bc0
children d2d6b1ef2cb4
files Changes mc-code-i64.c mc-code-ia32.c
diffstat 3 files changed, 272 insertions(+), 269 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Thu Nov 04 21:10:20 2010 +0900
+++ b/Changes	Thu Nov 04 23:18:42 2010 +0900
@@ -9848,4 +9848,8 @@
     そうすれば、goto 文は、かなり簡単になる。
 
 
-
+Thu Nov  4 22:47:08 JST 2010
+
+LP64 だと、scalar の扱いをなんとかしないと。
+
+
--- a/mc-code-i64.c	Thu Nov 04 21:10:20 2010 +0900
+++ b/mc-code-i64.c	Thu Nov 04 23:18:42 2010 +0900
@@ -260,9 +260,9 @@
 
 int code_lassop_p = 0;
 
-#define MAX_REGISTER 14            /* intel386のレジスタを6つまで使う*/
-#define REAL_MAX_REGISTER 16    /* intel386のレジスタが8つということ*/
-int MAX_REGISTER_VAR=8;    
+#define MAX_REGISTER 14                /* intel386のレジスタを6つまで使う*/
+#define REAL_MAX_REGISTER (1+16+16)    /* intel386のレジスタが8つということ*/
+int MAX_REGISTER_VAR=6;    
 static int MAX_DREGISTER=16;
 int MAX_DREGISTER_VAR=8;
 
@@ -322,10 +322,8 @@
 	kept in FPU stack (no register)
  */
 
-#define REAL_MAX_LREGISTER 2
 static int ia32regs[1+REAL_MAX_REGISTER];
 
-
 static int *regs  = ia32regs;
 
 static int ia32fregs[1+MAX_DREGISTER];
@@ -340,25 +338,26 @@
 //    2 (REG_VAR) register variable
 //    3 pointer cache (not used in ia32)
 
-#define REG_EBP   1
-#define REG_ESP   2
+#define REG_ESP   1
+#define REG_EBP   2
 #define REG_EDI   3    // first argument register
 #define REG_ESI   4
 #define REG_EDX   5
 #define REG_ECX   6    // for strange reason (code_assop)
 #define REG_EAX   7
 #define REG_EBX   8
-#define is_int_reg(reg) 1 // (1<=reg&&reg<REG_EBP)
+#define is_int_reg(reg) (1<=reg&&reg<MAX_REGISTER)
+#define is_float_reg(reg) (RET_FREGISTER<=reg&&reg<REAL_MAX_REGISTER)
 
 //  return value register
-#define RET_FREGISTER   1
-#define RET_DREGISTER   1
+#define RET_FREGISTER   18
+#define RET_DREGISTER   18
 #define RET_LREGISTER   REG_EAX
 #define RET_REGISTER    REG_EAX
 
 //  defalut current register
 #define CREG_REGISTER   REG_ECX
-#define FREG_FREGISTER  2
+#define FREG_FREGISTER  19
 
 static char *reg_name_l[] = {0,
     0,
@@ -416,6 +415,12 @@
     "%r15d",
     "%r16d"};
 
+#define REG_VAR_BASE    (RET_FREGISTER-1)
+#define REG_VAR_MIN     (RET_FREGISTER-1-MAX_REGISTER_VAR)
+
+#define FREG_VAR_BASE    (RET_FREGISTER+16)
+#define FREG_VAR_MIN     (RET_FREGISTER+16-MAX_DREGISTER_VAR)
+
 static char *reg_name_q[] = {0,
     "%rsp",
     "%rbp",
@@ -433,10 +438,8 @@
     "%r13",
     "%r14",
     "%r15",
-    "%r16"};
-
-static char *reg_name_q[16+1] = {0,
-    "%xmm0",
+    "%r16",
+    "%xmm0", // 18
     "%xmm1",
     "%xmm2",
     "%xmm3",
@@ -580,15 +583,15 @@
 {
     if (is_code(fnptr)) {
         if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
-            printf("%d(%%esp)",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET));
+            printf("%d(%%rsp)",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET));
         } else
-            printf("%d(%%ebp)",CODE_LVAR(l));
+            printf("%d(%%rbp)",CODE_LVAR(l));
     } else if (l<0) {  /* local variable */
-        printf("%d(%%ebp)",FUNC_LVAR(l));
+        printf("%d(%%rbp)",FUNC_LVAR(l));
     } else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
-        printf("%d(%%esp)",CALLER_ARG(l-ARG_LVAR_OFFSET));
+        printf("%d(%%rsp)",CALLER_ARG(l-ARG_LVAR_OFFSET));
     } else { /* callee's arguments */
-        printf("%d(%%ebp)",CALLEE_ARG(l));
+        printf("%d(%%rbp)",CALLEE_ARG(l));
     }
 }
 
@@ -599,7 +602,6 @@
 use_int0() { 
     int i = creg;
     if (!i||!ireg||!is_int_reg(i)) {
-        if (lreg) { if (regs[lreg]) free_register(lreg); lreg = 0; }
         if (!ireg) {
 	    ireg = get_register();
 	}
@@ -610,8 +612,8 @@
     return i;
 }
 
-#define is_data_reg(reg) (REG_EAX<=reg&&reg<=REG_EDX)
-#define is_pointer_reg(reg) (REG_ESI<=reg&&reg<=REG_EBP)
+#define is_data_reg(reg) (reg_name_l[reg]!=0)
+#define is_pointer_reg(reg) (reg> REG_EBP)
 
 static int 
 use_register(int reg0, int reg1, int move)
@@ -623,9 +625,9 @@
 
     char *move_op;
     code_clear_stack_reg(reg1); 
-    move_op = (regs[reg1]||regs[reg1])?"\txchg %s,%s\n":"\tmovl %s,%s\n";
+    move_op = (regs[reg1]||regs[reg1])?"\txchg %s,%s\n":"\tmovq %s,%s\n";
     if (move && reg0!=reg1) {
-	printf(move_op,reg_name[reg0],reg_name[reg1]);
+	printf(move_op,reg_name_q[reg0],reg_name_q[reg1]);
 	if (!regs[reg1]) regs[reg1]=USING_REG;
     } 
     return reg0;
@@ -661,14 +663,28 @@
     if (!regs[i]) regs[i]=USING_REG;
     creg = ireg = i;
     if (ptreg && keep) {
-	printf("\tmovl %s,%s\n",reg_name[ptreg],reg_name[creg]);
+	printf("\tmovq %s,%s\n",reg_name_q[ptreg],reg_name_q[creg]);
     }
     return i;
 }
 
+#define fregister_name(reg)  reg_name_q[reg]
+
 static void
 set_freg(int reg,int mode)
 {
+    if (!is_float_reg(reg)) error(-1);
+    if (reg!=creg) {
+        if (freg && reg!=freg) {
+            free_register(freg);
+            if (mode) {
+                printf("\tmovapd %s,%s\n",fregister_name(reg),fregister_name(freg));
+            }
+        }
+        // if (creg!=ireg) free_register(creg);
+        regs[reg]=USING_REG;
+    }
+    creg = freg = reg;
 }
 
 static void
@@ -683,7 +699,7 @@
         if (ireg && reg!=ireg ) {
             if (regs[ireg]!=REG_VAR) free_register(ireg);
             if (mode) {
-                printf("\tmovl %s,%s\n",reg_name[ireg],reg_name[reg]);
+                printf("\tmovq %s,%s\n",reg_name_q[ireg],reg_name_q[reg]);
             }
         }
         if (creg>0 && regs[creg]!=REG_VAR) free_register(creg);
@@ -693,29 +709,8 @@
     if (!regs[reg]) regs[reg]=USING_REG;
 }
 
-#define is_long_reg(reg)   (reg==REG_LCREG||reg==REG_L)
-#define use_longlong(reg)   \
-    if (reg==-1||is_long_reg(reg)) reg=use_longlong0(reg)
-
-static int
-use_longlong0(int reg)
-{
-    int i = reg==USING_REG?creg:reg;
-    if (ireg) { if (regs[ireg]!=REG_VAR) free_register(ireg); ireg=0; }
-    if (!lreg||!regs[lreg]) {
-	// long long mode use all registers
-	code_save_stacks();
-#ifdef __APPLE__
-	clear_ptr_cache();
-#endif
-    }
-    i = lreg = (reg==USE_CREG)?REG_LCREG:reg;
-    if (!regs[i]) regs[i]=USING_REG;
-    if (!regs[regv_l(i)]) regs[regv_l(i)]=USING_REG;
-    if (!regs[regv_h(i)]) regs[regv_h(i)]=USING_REG;
-    creg = lreg = i;
-    return i;
-}
+#define is_long_reg(reg)   is_int_reg(reg)
+#define use_longlong(reg)   use_data_reg(reg)
 
 static void
 set_lreg(int reg,int mode)
@@ -723,15 +718,6 @@
     use_longlong(reg);
 }
 
-char *
-l_edx(int i) {
-    return i==REG_L?"%edi":"%edx";
-}
-char *
-l_eax(int i) {
-    return i==REG_L?"%esi":"%eax";
-}
-
 extern void
 code_init(void)
 {
@@ -750,11 +736,7 @@
     struct_align = size_of_int;
 
 
-    // MAX_REGISTER=6;
-    MAX_DATA_REG=4;    
-    MAX_POINTER=3;    
-    MAX_REGISTER_VAR=2;    
-
+    MAX_DATA_REG=6;    
 
 }
 
@@ -774,14 +756,16 @@
 {
     if (i<=0) {
 	error(REG_ERR);
-	return "%eax";
+	return "%rax";
     }
-    if (byte==1 && i <= REG_EDX) {
+    if (byte==1 && is_data_reg(i)) {
 	return reg_name_l[i];
-    } else if (byte==SIZE_OF_SHORT && i <= REG_EDX) {
+    } else if (byte==SIZE_OF_SHORT && is_data_reg(i)) {
 	return reg_name_w[i];
+    } else if (byte==SIZE_OF_INT) {
+	return reg_name[i];
     } else {
-	return reg_name[i]; /* 0 or 4 means int */
+	return reg_name_q[i]; 
     }
 }
 
@@ -834,7 +818,7 @@
 get_data_register(void)
 {    /* 使われていないレジスタを調べる */
     int i,reg,j;
-    for(i=REG_EAX;i<=REG_EDX;i++) {
+    for(i=1;is_data_reg(i) && i<MAX_REGISTER+1;i++) {
 	if (! regs[i]) {    /* 使われていないなら */
 	    regs[i]=1;      /* そのレジスタを使うことを宣言し */
 	    return i;       /* その場所を表す番号を返す */
@@ -891,12 +875,10 @@
 #ifdef __APPLE__
     char *rrn = register_name(r,0);
     if (nptr->sc==STATIC && !(is_code(nptr)||is_function(nptr))) {
-        printf("\tleal _%s-_%d(%%ebx),%s\n",nptr->nm,
-            goffset_label,rrn);
+        printf("\tleaq _%s(%%rip),%s\n",nptr->nm, rrn);
     } else {
-        printf("\tmovl L_%s$non_lazy_ptr-_%d(%%ebx),%s\n",
-	    nptr->nm,
-            goffset_label,rrn);
+        printf("\tmovq _%s@GOTPCREL(%%rip),%s\n",
+	    nptr->nm, rrn);
     }
 #else
     error(-1);
@@ -944,32 +926,46 @@
     return 0;
 }
 
+#if FLOAT_CODE
 int 
 get_dregister(int d)
-{
-    return -1;
-}
-
-int 
-get_lregister_var(NMTBL *n)
-{
-    int h,l;
-    h = REG_ESI;
-    l = REG_EDI;
-    if (regs[h]==0&&regs[l]==0) {
-	regs[h]=regs[l]=REG_VAR; regs[REG_L]=REG_VAR;
-	reg_var=2; 
-	return list2(LREGISTER,REG_L);
+{    /* 使われていないレジスタを調べる */
+    int i,reg;
+    for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) {
+        if (regs[i]) continue;    /* 使われている */
+        regs[i]=USING_REG;      /* そのレジスタを使うことを宣言し */
+        return i;   /* その場所を表す番号を返す */
+    }
+    /* search register stack */
+    for(i=0;i<freg_sp;i++) {
+        if ((reg=freg_stack[i])>=0) {
+            code_dassign_lvar(
+                (freg_stack[i]=new_lvar(SIZE_OF_DOUBLE)),reg,1); 
+            freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET;
+            return reg;
+        }
     }
-    return list3n(LVAR,new_lvar(SIZE_OF_LONGLONG),0);
-}
-
-int 
-get_lregister()
-{
-    return -1;
-}
-
+    for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) {
+        reg =FREG_VAR_BASE-i+FREG_OFFSET;
+        if (! regs[reg]) {       /* 使われていないなら */
+            regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */
+            if (i>max_freg_var) max_freg_var=i;
+            return reg;   /* その場所を表す番号を返す */
+        }
+    }
+    /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */
+    error(REG_ERR); return freg;
+}
+
+int
+pop_fregister(void)
+{     /* レジスタから値を取り出す */
+    return freg_stack[--freg_sp];
+}
+#endif
+
+#define get_lregister_var(n) get_register_var(n)
+#define get_lregister() get_register()
 
 int
 register_full(void)
@@ -998,7 +994,7 @@
 free_all_register(void)
 {
     int i;
-    for(i=1;i<MAX_REGISTER+REAL_MAX_LREGISTER+1;i++) {
+    for(i=1;i<REAL_MAX_REGISTER;i++) {
 	regs[i]=0;
     }
     lreg = creg = ireg = 0;
@@ -1009,14 +1005,8 @@
 extern int
 code_register_overlap(int s,int t)
 {
-    if (car(s)==REGISTER) {
-	if (car(t)==REGISTER) return cadr(s)==cadr(t);
-	if (car(t)==LREGISTER)
-	    return cadr(s)==REG_ESI|| cadr(s)==REG_EDI;
-    } else if (car(s)==LREGISTER) {
-	if (car(t)==LREGISTER) return 1;
-	if (car(t)==REGISTER)
-	    return cadr(t)==REG_ESI|| cadr(t)==REG_EDI;
+    if (car(s)==REGISTER||car(s)==LREGISTER) {
+	if (car(t)==REGISTER||car(t)==LREGISTER) return cadr(s)==cadr(t);
     }
     return 0;
 }
@@ -1037,6 +1027,9 @@
 	    printf(" %s",register_name(reg_stack[i],0));
     }
 #endif
+    for(i=RET_FREGISTER;i<REAL_MAX_REGISTER;i++) {
+	printf("%d",regs[i]);
+    }
     printf("## f:%d",freg_sp);
     printf("\n");
 }
@@ -1060,14 +1053,15 @@
 	// n->dsp = offset;
 // printf("###  %s %d %d\n",n->nm,n->dsp,n->ty);
         if (scalar(type)) {
+	    int sz =size(type)<=SIZE_OF_INT?SIZE_OF_INT:size(type); 
             if ((reg = get_input_register_var(reg_var,n,is_code0))) {
                 n->sc = REGISTER;
                 n->dsp = cadr(reg);
                 regs[n->dsp]= INPUT_REG;
                 reg_var++;
-                caddr(args)=SIZE_OF_INT; /* why we need this? */
+                caddr(args)=sz;
             }
-	    offset+=SIZE_OF_INT;
+	    offset+=sz;
         } else if (type==FLOAT||type==DOUBLE) {
             if ((reg = get_input_dregister_var(freg_var,n,is_code0,1))) {
                 n->sc = DREGISTER;
@@ -1127,11 +1121,14 @@
 get_register_var(NMTBL *nptr)
 {
     int i;
-    for(i=REG_ESI;i<REG_EBP;i++) {
-	if (! regs[i]) {    /* 使われていないなら */
-	    regs[i]=REG_VAR;      /* そのレジスタを使うことを宣言し */
-	    return list3n(REGISTER,i,nptr); /* その場所を表す番号を返す */
-	}
+    for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
+        if (! regs[REG_VAR_BASE-i]) {       /* 使われていないなら */
+            /* そのレジスタを使うことを宣言し */
+            regs[REG_VAR_BASE-i]=REG_VAR; 
+            if (i>max_reg_var) max_reg_var=i;
+            /* その場所を表す番号を返す */
+            return list3n(REGISTER,REG_VAR_BASE-i,n); 
+        }
     }
     return list3n(LVAR,new_lvar(SIZE_OF_INT),0);
 }
@@ -1139,7 +1136,17 @@
 int
 get_dregister_var(NMTBL *nptr,int d)
 {
-    return list3n(LVAR,new_lvar(d?SIZE_OF_DOUBLE:SIZE_OF_FLOAT),0);
+    int i;
+    for(i=0;i<FREG_VAR_BASE-FREG_VAR_MIN;i++) {
+        if (! regs[FREG_VAR_BASE-i+FREG_OFFSET]) {       /* 使われていないなら */
+            regs[FREG_VAR_BASE-i+FREG_OFFSET]=REG_VAR; /*そのレジスタを使うことを宣言し*/
+            if (i>max_freg_var) max_freg_var=i;
+            /* その場所を表す番号を返す */
+            return list3n(DREGISTER,
+                FREG_VAR_BASE-i+FREG_OFFSET,n); 
+        }
+    }
+    return list3n(LVAR,new_lvar(SIZE_OF_DOUBLE),0);
 }
 
 
@@ -1184,19 +1191,24 @@
 code_gvar(int e1,int creg) {
     use_int(creg);
 #ifdef __APPLE__
-    int r = get_ptr_cache(ncaddr(e1));
+    NMTBL nptr = ncaddr(e1);
+    if (nptr->sc==STATIC && !(is_code(nptr)||is_function(nptr))) {
+	printf("\tleaq _%s+%d(%%rip),%s\n", ntpr->nm,cadr(e1),register_name(creg,0));
+	return;
+    }
+    int r = get_ptr_cache(ntpr);
     if (cadr(e1)) {
-	printf("\tleal %d(%s),%s\n", cadr(e1),register_name(r,0),
+	printf("\tleaq %d(%s),%s\n", cadr(e1),register_name(r,0),
 		register_name(creg,0));
     } else {
-	printf("\tmovl %s,%s\n", register_name(r,0), register_name(creg,0));
+	printf("\tmovq %s,%s\n", register_name(r,0), register_name(creg,0));
     }
 #else
     if (cadr(e1)) {
-	printf("\tmovl $%s+%d,%s\n",(ncaddr(e1))->nm,cadr(e1),
+	printf("\tmovq $%s+%d,%s\n",nptr->nm,cadr(e1),
 		register_name(creg,0));
     } else {
-	printf("\tmovl $%s,%s\n",(ncaddr(e1))->nm,register_name(creg,0));
+	printf("\tmovq $%s,%s\n",nptr->nm,register_name(creg,0));
     }
 #endif
 
@@ -1206,19 +1218,24 @@
 code_rgvar(int e1,int creg) {
     use_int(creg);
 #ifdef __APPLE__
+    NMTBL nptr = ncaddr(e1);
+    if (nptr->sc==STATIC && !(is_code(nptr)||is_function(nptr))) {
+	printf("\tmovl _%s+%d(%%rip),%s\n", ntpr->nm,cadr(e1),register_name(creg,SIZE_OF_INT));
+	return;
+    }
     int r = get_ptr_cache(ncaddr(e1));
     if (cadr(e1)) {
         printf("\tmovl %d(%s),%s\n", cadr(e1),register_name(r,0),
                 register_name(creg,0));
     } else {
-        printf("\tmovl (%s),%s\n", register_name(r,0), register_name(creg,0));
+        printf("\tmovl (%s),%s\n", register_name(r,0), register_name(creg,SIZE_OF_INT));
     }
 #else
     if (cadr(e1)) {
-	printf("\tmovl %s+%d,%s\n",(ncaddr(e1))->nm,cadr(e1),
-		register_name(creg,0));
+	printf("\tmovl %s+%d,%s\n",nptr->nm,cadr(e1),
+		register_name(creg,SIZE_OF_INT));
     } else
-	printf("\tmovl %s,%s\n",(ncaddr(e1))->nm,register_name(creg,0));
+	printf("\tmovl %s,%s\n",nptr->nm,register_name(creg,SIZE_OF_INT));
 #endif
 
 }
@@ -1233,21 +1250,26 @@
 code_crgvar(int e1,int creg,int sign,int sz){
     use_int(creg);
 #ifdef __APPLE__
+    NMTBL nptr = ncaddr(e1);
+    if (nptr->sc==STATIC && !(is_code(nptr)||is_function(nptr))) {
+	printf("\t%s _%s+%d(%%rip),%s\n", cload(sign,sz),ntpr->nm,cadr(e1),register_name(creg,SIZE_OF_INT));
+	return;
+    }
     int r = get_ptr_cache(ncaddr(e1));
     if (cadr(e1)) {
         printf("\t%s %d(%s),%s\n", cload(sign,sz),cadr(e1),register_name(r,0),
-                register_name(creg,0));
+                register_name(creg,SIZE_OF_INT));
     } else {
         printf("\t%s (%s),%s\n", cload(sign,sz),
-		register_name(r,0), register_name(creg,0));
+		register_name(r,0), register_name(creg,SIZE_OF_INT));
     }
 #else
     if (cadr(e1)) {
 	printf("\t%s %s+%d,%s\n",cload(sign,sz),
-		(ncaddr(e1))->nm,cadr(e1),register_name(creg,0));
+		nptr->nm,cadr(e1),register_name(creg,SIZE_OF_INT));
     } else
 	printf("\t%s %s,%s\n",cload(sign,sz),
-		(ncaddr(e1))->nm,register_name(creg,0));
+		nptr->nm,register_name(creg,SIZE_OF_INT));
 #endif
 
 }
@@ -1256,7 +1278,7 @@
 void
 code_lvar(int e2,int creg) {
     use_int(creg);
-    printf("\tlea "); lvar(e2);
+    printf("\tleaq "); lvar(e2);
     printf(",%s\n",register_name(creg,0));
 }
 
@@ -1265,7 +1287,7 @@
 code_register(int e2,int creg) {
     use_int(creg);
     if (e2!=creg)
-    printf("\tmovl %s,%s\n",register_name(e2,0),register_name(creg,0));
+    printf("\tmovq %s,%s\n",register_name(e2,0),register_name(creg,0));
 }
 
 
@@ -1273,7 +1295,7 @@
 code_rlvar(int e2,int reg) {
     use_int(reg);
     printf("\tmovl "); lvar(e2);
-    printf(",%s\n",register_name(reg,0));
+    printf(",%s\n",register_name(reg,SIZE_OF_INT));
 }
 
 extern void
@@ -1281,7 +1303,7 @@
 {
     use_data_reg(reg,1);
     printf("\t%s %s,%s\n",cload(1,1),
-	register_name(reg,1),register_name(reg,0));
+	register_name(reg,1),register_name(reg,SIZE_OF_INT));
 }
 
 extern void
@@ -1289,7 +1311,7 @@
 {
     use_data_reg(reg,1);
     printf("\t%s %s,%s\n",cload(1,SIZE_OF_SHORT),
-	register_name(reg,2),register_name(reg,0));
+	register_name(reg,2),register_name(reg,SIZE_OF_INT));
 }
 
 extern void
@@ -1297,7 +1319,7 @@
 {   
     use_data_reg(reg,1);
     printf("\t%s %s,%s\n",cload(0,1),
-	register_name(reg,1),register_name(reg,0));
+	register_name(reg,1),register_name(reg,SIZE_OF_INT));
 }
 
 extern void
@@ -1305,14 +1327,14 @@
 {   
     use_data_reg(reg,1);
     printf("\t%s %s,%s\n",cload(0,SIZE_OF_SHORT),
-	register_name(reg,2),register_name(reg,0));
+	register_name(reg,2),register_name(reg,SIZE_OF_INT));
 }
 
 void
 code_crlvar(int e2,int reg,int sign,int sz) {
     use_int(reg);
     printf("\t%s ",cload(sign,sz)); lvar(e2);
-    printf(",%s\n",register_name(reg,0));
+    printf(",%s\n",register_name(reg,SIZE_OF_INT));
 
 }
 
@@ -1322,14 +1344,14 @@
     use_int(creg);
 #ifdef __APPLE__
     if (n->sc==STATIC) {
-	printf("\tleal _%s-_%d(%%ebx),%s\n", n->nm, goffset_label,
+	printf("\tleaq _%s(%%rip),%s\n", n->nm, 
 	    register_name(creg,0));
 	return;
     }
     int r = get_ptr_cache(n);
-    printf("\tmovl %s,%s\n", register_name(r,0), register_name(creg,0));
+    printf("\tmovq %s,%s\n", register_name(r,0), register_name(creg,0));
 #else
-    printf("\tmovl $%s,%s\n",n->nm,register_name(creg,0));
+    printf("\tmovq $%s,%s\n",n->nm,register_name(creg,0));
 #endif
 }
 
@@ -1337,30 +1359,30 @@
 code_label_value(int label,int reg) {
     use_int(reg);
 #ifdef __APPLE__
-    printf("\tleal _%d-_%d(%%ebx),%s\n",
-	label,goffset_label,register_name(reg,0));
+    printf("\tleaq _%d(%%rip),%s\n",
+	label,register_name(reg,0));
 #else
-    printf("\tleal _%d,%s\n",label,register_name(reg,0));
+    printf("\tleaq _%d,%s\n",label,register_name(reg,0));
 #endif
 }
 
 void
 code_const(int e2,int creg) {
     use_int(creg);
-    printf("\tmovl $%d,%s\n",e2,register_name(creg,0));
+    printf("\tmovl $%d,%s\n",e2,register_name(creg,SIZE_OF_INT));
 }
 
 void
 code_neg(int creg) {
     use_int(creg);
-    printf("\tnegl %s\n", register_name(creg,0));
+    printf("\tnegl %s\n", register_name(creg,SIZE_OF_INT));
 }
 
 
 void
 code_not(int creg) {
     use_int(creg);
-    printf("\tnotl %s\n", register_name(creg,0));
+    printf("\tnotl %s\n", register_name(creg,SIZE_OF_INT));
 }
 
 
@@ -1370,9 +1392,9 @@
 
     use_data_reg(creg,1);
     xrn = register_name(creg,1);
-    printf("\tcmpl $0,%s\n", register_name(creg,0));
+    printf("\tcmpl $0,%s\n", register_name(creg,SIZE_OF_INT));
     printf("\tsete %s\n", xrn);
-    printf("\tmovzbl %s,%s\n", xrn,register_name(creg,0));
+    printf("\tmovzbl %s,%s\n", xrn,register_name(creg,SIZE_OF_INT));
 }
 
 void
@@ -1380,9 +1402,9 @@
     char *xrn;
     if (car(e2)==REGISTER) {
 	use_int(reg);
-	printf("\taddl $%d,%s\n",dir,register_name(cadr(e2),0));
+	printf("\taddl $%d,%s\n",dir,register_name(cadr(e2),SIZE_OF_INT));
 	if (use)
-	    printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(reg,0));
+	    printf("\tmovl %s,%s\n",register_name(cadr(e2),SIZE_OF_INT),register_name(reg,SIZE_OF_INT));
 	return;
     } 
     g_expr(e2);
@@ -1400,8 +1422,8 @@
     if (car(e2)==REGISTER) {
 	use_int(reg);
 	if (use)
-	    printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(reg,0));
-	printf("\taddl $%d,%s\n",dir,register_name(cadr(e2),0));
+	    printf("\tmovl %s,%s\n",register_name(cadr(e2),SIZE_OF_INT),register_name(reg,SIZE_OF_INT));
+	printf("\taddl $%d,%s\n",dir,register_name(cadr(e2),SIZE_OF_INT));
 
 	return;
     } 
@@ -1410,7 +1432,7 @@
     xrn = register_name((e2=emit_pop(0)),0);
     use_int(reg);
     if (use)
-	printf("\t%s (%s),%s\n",cload(sign,sz),xrn,register_name(reg,0));
+	printf("\t%s (%s),%s\n",cload(sign,sz),xrn,register_name(reg,SIZE_OF_INT));
     printf("\t%s $%d,(%s)\n",(sz==1)?"addb":(sz==SIZE_OF_SHORT)?"addw":"addl",dir,xrn);
     emit_pop_free(e2);
 }
@@ -1420,14 +1442,18 @@
 void
 code_return(int creg) {
     use_int(creg);
-    printf("\tleal _%d,%s\n",retcont,register_name(creg,0));
+#ifdef __APPLE__
+    printf("\tleaq _%d(%%rip),%s\n",retcont,register_name(creg,0));
+#else
+    printf("\tleaq _%d,%s\n",retcont,register_name(creg,0));
+#endif
 }
 
 
 void
 code_environment(int creg) {
     use_int(creg);
-    printf("\tmovl %%ebp,%s\n",register_name(creg,0));
+    printf("\tmovq %%rbp,%s\n",register_name(creg,0));
 }
 
 static int rexpr_bool(int e1,int reg);
@@ -1447,7 +1473,7 @@
     if (use) {
 	use_int(reg);
 	xrn = register_name(reg,0);
-	printf("\txorl %s,%s\n",xrn,xrn);
+	printf("\txorq %s,%s\n",xrn,xrn);
 	jmp(e3=fwdlabel());
 	fwddef(e2);
 	printf("\tmovl $1,%s\n",xrn);
@@ -1557,7 +1583,7 @@
 void
 code_cmp_register(int e2,int label,int cond) {
     use_int(e2);
-    printf("\tcmpl $0,%s\n",register_name(e2,0));
+    printf("\tcmpl $0,%s\n",register_name(e2,SIZE_OF_INT));
     jcond(label,cond);
 }
 
@@ -1583,11 +1609,10 @@
 	text_mode(0);
     }
 #ifdef __APPLE__
-    printf("\tleal _%d-_%d(%%ebx),%s\n",lb,
-	    goffset_label,
+    printf("\tleaq _%d(%%rip),%s\n",lb,
 	    register_name(creg,0));
 #else
-    printf("\tlea _%d,%s\n",lb,register_name(creg,0));
+    printf("\tleaq _%d,%s\n",lb,register_name(creg,0));
 #endif
     set_attr(n,LABEL,lb);
 }
@@ -1624,14 +1649,22 @@
 	free_register(dreg);
         break;
     case 4: case -4:
-	drn = register_name(dreg = get_register(),0);
+	drn = register_name(dreg = get_register(),SIZE_OF_INT);
         printf("\tmovl %d(%s),%s\n",offset,frn,drn);
         printf("\tmovl %s,%d(%s)\n",drn,offset,trn);
 	free_register(dreg);
         break;
+    case 8: case -8:
+	drn = register_name(dreg = get_register(),0);
+        printf("\tmovq %d(%s),%s\n",offset,frn,drn);
+        printf("\tmovq %s,%d(%s)\n",drn,offset,trn);
+	free_register(dreg);
+        break;
     default:
         if (length <0) {
             if (length > -MAX_COPY_LEN) {
+                for(;length<=-8;length+=8,offset-=8)
+                    emit_copy(from,to,-8,offset-8,0,det);
                 for(;length<=-4;length+=4,offset-=4)
                     emit_copy(from,to,-4,offset-4,0,det);
                 for(;length<=-2;length+=2,offset-=2)
@@ -1641,6 +1674,8 @@
                 break;
             }
         } else if (length <=MAX_COPY_LEN) {
+            for(;length>=8;length-=8,offset+=8)
+                emit_copy(from,to,8,offset,0,det);
             for(;length>=4;length-=4,offset+=4)
                 emit_copy(from,to,4,offset,0,det);
             for(;length>=2;length-=2,offset+=2)
@@ -1653,36 +1688,36 @@
 	// clear_ptr_cache();
 	// code_save_stacks();
 
-	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("\tpushq %%rsi\n");
+	printf("\tpushq %%rdi\n");
+	printf("\tpushq %%rcx\n");
+	printf("\tpushq %s\n",register_name(from,0));
+	printf("\tpushq %s\n",register_name(to,0));
 	printf("\tpopl %%edi\n");
 	printf("\tpopl %%esi\n");
 	if (length<0) {
-	    printf("\tmovl $%d,%%ecx\n",-length/4);
-	    printf("\taddl $%d,%%esi\n",-length-4);
-	    printf("\taddl $%d,%%edi\n",-length-4
-		+(to==REG_ESP?4*4:0)
+	    printf("\tmovq $%d,%%rcx\n",-length/4);
+	    printf("\taddq $%d,%%rsi\n",-length-4);
+	    printf("\taddq $%d,%%rdi\n",-length-4
+		+(to==REG_ESP?8*8:0)
 		);
 	    printf("\tstd\n\trep\n\tmovsl\n");
-	    printf("\tpopl %%ecx\n");
-	    printf("\tpopl %%edi\n");
-	    printf("\tpopl %%esi\n");
+	    printf("\tpopq %%rcx\n");
+	    printf("\tpopq %%rdi\n");
+	    printf("\tpopq %%rsi\n");
 	    if(length%4) {
 		offset = offset+length/SIZE_OF_INT;
 		length=length%4;
 		emit_copy(from,to,length,offset,0,det);
 	    }
 	} else {
-	    printf("\tmovl $%d,%%ecx\n",length/4);
+	    printf("\tmovq $%d,%%rcx\n",length/4);
 	    if (to==REG_ESP)
-		printf("\taddl $%d,%%edi\n",4*4);
+		printf("\taddl $%d,%%rdi\n",8*4);
 	    printf("\tcld\n\trep\n\tmovsl\n");
-	    printf("\tpopl %%ecx\n");
-	    printf("\tpopl %%edi\n");
-	    printf("\tpopl %%esi\n");
+	    printf("\tpopq %%rcx\n");
+	    printf("\tpopq %%rdi\n");
+	    printf("\tpopq %%rsi\n");
 	    if(length%4) {
 		offset = offset+length/SIZE_OF_INT;
 		length=length%4;
@@ -1761,19 +1796,25 @@
     return reg_arg_list;
 }
 
-
 static void
 increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) {
     int nargs=0,reg_arg=0,freg_arg=0;
-    int t=caddr(e3);
+    int t=type_value(caddr(e3));
+    if (t>=0&&(car(t)==BIT_FIELD)) {
+        t = type_value(cadr(t));
+    }
     if(scalar(t)) {
-        nargs ++ ; reg_arg++; freg_arg++;
-    } else if (t==LONGLONG||t==ULONGLONG||t==DOUBLE) {
         nargs ++ ; reg_arg++;
+        if (size(t)>SIZE_OF_INT) nargs++;
+    } else if (t==LONGLONG||t==ULONGLONG) {
+        nargs ++ ; 
         nargs ++ ; reg_arg++;
     } else if (t==FLOAT) {
-        reg_arg ++ ; freg_arg++;
+        freg_arg++;
         nargs += size(t)/SIZE_OF_INT;
+    } else if (t==DOUBLE) {
+        nargs += size(t)/SIZE_OF_INT;
+        freg_arg++;
     } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
         nargs += round4(size(t))/SIZE_OF_INT;
     } else {
@@ -1785,6 +1826,7 @@
     *pfreg_arg += freg_arg;
 }
 
+
 #define AS_SAVE 1
 #define AS_ARG  0
 
@@ -1838,11 +1880,7 @@
 code_call(int e2,NMTBL *fn,int jmp)
 {
     if (car(e2) == FNAME) {     
-#ifdef __APPLE__
-        printf("\tcall\tL_%s$stub\n",fn->nm);
-#else
-        printf("\tcall\t%s\n",fn->nm);
-#endif
+        printf("\tcall\t_%s\n",fn->nm);
     } else {
         printf("\tcall\t*%s\n",register_name(REG_EAX,0));
     }
@@ -1926,10 +1964,10 @@
                     arg = get_register_var(0);
 #if ARG_ORDER==1
 		    delayed_arg = list2(
-			assign_expr0(arg,e4,INT,INT),
+			assign_expr0(arg,e4,LONGLONG,LONGLONG),
 			delayed_arg);
 #else
-                    g_expr_u(assign_expr0(arg,e4,INT,INT));
+                    g_expr_u(assign_expr0(arg,e4,LONGLONG,LONGLONG));
 #endif
                     car(e3)=arg;
                     reg_arg_list = list2(arg,reg_arg_list);
@@ -2051,16 +2089,16 @@
 	code_const(round16(cadr(e1)),reg);
     }
     crn = register_name(reg,0);
-    printf("\tsubl\t%s, %%esp\n",crn);
+    printf("\tsubq\t%s, %%rsp\n",crn);
     if (!max_func_arg_label) max_func_arg_label = fwdlabel();
-    printf("\tmovl $%s%d,%s\n",lpfx,max_func_arg_label ,crn);
-    printf("\tadd\t%%esp, %s\n",crn);
+    printf("\tmovq $%s%d,%s\n",lpfx,max_func_arg_label ,crn);
+    printf("\taddq\t%%rsp, %s\n",crn);
 }
 
 void
 code_frame_pointer(int e3) {
     use_int(e3);
-    printf("\tmovl %s,%%ebp\n",register_name(e3,0));
+    printf("\tmovq %s,%%rbp\n",register_name(e3,0));
 }
 
 int
@@ -2076,11 +2114,7 @@
 
 void
 code_jmp(char *s) {
-#ifdef __APPLE__
-    printf("\tjmp\tL_%s$stub\n",s);
-#else
-    printf("\tjmp %s\n",s);
-#endif
+    printf("\tjmp _%s\n",s);
 }
 
 
@@ -2098,7 +2132,7 @@
     op=cload(sign,byte);
     crn = register_name(creg,0);
     use_int(reg);
-    printf("\t%s %d(%s),%s\n",op,offset,crn,register_name(reg,0));
+    printf("\t%s %d(%s),%s\n",op,offset,crn,register_name(reg,SIZE_OF_INT));
 }
 
 #if FLOAT_CODE
@@ -2106,7 +2140,7 @@
 code_drindirect(int e1, int reg,int offset, int d)
 {
     g_expr(e1);
-    printf("\t%s %d(%s)\n",fload(d),offset,register_name(creg,0));
+    printf("\t%s %d(%s),%s\n",fload(d),offset,register_name(creg,0),register_name(reg,0));
     return DOUBLE;
 }
 #endif
@@ -2118,13 +2152,7 @@
 {
     char *crn = register_name(creg,0);
     use_longlong(reg);
-    if((reg==REG_L&&creg==REG_ESI)||(creg==REG_EAX)) {
-	printf("\tmovl %d(%s),%s\n",offset+SIZE_OF_INT,crn,l_edx(reg));
-	printf("\tmovl %d(%s),%s\n",offset,crn,l_eax(reg));
-    } else {
-	printf("\tmovl %d(%s),%s\n",offset,crn,l_eax(reg));
-	printf("\tmovl %d(%s),%s\n",offset+SIZE_OF_INT,crn,l_edx(reg));
-    }
+    printf("\tmovq %d(%s),%s\n",offset,crn,register_name(reg,0));
 }
 
 int
@@ -2142,7 +2170,8 @@
 char *
 move(int byte)
 {
-    return byte==1?"movb":byte==SIZE_OF_SHORT?"movw":"movl";
+    return byte==1?"movb":byte==SIZE_OF_SHORT?"movw":
+	byte==SIZE_OF_INT?"movl":"movq";
 }
 
 void
@@ -2177,7 +2206,7 @@
 code_assign_register(int e2,int byte,int creg) {
     use_int(creg);
     if (creg!=e2)
-	printf("\tmovl %s,%s\n",register_name(creg,0),register_name(e2,0));
+	printf("\tmovq %s,%s\n",register_name(creg,0),register_name(e2,0));
 }
 
 void
@@ -2261,8 +2290,8 @@
 	return;
     }
     // regs[oreg]=1;
-    orn = register_name(oreg,0);
-    crn = register_name(reg,0);
+    orn = register_name(oreg,SIZE_OF_INT);
+    crn = register_name(reg,SIZE_OF_INT);
     switch(op) {
     case ADD:
 	printf("\taddl %s,%s\n",orn,crn);
@@ -2326,7 +2355,7 @@
     char *crn;
     int datareg;
     use_int(reg);
-    crn = register_name(reg,0);
+    crn = register_name(reg,SIZE_OF_INT);
     orn = cadr(orn);
     datareg=is_data_reg(reg);
 
@@ -2389,7 +2418,7 @@
     int dreg;
     use_register(oreg,REG_ECX,1);
     dreg = (reg==REG_ECX)?oreg:reg;
-    printf("\t%s %%cl,%s\n",op,register_name(dreg,0));
+    printf("\t%s %%cl,%s\n",op,register_name(dreg,SIZE_OF_INT));
     set_ireg(dreg,0);
     set_ireg(reg,1);
 }
@@ -2404,10 +2433,10 @@
     }
     if (n) 
 	    printf("\t%s %d(%s),%s\n",cload(sign,byte),n,
-		register_name(xreg,0),register_name(reg,0));
+		register_name(xreg,0),register_name(reg,SIZE_OF_INT));
     else
 	    printf("\t%s (%s),%s\n",cload(sign,byte),
-		register_name(xreg,0),register_name(reg,0));
+		register_name(xreg,0),register_name(reg,SIZE_OF_INT));
 }
 
 int
@@ -2467,7 +2496,7 @@
     g_expr(list3(CMP,cadr(e1),caddr(e1)));
     use_data_reg(reg,1);
     printf("\tset%s\t%s\n",s,register_name(reg,1));
-    printf("\tmovzbl %s,%s\n",register_name(reg,1),register_name(reg,0));
+    printf("\tmovzbl %s,%s\n",register_name(reg,1),register_name(reg,SIZE_OF_INT));
     return 1;
 }
 
@@ -2528,16 +2557,9 @@
 code_enter1(int args)
 {
     code_disp_label=fwdlabel();
-    printf("\tlea -_%d(%%ebp),%%esp\n",code_disp_label);
+    printf("\tlea -_%d(%%rbp),%%rsp\n",code_disp_label);
 
     // printf("## args %d disp %d  code_disp_offset=%d\n",args,disp,code_disp_offset); 
-#ifdef __APPLE__
-    printf("\tcall\t___i686.get_pc_thunk.bx\n");
-    printf("_%d:\n",labelno);
-    goffset_label = labelno;
-    labelno++;
-    regs[REG_EBX] = 1;
-#endif
 }
 
 void
@@ -2575,18 +2597,11 @@
     r1_offset_label = fwdlabel();
     max_func_args = 0;
 
-    printf("\tpushl %%ebp\n");
-    printf("\tmovl %%esp,%%ebp\n");
-    printf("\tpushl %%ebx\n");
-    printf("\tpushl %%esi\n");
-    printf("\tpushl %%edi\n");
+    printf("\tpushq %%rbp\n");
+    printf("\tmovq %%rsp,%%rbp\n");
+    printf("\tpushq %%rbx\n");
     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);
-    goffset_label = labelno;
-    labelno++;
-    regs[REG_EBX] = 1;
     clear_ptr_cache();
 #endif
 
@@ -2618,20 +2633,20 @@
     int ty = cadr(fnptr->ty);
     fwddef(retcont);
     if (ty==FLOAT||ty==DOUBLE) {
-	printf("\tfldl %d(%%ebp)\n",-SIZE_OF_DOUBLE);
-	printf("\tmovl %s,%%ebp\n",reg_name[REG_ESI]);
+	printf("\tmovsd %d(%%rbp),%s\n",-SIZE_OF_DOUBLE,register_name(creg,0));
+	printf("\tmovq %s,%%rbp\n",reg_name_l[REG_ESI]);
     } else if (ty==LONGLONG||ty==ULONGLONG) {
 	set_lreg(RET_LREGISTER,0);
-	printf("\tmovl %d(%%ebp),%%ebp\n",disp-SIZE_OF_INT);
+	printf("\tmovq %d(%%rbp),%%rbp\n",disp-SIZE_OF_LONGLONG);
     } else if (ty>0&&( car(ty)==STRUCT || car(ty)==UNION)) {
 	set_ireg(RET_REGISTER,0);
-	printf("\tmovl %d(%%ebp),%s\n",disp-SIZE_OF_INT,
+	printf("\tmovq %d(%%rbp),%s\n",disp-SIZE_OF_LONGLONG,
 	    register_name(creg,0));
-	printf("\tmovl %s,%%ebp\n",reg_name[REG_EDI]);
+	printf("\tmovq %s,%%rbp\n",reg_name_l[REG_EDI]);
     } else if (ty!=VOID) {
 	set_ireg(RET_REGISTER,0);
-	printf("\tmovl %s,%s\n",reg_name[REG_ESI],register_name(creg,0));
-	printf("\tmovl %s,%%ebp\n",reg_name[REG_EDI]);
+	printf("\tmovq %s,%s\n",reg_name_l[REG_ESI],register_name(creg,0));
+	printf("\tmovq %s,%%rbp\n",reg_name_l[REG_EDI]);
     }
 }
 
@@ -2656,9 +2671,7 @@
     code_offset_set(fnptr);
 
     printf("\tlea %d(%%ebp),%%esp\n",-12);
-    printf("\tpopl %%edi\n");
-    printf("\tpopl %%esi\n");
-    printf("\tpopl %%ebx\n");
+    printf("\tpopq %%rbx\n");  <--- register save
     printf("\tleave\n");
     printf("\tret\n");
 #ifndef __APPLE__
@@ -2702,10 +2715,10 @@
 code_set_return_register(int mode) {
     // before goto leave code, set return register
     if (cadr(fnptr->ty)==FLOAT) {
-        // set_freg(RET_FREGISTER,mode);
+        set_freg(RET_FREGISTER,mode);
 	return 0;
     } else if (cadr(fnptr->ty)==DOUBLE) {
-        // set_dreg(RET_DREGISTER,mode);
+        set_dreg(RET_DREGISTER,mode);
 	return 0;
     } else if (cadr(fnptr->ty)==LONGLONG||cadr(fnptr->ty)==ULONGLONG) {
         set_lreg(RET_LREGISTER,mode);
@@ -2847,11 +2860,7 @@
 #if LONGLONG_CODE
     long long ll = lcadr(e);
     data_mode(0);
-#if (ENDIAN_L==0)
-        printf("\t.long\t0x%x,0x%x\n",code_l1(ll),code_l2(ll));
-#else
-        printf("\t.long\t0x%x,0x%x\n",code_l2(ll),code_l1(ll));
-#endif
+    printf("\t.quad\t0x%llx\n",ll);
 #endif
 }
 
@@ -3088,24 +3097,9 @@
 
 
 char *
-fstore(int d)
-{
-    return use?
-	(d?"fstl":"fsts"):
-	(d?"fstpl":"fstps")
-    ;
-}
-
-char *
-fstore_u(int d)
-{
-    return d?"fstpl":"fstps";
-}
-
-char *
 fload(int d)
 {
-    return d?"fldl":"flds";
+    return d?"movsd":"movss";
 }
 
 
--- a/mc-code-ia32.c	Thu Nov 04 21:10:20 2010 +0900
+++ b/mc-code-ia32.c	Thu Nov 04 23:18:42 2010 +0900
@@ -1358,9 +1358,14 @@
 void
 code_return(int creg) {
     use_int(creg);
+#ifdef __APPLE__
+    // printf("\tleal _%d(%%rip),%s\n",retcont,register_name(creg,0));
+    printf("\tleal _%d-_%d(%%ebx),%s\n",
+	retcont,goffset_label,register_name(reg,0));
+#else
     printf("\tleal _%d,%s\n",retcont,register_name(creg,0));
-}
-
+#endif
+}
 
 void
 code_environment(int creg) {