changeset 149:0f36fdbcba9b

mips no compile error
author kono
date Mon, 14 Jul 2003 07:56:26 +0900
parents e0eba2993c37
children f8271009a314
files mc-code-mips.c
diffstat 1 files changed, 392 insertions(+), 348 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-mips.c	Sun Jul 13 23:59:26 2003 +0900
+++ b/mc-code-mips.c	Mon Jul 14 07:56:26 2003 +0900
@@ -11,7 +11,6 @@
 #define RODATA_EMIT_MODE 2
 
 static void data_mode(char *name);
-static void init_ptr_cache();
 static void ld_indexx(int byte, int n, int xreg);
 static void local_table(void);
 static void shift(char *op, int reg);
@@ -28,7 +27,7 @@
 static int reg_save;
 static int freg_save;
 
-static int freg,ireg;
+static int freg,ireg,dreg;
 
 /* mips requires two registers for compare */
 static int cmpreg = -1;
@@ -59,6 +58,11 @@
 #define MIN_TMP_REG 4
 #define MAX_TMP_REG 11
 
+#define DREG_VAR_BASE 29
+#define DREG_VAR_MIN  18
+#define MIN_TMP_DREG 4
+#define MAX_TMP_DREG 11
+
 #define PTRC_REG 3
 
 #define FREG_VAR_BASE 31
@@ -89,15 +93,15 @@
 
 #define CREG_REGISTER  MAX_TMP_REG
 #define FREG_FREGISTER (MAX_TMP_FREG+FREG_OFFSET)
-#define DREG_DREGISTER (2+DFREG_OFFSET)
+#define DREG_DREGISTER (2+DREG_OFFSET)
 
-int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REL_MAX_DREGISTER];
-int powerpc_regv[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REL_MAX_DREGISTER];
+int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_DREGISTER];
+int powerpc_regv[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_DREGISTER];
 
-unsigned char dreg_pair0[REL_MAX_DREGISTER] = {
+unsigned char dreg_pair0[REAL_MAX_DREGISTER] = {
     0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
 };
-unsigned char dreg_pair1[REL_MAX_DREGISTER] = {
+unsigned char dreg_pair1[REAL_MAX_DREGISTER] = {
     1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
 };
 
@@ -121,19 +125,34 @@
 
 #define register_name(i)  reg_name0(i)
 #define fregister_name(i) reg_name0(i)
+#define dregister_name0(i) reg_name1(i,dreg_pair0)
+#define dregister_name1(i) reg_name1(i,dreg_pair1)
 
-static
+static char *
 reg_name0(int i)
 {
     if (i<=REAL_MAX_REGISTER+REAL_MAX_FREGISTER)
 	return reg_name[i];
-    else
+    else {
 	error(-1);
+	return reg_name[0];
+    }
 }
 
+static char *
+reg_name1(int i,unsigned char *d)
+{
+    if (i<=REAL_MAX_REGISTER+REAL_MAX_FREGISTER) {
+	error(-1);
+	return reg_name[0];
+    } else
+	return reg_name[d[i-DREG_OFFSET]];
+}
+
+
 #define is_int_reg(i)  (0<=i&&i<REAL_MAX_REGISTER)
 #define is_float_reg(i)  (REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER)
-#define is_double_reg(i)  (REAL_MAX_REGISTER+REAL_MAX_FREGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER+REL_MAX_DREGISTER)
+#define is_double_reg(i)  (REAL_MAX_REGISTER+REAL_MAX_FREGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER+REAL_MAX_DREGISTER)
 
 
 int use_int(int i) { 
@@ -154,7 +173,9 @@
     return i;
 }
 
-static char * fload(int d);
+static int code_d1(double d);
+static int code_d2(double d);
+
 static void code_save_stacks();
 static void code_save_input_registers();
 static void    set_creg(int,int);
@@ -377,7 +398,7 @@
             code_dassign_lvar(
                 (dreg_stack[i]=new_lvar(size_of_double)),reg,1); 
             dreg_stack[i]= dreg_stack[i]-REG_LVAR_OFFSET;
-	    free_dregister(reg);
+	    free_register(reg);
 	    return get_register(); /* 今度は必ずある */
 	}
     }
@@ -402,6 +423,7 @@
 
 static int
 get_dregister1() {
+    int i;
     for(i=MAX_TMP_DREG;i>MIN_TMP_DREG;i--) {
 	if (regs[i]) continue;  /* 使われている */
 	if (regs[dreg_pair0[i-DREG_OFFSET]]) continue;
@@ -417,7 +439,7 @@
 static int 
 get_dregister0()
 {
-    int i0,i1,reg,i;
+    int reg,i;
     /* とりあえず、空き int register pair を探す */
     if ((i=get_dregister1())!=-1) {
 	return i;
@@ -480,8 +502,7 @@
 
 int 
 get_dregister(int d)
-{    /* 使われていないレジスタを調べる */
-    int i,reg;
+{
     if (d) {
 	return get_dregister0();
     } else {
@@ -717,13 +738,13 @@
     int i,j;
     if (d) {
 	for(i=0;i<DREG_VAR_BASE-DREG_VAR_MIN;i++) {
-	    if (! regs[j=(DREG_VAR_BASE-i+DREG_OFFSET])) {       /* 使われていないなら */
+	    if (! regs[j=(DREG_VAR_BASE-i+DREG_OFFSET)]) {       /* 使われていないなら */
 		if (regs[dreg_pair0[j]] || regs[dreg_pair1[j]]) continue;
 		regs[DREG_VAR_BASE-i+DREG_OFFSET]=USING_REG; /*そのレジスタを使うことを宣言し*/
 		regv[DREG_VAR_BASE-i+DREG_OFFSET]=0;
 		regs[dreg_pair0[j]] = regs[dreg_pair1[j]] = USING_REG;
 		regv[dreg_pair0[j]] = regv[dreg_pair1[j]] = 0;
-		if (dreg_pair1[j]>max_reg_var) max_reg_var=dreg_pair[j];
+		if (dreg_pair1[j]>max_reg_var) max_reg_var=dreg_pair1[j];
 		/* その場所を表す番号を返す */
 		return list3(DREGISTER,DREG_VAR_BASE-i+DREG_OFFSET,(int)n); 
 	    }
@@ -772,7 +793,6 @@
 void
 code_label(int labelno)
 {
-    clear_ptr_cache();
     printf("L_%d:\n",labelno);
 }
 
@@ -1112,7 +1132,7 @@
 void
 code_cmp_rlvar(int e2) {
     if (cmpreg==-1) cmpreg = get_register();
-    code_rlvar(e1,cmpreg);
+    code_rlvar(e2,cmpreg);
     regv[cmpreg]=1;
 }
 
@@ -1224,6 +1244,7 @@
         }
         break;
     }
+    if (value) {
     /* creg must point top of the destination data */
     /* this code is necessary for the value of assignment or function call */
     /* otherwise we don't need this */
@@ -1299,22 +1320,30 @@
     }
 }
 
+static void
+move_dreg(int reg,int dreg)
+{
+    if (reg!=dreg) {
+	printf("\tmove %s,%s\n",dregister_name0(reg),
+				dregister_name0(dreg));
+	printf("\tmove %s,%s\n",dregister_name1(reg),
+				dregister_name1(dreg));
+    }
+}
+
 void
 set_dreg(int reg,int mode)
 {
     if (!is_double_reg(reg)) error(-1);
     if (reg!=creg) {
-	if (reg!=dreg && mode) {
-            printf("\tmove %s,%s\n",register_name(dreg_pair0(reg)),
-                                    register_name(dreg_pari0(dreg)));
-            printf("\tmove %s,%s\n",register_name(dreg_pari1(reg)),
-                                    register_name(dreg_pari1(dreg)));
+	if (mode) {
+	    move_dreg(reg,dreg);
 	}
 	free_register(creg);
 	creg = dreg = reg;
 	regs[dreg]=1;
-	regs[dreg_pair0(dreg)]=1;
-	regs[dreg_pair1(dreg)]=1;
+	regs[dreg_pair0[dreg]]=1;
+	regs[dreg_pair1[dreg]]=1;
     }
 }
 
@@ -1521,7 +1550,6 @@
     for(;arg_assign;arg_assign=cadr(arg_assign)) {
 	g_expr_u(car(arg_assign));
     }
-    clear_ptr_cache();
     if (car(e2) == FNAME) {	
 	printf("\tbl\tL_%s$stub\n",fn->nm);
     } else {
@@ -1599,10 +1627,18 @@
     g_expr(e2);
     crn=register_name(creg);
     switch (car(e1)) {
-    case FRINDIRECT: case DRINDIRECT:
-        printf("\t%s %s,%d(%s)\n",fload(car(e1)==DRINDIRECT),
-            fregister_name(freg),offset,crn);
+    case FRINDIRECT: 
+        printf("\tl.s %s,%d(%s)\n", fregister_name(freg),offset,crn);
         regv[creg]=0; regv[freg]=1;
+	creg = freg;
+        return FLOAT;
+    case DRINDIRECT: 
+        printf("\tlw %s,%d(%s)\n",
+            dregister_name0(dreg),offset,crn);
+        printf("\tlw %s,%d(%s)\n",
+            dregister_name1(dreg),offset+size_of_int,crn);
+        regv[creg]=0; regv[dreg]=1;
+	creg = dreg;
         return DOUBLE;
     case CRINDIRECT: 
         printf("\tlb %s,%d(%s)\n",crn,offset,crn);
@@ -1699,7 +1735,7 @@
 tosop(int op,int oreg)
 {
     int dx;
-    char *orn,*crn,*drn;
+    char *orn,*crn;
 
     if(oreg==-1) {
 	error(-1);
@@ -1755,7 +1791,7 @@
     case DIV:
 	printf("\tdivw %s,%s,%s\n",crn,crn,orn);
 	break;
-    case DIV: case UDIV: case MOD: case UMOD:
+    case UDIV: case MOD: case UMOD:
         printf("\t%s $0,%s,%s\n",(op==UDIV||op==UMOD)?"divu":"div",crn,orn);
         printf("\t%s %s\n",(op==MOD||op==UMOD)?"mflo":"mfhi",crn);
         printf("\t.set    noreorder\n");
@@ -2191,6 +2227,7 @@
     }
 }
 
+void
 global_table(void)
 {
     NMTBL *n;
@@ -2269,60 +2306,93 @@
 void
 code_cmp_dregister(int e2,int d)
 {
-    char *frn,*rrn,*grn;
-    int greg,r;
-    grn =  register_name(greg = get_dregister(d));
-    frn = register_name(e2);
-    float_zero_lib_used=1;
-    r = get_ptr_cache(&float_zero);
-    rrn = register_name(r);
-    printf("\tlfs %s,0(%s)\n",grn,rrn);
-    printf("\tfcmpu cr0,%s,%s\n",grn,frn);
-    free_register(greg);
-    return;
+    char *frn,*grn;
+    int greg;
+
+    if (d) {
+	printf("\tli.d $6,%g\n",0.0);
+        code_save_stacks();
+	move_dreg(4+DREG_OFFSET,freg);
+	printf("\tjal dpcmp\n");
+        set_dreg(RET_DREGISTER,0);
+	return;
+    } else {
+	grn =  register_name(greg = get_dregister(d));
+	frn = register_name(e2);
+	printf("\tli.s %s,%g\n",grn,0.0);
+	printf("\tc.eq.s %s,%s\n",grn,frn);
+	free_register(greg);
+	return;
+    }
 }
 
 void
 code_dregister(int e2,int freg,int d)
 {
     if (freg!=e2) {
-	if (is_int_reg(e2)) error(-1);
-	printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2));
+	if (d) {
+	    if (!is_double_reg(e2)) error(-1);
+	    move_dreg(freg,e2);
+	} else {
+	    if (!is_float_reg(e2)) error(-1);
+	    printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2));
+	}
     }
     regv[freg]=1;
 }
 
 void code_dassign_gvar(int e2,int freg,int d)
 { 
-    int r;
-    r = get_ptr_cache((NMTBL*)cadr(e2));
-    if (!is_float_reg(freg)) error(-1);
-    printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(r));
+    NMTBL *n = (NMTBL*)cadr(e2);
+    if (d) {
+	if (!is_double_reg(freg)) error(-1);
+        printf("\tsw %s,0(%s)\n",dregister_name0(freg),n->nm);
+        printf("\tsw %s,0(%s)\n",dregister_name1(freg),n->nm);
+    } else {
+        printf("\ts.s %s,0(%s)\n",fregister_name(freg),n->nm);
+    }
     regv[freg]=1;
 }
 
 void code_dassign_lvar(int e2,int freg,int d)
 { 
-    lvar_intro(e2);
-    if (!is_float_reg(freg)) error(-1);
-    printf("\t%s %s,",fstore(d),fregister_name(freg));
+    if (d) {
+	if (!is_double_reg(freg)) error(-1);
+        printf("\tsw %s,",dregister_name0(freg));
+        lvar(e2);
+        printf("\tsw %s,",dregister_name1(freg));
+        e2 += size_of_double/2;
+    } else {
+        printf("\ts.s %s,",fregister_name(freg));
+    }
     lvar(e2);
     regv[freg]=1;
 }
 
 void code_dassign(int e2,int freg,int d)
 { 
-    if (!is_float_reg(freg)) error(-1);
-    printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(e2));
+    if (d) {
+	if (!is_double_reg(freg)) error(-1);
+        printf("\tsw %s,0(%s)\n",dregister_name0(freg),register_name(e2));
+        printf("\tsw %s,4(%s)\n",dregister_name1(freg),register_name(e2));
+    } else {
+        printf("\ts.s %s,0(%s)\n",fregister_name(freg),register_name(e2));
+    }
     regv[freg]=1;
 }
 
 void
 code_dassign_dregister(int e2,int d,int freg) {
+    /* これってさ、code_dregister と同じ? */
     if (e2!=freg) {
-	if (is_int_reg(freg)) error(-1);
-	printf("\tfmr %s,%s\n",fregister_name(e2),fregister_name(freg));
+        if (d) {
+	    if (!is_double_reg(freg)) error(-1);
+	    move_dreg(freg,e2);
+        } else {
+            printf("\tmov.s %s,%s\n",fregister_name(e2),fregister_name(freg));
+        }
     }
+
 }
 
 static double d0 = 1.0;
@@ -2352,298 +2422,241 @@
 void 
 code_dconst(int e2,int freg,int d)
 { 
-    int lb;
     double value = dcadr(e2);
-    int r;
-    char *rrn,*frn;
-    frn = fregister_name(freg);
-    if (value==0.0) {
-	float_zero_lib_used=1;
-	r = get_ptr_cache(&float_zero);
-	rrn = register_name(r);
-	printf("\tlfs %s,0(%s)\n",frn,rrn);
-	return;
-    }
-    if (value==1.0) {
-	float_one_lib_used=1;
-	r = get_ptr_cache(&float_one);
-	rrn = register_name(r);
-	printf("\tlfs %s,0(%s)\n",frn,rrn);
-	return;
+    char *frn;
+    if (d) {
+        printf("\tli.d %s,%g\n",dregister_name0(freg),value);
+    } else {
+        frn = fregister_name(freg);
+        printf("\tli.s %s,%g\n",frn,value);
     }
-    rrn = register_name((r=get_register()));
-    printf(" \t.data\n\t.align 3\n");
-    lb=fwdlabel();
-    printf("L_%d:\n",lb);
-    if (d) {
-	printf("\t.long\t0x%x,0x%x\n",code_d2(value),code_d1(value));
-    } else {
-	printf("\t.long\t0x%x\n",code_f(value));
-    }
-    if (output_mode==TEXT_EMIT_MODE) {
-	printf(".text\n");
-    } else {
-	text_mode();
-    }
-    printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",rrn,lb,code_base);
-    printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",rrn,lb,code_base,rrn);
-    if (d) {
-	printf("\tlfd %s,0(%s)\n",frn,rrn);
-    } else {
-	printf("\tlfs %s,0(%s)\n",frn,rrn);
-    }
-    free_register(r);
     regv[freg]=1;
 }
 
 
 void code_dneg(int freg,int d)
 { 
-    char *frn = fregister_name(freg);
-    if (is_int_reg(freg)) error(-1);
-    printf("\tfneg %s,%s\n",frn,frn);
+    char *frn;
+    if (d) {
+        code_save_stacks();
+	move_dreg(4+DREG_OFFSET,freg);
+        printf("\tjal dpneg\n");
+        set_dreg(RET_DREGISTER,0);
+    } else {
+        frn = fregister_name(freg);
+        printf("\tfneg %s,%s\n",frn,frn);
+    }
 }
 
 void code_d2i(int freg0)
 { 
-    char *frn;
-    char *crn;
-    int e2 = new_lvar(size_of_double);
-
-    freg0 = use_double(freg0);
-    frn = fregister_name(freg0);
-    creg = use_int(creg);
-    crn = register_name(creg);
-
-    freg = freg0;
-    free_lvar(e2);
-    printf("\tfctiwz  %s,%s\n",frn,frn);
-    lvar_intro(e2);
-    printf("\tstfd  %s,",frn); lvar(e2);
-    lvar_intro(e2+size_of_double-size_of_int);
-    printf("\tlwz %s,",crn); lvar(e2+size_of_double-size_of_int);
+    code_save_stacks();
+    set_dreg(RET_DREGISTER,1);
+    printf("\tjal dptoli\n");
+    set_creg(RET_REGISTER,0);
+    regv[freg]=0;
     regv[creg]=1;
 }
 
-static int i2d_lib_used=0;
-static char *i2d_lib[] = {
-".data",
-/* ".literal8", */
-"        .align 3",
-"__i2dLC0:",
-"        .long   1127219200",
-"        .long   -2147483648",
-".text",
-"        .align 2",
-"i2d_:",
-"        mflr r0",
-"        bcl 20,31,__i2dL1$pb",
-"__i2dL1$pb:",
-"        mflr r10",
-"        mtlr r0",
-"        xoris r3,r3,0x8000",
-"        stw r3,-28(r30)",
-"        lis r0,0x4330",
-"        stw r0,-32(r30)",
-"        lfd f0,-32(r30)",
-"        addis r9,r10,ha16(__i2dLC0-__i2dL1$pb)",
-"        lfd f1,lo16(__i2dLC0-__i2dL1$pb)(r9)",
-"        fsub f1,f0,f1",
-"        blr",
-0
-};
-
 void code_i2d(int creg0)
 { 
-    i2d_lib_used = 1;
-    clear_ptr_cache();
     code_save_stacks();
     set_creg(RET_REGISTER,1);
-    printf("\tbl i2d_\n");
-    set_freg(RET_FREGISTER,0);
+    printf("\tjal litodp\n");
+    set_freg(RET_DREGISTER,0);
     regv[freg]=1;
+    regv[creg]=0;
 }
 
-static int d2u_lib_used=0;
-static char *d2u_lib[] = {
-/* ".literal8", */
-"        .align 3",
-"__d2uLC0:",
-"        .long   1105199104",
-"        .long   0",
-".text",
-"        .align 2",
-"d2u_:",
-"        mflr r0",
-"        bcl 20,31,__d2uL1$pb",
-"__d2uL1$pb:",
-"        mflr r10",
-"        mtlr r0",
-"        addis r9,r10,ha16(__d2uLC0-__d2uL1$pb)",
-"        lfd f0,lo16(__d2uLC0-__d2uL1$pb)(r9)",
-"        fcmpu cr0,f1,f0",
-"        cror 2,1,2",
-"        beq- cr0,__d2uL2",
-"        fctiwz f0,f1",
-"        stfd f0,-32(r30)",
-"        lwz r3,-28(r30)",
-"        blr",
-"__d2uL2:",
-"        addis r9,r10,ha16(__d2uLC0-__d2uL1$pb)",
-"        lfd f0,lo16(__d2uLC0-__d2uL1$pb)(r9)",
-"        fsub f0,f1,f0",
-"        fctiwz f0,f0",
-"        stfd f0,-24(r30)",
-"        lwz r3,-20(r30)",
-"        xoris r3,r3,0x8000",
-"        blr",
-0
-};
-
 void code_d2u(int freg0)
 { 
     code_save_stacks();
-    clear_ptr_cache();
-    d2u_lib_used=1;
-    set_freg(RET_FREGISTER,1);
-    printf("\tbl d2u_\n");
+    set_dreg(RET_DREGISTER,1);
+    printf("\tjal dptoul\n");
     set_creg(RET_REGISTER,0);
     regv[freg]=1;
 }
 
-static int u2d_lib_used=0;
-static char *u2d_lib[] = {
-".data",
-/* ".literal8", */
-"        .align 3",
-"__u2dLC1:",
-"        .long   1127219200",
-"        .long   0",
-".text",
-"        .align 2",
-"u2d_:",
-"        mflr r0",
-"        bcl 20,31,__u2dL2$pb",
-"__u2dL2$pb:",
-"        mflr r10",
-"        mtlr r0",
-"        stw r3,-28(r30)",
-"        lis r0,0x4330",
-"        stw r0,-32(r30)",
-"        lfd f0,-32(r30)",
-"        addis r9,r10,ha16(__u2dLC1-__u2dL2$pb)",
-"        lfd f1,lo16(__u2dLC1-__u2dL2$pb)(r9)",
-"        fsub f1,f0,f1",
-"        blr",
-0
-};
-
 void code_u2d(int creg0)
 { 
     code_save_stacks();
-    clear_ptr_cache();
-    u2d_lib_used = 1;
     set_creg(RET_REGISTER,1);
-    printf("\tbl u2d_\n");
-    set_freg(FREG_FREGISTER,0);
+    printf("\tjal ultodp\n");
+    set_dreg(RET_DREGISTER,0);
     regv[freg]=1;
 }
 
-void code_d2f(int freg) { }
-void code_f2d(int freg) { }
-void code_f2i(int freg) { code_d2i(freg); }
-void code_f2u(int freg) { code_d2u(freg); }
-void code_i2f(int creg) { code_i2d(creg); }
-void code_u2f(int creg) { code_u2d(creg); }
+void code_d2f(int freg) {
+    code_save_stacks();
+    set_dreg(RET_DREGISTER,1);
+    printf("\tjal dptofp\n");
+    set_freg(RET_FREGISTER,0);
+}
+
+void code_f2d(int freg) {
+    code_save_stacks();
+    set_freg(RET_FREGISTER,1);
+    printf("\tjal fptodp\n");
+    set_dreg(RET_DREGISTER,0);
+}
+
+void code_f2i(int freg) {
+    printf("\ttrunc.w.s %s,%s,%s\n",register_name(freg),
+	register_name(freg),register_name(ireg));
+    creg = ireg;
+}
+
+void code_f2u(int freg) {
+    printf("\ttrunc.w.s %s,%s,%s\n",register_name(freg),
+	register_name(freg),register_name(ireg));
+    creg = ireg;
+}
+
+void code_i2f(int creg0) {
+    printf("\tcvt.s.w %s,%s\n",register_name(freg),register_name(freg));
+    creg = freg;
+}
+
+void code_u2f(int creg0) {
+    printf("\tcvt.s.w %s,%s\n",register_name(freg),register_name(freg));
+    creg = freg;
+}
 
 void code_drgvar(int e2,int d,int freg)
 { 
-    int r;
-    r = get_ptr_cache((NMTBL*)cadr(e2));
-    printf("\t%s %s,0(%s)\n",fload(d),fregister_name(freg),register_name(r));
+    char *nm = ((NMTBL*)cadr(e2))->nm;
+    if (d) {
+        printf("\tlw %s,%s\n",dregister_name0(freg),nm);
+        printf("\tlw %s,%s\n",dregister_name1(freg),nm);
+    } else {
+        printf("\tl.s %s,%s\n",fregister_name(freg),nm);
+    }
     regv[freg]=1;
 }
 
 
 void code_drlvar(int e2,int d,int freg)
 { 
-    lvar_intro(e2);
-    printf("\t%s %s,",fload(d),fregister_name(freg)); lvar(e2);
+    if (d) {
+        printf("\tlw %s,\n",dregister_name0(freg)); lvar(e2);
+        printf("\tlw %s,\n",dregister_name1(freg)); lvar(e2+size_of_double/2);
+    } else {
+        printf("\tl.s %s,",fregister_name(freg)); lvar(e2);
+    }
     regv[freg]=1;
 }
 
 void code_cmp_drgvar(int e2,int d)
 { 
-    int r;
-    char *frn=fregister_name(freg);
-    int g=get_dregister(d);
-    char *grn=fregister_name(g);
-    r = get_ptr_cache((NMTBL*)cadr(e2));
-    printf("\t%s %s,0(%s)\n",fload(1),grn,register_name(r));
-    printf("\tfcmpu cr0,%s,%s\n",frn,grn);
-    free_register(g);
-    regv[freg]=0;
+    char *frn;
+    int g;
+    if (d) {
+	code_save_stacks();
+	set_dreg(RET_DREGISTER,1);
+        code_drgvar(e2,d,RET_DREGISTER+2);
+        printf("\tjal dcmp\n");
+	regv[dreg]=0;
+    } else {
+	frn=fregister_name(freg);
+        g=get_dregister(d);
+        code_drgvar(e2,d,g);
+        printf("\tfc.eq.s %s,%s\n",frn,fregister_name(g));
+	free_register(g);
+	regv[freg]=0;
+    }
 }
 
 void code_cmp_drlvar(int e2,int d)
 { 
     char *frn=fregister_name(freg);
-    int g=get_dregister(d);
-    char *grn=fregister_name(g);
+    int g;
+    if (d) {
+	code_save_stacks();
+	set_dreg(RET_DREGISTER,1);
+        code_drgvar(e2,d,RET_DREGISTER+2);
+        printf("\tjal dcmp\n");
+	regv[dreg]=0;
+    } else {
+        g=get_dregister(d);
+        code_drlvar(e2,d,g);
+        printf("\tc.eq.s %s,%s\n",frn,fregister_name(g));
+	free_register(g);
+	regv[freg]=0;
+    }
+}
 
-    lvar_intro(e2);
-    printf("\t%s %s,",fload(1),grn); lvar(e2);
-    printf("\tfcmpu cr0,%s,%s\n",frn,grn);
-    free_register(g);
-    regv[freg]=0;
+static void
+dtosop0(char *opn,int e1,int d,int cmp)
+{
+    char *frn;
+    char *grn;
+    if (d) {
+	code_save_stacks();
+	set_dreg(RET_DREGISTER,1);
+	move_dreg(RET_DREGISTER+2,e1);
+        printf("\tjal %s\n",opn);
+    } else {
+        frn=fregister_name(freg);
+        grn=fregister_name(e1);
+        if (cmp) {
+            printf("\t%s %s,%s\n",opn,frn,grn);
+        } else {
+            printf("\t%s %s,%s,%s\n",opn,frn,frn,grn);
+        }
+    }
+    free_register(e1);
 }
 
+
 void dtosop(int op,int e1)
 { 
-    char *opn="";
-    char *frn=fregister_name(freg);
-    char *grn=fregister_name(e1);
     regv[freg]=1;
     switch(op) {
-    case FADD:
-    case DADD: opn="fadd"; break;
-    case FSUB:
-    case DSUB: opn="fsub"; break;
-    case FDIV:
-    case DDIV: opn="fdiv"; break;
-    case FMUL:
-    case DMUL: opn="fmul"; break;
-    case FCMP:
-    case DCMP: 
-	printf("\tfcmpu cr0,%s,%s\n",frn,grn);
-	free_register(e1);
-	return;
-    case FCMPGE: 
+    case FADD: dtosop0("fadd",e1,0,0); return;
+    case DADD: dtosop0("dpadd",e1,1,0); return;
+    case FSUB: dtosop0("fadd",e1,0,0); return;
+    case DSUB: dtosop0("dpsub",e1,1,0); return;
+    case FDIV: dtosop0("fadd",e1,0,0); return;
+    case DDIV: dtosop0("dpdiv",e1,1,0); return;
+    case FMUL: dtosop0("fadd",e1,0,0); return;
+    case DMUL: dtosop0("dpmul",e1,1,0); return;
     case DCMPGE: 
-	printf("\tfcmpu cr7,%s,%s\n",frn,grn);
-	free_register(e1);
-	return;
+    case DCMP:  dtosop0("dpcmp",e1,1,1); return;
+    case FCMPGE: dtosop0("c.le.s",e1,0,1); return;
+    case FCMP: dtosop0("c.eq.s",e1,0,1); return;
     default:
-	error(-1); return;
+        error(-1); return;
     }
-    printf("\t%s %s,%s,%s\n",opn,frn,frn,grn);
-    regv[freg]=1;
-    free_register(e1);
 }
 
 void
 code_dassop(int op,int d) {
     /* we have lvalue in creg, applied floating value is in freg */
-    char *frn=fregister_name(freg);
-    int  xreg=emit_dpop(d);
+    char *frn;
+    int  xreg;
     char *crn=register_name(creg);
 
-    if (!is_float_reg(freg)) error(-1);
-    printf("\t%s %s,0(%s)\n",fload(d),frn,crn);
-    dtosop(op,xreg);
-    printf("\t%s %s,0(%s)\n",fstore(d),frn,crn);
-    emit_dpop_free(xreg,d);
-    regv[freg]=1;
+    if (d) {
+        xreg=emit_dpop(d);
+        printf("\tlw %s,0(%s)\n",dregister_name0(freg),crn);
+        printf("\tlw %s,%d(%s)\n",dregister_name1(freg),size_of_int,crn);
+        dtosop(op,xreg);
+        printf("\tsw %s,0(%s)\n",dregister_name0(freg),crn);
+        printf("\tsw %s,%d(%s)\n",dregister_name1(freg),size_of_int,crn);
+        emit_dpop_free(xreg,d);
+	creg = dreg;
+    } else {
+        xreg=emit_dpop(d);
+        frn=fregister_name(freg);
+        crn=register_name(creg);
+
+        printf("\tl.s %s,0(%s)\n",frn,crn);
+        dtosop(op,xreg);
+        printf("\ts.s %s,0(%s)\n",frn,crn);
+        emit_dpop_free(xreg,d);
+	creg = freg;
+    }
+    regv[creg]=1;
 }
 
 
@@ -2652,33 +2665,42 @@
     char *frn;
     char *crn;
     int  g;
-    char *grn,*drn;
-    int r;
-    r = get_ptr_cache(&float_one);
-    float_one_lib_used=1;
+    char *grn;
 
-    if (car(e2)==DREGISTER||car(e2)==FREGISTER) {
-	error(-1); /* unspported now */
-    }
     g_expr(e2);
 
-    crn=register_name(creg);
-    frn=fregister_name(freg);
-    drn=register_name(r);
-    grn=fregister_name(g=get_dregister(d));
+    if (d) {
+        crn=register_name(creg);
+        frn=fregister_name(freg);
 
-    printf("\t%s %s,0(%s)\n",fload(d),frn,crn);
-    printf("\tlfs %s,0(%s)\n",grn,drn);
-    if (caddr(e1)>0)
-	printf("\tfadd %s,%s,%s\n",frn,frn,grn);
-    else
-	printf("\tfsub %s,%s,%s\n",frn,frn,grn);
-    if (!is_float_reg(freg)) error(-1);
-    printf("\t%s %s,0(%s)\n",fstore(d),frn,crn);
-    free_register(g);
-    regv[freg]=1;
-    regv[ireg]=0;
-    creg = freg;
+	code_save_stacks();
+        set_dreg(RET_DREGISTER,0);
+        printf("\tlw $4,0(%s)\n",crn);
+        printf("\tlw $5,%d(%s)\n",size_of_int,crn);
+        printf("\tli.d $6,1.0\n");
+        if (caddr(e1)>0)
+            printf("\tjal dpadd\n");
+        else
+            printf("\tjal dpsub\n");
+        printf("\tsw $2,0(%s)\n",crn);
+        printf("\tsw $3,%d(%s)\n",size_of_int,crn);
+	creg = dreg;
+    } else {
+        crn=register_name(creg);
+        frn=fregister_name(freg);
+        grn=fregister_name(g=get_dregister(d));
+
+        printf("\tl.s %s,0(%s)\n",frn,crn);
+        printf("\tli.s %s,1.0\n",grn);
+        if (caddr(e1)>0)
+            printf("\tfadd %s,%s,%s\n",frn,frn,grn);
+        else
+            printf("\tfsub %s,%s,%s\n",frn,frn,grn);
+        printf("\ts.s %s,0(%s)\n",frn,crn);
+        free_register(g);
+	creg = freg;
+    }
+    regv[creg]=1;
 }
 
 void
@@ -2686,57 +2708,76 @@
     char *frn;
     char *crn;
     int  g;
-    char *grn,*drn;
-    int r;
-    r = get_ptr_cache(&float_one);
-    float_one_lib_used=1;
+    char *grn;
 
-    if (car(e2)==DREGISTER||car(e2)==FREGISTER) {
-	error(-1); /* unspported now */
-    }
     g_expr(e2);
 
-    crn=register_name(creg);
-    frn=fregister_name(freg);
-    drn=register_name(r);
-    grn=fregister_name(g=get_dregister(d));
+    if (d) {
+        crn=register_name(creg);
+	g = get_dregister(d);
+        set_dreg(RET_DREGISTER,0);
+        printf("\tlw $4,0(%s)\n",crn);
+        printf("\tlw $5,%d(%s)\n",size_of_int,crn);
+	move_dreg(g,4+DREG_OFFSET);
+        printf("\tli.d $6,1.0\n");
+        if (caddr(e1)>0)
+            printf("\tjal dpadd\n");
+        else
+            printf("\tjal dpsub\n");
+        set_dreg(RET_DREGISTER,0);
+        printf("\tsw $2,0(%s)\n",crn);
+        printf("\tsw $3,%d(%s)\n",size_of_int,crn);
+        free_register(freg);
+        set_dreg(g,0);
+	creg = g;
+    } else {
+        crn=register_name(creg);
+        frn=fregister_name(freg);
+        grn=fregister_name(g=get_dregister(d));
 
-    printf("\t%s %s,0(%s)\n",fload(d),frn,crn);
-    printf("\tlfs %s,0(%s)\n",grn,drn);
-    if (caddr(e1)>0)
-	printf("\tfadd %s,%s,%s\n",grn,frn,grn);
-    else
-	printf("\tfsub %s,%s,%s\n",grn,frn,grn);
-    if (!is_float_reg(freg)) error(-1);
-    printf("\t%s %s,0(%s)\n",fstore(d),grn,crn);
-    free_register(g);
-    regv[freg]=1;
-    regv[ireg]=0;
-    creg = freg;
+        printf("\tl.s %s,0(%s)\n",frn,crn);
+        printf("\tli.s %s,1.0\n",grn);
+        if (caddr(e1)>0)
+            printf("\tfadd %s,%s,%s\n",frn,frn,grn);
+        else
+            printf("\tfsub %s,%s,%s\n",frn,frn,grn);
+        printf("\ts.s %s,0(%s)\n",grn,crn);
+        free_register(g);
+	creg = freg;
+    }
+    regv[creg]=1;
+
 }
 
 void
 drexpr(int e1, int e2,int l1, int op)
 {       
-    g_expr(list3(((op==DOP+GE)?DCMPGE:DCMP),e1,e2));
+    g_expr(list3(((op==FOP+EQ||op==FOP+NEQ)?DCMP:FCMPGE),e1,e2));
     switch(op) {
-	case DOP+GE:
-	case FOP+GE:
-	    printf("\tcror 2,29,30\n");
-	    printf("\tbne\tcr0,L_%d\n",l1);
-	    break;
-	case DOP+GT:
-	case FOP+GT:
-	    printf("\tble\tcr0,L_%d\n",l1);
-	    break;
-	case DOP+EQ:
-	case FOP+EQ:
-	    printf("\tbne\tcr0,L_%d\n",l1);
-	    break;
-	case DOP+NEQ:
-	case FOP+NEQ:
-	    printf("\tbeq\tcr0,L_%d\n",l1);
-	    break;
+        case DOP+GE:
+            printf("\tbgez\tL_%d\n",l1);
+            break;
+        case DOP+GT:
+            printf("\tbltz\tL_%d\n",l1);
+            break;
+        case DOP+EQ:
+            printf("\tbeq\tL_%d\n",l1);
+            break;
+        case DOP+NEQ:
+            printf("\tbne\tL_%d\n",l1);
+            break;
+        case FOP+GE:
+            printf("\tbc1tl\tL_%d\n",l1);
+            break;
+        case FOP+GT:
+            printf("\tbc1tl\tL_%d\n",l1);
+            break;
+        case FOP+EQ:
+            printf("\tbc1f\tL_%d\n",l1);
+            break;
+        case FOP+NEQ:
+            printf("\tbc1f\tL_%d\n",l1);
+            break;
     }
 }
 
@@ -2746,7 +2787,7 @@
     xreg=pop_fregister();
     if (xreg<= -REG_LVAR_OFFSET) {
 	reg = get_dregister(d);
-        code_drlvar(REG_LVAR_OFFSET+xreg,1,reg);
+        code_drlvar(REG_LVAR_OFFSET+xreg,d,reg);
 	free_lvar(REG_LVAR_OFFSET+xreg);
 	regv[reg]=1; xreg=reg;
     }
@@ -2762,7 +2803,7 @@
 { 
     int new_reg;
     if (freg_sp>MAX_MAX) error(-1);
-    new_reg = get_dregister(1);
+    new_reg = get_dregister(d);
     freg_stack[freg_sp++] = freg;     /* push するかわりにレジスタを使う */
     creg = freg = new_reg;
     regv[freg]=1;
@@ -2779,10 +2820,17 @@
             reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET;
         }
     }
+    for(i=0;i<dreg_sp;i++) {
+        if ((reg=dreg_stack[i])>=0) {
+            code_dassign_lvar(
+                (dreg_stack[i]=new_lvar(size_of_double)),reg,1); 
+            dreg_stack[i]= dreg_stack[i]-REG_LVAR_OFFSET;
+        }
+    }
     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]=new_lvar(size_of_float)),reg,0); 
             freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET;
         }
     }
@@ -2799,13 +2847,9 @@
 void
 code_closing()
 {
-    if (d2u_lib_used) emit_lib(d2u_lib);
-    if (u2d_lib_used) emit_lib(u2d_lib);
-    if (float_one_lib_used) emit_lib(float_one_lib);
-    if (float_zero_lib_used) emit_lib(float_zero_lib);
-    if (i2d_lib_used) emit_lib(i2d_lib);
     global_table();
     /* printf("\t.ident \"Micro-C compiled\"\n"); */
+    fclose(asi);
 }
 
 /* end */