changeset 735:31e5641bd7c7

i64 continue...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 06 Nov 2010 18:43:29 +0900
parents d2d6b1ef2cb4
children d7a976af188a
files mc-code-i64.c
diffstat 1 files changed, 210 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-i64.c	Fri Nov 05 22:36:39 2010 +0900
+++ b/mc-code-i64.c	Sat Nov 06 18:43:29 2010 +0900
@@ -3240,34 +3240,63 @@
 
 void code_d2u(int reg)
 { 
+    int f = reg;
     use_int(reg);
-    printf("\tlea -%d(%%esp),%%esp\n",SIZE_OF_INT*3);
-    printf("\tfnstcw  (%%esp)\n");
-    printf("\tmovl    (%%esp), %s\n",register_name(reg,0));
-    printf("\tmovb    $12, 1(%%esp)\n");
-    printf("\tfldcw   (%%esp)\n");
-    printf("\tmovl    %s, (%%esp)\n",register_name(reg,0));
-    printf("\tfistpll %d(%%esp)\n",SIZE_OF_INT);
-    printf("\tfldcw   (%%esp)\n");
-    printf("\tmovl    %d(%%esp),%s\n",SIZE_OF_INT,register_name(reg,0));
-    printf("\tlea %d(%%esp),%%esp\n",SIZE_OF_INT*3);
-}
-
-void code_u2d(int reg)
+    printf("\tcvttsd2siq      %s,%s\n",register_name(f,0),register_name(reg,0));
+}
+
+void code_u2d1(int reg,int db)
 { 
-    printf("\tpushl  %s\n",register_name(creg,0));
-    printf("\tpushl  %s\n",register_name(creg,0));
-    printf("\tmovl   $0, %d(%%esp)\n",SIZE_OF_INT);
-    printf("\tfildll (%%esp)\n");
-    printf("\tlea %d(%%esp),%%esp\n",SIZE_OF_INT*2);
+    int i = reg;
+    char *u = get_regsiter_name(i);
+    int tmp = get_data_register();
+    char *t = get_regsiter_name(tmp);
+    use_int(reg);
+    char *d = get_regsiter_name(reg);
+    int td = get_dregsiter();
+    char *dbs = db?"d":"s";
+    printf("        cmpq    $0, %s\n",u);
+    printf("        js      f1\n");
+    printf("        cvtsi2%sdq       %s,%s\n",dbs,u,d);
+    printf("        jmp     f2\n");
+    printf("1:\n");
+    printf("        movq    %s, %s\n",u,t);
+    printf("        shrq    %s\n",get_register_name(t));
+    printf("        andl    $1, %s\n",get_register_name(u,SIZE_OF_INT));
+    printf("        orq     %s, %s\n",t,u);
+    printf("        cvtsi2%sdq       %s, %s\n",dbs,u,d);
+    printf("        movap%s  %s, %s\n",db,d,get_register_name(td,0));
+    printf("        adds%s   %s, %s\n",db,d,get_register_name(td,0));
+    printf("2:\n");
+    free_register(tmp);
+    free_register(td);
+}
+void code_u2d1(int reg) {
+    code_u2d1(reg,1);
 }
 
 void code_d2f(int reg) { }
 void code_f2d(int reg) { }
-void code_f2i(int reg) { code_d2i(reg); }
-void code_f2u(int reg) { code_d2u(reg); }
-void code_i2f(int reg) { code_i2d(reg); }
-void code_u2f(int reg) { code_u2d(reg); }
+void code_f2i(int reg) { 
+    int f = reg;
+    use_int(reg);
+    printf("\tcvttss2si    %s,%s\n",register_name(f,0),register_name(creg,0));
+}
+
+void code_f2u(int reg) { 
+    int f = reg;
+    use_int(reg);
+    printf("\tcvttss2siq      %s,%s\n",register_name(f,0),register_name(reg,0));
+}
+
+void code_i2f(int reg) { 
+    int c = reg;
+    use_double(reg);
+    printf("\tcvtsi2ss     %s,%s\n",register_name(c,0),register_name(creg,0));
+}
+void code_u2f(int reg) { 
+    code_u2d1(reg,0);
+}
 
 void code_drgvar(int e2,int d,int freg)
 { 
@@ -3288,23 +3317,29 @@
 
 void code_drlvar(int e2,int d,int freg)
 { 
-    printf("\t%s ",fload(d)); lvar(e2); printf("\n");
+    printf("\t%s ",fload(d)); lvar(e2); printf(",%s\n", register_name(freg,0));
 }
 
 void code_cmp_drgvar(int e2,int reg,int d,int label,int cond)
 { 
+    char *db = d?"d":"s";
+    char *f = get_register_name(reg,0);
+    int t = get_dregister();
 #ifdef __APPLE__
     int r = get_ptr_cache(ncaddr(e2));
     if (cadr(e2))
-	printf("\tfcomp %d(%s)\n",cadr(e2),register_name(r,0));
+	printf("\tmovs%s %d(%s),%s\n",db,cadr(e2),register_name(r,0),f);
     else
-	printf("\tfcomp (%s)\n",register_name(r,0));
+	printf("\tmovs%s (%s),%s\n",db,register_name(r,0),f);
 #else
     if (cadr(e2))
-	printf("\tfcomp %s+%d\n",(ncaddr(e2))->nm,cadr(e2));
+	printf("\tmovs%s %s+%d,%s\n",db,(ncaddr(e2))->nm,cadr(e2),f);
     else
-	printf("\tfcomp %s\n",(ncaddr(e2))->nm);
+	printf("\tmovs%s %s,%s\n",db,(ncaddr(e2))->nm,f);
 #endif
+    printf("\txorp%s %s,%s\n",db,f,register_name(t,0));
+    printf("\tucomis%s %s,%s\n",db,f,get_register_name(t,0));
+    free_register(t);
     jcond(label,cond);
 }
 
@@ -3314,68 +3349,171 @@
     jcond(label,cond);
 }
 
-void dtosop(int op,int reg,int e1)
-{
+dtosop(int op,int reg,int oreg)
+{ 
+    char *opn="";
+    char *frn;
+    char *grn;
+    int ox = -1;
+
+    use_float(1,reg);
+    if (!(oreg<= -REG_LVAR_OFFSET)) {
+	grn=fregister_name(oreg);
+    }
+    frn=fregister_name(reg);
     switch(op) {
-    case FADD:
-    case DADD: printf("\tfaddp %%st,%%st(1)\n"); break;
-    case FSUB:
-    case DSUB: printf("\tfsubp %%st,%%st(1)\n"); break;
-    case FDIV:
-    case DDIV: printf("\tfdivp %%st,%%st(1)\n"); break;
-    case FMUL:
-    case DMUL: printf("\tfmulp %%st,%%st(1)\n"); break;
+    case FADD: opn="addss"; break;
+    case DADD: opn="addsd"; break;
+    case FSUB: opn="subss"; break;
+    case DSUB: opn="subsd"; break;
+    case FDIV: opn="divss"; break;
+    case DDIV: opn="divsd"; break;
+    case FMUL: opn="mulss"; break;
+    case DMUL: opn="mulsd"; break;
     case FCMP:
+	if (oreg<= -REG_LVAR_OFFSET) {
+	    printf("\tucomiss "); lvar(oreg);
+	    printf(",%s\n",frn);
+        } else {
+	    printf("\tucomiss %s,%s\n",frn,grn);
+        }
+        if (ox!=-1) free_register(ox);
+        return;
     case DCMP: 
-	printf("\tfucompp\n");
-	printf("\tfnstsw\t%%ax\n");
-#ifdef __APPLE__
-	if (regs[REG_EAX]==PTRC_REG)
-	    clear_ptr_cache_reg(REG_EAX);
-#endif
-	break;
+	if (oreg<= -REG_LVAR_OFFSET) {
+	    printf("\tucomisd "); lvar(oreg);
+	    printf(",%s\n",frn);
+        } else {
+	    printf("\tucomisd %s,%s\n",frn,grn);
+        }
+        if (ox!=-1) free_register(ox);
+        return;
+    case DCMPGE: 
+    case FCMPGE: 
+    default:
+        error(-1); return;
     }
-}
+    if (oreg<= -REG_LVAR_OFFSET) {
+	printf("\t%s ",opn);
+        lvar(oreg);
+        printf(",%s\n",frn);
+    } else {
+	printf("\t%s %s,%s\n",opn,frn,grn);
+    } 
+    if (ox!=-1) free_register(ox);
+}
+
 
 void
 code_dassop(int op,int reg,int d) {
-    /* we have lvalue in creg, applied floating value is in %st(0) */
-    emit_dpop(d);                            /* do nothing for 387 */
-    printf("\t%s (%s)\n",fload(d),register_name(creg,0));
-    dtosop(op,reg,0);
-    printf("\t%s (%s)\n",fstore(d),register_name(creg,0));
+    /* we have lvalue in creg, applied floating value is in freg */
+    //  (*creg) op = pop()
+    int  xreg=emit_dpop(d);
+    char *crn;
+    char *frn;
+
+    crn=register_name(ireg,0);
+    use_float(d,reg);
+    frn  =register_name(reg,0);
+
+    printf("\t%s %s,0(%s)\n",fload(d),frn,crn);
+    dtosop(op,reg,xreg);
+    printf("\t%s %s,0(%s)\n",fstore(d),frn,crn);
+    emit_dpop_free(xreg,d);
 }
 
 void
 code_register_dassop(int reg,int op,int d) {
-    error(-1);
+    // reg op= dpop()
+    int  xreg=emit_dpop(d);
+    dtosop(op,reg,xreg);
+    emit_dpop_free(xreg,d);
+}
+
+#define fregister_name(a)  register_name(a,0)
+
+static int
+code_dload_1(int d)
+{
+    int r,g;
+    char *drn,*grn;
+    // load 1
+    float_one_lib_used=1;
+    r = get_ptr_cache(&float_one);
+    drn=register_name(r);
+    grn=fregister_name(g=get_dregister(d));
+    printf("\tmovs%s %s,0(%s)\n",d?"d":"s",grn,drn);
+    return g;
 }
 
 void
-code_dpreinc(int e1,int e2,int d,int freg) {
-    g_expr(e2);
-    printf("\t%s (%s)\n",fload(d),register_name(creg,0));
-    printf("\tfld1\n");
-    if (caddr(e1)>0)
-	printf("\tfaddp %%st,%%st(1)\n");
-    else
-	printf("\tfsubrp %%st,%%st(1)\n");
-    printf("\t%s (%s)\n",fstore(d),register_name(creg,0));
+code_dpreinc(int e1,int e2,int d,int reg) {
+    char *frn,*crn,*grn;
+    int  g;
+    char *ops = (caddr(e1)>0)?(d?"addsd":"addss"):(d?"subsd":"addss");
+
+    if (car(e2)==DREGISTER||car(e2)==FREGISTER) {
+        crn=register_name(cadr(e2));
+        grn = fregister_name(g = code_dload_1(d));
+        if (reg==USE_CREG) {
+            reg=get_dregister(d); if (!reg) error(-1);
+            set_freg(reg,0);
+        }
+        frn=fregister_name(reg);
+        printf("\t%s %s,%s,%s\n",ops,crn,crn,grn);
+        if (use && reg!=cadr(e2))
+            printf("\movap%s %s,%s\n",d?"d":"s",frn,crn);
+    } else {
+        g_expr(e2);
+        if (!is_int_reg(creg)) error(-1);
+        crn=register_name(ireg);
+        if (reg==USE_CREG) {
+            reg=get_dregister(d); if (!reg) error(-1);
+            set_freg(reg,0);
+        }
+        frn=fregister_name(reg);
+        grn = fregister_name(g = code_dload_1(d));
+        printf("\t%s %s,0(%s)\n",fload(d),frn,crn);
+        printf("\t%s %s,%s,%s\n",ops,frn,frn,grn);
+        printf("\t%s %s,0(%s)\n",fstore(d),frn,crn);
+    }
+    free_register(g);
 }
 
 void
-code_dpostinc(int e1,int e2,int d,int freg) {
-    g_expr(e2);
-    printf("\t%s (%s)\n",fload(d),register_name(creg,0));
-    if (use)
-	printf("\t%s (%s)\n",fload(d),register_name(creg,0));
-    printf("\tfld1\n");
-    if (caddr(e1)>0)
-	printf("\tfaddp %%st,%%st(1)\n");
-    else
-	printf("\tfsubrp %%st,%%st(1)\n");
-    printf("\t%s (%s)\n",(use?fstore_u(d):fstore(d)),register_name(creg,0));
-}
+code_dpostinc(int e1,int e2,int d,int reg) {
+    char *frn,*crn,*grn;
+    int  g;
+    char *ops = (caddr(e1)>0)?(d?"addsd":"addss"):(d?"subsd":"addss");
+
+    if (car(e2)==DREGISTER||car(e2)==FREGISTER) {
+        crn=register_name(cadr(e2));
+        grn = fregister_name(g = code_dload_1(d));
+        if (reg==USE_CREG) {
+            reg=get_dregister(d); if (!reg) error(-1);
+            set_freg(reg,0);
+        }
+        frn=fregister_name(reg);
+        if (use && reg!=cadr(e2))
+            printf("\tmovap%s %s,%s\n",d?"d":"s",frn,crn);
+        printf("\t%s %s,%s,%s\n",ops,crn,crn,grn);
+    } else {
+        g_expr(e2);
+        if (!is_int_reg(creg)) error(-1);
+        crn=register_name(ireg);
+        if (reg==USE_CREG) {
+            reg=get_dregister(d); if (!reg) error(-1);
+            set_freg(reg,0);
+        }
+        frn=fregister_name(reg);
+        grn = fregister_name(g = code_dload_1(d));
+        printf("\t%s %s,0(%s)\n",fload(d),frn,crn);
+        printf("\t%s %s,%s,%s\n",ops,grn,frn,grn);
+        printf("\t%s %s,0(%s)\n",fstore(d),grn,crn);
+    }
+    free_register(g);
+}
+
 
 #define COND_BRANCH 1
 #define COND_VALUE  2