changeset 736:d7a976af188a

i64 continue...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 07 Nov 2010 22:52:33 +0900
parents 31e5641bd7c7
children d8b207cfbafe
files mc-code-i64.c
diffstat 1 files changed, 196 insertions(+), 574 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-i64.c	Sat Nov 06 18:43:29 2010 +0900
+++ b/mc-code-i64.c	Sun Nov 07 22:52:33 2010 +0900
@@ -1343,8 +1343,7 @@
 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,SIZE_OF_INT));
-
+    printf(",%s\n",register_name(reg,sz<=SIZE_OF_INT?SIZE_OF_INT:0));
 }
 
 
@@ -2266,7 +2265,7 @@
 }
 
 void
-tosop(int op,int reg,int oreg)
+tosop1(int op,int reg,int oreg,int sz)
 {
     int ox=0;
     char *orn,*crn;
@@ -2278,7 +2277,10 @@
         error(-1);
     } else if (oreg<= -REG_LVAR_OFFSET) {
         ox = get_register(); if (ox<0) error(-1);
-        code_rlvar(oreg+REG_LVAR_OFFSET,ox);
+	if (sz<=SIZE_OF_INT)
+	    code_rlvar(oreg+REG_LVAR_OFFSET,ox);
+	else
+	    code_lrlvar(oreg+REG_LVAR_OFFSET,ox);
         free_lvar(oreg+REG_LVAR_OFFSET);
         oreg = ox;
     }
@@ -2286,43 +2288,44 @@
     switch(op) {
     case LSHIFT:
     case ULSHIFT:
-	shift("sall",oreg,reg);
+	shift(sz<=SIZE_OF_INT?"sall":"salq",oreg,reg);
         if(ox) free_register(ox);
 	return;
     case RSHIFT:
-	shift("sarl",oreg,reg);
+	shift(sz<=SIZE_OF_INT?"sarl":"sarq",oreg,reg);
         if(ox) free_register(ox);
 	return;
     case URSHIFT:
-	shift("shrl",oreg,reg);
+	shift(sz<=SIZE_OF_INT?"shrl":"shrq",oreg,reg);
         if(ox) free_register(ox);
 	return;
     }
     // regs[oreg]=1;
-    orn = register_name(oreg,SIZE_OF_INT);
-    crn = register_name(reg,SIZE_OF_INT);
+    orn = register_name(oreg,sz<=SIZE_OF_INT?SIZE_OF_INT:0);
+    crn = register_name(reg,sz<=SIZE_OF_INT?SIZE_OF_INT:0);
+    char *q = sz<=SIZE_OF_INT?"l":"q";
     switch(op) {
     case ADD:
-	printf("\taddl %s,%s\n",orn,crn);
+	printf("\tadd%s %s,%s\n",q,orn,crn);
 	break;
     case SUB: 
-	printf("\tsubl %s,%s\n",orn,crn);
+	printf("\tsub%s %s,%s\n",q,orn,crn);
 	break;
     case CMP:
-	printf("\tcmpl %s,%s\n",orn,crn);
+	printf("\tcmp%s %s,%s\n",q,orn,crn);
 	break;
     case BAND: 
-	printf("\tandl %s,%s\n",orn,crn);
+	printf("\tand%s %s,%s\n",q,orn,crn);
 	break;
     case EOR: 
-	printf("\txorl %s,%s\n",orn,crn);
+	printf("\txor%s %s,%s\n",q,orn,crn);
 	break;
     case BOR:
-	printf("\torl %s,%s\n",orn,crn);
+	printf("\tor%s %s,%s\n",q,orn,crn);
 	break;
     case MUL:
     case UMUL:
-	printf("\t%s %s,%s\n","imull",orn,crn);
+	printf("\t%s %s,%s\n","imul%s",q,orn,crn);
 	break;
     case DIV:
     case UDIV:
@@ -2338,10 +2341,17 @@
 	    use_register(oreg,REG_ECX,1);
 	    oreg = REG_ECX;
 	}
-	orn = register_name(oreg,0);
-	printf((op==DIV||op==MOD)?
-	    "\tcltd\n\tidivl %s\n":
-	    "\txor %%edx,%%edx\n\tdivl %s\n",orn);
+        if (sz<=SIZE_OF_INT) {
+	    orn = register_name(oreg,SIZE_OF_INT);
+	    printf((op==DIV||op==MOD)?
+		"\tcltd\n\tidivl %s\n":
+		"\txorl %%edx,%%edx\n\tdivl %s\n",orn);
+        } else {
+	    orn = register_name(oreg,0);
+	    printf((op==DIV||op==MOD)?
+		"\tcltq\n\tidivq %s\n":
+		"\txorl %%edx,%%edx\n\tdivq %s\n",orn);
+        }
 	set_ireg((op==MOD||op==UMOD)?REG_EDX:REG_EAX,0);
 	set_ireg(reg,1);
 	break;
@@ -2349,6 +2359,12 @@
     if(ox && ox!=ireg) free_register(ox);
 }
 
+void
+tosop(int op,int reg,int oreg)
+{
+    tosop1(op,reg,oreg,SIZE_OF_INT);
+}
+
 int
 code_const_op_p(int op,int e)
 {
@@ -2359,67 +2375,82 @@
 }
 
 void
-oprtc(int op,int reg,int orn)
+oprtc1(int op,int reg,int orn1,int sz)
 {
     char *crn;
     int datareg;
     use_int(reg);
-    crn = register_name(reg,SIZE_OF_INT);
-    orn = cadr(orn);
+    char *q = sz<SIZE_OF_INT?"l":"q";
+    crn = register_name(reg,sz<=SIZE_OF_INT?SIZE_OF_INT:0);
+    long orn ;
+    if (car(orn1)==CONST) orn = cadr(orn1);
+    else if (car(orn1)==LCONST) orn = lcadr(orn1);
+    else error(-1);
+
     datareg=is_data_reg(reg);
 
     switch(op) {
     case LSHIFT:
     case ULSHIFT:
-	printf("\tsall $%d,%s\n",orn,crn);
+	printf("\tsal%s $%ld,%s\n",q,orn,crn);
 	return;
     case DIV:
 	orn = ilog(orn);
     case RSHIFT:
-	printf("\tsarl $%d,%s\n",orn,crn);
+	printf("\tsar%s $%ld,%s\n",q,orn,crn);
 	return;
     case UDIV:
 	orn = ilog(orn);
     case URSHIFT:
-	printf("\tshrl $%d,%s\n",orn,crn);
+	printf("\tshr%s $%ld,%s\n",q,orn,crn);
 	return;
     case ADD:
-	printf("\taddl $%d,%s\n",orn,crn);
+	printf("\tadd%s $%ld,%s\n",q,orn,crn);
 	break;
     case SUB: case CMP:
-	printf("\tsubl $%d,%s\n",orn,crn);
+	printf("\tsub%s $%ld,%s\n",q,orn,crn);
 	break;
     case BAND: 
 	if (datareg&&(orn & ~255)==~255)
-	    printf("\tandb $%d,%s\n",orn,register_name(reg,1));
+	    printf("\tandb $%ld,%s\n",orn,register_name(reg,1));
 	else if (datareg&&(orn & ~65535)==~65535)
-	    printf("\tandw $%d,%s\n",orn,register_name(reg,2));
+	    printf("\tandw $%ld,%s\n",orn,register_name(reg,2));
+	else if (sz<=SIZE_OF_INT||(datareg&&(orn & ~0xffffffff)==~0xffffffff))
+	    printf("\tandl $%ld,%s\n",orn,register_name(reg,4));
 	else
-	    printf("\tandl $%d,%s\n",orn,crn);
+	    printf("\tandq $%ld,%s\n",orn,crn);
 	break;
     case EOR: 
-	printf("\txorl $%d,%s\n",orn,crn);
+	printf("\txor%s $%ld,%s\n",q,orn,crn);
 	break;
     case BOR:
 	if (datareg&&(orn & ~255)==0)
-	    printf("\tor $%d,%s\n",orn,register_name(reg,1));
+	    printf("\tor $%ld,%s\n",orn,register_name(reg,1));
 	else if (datareg&&(orn & ~65535)==0)
-	    printf("\tor $%d,%s\n",orn,register_name(reg,2));
+	    printf("\tor $%ld,%s\n",orn,register_name(reg,2));
+	else if (sz<=SIZE_OF_INT||(datareg&&(orn & ~0xffffffff)==0))
+	    printf("\torl $%ld,%s\n",orn,register_name(reg,4));
 	else
-	    printf("\torl $%d,%s\n",orn,crn);
+	    printf("\torq $%ld,%s\n",orn,crn);
 	break;
     case MUL:
     case UMUL:
 	if (ilog(orn)) {
-	    printf("\tsall $%d,%s\n",ilog(orn),crn);
+	    printf("\tsal%s $%ld,%s\n",q,ilog(orn),crn);
 	} else
-	    printf("\t%s $%d,%s\n","imull",orn,crn);
+	    printf("\t%s%s $%ld,%s\n","imul",q,orn,crn);
 	break;
     default:
 	error(-1);
     }
 }
 
+void
+oprtc(int op,int reg,int orn)
+{
+    oprtc1(op,reg,orn,SIZE_OF_INT);
+}
+
 
 void
 shift(char *op, int oreg,int reg)
@@ -3213,7 +3244,7 @@
 
 void code_dneg(int freg,int d)
 { 
-    int reg = get_dregister();
+    int reg = get_dregister(d);
     if (d) {
 	printf("\txorpd      %s,%s\n",register_name(freg,0),register_name(reg,0));
 	printf("\tmovapd     %s,%s\n",register_name(reg,0),register_name(freg,0));
@@ -3253,7 +3284,7 @@
     char *t = get_regsiter_name(tmp);
     use_int(reg);
     char *d = get_regsiter_name(reg);
-    int td = get_dregsiter();
+    int td = get_dregsiter(d);
     char *dbs = db?"d":"s";
     printf("        cmpq    $0, %s\n",u);
     printf("        js      f1\n");
@@ -3324,7 +3355,7 @@
 { 
     char *db = d?"d":"s";
     char *f = get_register_name(reg,0);
-    int t = get_dregister();
+    int t = get_dregister(d);
 #ifdef __APPLE__
     int r = get_ptr_cache(ncaddr(e2));
     if (cadr(e2))
@@ -3545,29 +3576,30 @@
 	default: return 0;
 	}
     }
-    s = "e";
+    s = "a";
+    int cmp = FCMP;
     switch(op) {
 	case DOP+GE:
+	    cmp = DCMP;
 	case FOP+GE:
-	    g_expr(list3(DCMP,e1,e2));
-	    printf("\ttestb\t$5,%%ah\n");
+	    g_expr(list3(cmp,e1,e2));
+	    s = "ae";
 	    break;
 	case DOP+GT:
+	    cmp = DCMP;
 	case FOP+GT:
-	    g_expr(list3(DCMP,e1,e2));
-	    printf("\ttestb\t$69,%%ah\n");
+	    g_expr(list3(cmp,e1,e2));
 	    break;
 	case DOP+EQ:
+	    cmp = DCMP;
 	case FOP+EQ:
-	    g_expr(list3(DCMP,e1,e2));
-	    printf("\tandb\t$69,%%ah\n");
-	    printf("\txorb\t$64,%%ah\n");
+	    s = "e";
+	    g_expr(list3(cmp,e1,e2));
 	    break;
 	case DOP+NEQ:
+	    cmp = DCMP;
 	case FOP+NEQ:
-	    g_expr(list3(DCMP,e1,e2));
-	    printf("\tandb\t$69,%%ah\n");
-	    printf("\txorb\t$64,%%ah\n");
+	    g_expr(list3(cmp,e1,e2));
 	    s = "ne";
 	    break;
 	default:
@@ -3607,54 +3639,55 @@
 void
 code_cmp_dregister(int e2,int d,int label,int cond)
 {
-    if (e2!=USE_CREG)
-	error(-1);
+    use_float(d,e2);
 #ifdef __APPLE__
 	if (regs[REG_EAX]==PTRC_REG)
 	    clear_ptr_cache_reg(REG_EAX);
 #endif
-    printf("\tfldz\n"); 
-    printf("\tfucompp\n");
-    printf("\tfnstsw\t%%ax\n");
-    printf("\tandb\t$69,%%ah\n");
-    printf("\txorb\t$64,%%ah\n");
+    int tmp = get_dregister(d);
+    char *n = register_name(tmp,0);
+    char *c = register_name(creg,0);
+    char *sd = d?"d":"s";
+    printf("\txorp%s %s,%s\n",sd,n,n); 
+    printf("\tucomis%s %s,%s\n",sd,register_name(ca),s);
     jcond(label,cond);
 }
 
 int pop_fregister()
 { 
     if (freg_sp<0) { error(-1); return -1;}
-    // printf("## fpop: %d\n",freg_sp-1);
     return freg_stack[--freg_sp];
 }
 
-int
-emit_dpop(int d)
-{
-    int xreg;
-    if ((xreg=pop_fregister())==-1) {
-    } else if (xreg<= -REG_LVAR_OFFSET) {
-	code_drlvar(REG_LVAR_OFFSET+xreg,1,freg);
-	free_lvar(xreg+REG_LVAR_OFFSET);
-	/* pushed order is reversed.   We don't need this for commutable 
-	    operator, but it is ok to do this.  */
-        printf("\tfxch\t%%st(1)\n");
-    } 
+int emit_dpop(int d)
+{ 
+    int xreg,reg;
+    xreg=pop_fregister();
+    if (xreg<= -REG_LVAR_OFFSET) {
+        reg = get_dregister(d);
+        code_drlvar(REG_LVAR_OFFSET+xreg,d,reg);
+        free_lvar(REG_LVAR_OFFSET+xreg);
+        xreg=reg;
+    }
     return xreg;
 }
 
-
 void emit_dpop_free(int e1,int d)
 { 
-}
-
-void emit_dpush(int type)
+    free_register(e1);
+}
+
+void
+emit_dpush(int d)
 { 
-    if (freg_sp>=MAX_FPU_STACK) code_save_fstacks();
+    int new_reg;
+    if (!is_float_reg(creg)) error(-1);
     if (freg_sp>MAX_MAX) error(-1);
-    freg_stack[freg_sp++]=-1;
-    // printf("## fpush:%d\n",freg_sp);
-}
+    new_reg = get_dregister(d);       /* 絶対に取れる */
+    freg_stack[freg_sp++] = freg;     /* push するかわりにレジスタを使う */
+    creg = freg = new_reg;
+}
+
 
 #endif
 
@@ -3672,7 +3705,14 @@
         }
     }
 #if FLOAT_CODE
-    code_save_fstacks();
+    for(i=0;i<freg_sp;i++) {
+        if ((reg=freg_stack[i])>=0) {
+            code_dassign_lvar(
+                (freg_stack[i]=new_lvar(SIZE_OF_FLOAT)),reg,0); 
+            freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET;
+            free_register(reg);
+        }
+    }
 #endif
 }
 
@@ -3695,386 +3735,113 @@
     }
 }
 
-#if FLOAT_CODE
-void
-code_save_fstacks()
-{
-    /* stacks in fpu are saved in local variable */
-    int xreg,sp,uses;
-    uses = use; use = 0;
-    sp=freg_sp;
-    while(sp-->0) {
-	if ((xreg=freg_stack[sp])==-1) {
-	    code_dassign_lvar(
-		(freg_stack[sp]=new_lvar(SIZE_OF_DOUBLE)),freg,1); 
-	    freg_stack[sp]= freg_stack[sp]-REG_LVAR_OFFSET;
-	}
-    }
-    use = uses;
-}
-#endif
-
-
 
 #if LONGLONG_CODE
 
 
-/* 64bit int part */
-
-static void
-pcond(char *s,int l1)
-{
-    printf("\tj%s\t_%d\n",s,l1);
-}
+/* 64bit int part 
+    In INTEL64 mode, basically save as 32bit operatoin 
+ */
 
 int
 lrexpr(int e1, int e2,int l1, int op,int cond)
 {
-    int l2;
-    code_save_stacks();
-    g_expr(e1);
-    emit_lpush();
-    g_expr(e2);
-    // we are sure %ecx is free
-    // %ebx is used in Intel Mac
-    stack_depth -= SIZE_OF_INT * 2;
-    printf("\tpopl %%ecx\n");   // LSW
-    printf("\tcmpl %%edx,(%%esp)\n");  // MSW
-    printf("\tpopl %%edx\n"); 
-    l2 = fwdlabel();
-    // cond==0 jump on false condtion   ( if(x) => rexpr(..  cond=0 ...) )
-    switch(op) {
-    case LOP+GT:
-    case LOP+GE:
-        pcond(code_gt(1),cond?l1:l2);
-        pcond(code_eq(0),cond?l2:l1);
-        break;
-    case LOP+UGT:
-    case LOP+UGE:
-        pcond(code_ugt(1),cond?l1:l2);
-        pcond(code_eq(0), cond?l2:l1);
-        break;
-    case LOP+EQ:
-        pcond(code_eq(0),(cond?l2:l1));
-        break;
-    case LOP+NEQ:
-        pcond(code_eq(0),(cond?l1:l2));
-        break;
-    default:
-        error(-1);
-    }
-    printf("\tsubl %%eax,%%ecx\n");
-    switch(op) {
-    case LOP+GT:  pcond(code_gt(cond),  l1); break;
-    case LOP+GE:  pcond(code_ge(cond),  l1); break;
-    case LOP+UGT: pcond(code_ugt(cond), l1); break;  
-    case LOP+UGE: pcond(code_uge(cond), l1); break;  
-    case LOP+EQ:  pcond(code_eq(cond),l1); break;
-    case LOP+NEQ: pcond(code_eq(!cond),l1); break;
-    }  
-    fwddef(l2); 
+    g_expr(list3(LCMP,cadr(e1),caddr(e1)));
+    printf("\tj%s\t_%d\n",code_cond(car(e1),cond),l1);
     return l1;
 }
 
 int emit_lpop()
 {
-    return 0;
+    return emit_pop(0);
 }
 
 void code_lregister(int e2,int reg)
 {
-    use_longlong(reg);
-    if (reg!=REG_L) {
-	printf("\tmovl %%esi,%s\n",l_eax(reg));
-	printf("\tmovl %%edi,%s\n",l_edx(reg));
-    }
+    return code_register(e2,reg);
 }
 
 void code_cmp_lregister(int reg,int label,int cond)
 {
-    char *crn;
-    use_int(reg);
-    crn = register_name(reg,0);
-    printf("\tmovl %%esi,%s\n",crn);
-    printf("\torl %%edi,%s\n",crn);
-    printf("\ttestl %s,%s\n",crn,crn);
+    use_longlong(e2);
+    printf("\tcmpq $0,%s\n",register_name(e2,0));
     jcond(label,cond);
 }
 
 void code_cmp_lrgvar(int e1,int e2,int label,int cond)
 {
-    char *n,*crn;
-    use_int(e2);
-    crn = register_name(e2,0);
+    use_longlong(reg);
 #ifdef __APPLE__
     int r = get_ptr_cache(ncaddr(e1));
-    n = register_name(r,0);
-    if (cadr(e1)) {
-	printf("\tmovl %d(%s),%s\n",cadr(e1),n,crn);
-	printf("\torl  %d(%s),%s\n",cadr(e1)+4,n,crn);
-    } else {
-	printf("\tmovl (%s),%s\n",n,crn);
-	printf("\torl  4(%s),%s\n",n,crn);
-    }
+    if (cadr(e1))
+        printf("\tcmpq $0,%d(%s)\n",cadr(e1),register_name(r,0));
+    else
+        printf("\tcmpq $0,(%s)\n",register_name(r,0));
 #else
-    n = (ncaddr(e1))->nm;
-    if (cadr(e1)) {
-	printf("\tmovl %s+%d,%s\n",n,cadr(e1),crn);
-	printf("\torl  %s+%d,%s\n",n,cadr(e1)+4,crn);
-    } else {
-	printf("\tmovl %s,%s\n",n,crn);
-	printf("\torl  %s+4,%s\n",n,crn);
-    }
+    if (cadr(e1))
+        printf("\tcmpq $0,%s+%d\n",(ncaddr(e1))->nm,cadr(e1));
+    else
+        printf("\tcmpq $0,%s\n",(ncaddr(e1))->nm);
 #endif
-    printf("\ttestl %s,%s\n",crn,crn);
     jcond(label,cond);
 }
 
 void code_cmp_lrlvar(int e1,int e2,int label,int cond)
 {
-    char *crn;
-    use_int(e2);
-    crn = register_name(e2,0);
-    printf("\tmovl "); lvar(e1); printf(",%s\n",crn);
-    printf("\torl  "); lvar(e1+4); printf(",%s\n",crn);
-    printf("\ttestl %s,%s\n",crn,crn);
+    use_longlong(reg);
+    printf("\tcmpq $0,"); lvar(e1); printf("\n");
     jcond(label,cond);
 }
 
 void code_lassign(int e1,int e2)
 {
-    char *rn;
-    // e1 = e2
     use_longlong(e2);
-    rn = register_name(e1,0);
-#if ENDIAN_L==0
-    printf("\tmovl %s,(%s)\n",l_eax(e2),rn);
-    printf("\tmovl %s,4(%s)\n",l_edx(e2),rn);
-#endif
+    use_longlong(creg);
+    printf("\tmovq %s,(%s)\n",register_name(creg,0),register_name(e2,0));
 }
 
 void code_lassign_gvar(int e1,int e2)
 {
-    char *n;
-    use_longlong(e2);
-#if ENDIAN_L==0
-#ifdef __APPLE__
-    int r = get_ptr_cache(ncaddr(e1));
-    n = register_name(r,0);
-    if (cadr(e1)) {
-	printf("\tmovl %s,%d(%s)\n",l_eax(e2),cadr(e1),n);
-	printf("\tmovl %s,%d(%s)\n",l_edx(e2),cadr(e1)+4,n);
-    } else {
-	printf("\tmovl %s,(%s)\n",l_eax(e2),n);
-	printf("\tmovl %s,4(%s)\n",l_edx(e2),n);
-    }
-#else
-    n = (ncaddr(e1))->nm;
-    if (cadr(e1)) {
-	printf("\tmovl %s,%s+%d\n",l_eax(e2),n,cadr(e1));
-	printf("\tmovl %s,%s+%d\n",l_edx(e2),n,cadr(e1)+4);
-    } else {
-	printf("\tmovl %s,%s\n",l_eax(e2),n);
-	printf("\tmovl %s,%s+4\n",l_edx(e2),n);
-    }
-#endif
-#endif
+    code_assign_gvar(e1,e2,SIZE_OF_LONGLONG);
 }
 
 void code_lassign_lvar(int e1,int e2)
 {
-    use_longlong(e2);
-#if ENDIAN_L==0
-    printf("\tmovl %s,",l_eax(e2)); lvar(e1); printf("\n");
-    printf("\tmovl %s,",l_edx(e2)); lvar(e1+4); printf("\n");
-#endif
+    code_assign_lvar(e1,e2,SIZE_OF_LONGLONG)
 }
 
 void code_lassign_lregister(int e2,int reg)
 {
-    // e2 = reg
-    use_longlong(reg);
-    if (e2!=reg) {
-	printf("\tmovl %s,%s\n",l_eax(reg),l_eax(e2));
-	printf("\tmovl %s,%s\n",l_edx(reg),l_edx(e2));
-    }
+    code_lassign_lregister(e2,SIZE_OF_LONGLONG,reg)
 }
 
 void
 code_lconst(int e1,int creg)
 {
     use_longlong(creg);
-#if ENDIAN_L==0
-    printf("\tmovl $%d,%s\n",code_l1(lcadr(e1)),l_eax(creg));
-    printf("\tmovl $%d,%s\n",code_l2(lcadr(e1)),l_edx(creg));
-#endif
+    printf("\tmovq $%ld,%s\n",lcadr(e1),l_eax(creg));
 }
 
 void code_lneg(int e1)
 {
     use_longlong(e1);
-    printf("\tnegl %s\n",l_eax(e1));
-    printf("\tadcl $0,%s\n",l_edx(e1));
-    printf("\tnegl %s\n",l_edx(e1));
+    printf("\tnegq %s\n",register_name(e1,0));
 }
 
 void code_lrgvar(int e1,int e2)
 {
-    char *n;
-    use_longlong(e2);
-#if ENDIAN_L==0
-#ifdef __APPLE__
-    int r = get_ptr_cache(ncaddr(e1));
-    n = register_name(r,0);
-    if (cadr(e1)) {
-	printf("\tmovl %d(%s),%s\n",cadr(e1),n,l_eax(e2));
-	printf("\tmovl %d(%s),%s\n",cadr(e1)+4,n,l_edx(e2));
-    } else {
-	printf("\tmovl (%s),%s\n",n,l_eax(e2));
-	printf("\tmovl 4(%s),%s\n",n,l_edx(e2));
-    }
-#else
-    n = (ncaddr(e1))->nm;
-    if (cadr(e1)) {
-	printf("\tmovl %s+%d,%s\n",n,cadr(e1),l_eax(e2));
-	printf("\tmovl %s+%d,%s\n",n,cadr(e1)+4,l_edx(e2));
-    } else {
-	printf("\tmovl %s,%s\n",n,l_eax(e2));
-	printf("\tmovl %s+4,%s\n",n,l_edx(e2));
-    }
-#endif
-#endif
+    code_crgvar(e1,e2,0,SIZE_OF_LONGLONG);
 }
 
 void code_lrlvar(int e1,int e2)
 {
-    use_longlong(e2);
-#if ENDIAN_L==0
-    printf("\tmovl "); lvar(e1); printf(",%s\n",l_eax(e2));
-    printf("\tmovl "); lvar(e1+4); printf(",%s\n",l_edx(e2));
-#endif
-}
-
-#define check_lreg(reg) if (reg==REG_L) code_lassign_lregister(reg,REG_LCREG)
+    code_crlvar(e1,e2,0,SIZE_OF_LONGLONG);
+}
 
 void
 ltosop(int op,int reg,int e2)
 {
-    char *opl,*oph,*call;
-    int lb;
-
-    // e2 (operand) is on the top of the stack
-    use_longlong(reg);
-    opl = 0; call=0;
-    stack_depth -= SIZE_OF_INT * 2;
-
-    switch(op) {
-    case LLSHIFT:
-    case LULSHIFT:
-	printf("\tmovl %%ecx,4(%%esp)\n");
-	printf("\tpopl %%ecx\n");
-        printf("\tshldl %%eax,%%edx\n");
-        printf("\tsall %%cl,%%eax\n");
-        printf("\ttestb $32,%%cl\n");
-	printf("\tje\t_%d\n",(lb=fwdlabel()));
-        printf("\tmovl %%eax,%%edx\n");
-        printf("\txorl %%eax,%%eax\n");
-	fwddef(lb);
-	printf("\tpopl %%ecx\n");
-	check_lreg(reg);
-	return;
-    case LRSHIFT:
-	printf("\tmovl %%ecx,4(%%esp)\n");
-	printf("\tpopl %%ecx\n");
-        printf("\tshrdl %%edx,%%eax\n");
-        printf("\tsarl %%cl,%%edx\n");
-        printf("\ttestb $32,%%cl\n");
-	printf("\tje\t_%d\n",(lb=fwdlabel()));
-        printf("\tmovl %%edx,%%eax\n");
-        printf("\tsarl $31,%%edx\n");
-	fwddef(lb);
-	printf("\tpopl %%ecx\n");
-	check_lreg(reg);
-	return;
-    case LURSHIFT:
-	printf("\tmovl %%ecx,4(%%esp)\n");
-	printf("\tpopl %%ecx\n");
-        printf("\tshrdl %%edx,%%eax\n");
-        printf("\tshrl %%cl,%%edx\n");
-        printf("\ttestb $32,%%cl\n");
-	printf("\tje\t_%d\n",(lb=fwdlabel()));
-        printf("\tmovl %%edx,%%eax\n");
-        printf("\txorl %%edx,%%edx\n");
-	fwddef(lb);
-	printf("\tpopl %%ecx\n");
-	check_lreg(reg);
-	return;
-    }
-    switch(op) {
-    case LADD:  opl="addl";oph="adcl"; break;
-    case LSUB:  opl="subl";oph="sbbl"; break;
-    case LBAND: opl=oph="andl"; break;
-    case LEOR:  opl=oph="xorl"; break;
-    case LBOR:  opl=oph="orl"; break;
-    case LMUL:
-    case LUMUL:
-	printf("\tpushl %%edx\n");
-	printf("\tpushl %%eax\n");
-	printf("\tpushl %%ecx\n");
-	//       0   saved ecx
-	//       4   c_l
-	//       8   c_h
-	//      12   o_l
-	//      16   o_h
-        printf("\tmull 12(%%esp)\n");          //  c_l*o_l -> %edx,%eax
-        printf("\tmovl 4(%%esp),%%ecx\n");     //  c_l->%ecx
-        printf("\timull 16(%%esp),%%ecx\n");   //  c_l*o_h->%ecx
-        printf("\taddl %%ecx,%%edx\n");        //  %edx+%ecx->%edx
-        printf("\tmovl 8(%%esp),%%ecx\n");     //  c_h->%ecx
-        printf("\timull 12(%%esp),%%ecx\n");   //  c_h*o_l->%ecx
-        printf("\taddl %%ecx,%%edx\n");        //  %edx+%ecx->%edx
-	printf("\tpopl %%ecx\n");
-	// printf("\taddl $8,%%esp\n");
-	printf("\tlea 16(%%esp),%%esp\n");
-	return;
-#ifdef __APPLE__
-    case LDIV:  call="L___divdi3$stub"; 
-         extern_define("__divdi3",0,FUNCTION,1); break;
-    case LUDIV: call="L___udivdi3$stub";
-         extern_define("__udivdi3",0,FUNCTION,1); break;
-    case LMOD:  call="L___moddi3$stub";
-         extern_define("__moddi3",0,FUNCTION,1); break;
-    case LUMOD: call="L___umoddi3$stub";
-         extern_define("__umoddi3",0,FUNCTION,1); break;
-#else
-    case LDIV:  call="__divdi3"; break;
-    case LUDIV: call="__udivdi3"; break;
-    case LMOD:  call="__moddi3"; break;
-    case LUMOD: call="__umoddi3"; break;
-#endif
-    default: error(-1);
-    }
-    if (opl) {
-	printf("\t%s (%%esp),%%eax\n\t%s 4(%%esp),%%edx\n",opl,oph);
-	printf("\tlea 8(%%esp),%%esp\n");
-	check_lreg(reg);
-    } else if (call) {
-#ifdef __APPLE__
-	clear_ptr_cache();
-	printf("\tpushl %%edx\n");
-	printf("\tpushl %%eax\n");
-	printf("\tcall %s\n",call);
-	printf("\tlea 16(%%esp),%%esp\n");
-#else
-	printf("\tpushl %%edx\n");
-	printf("\tpushl %%eax\n");
-	printf("\tcall %s\n",call);
-	printf("\tlea 16(%%esp),%%esp\n");
-#endif
-	check_lreg(reg);
-    } else {
-	error(-1);
-    }
+    tosop1(op,reg,e2,"q");
 }
 
 int code_lconst_op_p(int op,int e) {
@@ -4106,96 +3873,17 @@
 }
 
 void loprtc(int op,int reg,int e) {
-    char *opl,*oph=0;
-    int vl,il;
-    int vh;
-    long long l=0;
-
-    if (car(e)==CONST) l = cadr(e);
-    else if (car(e)==LCONST) l = lcadr(e);
-    else error(-1);
-
-    vl = code_l1(l);
-    vh = code_l2(l);
-    il = l;
-
-    use_longlong(reg);
-    opl = 0;
-
-    switch(op) {
-    case LMUL: case LUMUL:
-        vl=il=ilog(il);
-    case LLSHIFT:
-    case LULSHIFT:
-	if (il==0) return;
-	else if (il==32) {
-	    code_register(regv_l(reg),regv_h(reg));
-	    code_const(0,regv_l(reg));
-	    return;
-	} else if (il>32) {
-	    code_register(regv_l(reg),regv_h(reg));
-	    printf("\tsall $%d,%s\n",(int)il-32,l_edx(reg));
-	    code_const(0,regv_l(reg));
-	    return;
-	}
-        printf("\tshldl $%d,%s,%s\n",vl,l_eax(reg),l_edx(reg));
-        printf("\tsall $%d,%s\n",(int)il,l_eax(reg)); return;
-    case LRSHIFT:
-	if (il==0) return;
-	else if (il==32) {
-	    code_register(regv_h(reg),regv_l(reg));
-	    creg = ireg = REG_EAX;
-	    code_i2ll(reg);
-	    return;
-	} else if (il>32) {
-	    code_register(regv_h(reg),regv_l(reg));
-	    printf("\tsarl $%d,%s\n",(int)il-32,l_eax(reg));
-	    creg = ireg = REG_EAX;
-	    code_i2ll(reg);
-	    return;
-	}
-        printf("\tshrdl $%d,%s,%s\n",(int)il,l_edx(reg),l_eax(reg));
-        printf("\tsarl $%d,%s\n",(int)il,l_edx(reg));
-	return;
-    case LUDIV:
-        il=ilog(il);
-    case LURSHIFT:
-	if (il==0) return;
-	else if (il==32) {
-	    code_register(regv_h(reg),regv_l(reg));
-	    code_const(0,regv_h(reg));
-	    return;
-	} else if (il>32) {
-	    if (il>64) error(-1);
-	    code_register(regv_h(reg),regv_l(reg));
-	    printf("\tsarl $%d,%s\n",(int)il-32,l_eax(reg));
-	    code_const(0,regv_h(reg));
-	    return;
-	}
-        printf("\tshrdl $%d,%s,%s\n",(int)il,l_edx(reg),l_eax(reg));
-        printf("\tshrl $%d,%s\n",(int)il,l_edx(reg));
-	return;
-    }
-    switch(op) {
-    case LADD: opl="addl";oph="adcl"; break;
-    case LSUB: opl="subl";oph="sbbl"; break;
-    case LEOR:  opl=oph="xorl"; break;
-    case LBOR:  opl=oph="orl"; break;
-    case LBAND: opl=oph="andl"; break;
-    default: error(-1);
-    }
-    printf("\t%s $%d,%s\n\t%s $%d,%s\n",opl,vl,l_eax(reg),oph,vh,l_edx(reg));
+    oprtc(op,reg,e,SIZE_OF_LONGLONG);
 }
 
 void emit_lpop_free(int e1)
 {
-//     printf("\taddl $8,%%esp\n");
+    emit_pop_free(e1);
 }
 
 void emit_lpush()
 {
-    stack_depth += SIZE_OF_INT * 2;
-    printf("\tpushl %%edx\n\tpushl %%eax\n");
+    emit_push();
 }
 
 void code_i2ll(int reg)
@@ -4206,8 +3894,7 @@
     use_longlong(reg0);
     use_register(creg0,REG_EAX,1);
 
-    printf("\tcltd\n");
-    check_lreg(reg);
+    printf("\tcltq\n");
     lreg = creg = reg0;
 }
 
@@ -4218,16 +3905,8 @@
 
 void code_u2ll(int reg)
 {
-    int reg0 = USE_CREG;
-    int creg0 = creg;
-
-    use_longlong(reg0);
-    use_register(creg0,REG_EAX,1);
-
-    use_longlong(reg0);
-    printf("\txorl %%edx,%%edx\n");
-    check_lreg(reg);
-    lreg = creg = reg0;
+    printf("\tshlq $32,%s",regisnter_name(reg,0));
+    printf("\tshrq $32,%s",regisnter_name(reg,0));
 }
 
 void code_u2ull(int reg)
@@ -4237,104 +3916,55 @@
 
 void code_ll2i(int reg)
 {
-    use_int(reg);
-    if (REG_EAX!=reg)
-	printf("\tmovl %%eax,%s\n",register_name(creg,0));
 }
 
 void code_ll2u(int reg)
 {
-    code_ll2i(reg);
 }
 
 void code_ull2i(int reg)
 {
-    code_ll2i(reg);
 }
 
 void code_ull2u(int reg)
 {
-    code_ll2i(reg);
 }
 
 #if FLOAT_CODE
 void code_d2ll(int reg)
 {
+    char *f = register_name(reg,0);
     use_longlong(reg);
-#if 1
-        printf("\tsubl    $64, %%esp\n");
-        printf("\tfnstcw  34(%%esp)\n");
-        printf("\tmovzwl  34(%%esp), %%eax\n");
-        printf("\tmovb    $12, %%ah\n");
-        printf("\tmovw    %%ax, 32(%%esp)\n");
-        printf("\tfldcw   32(%%esp)\n");
-        printf("\tfistpll 52(%%esp)\n");
-        printf("\tfldcw   34(%%esp)\n");
-        printf("\tmovl    52(%%esp), %%eax\n");
-        printf("\tmovl    56(%%esp), %%edx\n");
-        printf("\taddl    $64, %%esp\n");
-#else
-        printf("\tsubl $40,%%esp\n");
-        printf("\tfnstcw 2(%%esp)\n");
-        printf("\tmovw 2(%%esp),%%ax\n");
-        printf("\torw $3072,%%ax\n");
-        printf("\tmovw %%ax,0(%%esp)\n");
-        printf("\tfldcw 0(%%esp)\n");
-        printf("\tfistpll 12(%%esp)\n");
-        printf("\tfldcw 2(%%esp)\n");
-        printf("\tmovl 12(%%esp),%%eax\n");
-        printf("\tmovl 16(%%esp),%%edx\n");
-        printf("\taddl $40,%%esp\n");
-#endif
-	check_lreg(reg);
+    printf("\tcvttsd2siq      %s,%s\n",f,register_name(reg,0));
 }
 
 void code_d2ull(int reg)
 {
+    char *f = register_name(reg,0);
     use_longlong(reg);
-#ifdef __APPLE__
-    clear_ptr_cache();
-#endif
-        printf("\tsubl $16,%%esp\n");
-        printf("\tfstpl (%%esp)\n");
-#ifdef __APPLE__
-        printf("\tcall L___fixunsdfdi$stub\n");
-        extern_define("__fixunsdfdi",0,FUNCTION,1); 
-#else
-        printf("\tcall __fixunsdfdi\n");
-#endif
-        printf("\taddl $16,%%esp\n");
+    printf("\tcvttsd2siq      %s,%s\n",f,register_name(reg,0));
+    use_longlong(reg);
 }
 
 void code_f2ll(int reg)
 {
-    code_d2ll(reg);
+    char *f = register_name(reg,0);
+    use_longlong(reg);
+    printf("\tcvttss2siq      %s,%s\n",f,register_name(reg,0));
 }
 
 void code_f2ull(int reg)
 {
+    char *f = register_name(reg,0);
     use_longlong(reg);
-#ifdef __APPLE__
-    clear_ptr_cache();
-#endif
-        printf("\tsubl $16,%%esp\n");
-        printf("\tfstps (%%esp)\n");
-#ifdef __APPLE__
-        printf("\tcall L___fixunssfdi$stub\n");
-        extern_define("__fixunssfdi",0,FUNCTION,1); 
-#else
-        printf("\tcall __fixunssfdi\n");
-#endif
-        printf("\taddl $16,%%esp\n");
+    printf("\tcvttss2siq      %s,%s\n",f,register_name(reg,0));
 }
 
 void code_ll2d(int reg)
 {
-        printf("\tsubl $8,%%esp\n");
-        printf("\tmovl %%eax,(%%esp)\n");
-        printf("\tmovl %%edx,4(%%esp)\n");
-        printf("\tfildll (%%esp)\n");
-        printf("\taddl $8,%%esp\n");
+    char *f = register_name(reg,0);
+    use_float(reg,1);
+    printf("\tcvtsi2sdq      %s,%s\n",f,register_name(reg,0));
 }
 
 void code_ll2f(int reg)
@@ -4357,50 +3987,42 @@
 
 void code_lpreinc(int e1,int e2,int reg)
 {
-    int dir = caddr(e1);
-    int creg0;
-    char *crn;
-    if (car(e2)==LREGISTER) {
-        use_longlong(reg);
-        printf("\taddl $%d,%%esi\n",dir);
-	printf("\tadcl $%d,%%edi\n",dir>0?0:-1);
-	if (use && reg!=REG_L) {
-	    code_lregister(REG_L,reg);
-	}
+    char *xrn;
+    if (car(e2)==REGISTER) {
+        use_int(reg);
+        printf("\taddq $%d,%s\n",dir,register_name(cadr(e2),0));
+        if (use)
+            printf("\tmovq %s,%s\n",register_name(cadr(e2),0),register_name(reg,0));
         return;
     } 
     g_expr(e2);
-    crn = register_name(creg0=creg,0);
-    printf("\taddl $%d,(%s)\n",dir,crn);
-    printf("\tadcl $%d,4(%s)\n",dir>0?0:-1,crn);
-    use_longlong(reg);
-    lload(creg0,0,reg);
+    xrn = register_name(creg,0);
+    use_int(reg);
+    printf("\taddq $%d,(%s)\n",dir,xrn)
+;
+    if (use)
+        printf("\t%s (%s),%s\n",cload(sign,SIZE_OF_LONGLONG),xrn,register_name(reg,0));
 }
 
 void code_lpostinc(int e1,int e2,int reg)
 {
-    int dir = caddr(e1);
-    int creg0;
-    char *crn;
-    if (car(e2)==LREGISTER) {
-        use_longlong(reg);
-	if (use && reg!=REG_L) {
-	    code_lregister(REG_L,reg);
-	}
-        printf("\taddl $%d,%%esi\n",dir);
-	printf("\tadcl $%d,%%edi\n",dir>0?0:-1);
+    char *xrn;
+    if (car(e2)==REGISTER) {
+        use_int(reg);
+        if (use)
+            printf("\tmovq %s,%s\n",register_name(cadr(e2),0),register_name(reg,0));
+        printf("\taddq $%d,%s\n",dir,register_name(cadr(e2),0));
+
         return;
     } 
     g_expr(e2);
-    crn = register_name(creg0=creg,0);
-    printf("\taddl $%d,(%s)\n",dir,crn);
-    printf("\tadcl $%d,4(%s)\n",dir>0?0:-1,crn);
-    if (use) {
-	use_longlong(reg);
-	lload(creg0,0,reg);
-	printf("\taddl $%d,%s\n",-dir,l_eax(reg));
-	printf("\tadcl $%d,%s\n",-dir>0?0:-1,l_edx(reg));
-    }
+    emit_push();  
+    xrn = register_name((e2=emit_pop(0)),0);
+    use_int(reg);
+    if (use)
+        printf("\t%s (%s),%s\n",cload(sign,SIZE_OF_LONGLONG),xrn,register_name(reg,0));
+    printf("\taddq $%d,(%s)\n",dir,xrn)
+    emit_pop_free(e2);
 }
 
 void code_lassop(int op,int reg)