changeset 381:5a9a27fadb9b

ARM continue...
author kono
date Mon, 19 Jul 2004 15:16:26 +0900
parents c9ae2ea267c2
children 832e1f6bba82
files Changes mc-code-arm.c
diffstat 2 files changed, 455 insertions(+), 550 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Sun Jul 18 20:47:25 2004 +0900
+++ b/Changes	Mon Jul 19 15:16:26 2004 +0900
@@ -5878,3 +5878,4 @@
 Sun Jul 18 20:45:48 JST 2004
 
 なかなか終らないね。GBAとLinux Zaurus と両方だからな。
+(やっぱ ARM に手をつけたのは失敗でした)
--- a/mc-code-arm.c	Sun Jul 18 20:47:25 2004 +0900
+++ b/mc-code-arm.c	Mon Jul 19 15:16:26 2004 +0900
@@ -220,6 +220,9 @@
 
 
 #if FLOAT_CODE
+
+#define dsuffix(d) (d?'d':'s')
+
 #define  use_float(d,reg) if (reg==USE_CREG) arch_mode&UseFPP?use_float0():(reg=d?use_double0():use_float0())
 static
 int use_float0() { 
@@ -3732,18 +3735,18 @@
 }
 
 void
-code_d2i(int reg)
+code_d2i0(int reg,int d)
 { 
     int lreg;
     if (!(arch_mode&UseFPP)) {
-	use_float(1,reg);
+	use_float(d,reg);
 	code_save_stacks();
 	clear_ptr_cache();
-	set_dreg(DREGISTER_OPERAND,1);
-	extern_conv("__fixdfsi");
+	set_dreg(d?DREGISTER_OPERAND:FREGISTER_OPERAND,1);
+	extern_conv(d?"__fixdfsi":"__fixsfsi");
 	set_ireg(RET_REGISTER,0);
     } else {
-	use_float(1,reg);
+	use_float(d,reg);
 	lreg = get_register();
 	printf("\tfixz\t%s, %s\n",register_name(lreg),register_name(reg));
 	set_ireg(lreg,0);
@@ -3752,27 +3755,28 @@
 }
 
 void
-code_i2d(int reg)
+code_i2d0(int reg,int d)
 { 
     int lreg;
     if (!(arch_mode&UseFPP)) {
 	set_ireg(REGISTER_OPERAND,1);
 	code_save_stacks();
 	clear_ptr_cache();
-	extern_conv("__floatsidf");
-	set_dreg(RET_DREGISTER,0);
-	use_float(1,reg);
+	extern_conv(d?"__floatsidf":"__floatsisf");
+	set_dreg(d?RET_DREGISTER:RET_FREGISTER,0);
+	use_float(d,reg);
     } else {
 	use_int(reg);
 	lreg = get_dregister(1);
-	printf("\tfltd\t%s, %s\n",register_name(lreg),register_name(reg));
+	printf("\tflt%c\t%s, %s\n",dsuffix(d),
+		register_name(lreg),register_name(reg));
 	set_dreg(lreg,0);
     }
     return;
 }
 
 void
-code_d2u(int reg)
+code_d2u0(int reg,int d)
 { 
     int lreg,label,disp,reg;
     char *lrn,*frn,*crn;
@@ -3780,11 +3784,12 @@
 	use_float(1,reg);
 	code_save_stacks();
 	clear_ptr_cache();
-	set_dreg(DREGISTER_OPERAND,1);
-	extern_conv("__fixunsdfsi");
+	set_dreg(d?DREGISTER_OPERAND:FREGISTER_OPERAND,1);
+	extern_conv(d?"__fixunsdfsi":"__fixunssfsi");
 	set_ireg(RET_REGISTER,0);
     } else {
 	//   u = (d>2.1e9)?((int)(d-2.1e9)^2147483648):(int)d
+        if (!d) printf("\tmvfd    %s, %s\n",frn,frn);
 	emit_dpush(1);
 	code_dconst(dlist2(DCONST,2.147483648e9),USE_CREG,1);
 	lrn = register_name(lreg = emit_dpop());
@@ -3806,7 +3811,7 @@
 }
 
 void
-code_u2d(int reg)
+code_u2d0(int reg,int d)
 { 
     int tmp;
     if (!(arch_mode&UseFPP)) {
@@ -3815,17 +3820,26 @@
 	code_assign_lvar(tmp,REGISTER_OPERAND,0);
 	code_save_stacks();
 	clear_ptr_cache();
-	extern_conv("__floatsidf");
+	extern_conv(d?"__floatsidf":"__floatsisf");
 	code_rlvar(tmp,REGISTER_OPERAND);
 	printf("\tcmp\t%s, #0\n",register_name(REGISTER_OPERAND));
 	printf("\tbge\t1f\n");
-	code_double_lib_c("__adddf3",RET_DREGISTER,RET_DREGISTER,4.29496729600000000000e9);
+	if (d)
+	    code_double_lib_c("__adddf3",RET_DREGISTER,RET_DREGISTER,4.29496729600000000000e9);
+	else 
+	    code_double_lib_c("__addsf3",RET_FREGISTER,RET_FREGISTER,4.29496729600000000000e9);
 	printf("1:\n");
-	set_dreg(RET_DREGISTER,0);
+	set_dreg(d?RET_DREGISTER:RET_FREGISTER,0);
 	if (reg!=USE_CREG) {
-	    use_float(1,reg);
-	    if (reg!=RET_DREGISTER) {
-		lmove(reg,RET_DREGISTER);
+	    use_float(d,reg);
+	    if (d) {
+		if (reg!=RET_DREGISTER) {
+		    lmove(reg,RET_DREGISTER);
+		}
+	    } else {
+		if (reg!=RET_FREGISTER) {
+		    code_register(reg,RET_FREGISTER);
+		}
 	    }
 	}
 	free_lvar(tmp);
@@ -3842,6 +3856,8 @@
 	lrn = register_name(lreg = emit_dpop());
 	printf("\tadfd\t%s, %s, %s\n",frn,frn,lrn);
 	printf("1:\n");
+	if (!d)
+	    printf("\tmvfs\t%s, %s\n",frn,frn);
 	emit_dpop_free(lreg);
     }
     return;
@@ -3882,181 +3898,107 @@
 }
 
 void
+code_d2i(int reg) {
+    code_d2i0(reg,1);
+}
+
+void
+code_d2u(int reg) {
+    code_d2u0(reg,1);
+}
+
+void
 code_f2i(int reg) {
-#if 0
-    int tmp=new_lvar(SIZE_OF_INT);
-    use_int(reg);
-    printf("\ttrunc.w.s %s,%s,%s\n",register_name(freg),
-	register_name(freg),register_name(ireg));
-    code_dassign_lvar(tmp,freg,1);
-    code_rlvar(tmp,reg);
-    free_lvar(tmp);
-#else
-    use_int(reg);
-    printf("\ttrunc.w.s %s,%s,%s\n",fregister_name(freg),
-	fregister_name(freg),register_name(ireg));
-    printf("\tmfc1    %s,%s\n",register_name(reg),fregister_name(freg));
-#endif
+    code_d2i0(reg,0);
 }
 
 void
 code_f2u(int reg) {
-    int freg0 = freg;
-    int freg1 = get_dregister(0);
-    int freg2 = get_dregister(0);
-    int ireg1 = get_register();
-    char *fr0 = fregister_name(freg0);
-    char *fr1 = fregister_name(freg1);
-    char *fr2 = fregister_name(freg2);
-    char *r1 = register_name(ireg1);
-    char *r0;
-    int lb1,lb2;
-
-    use_int(reg);
-    r0 = register_name(ireg);
-    
-    printf("\tli.s    %s,2.14748364800000000000e9\n",fr1);
-    printf("\tc.le.s  %s,%s\n",fr1,fr0);
-    printf("\tbc1t    $L_%d\n",lb1=fwdlabel());
-    printf("\ttrunc.w.s %s,%s,%s\n",fr2,fr0,r0);
-    printf("\tmfc1    %s,%s\n",r0,fr2);
-    printf("\tj       $L_%d\n",lb2=fwdlabel());
-    printf("\t.p2align 2\n");
-    fwddef(lb1);
-    printf("\tsub.s   %s,%s,%s\n",fr0,fr0,fr1);
-    printf("\tli      %s,-2147483648                  # 0x80000000\n",
-	r0);
-    printf("\ttrunc.w.s %s,%s,%s\n",fr1,fr0,r1);
-    printf("\tmfc1    %s,%s\n",r1,fr1);
-    printf("\tor      %s,%s,%s\n",r0,r1,r0);
-    fwddef(lb2);
-    free_register(freg1);
-    free_register(freg2);
-    free_register(ireg1);
+    code_d2u0(reg,0);
+}
+
+void
+code_i2d(int reg) {
+    code_i2f0(reg,1);
 }
 
 void
 code_i2f(int reg) {
-     int n = new_lvar(SIZE_OF_FLOAT);
-     use_int(reg);
-     code_assign_lvar(n,reg,0);
-     reg = USE_CREG;
-     use_float(0,reg);
-     code_drlvar(n,0,reg);
-     printf("\tcvt.s.w %s,%s\n",register_name(freg),register_name(freg));
-     free_lvar(n);
+    code_i2f0(reg,0);
+}
+
+void
+code_u2d(int reg) {
+    code_u2f0(reg,1);
 }
 
 void
 code_u2f(int reg) {
-     // int n = new_lvar(SIZE_OF_FLOAT);
-     int /*reg0,*/reg1;
-     int lb1,lb2;
-     char *frn,*r0,*r1;
-     // code_assign_lvar(n,ireg,0);
-     printf("\tbltz    %s,$L_%d\n",r0=register_name(ireg),lb1=fwdlabel());
-     use_float(0,reg);
-     // code_drlvar(n,0,reg);
-     // r0= register_name(reg0 = get_register());
-     r1= register_name(reg1 = get_register());
-     frn = fregister_name(reg);
-    printf("\tmtc1     %s,%s\n",r0,frn);
-     printf("\tcvt.s.w %s,%s\n",frn,frn);
-     printf("\tj       $L_%d\n",lb2=fwdlabel());
-    printf("\t.p2align 2\n");
-    fwddef(lb1);
-    printf("\tandi    %s,%s,0x1\n",r1,r0);
-    printf("\tsrl     %s,%s,1\n",r0,r0);
-    printf("\tor      %s,%s,%s\n",r1,r1,r0);
-    printf("\tmtc1    %s,%s\n",r1,frn);
-    printf("\tcvt.s.w %s,%s\n",frn,frn);
-    printf("\tadd.s   %s,%s,%s\n",frn,frn,frn);
-    fwddef(lb2);
-    // free_register(reg0);
-    free_register(reg1);
-}
+    code_u2f0(reg,0);
+}
+
+static char *
+fload(int d)  { return d?"ldfd":"ldfs"; }
+
+static char *
+fstore(int d) { return d?"stfd":"stfs"; }
 
 void
 code_drgvar(int e2,int d,int freg)
 { 
-    if (d) {
-         code_lrgvar(e2,freg);
-         set_double(freg);
-	 return;
-    }
-    use_float(d,freg);
-    code_ldf("l.s",fregister_name(freg),cadr(e2),
-        get_ptr_cache((NMTBL*)caddr(e2)));
+    if (!(arch_mode&UseFPP)) {
+	if (d) {
+	     code_lrgvar(e2,freg);
+	     set_double(freg);
+	     return;
+	} else {
+	     code_rgvar(e2,freg);
+	     set_float(freg);
+	     return;
+	}
+    } else {
+	use_float(d,freg);
+	code_ldf(fload(d),fregister_name(freg),cadr(e2),
+	    get_ptr_cache((NMTBL*)caddr(e2)));
+    }
 }
 
 
 void
 code_drlvar(int e2,int d,int freg)
 { 
-    if (d) {
-         code_lrlvar(e2,freg);
-         set_double(freg);
-	 return;
-    }
-    use_float(d,freg);
-    lvar_intro(e2);
-    printf("\tl.s %s,",fregister_name(freg)); lvar(e2,"");
+    if (!(arch_mode&UseFPP)) {
+	if (d) {
+	     code_lrlvar(e2,freg);
+	     set_double(freg);
+	     return;
+	} else {
+	     code_rlvar(e2,freg);
+	     set_float(freg);
+	     return;
+	}
+    } else {
+	use_float(d,freg);
+	lvar_intro(e2);
+	printf("\t%s\t%s,",fload(d),fregister_name(freg)); 
+	lvar(e2,d?"@ double":"@ float");
+    }
 }
 
 void
 code_cmp_drgvar(int e2,int reg,int d,int label,int cond)
 { 
-    char *frn,*fr1;
-    int g,cmpreg;
     use_float(d,reg);
-
-    if (d) {
-	code_save_stacks();
-	set_dreg(RET_DREGISTER,0);
-        code_drgvar(e2,d,RET_DREGISTER);
-	clear_ptr_cache();
-	printf("\tmove  $6,$0\n");
-	printf("\tmove  $7,$0\n");
-	extern_conv("dcmp");
-	cmpreg = 2;
-    } else {
-        code_drgvar(e2,d,USE_CREG);
-	frn = fregister_name(freg);
-	fr1=fregister_name(g = get_dregister(0));
-	printf("\tmtc1   $0,%s\n",fr1);
-        printf("\tfc.eq.s %s,%s\n",frn,fr1);
-	cmpreg = CMP_C1T;
-	free_register(g);
-    }
-    jcond(label,cond);
+    code_drgvar(e2,d,reg);
+    code_cmp_dregister(reg,d,label,cond);
 }
 
 void
 code_cmp_drlvar(int e2,int reg,int d,int label,int cond)
 { 
-    char *frn,*fr1;
-    int g,cmpreg;
     use_float(d,reg);
-
-    if (d) {
-	code_save_stacks();
-	set_dreg(RET_DREGISTER,0);
-        code_drlvar(e2,d,RET_DREGISTER);
-	clear_ptr_cache();
-	printf("\tmove  $6,$0\n");
-	printf("\tmove  $7,$0\n");
-	extern_conv("dcmp");
-	cmpreg = 2;
-    } else {
-        code_drlvar(e2,d,USE_CREG);
-	frn = fregister_name(freg);
-	fr1=fregister_name(g = get_dregister(0));
-	printf("\tmtc1   $0,%s\n",fr1);
-        printf("\tfc.eq.s %s,%s\n",frn,fr1);
-	cmpreg = CMP_C1T;
-	free_register(g);
-    }
-    jcond(label,cond);
+    code_drlvar(e2,d,reg);
+    code_cmp_dregister(reg,d,label,cond);
 }
 
 static void
@@ -4088,7 +4030,41 @@
 
 
 void
-dtosop(int op,int reg,int e1)
+dtosop_d(int op,int reg,int e1)
+{ 
+    char *opn="";
+    char *opc="";
+    char *grn,*frn;
+    int d;
+    int cmp=0;
+    int reg0=reg;
+
+    d=(op<FOP);
+    use_float(d,reg);
+    switch(op) {
+    case DADD:	opc="__adddf3"; break;
+    case DSUB:	opc="__subdf3"; break;
+    case DDIV:	opc="__divdf3"; break;
+    case DMUL:	opc="__muldf3"; break;
+    case DCMPGE:	 opc="__gedf2"; break;
+    case DCMP:	opc="__gtdf2"; break;
+    case FADD:	opc="__addsf3"; break;
+    case FSUB:	opc="__subsf3"; break;
+    case FDIV:	opc="__divsf3"; break;
+    case FMUL:	opc="__mulsf3"; break;
+    case FCMPGE:	 opc="__gesf2"; break;
+    case FCMP:	opc="__gtsf2"; break;
+    default:
+	error(-1); return;
+    }
+    if (d)
+        code_double_lib(opc,reg0==USE_CREG?RET_DREGISTER:reg,reg,e1);
+    else
+        code_float_lib(opc,reg0==USE_CREG?RET_FREGISTER:reg,reg,e1);
+}
+
+void
+dtosop_f(int op,int reg,int e1)
 { 
     char *opn="";
     char *opc="";
@@ -4099,43 +4075,42 @@
 
     d=(op<FOP);
     use_float(d,reg);
-    if (d) {
-	switch(op) {
-	case DADD: opc="dpadd"; break;
-	case DSUB: opc="dpsub"; break;
-	case DDIV: opc="dpdiv"; break;
-	case DMUL: opc="dpmul"; break;
-	case DCMPGE:
-	case DCMP:  opc="dpcmp"; break;
-	default:
-	    error(-1); return;
-	}
-        code_double_lib(opc,reg0==USE_CREG?RET_DREGISTER:reg,reg,e1);
+    switch(op) {
+    case DADD: opn="adfd"; break;
+    case DSUB: opn="sufd"; break;
+    case DDIV: opn="fdvd"; break;
+    case DMUL: opn="fmld"; break;
+    case DCMPGE:
+    case DCMP:  opn="cmfe"; cmp=1; break;
+    case FADD: opn="adfs"; break;
+    case FSUB: opn="sufs"; break;
+    case FDIV: opn="fdvs"; break;
+    case FMUL: opn="fmls"; break;
+    case FCMPGE:
+    case FCMP:  opn="cmfe"; cmp=1; break;
+    default:
+	error(-1); return;
+    }
+    grn = fregister_name(e1);
+    frn = fregister_name(reg);
+    if (cmp) {
+      printf("\t%s\t%s, %s\n",opn,frn,grn);
     } else {
-	switch(op) {
-	case FADD: opn="add.s"; break;
-	case FSUB: opn="sub.s"; break;
-	case FDIV: opn="div.s"; break;
-	case FMUL: opn="mul.s"; break;
-	case FCMP: opn="c.lt.s"; cmp=1; break;
-	case FCMPGE: opn="c.le.s"; cmp=1; break;
-	case FCMPEQ: opn="c.eq.s"; cmp=1; break;
-	default:
-	    error(-1); return;
-	}
-        grn = fregister_name(e1);
-        frn = fregister_name(reg);
-        if (cmp) {
-	  cmpreg=CMP_C1T;
-	  printf("\t%s %s,%s\n",opn,frn,grn);
-        } else {
-	  printf("\t%s %s,%s,%s\n",opn,frn,frn,grn);
-        }
+      printf("\t%s\t%s, %s, %s\n",opn,frn,frn,grn);
     }
 }
 
 void
-code_dassop(int op,int reg,int d) {
+dtosop(int op,int reg,int e1)
+{
+    if (!(arch_mode&UseFPP))
+	dtosop_d(op,reg,e1);
+    else
+	dtosop_f(op,reg,e1);
+}
+
+void
+code_dassop_d(int op,int reg,int d) {
     /* we have lvalue in creg, applied floating value is in freg */
     //  (*creg) op = pop()
     int  xreg;
@@ -4144,56 +4119,101 @@
     int edx,edx0=-1;
     int reg0=reg;
 
-    if (!d) {
-      xreg=emit_dpop(d);
-      crn=register_name(ireg);
-      use_float(d,reg);
-      frn  =fregister_name(reg);
-
-      printf("\tl.s %s,0(%s)\n",frn,crn);
-      dtosop(op,reg,xreg);
-      printf("\ts.s %s,0(%s)\n",frn,crn);
-      emit_dpop_free(xreg,d);
+    xreg = d?emit_pop(0):emit_lpop(0);       /* pop e3 value */
+    if (!is_int_reg(creg)) error(-1);
+    edx = ireg;
+    emit_push();
+    use_float(d,reg);
+    if (d) {
+	if (regv_l(lreg)==edx || regv_h(lreg)==edx) {
+	    edx0 = get_register(); if(!edx0) error(-1);
+	    printf("# dassop\n\tmov %s,%s\n",
+		register_name(edx0),register_name(edx));
+	    edx = edx0;
+	}
+	lload(edx,reg,0);
+	dtosop(op,USE_CREG,xreg);
+	if (lreg!=RET_DREGISTER) error(-1);
+	use_reg(lreg);
+	edx = emit_pop(0);
+	code_lassign(edx,RET_DREGISTER);
+	if (edx0!=-1)
+	    free_register(edx0);
+	emit_pop_free(edx);
+	emit_lpop_free(xreg);
+	if (reg0!=USE_CREG && reg!=RET_DREGISTER)
+	    lmove(reg,RET_DREGISTER);
+	set_double(reg);
     } else {
-      xreg = emit_lpop(0);       /* pop e3 value */
-      if (!is_int_reg(creg)) error(-1);
-      edx = ireg;
-      emit_push();
-      use_float(d,reg);
-      if (regv_l(lreg)==edx || regv_h(lreg)==edx) {
-	edx0 = get_register(); if(!edx0) error(-1);
-	printf("# dassop\n\tmove %s,%s\n",register_name(edx0),register_name(edx));
-	edx = edx0;
-      }
-      lload(edx,reg,0);
-      dtosop(op,USE_CREG,xreg);
-      if (lreg!=RET_DREGISTER) error(-1);
-      use_reg(lreg);
-      edx = emit_pop(0);
-      code_lassign(edx,RET_DREGISTER);
-      if (edx0!=-1)
-	free_register(edx0);
-      emit_pop_free(edx);
-      emit_lpop_free(xreg);
-      if (reg0!=USE_CREG && reg!=RET_DREGISTER)
-	lmove(reg,RET_DREGISTER);
-      set_double(reg);
-    }
+	if (freg==edx) {
+	    edx0 = get_register(); if(!edx0) error(-1);
+	    printf("# dassop\n\tmov %s,%s\n",
+		register_name(edx0),register_name(edx));
+	    edx = edx0;
+	}
+	code_rindirect(edx,reg,0,0,0);
+	dtosop(op,USE_CREG,xreg);
+	use_reg(freg);
+	edx = emit_pop(0);
+	code_assign(edx,RET_FREGISTER);
+	if (edx0!=-1)
+	    free_register(edx0);
+	emit_pop_free(edx);
+	emit_pop_free(xreg);
+	if (reg0!=USE_CREG && reg!=RET_DREGISTER)
+	    code_register(RET_DREGISTER,reg);
+	set_float(reg);
+    }
+}
+
+void
+code_dassop_f(int op,int reg,int d) {
+    /* we have lvalue in creg, applied floating value is in freg */
+    //  (*creg) op = pop()
+    int  xreg;
+    char *crn;
+    char *frn;
+    int edx,edx0=-1;
+    int reg0=reg;
+
+    xreg=emit_dpop(d);
+    crn=register_name(ireg);
+    use_float(d,reg);
+    frn  =fregister_name(reg);
+
+    code_ldf(fload(d),fregister_name(freg),0,ireg);
+    dtosop(op,reg,xreg);
+    code_ldf(fstore(d),fregister_name(freg),0,ireg);
+    emit_dpop_free(xreg,d);
+}
+
+void
+code_dassop(int op,int reg,int d) {
+    if (!(arch_mode&UseFPP))
+	code_dassop_d(op,reg,d);
+    else
+	code_dassop_d(op,reg,d);
 }
 
 void
 code_register_dassop(int reg,int op,int d) {
     // reg op= dpop()
     int  xreg;
-    if (!d) {
-      xreg=emit_dpop(d);
-      dtosop(op,reg,xreg);
-      emit_dpop_free(xreg,d);
+    if (!(arch_mode&UseFPP)) {
+	if (!d) {
+	    xreg=emit_pop(0);
+	    dtosop(op,reg,xreg);
+	    emit_pop_free(xreg);
+	} else {
+	    xreg=emit_lpop();
+	    dtosop(op,reg,xreg);
+	    emit_lpop_free(xreg);
+	    set_double(lreg);
+	}
     } else {
-       xreg=emit_lpop();
-       dtosop(op,reg,xreg);
-       emit_lpop_free(xreg);
-       set_double(lreg);
+	xreg=emit_dpop(d);
+	dtosop(op,reg,xreg);
+	emit_dpop_free(xreg,d);
     }
 }   
 
@@ -4201,15 +4221,15 @@
 code_dload_1(int d)
 {
     int g = get_dregister(d);
-    if (d)
+    if (!(arch_mode&UseFPP)) {
 	error(-1);
-    else
-	printf("\tli.s %s,1.0\n",fregister_name(g));
+    }
+    printf("\tmvf%c\t%s,#1\n",dsuffix(d),fregister_name(g));
     return g;
 }
 
 void
-code_dpreinc(int e1,int e2,int d,int reg) {
+code_dpreinc_d(int e1,int e2,int d,int reg) {
     char *frn;
     char *crn;
     int  g,xreg;
@@ -4218,36 +4238,33 @@
 
     if (!d) {
 	if (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",dir>0?"add.s":"sub.s",crn,crn,grn);
-	    if (use && reg!=cadr(e2))
-		printf("\tmov.s %s,%s\n",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("\tl.s %s,0(%s)\n",frn,crn);
-	    printf("\t%s %s,%s,%s\n",dir>0?"add.s":"sub.s",frn,frn,grn);
-	    printf("\ts.s %s,0(%s)\n",frn,crn);
+	    use_float(d,reg);
+	    code_save_stacks();
+	    code_float_lib_c("__addsf3",cadr(e2),cadr(e2),dir);
+	    if (reg!=cadr(e2)) code_register(cadr(e2),reg);
+	    return;
+	} 
+	g_expr(e2);
+	if(!is_int_reg(creg)) error(-1);
+	xreg = ireg;
+	emit_push();
+	code_save_stacks();
+	code_rindirect(xreg,FREGISTER_OPERAND,0,0,0);
+	code_double_lib_c("__addsf3",DREGISTER_OPERAND,RET_DREGISTER,dir);
+	xreg = emit_pop(0);
+	code_assign_register(xreg,RET_DREGISTER);
+	if (use) {
+	    if (reg==USE_CREG)
+		set_freg(RET_FREGISTER,0);
+	    else
+		code_register(RET_DREGISTER,reg);
 	}
-	free_register(g);
+	emit_pop_free(xreg);
     } else {
 	if (car(e2)==DREGISTER) {
 	    use_float(d,reg);
 	    code_save_stacks();
-	    code_double_lib_c("dpadd",cadr(e2),cadr(e2),dir);
+	    code_double_lib_c("__adddf3",cadr(e2),cadr(e2),dir);
 	    if (reg!=cadr(e2)) lmove(reg,cadr(e2));
 	    return;
 	} 
@@ -4257,7 +4274,7 @@
 	emit_push();
 	code_save_stacks();
 	lload(xreg,DREGISTER_OPERAND,0);
-	code_double_lib_c("dpadd",DREGISTER_OPERAND,RET_DREGISTER,dir);
+	code_float_lib_c("__adddf3",DREGISTER_OPERAND,RET_DREGISTER,dir);
 	xreg = emit_pop(0);
 	lstore(xreg,RET_DREGISTER);
 	if (use) {
@@ -4271,7 +4288,7 @@
 }
 
 void
-code_dpostinc(int e1,int e2,int d,int reg) {
+code_dpostinc_d(int e1,int e2,int d,int reg) {
     char *frn;
     char *crn;
     int  g,xreg;
@@ -4280,35 +4297,45 @@
 
     if (!d) {
 	if (car(e2)==FREGISTER) {
-	    crn=register_name(cadr(e2));
-	    grn=fregister_name(g=code_dload_1(d));
+	    xreg = cadr(e2);
+	    code_float_lib_c("__addsf3",xreg,RET_DREGISTER,dir);
+	    //    xreg は increment する
+            //    USE_CREG だと increment する前の値を creg にセット
+	    //    reg が指定されていれば、それに前の値をセット
 	    if (reg==USE_CREG) {
-		reg=get_dregister(d); if (!reg) error(-1);
+		use_float(d,reg);
+		if (reg==RET_FREGISTER) {
+		    reg = get_register(d);
+		}
 		set_freg(reg,0);
 	    }
-	    frn=fregister_name(reg);
-	    if (use && reg!=cadr(e2))
-		printf("\tmov.s %s,%s\n",frn,crn);
-	    printf("\t%s %s,%s,%s\n",dir>0?"add.s":"sub.s",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("\tl.s %s,0(%s)\n",frn,crn);
-	    printf("\t%s %s,%s,%s\n",dir>0?"add.s":"sub.s",grn,frn,grn);
-	    printf("\ts.s %s,0(%s)\n",grn,crn);
+	    g = list3(reg,0,xreg);
+	    g = list3(xreg,g,RET_FREGISTER);
+	    parallel_rassign(g);
+	    return;
+	} 
+	g_expr(e2);
+	if(!is_int_reg(creg)) error(-1);
+	xreg = ireg;
+	emit_push();
+	code_save_stacks();
+	use_float(0,reg);
+	code_rindirect(xreg,FREGISTER_OPERAND,0,0,0);
+	code_float_lib_c("__addsf3",DREGISTER_OPERAND,RET_DREGISTER,dir);
+	xreg = emit_pop(0);
+	emit_push();
+	if (use) {
+	    use_longlong(reg);
+	    code_rindirect(xreg,reg,0,0,0);
 	}
-	free_register(g);
+	reg = emit_lpop();
+	code_register_assign(xreg,reg);
+	emit_pop_free(reg);
+	emit_pop_free(xreg);
     } else {
 	if (car(e2)==DREGISTER) {
 	    xreg = cadr(e2);
-	    code_double_lib_c("dpadd",xreg,RET_DREGISTER,dir);
+	    code_double_lib_c("__adddf3",xreg,RET_DREGISTER,dir);
 	    //    xreg は increment する
             //    USE_CREG だと increment する前の値を creg にセット
 	    //    reg が指定されていれば、それに前の値をセット
@@ -4333,7 +4360,7 @@
 	code_save_stacks();
 	use_float(1,reg);
 	lload(xreg,DREGISTER_OPERAND,0);
-	code_double_lib_c("dpadd",DREGISTER_OPERAND,RET_DREGISTER,dir);
+	code_double_lib_c("__adddf3",DREGISTER_OPERAND,RET_DREGISTER,dir);
 	xreg = emit_pop(0);
 	emit_lpush();
 	if (use) {
@@ -4348,9 +4375,106 @@
 }
 
 void
+code_dpreinc_f(int e1,int e2,int d,int reg) {
+    char *frn;
+    char *crn;
+    int  g,xreg,reg0;
+    char *grn;
+    int dir=caddr(e1);
+
+    if (car(e2)==DREGISTER) {
+	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);
+	    if (d) set_dreg(reg,0); else set_freg(reg,0);
+	}
+	frn=fregister_name(reg);
+	printf("\t%s%c\t%s, %s, %s\n",
+	    dir>0?"adf":"suf",dsuffix(d),
+	    crn,crn,grn);
+	if (use && reg!=cadr(e2))
+	    printf("\tmvf%c\t%s, %s\n",dsuffix(d),frn,crn);
+    } else {
+	g_expr(e2);
+	if (!is_int_reg(creg)) error(-1);
+	reg0 = ireg;
+	if (reg==USE_CREG) {
+	    reg=get_dregister(d); if (!reg) error(-1);
+	    if (d) set_dreg(reg,0); else set_freg(reg,0);
+	}
+	grn = fregister_name(g = code_dload_1(d));
+	frn=fregister_name(reg);
+	code_ldf(fload(d),frn,0,reg0);
+	printf("\t%s%c\t%s, %s, %s\n",
+	    dir>0?"adf":"suf",dsuffix(d),
+	    frn,frn,grn);
+	code_ldf(fstore(d),frn,0,reg0);
+    }
+    free_register(g);
+}
+
+void
+code_dpostinc_f(int e1,int e2,int d,int reg) {
+    char *frn;
+    char *crn;
+    int  g,xreg;
+    char *grn;
+    int dir=caddr(e1);
+
+    if (car(e2)==DREGISTER) {
+	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("\tmvf%c\t%s, %s\n",dsuffix(d),frn,crn);
+	printf("\t%s%c\t%s,%s,%s\n",dir>0?"adf":"suf",
+	    dsuffix(d),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));
+	code_ldf(fload(d),frn,0,reg0);
+	printf("\t%s%c\t%s, %s, %s\n",
+	    dir>0?"adf":"suf",dsuffix(d),
+	    grn,frn,grn);
+	code_ldf(fstore(d),grn,0,reg0);
+    }
+    free_register(g);
+}
+
+void
+code_dpreinc(int e1,int e2,int d,int reg) {
+    if (!(arch_mode&UseFPP)) 
+	code_dpreinc_d(e1,e2,d,reg);
+    else
+	code_dpreinc_f(e1,e2,d,reg);
+}
+
+void
+code_dpostinc(int e1,int e2,int d,int reg) {
+    if (!(arch_mode&UseFPP)) 
+	code_dpostinc_d(e1,e2,d,reg);
+    else
+	code_dpostinc_f(e1,e2,d,reg);
+}
+
+
+void
 drexpr(int e1, int e2,int l1, int op,int cond)
 {
     int op1;
+    char *opn;
     if (!cond) {
 	switch(op) {
 	    case FOP+GT:
@@ -4372,27 +4496,18 @@
 	}
     }
     switch(op) {
-    case FOP+GT:  op1=FOP+CMP;   break;
-    case FOP+GE:  op1=FOP+CMPGE; break;
-    case FOP+EQ:  op1=FOP+CMPEQ; break;
-    case FOP+NEQ: op1=FOP+CMPEQ; break;
-    case DOP+GT:  op1=DOP+CMP;   break;
-    case DOP+GE:  op1=DOP+CMPGE; break;
-    case DOP+EQ:  op1=DOP+CMP;   break;
-    case DOP+NEQ: op1=DOP+CMP;   break;
+    case FOP+GT:  op1=FOP+CMP;   opn = "bgt"; break;
+    case FOP+GE:  op1=FOP+CMPGE; opn = "bge"; break;
+    case FOP+EQ:  op1=FOP+CMP;   opn = "beq"; break;
+    case FOP+NEQ: op1=FOP+CMP;   opn = "bne"; break;
+    case DOP+GT:  op1=DOP+CMP;   opn = "bgt"; break;
+    case DOP+GE:  op1=DOP+CMPGE; opn = "bge"; break;
+    case DOP+EQ:  op1=DOP+CMP;   opn = "beq"; break;
+    case DOP+NEQ: op1=DOP+CMP;   opn = "bne"; break;
     default: error(-1);
     }
     g_expr(list3(op1,e2,e1));
-    switch(op) {
-	case DOP+GT:	printf("\tbltz\t$2,$L_%d\n",l1);break;
-	case DOP+GE:	printf("\tblez\t$2,$L_%d\n",l1);break;
-	case DOP+EQ:	printf("\tbeq\t$2,$0,$L_%d\n",l1);break;
-	case DOP+NEQ:	printf("\tbne\t$2,$0,$L_%d\n",l1);break;
-	case FOP+GT:	printf("\tbc1t\t$L_%d\n",l1);break;
-	case FOP+GE:	printf("\tbc1t\t$L_%d\n",l1);break;
-	case FOP+EQ:	printf("\tbc1t\t$L_%d\n",l1);break;
-        case FOP+NEQ:	printf("\tbc1f\t$L_%d\n",l1);break;
-    }
+    printf("\t%s\t.L%d\n",opn,l1);
 }
 
 int emit_dpop(int d)
@@ -4411,30 +4526,6 @@
     return xreg;
 }
 
-#if 0
-static int emit_lpop_regvar();
-
-static
-int emit_dpop_regvar(int d)
-{ 
-    int xreg,reg;
-    if (d) {
-	reg =  emit_lpop_regvar();
-	regs[reg] = USING_DREG;
-	return  reg;
-    }
-    xreg=pop_fregister();
-    reg = cadr(get_dregister_var(0,d));
-    if (xreg<= -REG_LVAR_OFFSET) {
-        code_drlvar(REG_LVAR_OFFSET+xreg,1,reg);
-	free_lvar(REG_LVAR_OFFSET+xreg);
-	xreg=reg;
-    } else {
-        code_dassign_dregister(reg,d,xreg);
-    }
-    return xreg;
-}
-#endif
 
 void
 emit_dpop_free(int e1,int d)
@@ -4463,20 +4554,6 @@
 
 /* 64bit int part */
 
-#if 0
-static int
-lcmp(int op,int cond)
-{
-    if (op==LOP+UGT||op==LOP+UGE) {
-	return UCMP;
-    } else if (op==LOP+LE||op==LOP+GE) {
-	return CMPGE;
-    } else {
-	return CMP;
-    }
-}
-#endif
-
 void
 lrexpr(int e1, int e2,int l1, int op,int cond)
 {
@@ -4517,24 +4594,6 @@
     emit_lpop_free(e3);
 }
 
-#if 0
-static
-int emit_lpop_regvar()
-{ 
-    int xreg,reg;
-    xreg=lreg_stack[--lreg_sp];
-    reg = cadr(get_lregister_var(0));
-    if (xreg<= -REG_LVAR_OFFSET) {
-        code_lrlvar(REG_LVAR_OFFSET+xreg,reg);
-        free_lvar(REG_LVAR_OFFSET+xreg);
-        xreg = reg;
-    } else {
-        code_lassign_lregister(reg,xreg);
-    }
-    return xreg;
-}
-#endif
-
 int
 emit_lpop()
 {
@@ -4562,7 +4621,7 @@
 code_cmp_lregister(int reg,int label,int cond)
 {
     use_longlong(reg);
-    printf("\tor %s,%s,%s\n",
+    printf("\torr\t%s, %s, %s\n",
 		lregister_name_low(reg),
 		lregister_name_low(reg),
 		lregister_name_high(reg));
@@ -4618,11 +4677,11 @@
     crn_l = lregister_name_low(creg);
     lvar_intro(e2);
 #if ENDIAN==0
-    printf("\tsw %s,",crn_l);lvar(e2,"");
-    printf("\tsw %s,",crn_h);lvar(e2+SIZE_OF_INT,"");
+    printf("\tstr\t%s, ",crn_l);lvar(e2,"");
+    printf("\tstr\t%s, ",crn_h);lvar(e2+SIZE_OF_INT,"");
 #else
-    printf("\tsw %s,",crn_h);lvar(e2,"");
-    printf("\tsw %s,",crn_l);lvar(e2+SIZE_OF_INT,"");
+    printf("\tstr\t%s, ",crn_h);lvar(e2,"");
+    printf("\tstr\t%s, ",crn_l);lvar(e2+SIZE_OF_INT,"");
 #endif
 }
 
@@ -4672,15 +4731,8 @@
     use_longlong(creg);
     rl=lregister_name_low(creg);
     rh=lregister_name_high(creg);
-    dreg = get_lregister();
-    dl=lregister_name_low(dreg);
-    dh=lregister_name_high(dreg);
-    printf("\tsubu %s,$0,%s\n",dl,rl);
-    printf("\tsubu %s,$0,%s\n",dh,rh);
-    printf("\tsltu %s,$0,%s\n",rl,dl);
-    printf("\tsubu %s,%s,%s\n",dh,dh,rl);
-    free_register(lreg);
-    set_lreg(dreg,0);
+    printf("\trsbs\t%s, %s, #0\n",rl,rl);
+    printf("\trsc\t%s, %s, #0\n",rh,rh);
 }
 
 void
@@ -4694,11 +4746,11 @@
     crn_l = lregister_name_low(creg);
     r = get_ptr_cache((NMTBL*)caddr(e1));
 #if ENDIAN==0
-    code_ldf("lw",crn_l,cadr(e1),r);
-    code_ldf("lw",crn_h,cadr(e1)+SIZE_OF_INT,r);
+    code_ldf("ldr",crn_l,cadr(e1),r);
+    code_ldf("ldr",crn_h,cadr(e1)+SIZE_OF_INT,r);
 #else
-    code_ldf("lw",crn_h,cadr(e1),r);
-    code_ldf("lw",crn_l,cadr(e1)+SIZE_OF_INT,r);
+    code_ldf("ldr",crn_h,cadr(e1),r);
+    code_ldf("ldr",crn_l,cadr(e1)+SIZE_OF_INT,r);
 #endif
 }
 
@@ -4711,124 +4763,8 @@
     crn_h = lregister_name_high(creg);
     crn_l = lregister_name_low(creg);
     lvar_intro(e1);
-    printf("\tlw %s,",crn_l); lvar(e1,"");
-    printf("\tlw %s,",crn_h); lvar(e1+SIZE_OF_INT,"");
-}
-
-
-
-static void
-code_asld_lib(int reg,int oreg)
-{
-    char *ch,*cl,*oh,*ol,*dh,*dl;
-    //    5   4   7   3   2   6
-    int dreg = get_lregister();
-    ch = lregister_name_high(reg);
-    cl = lregister_name_low(reg);
-    oh = lregister_name_high(oreg);
-    ol = lregister_name_low(oreg);
-    dh = lregister_name_high(dreg);
-    dl = lregister_name_low(dreg);
-    
-    printf("\tsll     %s,%s,26\n",dh,ol);
-    printf("\tbgez    %s,1f\n",dh);
-    printf("\tsll     %s,%s,%s\n",oh,cl,ol);
-    printf("\t.set    noreorder\n");
-    printf("\tb       3f\n");
-    printf("\tmove    %s,$0\n",dl);
-    printf("\t.set    reorder\n");
-    printf("\t1:\n");
-    printf("\t.set    noreorder\n");
-    printf("\tbeq     %s,$0,2f\n",dh);
-    printf("\tsll     %s,%s,%s\n",oh,ch,ol);
-    printf("\t.set    reorder\n");
-    printf("\tsubu    %s,$0,%s\n",dh,ol);
-    printf("\tsrl     %s,%s,%s\n",dh,cl,dh);
-    printf("\tor      %s,%s,%s\n",oh,oh,dh);
-    printf("\t2:\n");
-    printf("\tsll     %s,%s,%s\n",dl,cl,ol);
-    printf("\t3:\n");
-    // printf("\tmove    %s,%s\n",cl,dl);
-    // printf("\tmove    %s,%s\n",ch,oh);
-    printf("\tmove    %s,%s\n",dh,oh);
-    set_lreg(dreg,0);
-    // free_register(dreg);
-}
-
-static void
-code_asrd_lib(int reg,int oreg) // ___ashrdi3$stub
-{
-    char *ch,*cl,*oh,*ol,*dh,*dl;
-    //    5   4   2   3   9   8
-    int dreg = get_lregister();
-    ch = lregister_name_high(creg);
-    cl = lregister_name_low(creg);
-    oh = lregister_name_high(oreg);
-    ol = lregister_name_low(oreg);
-    dh = lregister_name_high(dreg);
-    dl = lregister_name_low(dreg);
-
-    printf("\tsll     %s,%s,26\n",oh,ol);
-    printf("\tbgez    %s,1f\n",oh);
-    printf("\tsra     %s,%s,%s\n",dl,ch,ol);
-    printf("\t.set    noreorder\n");
-    printf("\tb       3f\n");
-    printf("\tsra     %s,%s,31\n",dh,ch);
-    printf("\t.set    reorder\n");
-    printf("\t1:\n");
-    printf("\t.set    noreorder\n");
-    printf("\tbeq     %s,$0,2f\n",oh);
-    printf("\tsrl     %s,%s,%s\n",dl,cl,ol);
-    printf("\t.set    reorder\n");
-    printf("\tsubu    %s,$0,%s\n",oh,ol);
-    printf("\tsll     %s,%s,%s\n",oh,ch,oh);
-    printf("\tor      %s,%s,%s\n",dl,dl,oh);
-    printf("\t2:\n");
-    printf("\tsra     %s,%s,%s\n",dh,ch,ol);
-    printf("\t3:\n");
-    // printf("\tmove    %s,%s\n",cl,dl);
-    // printf("\tmove    %s,%s\n",ch,dh);
-    set_lreg(dreg,0);
-    // free_register(dreg);
-}
-
-static void
-code_lsrd_lib(int reg,int oreg) // ___lshrdi3$stub
-{
-    char *ch,*cl,*oh,*ol,*dh,*dl;
-    //    5   4   2   3   9   8
-    int dreg = get_lregister();
-    ch = lregister_name_high(reg);
-    cl = lregister_name_low(reg);
-    oh = lregister_name_high(oreg);
-    ol = lregister_name_low(oreg);
-    dh = lregister_name_high(dreg);
-    dl = lregister_name_low(dreg);
-    
-    printf("\tsll     %s,%s,26\n",oh,ol);
-    printf("\tbgez    %s,1f\n",oh);
-    printf("\tsrl     %s,%s,%s\n",dl,ch,ol);
-    printf("\t.set    noreorder\n");
-    printf("\tb       3f\n");
-    printf("\tmove    %s,$0\n",dh);
-    printf("\t.set    reorder\n");
-    printf("\t\n");
-    printf("\t1:\n");
-    printf("\t.set    noreorder\n");
-    printf("\tbeq     %s,$0,2f\n",oh);
-    printf("\tsrl     %s,%s,%s\n",dl,cl,ol);
-    printf("\t.set    reorder\n");
-    printf("\t\n");
-    printf("\tsubu    %s,$0,%s\n",oh,ol);
-    printf("\tsll     %s,%s,%s\n",oh,ch,oh);
-    printf("\tor      %s,%s,%s\n",dl,dl,oh);
-    printf("\t2:\n");
-    printf("\tsrl     %s,%s,%s\n",dh,ch,ol);
-    printf("\t3:\n");
-    // printf("\tmove    %s,%s\n",cl,dl);
-    // printf("\tmove    %s,%s\n",ch,dh);
-    set_lreg(dreg,0);
-    // free_register(dreg);
+    printf("\tldr\t%s, ",crn_l); lvar(e1,"");
+    printf("\tldr\t%s, ",crn_h); lvar(e1+SIZE_OF_INT,"");
 }
 
 static void
@@ -4841,11 +4777,6 @@
     set_lreg(RET_LREGISTER,0);
 }
 
-#define code_ldiv_lib(reg,oreg)  code_longlong_lib("__divdi3",reg,oreg)
-#define code_ludiv_lib(reg,oreg) code_longlong_lib("__udivdi3",reg,oreg)
-#define code_lmod_lib(reg,oreg)  code_longlong_lib("__moddi3",reg,oreg)
-#define code_lumod_lib(reg,oreg) code_longlong_lib("__umoddi3",reg,oreg)
-
 #define check_lreg(reg) if (reg!=lreg) { lmove(reg,lreg); }
 
 void
@@ -4871,17 +4802,17 @@
     switch(op) {
     case LLSHIFT:
     case LULSHIFT:
-	code_asld_lib(reg,oreg); // ___ashldi3$stub
+	code_longlong_lib("__ashldi3",reg,oreg)
 	check_lreg(reg);
 	if(ox!=-1) free_register(ox);
 	return;
     case LRSHIFT:
-	code_asrd_lib(reg,oreg); // ___ashrdi3$stub
+	code_longlong_lib("__ashrdi3",reg,oreg)
 	check_lreg(reg);
 	if(ox!=-1) free_register(ox);
 	return;
     case LURSHIFT:
-	code_lsrd_lib(reg,oreg); // ___lshrdi3$stub
+	code_longlong_lib("__lshrdi3",reg,oreg)
 	check_lreg(reg);
 	if(ox!=-1) free_register(ox);
 	return;
@@ -4892,74 +4823,47 @@
     crn_l = lregister_name_low(reg);
     switch(op) {
     case LADD:
-        drn = register_name(dx = get_register());
-	printf("\taddu %s,%s,%s\n",crn_l,crn_l,orn_l);
-	printf("\tsltu %s,%s,%s\n",drn,crn_l,orn_l);
-	printf("\taddu %s,%s,%s\n",crn_h,crn_h,orn_h);
-	printf("\taddu %s,%s,%s\n",crn_h,crn_h,drn);
+        printf("\tadds\t%s, %s, %s\n",crn_l,crn_l,orn_l);
+        printf("\tadc\t%s, %s, %s\n",crn_h,crn_h,orn_h);
 	break;
     case LSUB:
-        drn = register_name(dx = get_register());
-	printf("\tsltu %s,%s,%s\n",drn,crn_l,orn_l);
-	printf("\tsubu %s,%s,%s\n",crn_l,crn_l,orn_l);
-	printf("\tsubu %s,%s,%s\n",crn_h,crn_h,orn_h);
-	printf("\tsubu %s,%s,%s\n",crn_h,crn_h,drn);
+        printf("\tsubs\t%s, %s, %s\n",crn_l,crn_l,orn_l);
+        printf("\tsbc\t%s, %s, %s\n",crn_h,crn_h,orn_h);
 	break;
     case LCMP:
 	error(-1);
 	break;
     case LBAND: 
-	printf("\tand %s,%s,%s\n",crn_l,crn_l,orn_l);
-	printf("\tand %s,%s,%s\n",crn_h,crn_h,orn_h);
+	printf("\tand\t%s, %s, %s\n",crn_l,crn_l,orn_l);
+	printf("\tand\t%s, %s, %s\n",crn_h,crn_h,orn_h);
 	break;
     case LEOR: 
-	printf("\txor %s,%s,%s\n",crn_l,crn_l,orn_l);
-	printf("\txor %s,%s,%s\n",crn_h,crn_h,orn_h);
+	printf("\teor\t%s, %s, %s\n",crn_l,crn_l,orn_l);
+	printf("\teor\t%s, %s, %s\n",crn_h,crn_h,orn_h);
 	break;
     case LBOR:
-	printf("\tor %s,%s,%s\n",crn_l,crn_l,orn_l);
-	printf("\tor %s,%s,%s\n",crn_h,crn_h,orn_h);
+	printf("\torr\t%s, %s, %s\n",crn_l,crn_l,orn_l);
+	printf("\torr\t%s, %s, %s\n",crn_h,crn_h,orn_h);
 	break;
     case LMUL:
     case LUMUL:
-	dx=get_lregister();
-	use_reg(dx);
-	drn_l = lregister_name_low(dx);
-	drn_h = lregister_name_high(dx);
-        /*
-            drn_l 4 = l32( crn_l * orn_l);  6, 2
-            drn_h 5 = h32( crn_l * orn_l);
-            orn_l 6 = l32( crn_h * orn_l);  7, 3
-	    drn_h 5 = drn_h + orn_l;  5, 6
-            crn_l 2 = l32( crn_l * orn_h);  2, 6
-	    crn_h 5 = drn_h + crn_l;  5, 2
-	    crn_l = drn_l;
-        */
-	printf("\tsra     %s,%s,31\n",drn_l,orn_l);
-	printf("\tmultu   %s,%s\n",crn_l,orn_l);
-	printf("\tmfhi    %s\n",drn_h);
-	printf("\tmflo    %s\n",drn_l);
-	printf("\tmult    %s,%s,%s\n",orn_l,crn_h,orn_l);
-	printf("\taddu    %s,%s,%s\n",drn_h,drn_h,orn_l);
-	printf("\tmult    %s,%s,%s\n",crn_l,crn_l,orn_h);
-	printf("\taddu    %s,%s,%s\n",crn_h,drn_h,crn_l);
-	printf("\tmove    %s,%s\n",crn_l,drn_l);
+	code_longlong_lib("__muldi3",reg,oreg)
+	check_lreg(reg);
 	break;
     case LDIV:
-	code_ldiv_lib(reg,oreg)
-;  // ___divdi3$stub
+	code_longlong_lib("____divdi3",reg,oreg)
 	check_lreg(reg);
 	break;
     case LUDIV:
-	code_ludiv_lib(reg,oreg); // ___udivdi3$stub
+	code_longlong_lib("___udivdi3",reg,oreg)
 	check_lreg(reg);
 	break;
     case LMOD:
-	code_lmod_lib(reg,oreg); // ___moddi3$stub
+	code_longlong_lib("___moddi3",reg,oreg)
 	check_lreg(reg);
 	break;
     case LUMOD:
-	code_lumod_lib(reg,oreg); // ___umoddi3$stub
+	code_longlong_lib("___umoddi3",reg,oreg)
 	check_lreg(reg);
 	break;
     default: