changeset 239:1849e0079f08

ia32 long long continue
author kono
date Mon, 03 May 2004 19:28:35 +0900
parents d64e9a6a66bd
children b59364f5b030
files Changes mc-code-ia32.c mc-code-powerpc.c mc-code.h mc-codegen.c
diffstat 5 files changed, 303 insertions(+), 275 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Fri Apr 30 14:46:09 2004 +0900
+++ b/Changes	Mon May 03 19:28:35 2004 +0900
@@ -4095,3 +4095,8 @@
 Thu Apr 29 19:40:08 JST 2004
 
 良くわかんないけど通った。
+
+Sun May  2 09:40:21 JST 2004
+
+やっぱり LREGISTER なんて作るんじゃなかった。code_lconst
+とかで edx,eda と dsi,edi pair の切替えをやらないと。
--- a/mc-code-ia32.c	Fri Apr 30 14:46:09 2004 +0900
+++ b/mc-code-ia32.c	Mon May 03 19:28:35 2004 +0900
@@ -26,6 +26,7 @@
 static int data_alignment = 0;
 
 static int creg;
+static int lreg;
 
 int code_lassop_p = 0;
 
@@ -35,28 +36,32 @@
 int size_of_double = 8;
 int size_of_longlong = 8;
 int endian = 0;
-int MAX_REGISTER=6;            /* intel386のレジスタを6つまで使う*/
+static int MAX_REGISTER=6;            /* intel386のレジスタを6つまで使う*/
 #define REAL_MAX_REGISTER 8    /* intel386のレジスタが8つということ*/
-int MAX_DATA_REG=4;    
-int MAX_POINTER=3;    
-int MAX_REGISTGER_VAR=2;    
-int MAX_FREGISTER=1;
+static int MAX_DATA_REG=4;    
+static int MAX_POINTER=3;    
+// static int MAX_REGISTGER_VAR=2;    
+// static int MAX_FREGISTER=1;
 
 #define MAX_FPU_STACK 7
+#define REG_VAR 3
 
-int MAX_INPUT_REGISTER_VAR = 0;
-int MAX_CODE_INPUT_REGISTER_VAR = 2;
-int MAX_INPUT_DREGISTER_VAR = 0;
-int MAX_INPUT_FREGISTER_VAR = 0;
-int MAX_CODE_INPUT_DREGISTER_VAR = 0;
+// static int MAX_INPUT_REGISTER_VAR = 0;
+static int MAX_CODE_INPUT_REGISTER_VAR = 2;
+// static int MAX_INPUT_DREGISTER_VAR = 0;
+// static int MAX_INPUT_FREGISTER_VAR = 0;
+// static int MAX_CODE_INPUT_DREGISTER_VAR = 0;
 
-int  reg_sp;   /* REGister Stack-Pointer */
-int reg_stack[MAX_MAX];  /* 実際のレジスタの領域 */
+static int  reg_sp;   /* REGister Stack-Pointer */
+static int reg_stack[MAX_MAX];  /* 実際のレジスタの領域 */
 
 /* floating point registers */
 
-int  freg_sp;  /* floating point REGister Stack-Pointer */
-int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */
+static int  freg_sp;  /* floating point REGister Stack-Pointer */
+static int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */
+
+static int reg_var;
+static int regvar[2];
 
 
 /*
@@ -76,11 +81,11 @@
           arg2       12 4
             see enter/enter1/leave           see code_enter
  */
-int arg_offset = 8;
-int disp_offset = -12;
-int func_disp_offset = -12;
-int code_disp_offset = 0;
-int jump_offset = 0;
+static int arg_offset = 8;
+static int disp_offset = -12;
+static int func_disp_offset = -12;
+static int code_disp_offset = 0;
+// static int jump_offset = 0;
 
 static int code_disp_label;
 static int func_disp_label;
@@ -115,7 +120,7 @@
 
 static int dreg; /* general temporal register */
 
-#define REAL_MAX_LREGISTER 1
+#define REAL_MAX_LREGISTER 2
 static int ia32regs[REAL_MAX_REGISTER+REAL_MAX_LREGISTER];
 static int ia32regv[REAL_MAX_REGISTER+REAL_MAX_LREGISTER];
 static int ia32rname[REAL_MAX_REGISTER+REAL_MAX_LREGISTER];
@@ -140,6 +145,9 @@
 #define REG_EDI   5
 #define REG_EBP   6
 #define REG_ESP   7
+#define is_int_reg(reg) (reg<REG_EBP)
+#define REG_LCREG     8
+#define REG_L     9
 
 
 #define DATA_REG 0    
@@ -165,7 +173,36 @@
 static void code_save_stacks();
 
 #define use_int(reg)   if (reg==-1) reg=use_int0()
-static int use_int0() { return creg; }
+static int use_int0() { lreg = 0; if (!is_int_reg(creg)) creg = virtual(REG_EBX); return creg; }
+
+#define use_longlong(reg)   reg=use_longlong0(reg)
+static int
+use_longlong0(int reg)
+{
+    int i;
+    if (reg==USE_CREG)
+	reg = REG_LCREG;
+    if (!lreg) {
+	code_save_stacks();
+	// make edx,eax free
+	use_register(creg,REG_EBX,0);
+	use_register(dreg,REG_ECX,0);
+	for(i=0;i<reg_var;i++)
+	    use_register(regvar[i],REG_ESI+i,1);
+    } 
+    lreg = reg;
+    return lreg;
+}
+
+char *
+l_edx(int i) {
+    return i==REG_L?"%edi":"%edx";
+}
+char *
+l_eax(int i) {
+    return i==REG_L?"%esi":"%eax";
+}
+
 
 void
 code_init(void)
@@ -262,10 +299,7 @@
 free_register(int i) {    /* いらなくなったレジスタを開放 */
     regv[i]=regs[i]=0;
     if(i==REAL_MAX_REGISTER) {
-/*###265 [cc] error: `REG_DSI' undeclared (first use in this function)%%%*/
-/*###265 [cc] error: for each function it appears in.)%%%*/
-/*###265 [cc] error: (Each undeclared identifier is reported only once%%%*/
-	regv[virtual(REG_ESI)]=regv[virtual(REG_DSI)]=0;
+	regv[virtual(REG_ESI)]=regv[virtual(REG_EDI)]=0;
     }
 }
 
@@ -275,7 +309,7 @@
     if (is_code) {
 	if (i>=MAX_CODE_INPUT_REGISTER_VAR) return 0;
 	i =  virtual(i+REG_ESI);
-	regs[i]=regv[i]=1;
+	regs[i]=regv[i]=INPUT_REG;
 	return list3(REGISTER,i,(int)nptr);
     } else {
 	return 0;
@@ -301,9 +335,10 @@
     h = virtual(REG_ESI);
     l = virtual(REG_EDI);
     if (regv[REAL_MAX_REGISTER]==0&&regs[h]==0&&regs[l]==0) {
-	regs[h]=regs[l]=1;
-	regv[h]=regv[l]=1;
+	regs[h]=regs[l]=REG_VAR;
+	regv[h]=regv[l]=REG_VAR;
 	regv[REAL_MAX_REGISTER]=1;
+	reg_var=2; regvar[0]=h; regvar[1]=l;
 	return list2(LREGISTER,REAL_MAX_REGISTER);
     }
     return list2(LVAR,new_lvar(size_of_longlong));
@@ -348,6 +383,7 @@
     }
     creg = get_register();
     dreg = get_register();
+    reg_var = 0;
     return;
 }
 
@@ -477,8 +513,9 @@
     int i;
     for(i=REG_ESI;i<REG_EBP;i++) {
         if (! regs[i]) {    /* 使われていないなら */
-            regs[i]=1;      /* そのレジスタを使うことを宣言し */
+            regs[i]=REG_VAR;      /* そのレジスタを使うことを宣言し */
             regv[i]=0;
+	    regvar[reg_var++]=i;
             return list3(REGISTER,i,(int)nptr); /* その場所を表す番号を返す */
         }
     }
@@ -1101,7 +1138,7 @@
     /* we don't have to save creg nor dreg */
     regs[creg]=0; regs[dreg]=0;
     regv[dreg]= regv[save]= 0;
-    use_register(dreg,REG_EDX,0);  /* will be destroyed */
+    use_register(dreg,REG_EBX,0);  /* will be destroyed */
     use_register(save,REG_ECX,0);  /* will be destroyed */
     regs[creg]=1; regs[dreg]=1;
 
@@ -1119,8 +1156,7 @@
     regv[save]=0;
     if (ret_type==DOUBLE||ret_type==FLOAT) {
 	fregv[freg]=1; regv[creg]=0;
-/*###1119 [cc] error: `ret_tpye' undeclared (first use in this function)%%%*/
-    } else if (ret_type==LONGLONG||ret_tpye==ULONGLONG) {
+    } else if (ret_type==LONGLONG||ret_type==ULONGLONG) {
 	fregv[freg]=0; regv[creg]=0;
     } else if (ret_type==VOID) {
 	fregv[freg]=0; regv[creg]=0;
@@ -1206,36 +1242,26 @@
 #if LONGLONG_CODE
 
 static void
-lload(int creg,int offset)
+lload(int creg,int offset,int reg)
 {
     char *crn = register_name(creg,0);
-    if(rname[creg]==REG_EAX) {
-/*###1209 [cc] error: `op' undeclared (first use in this function)%%%*/
-/*###1209 [cc] warning: format argument is not a pointer (arg 3)%%%*/
-/*###1209 [cc] warning: too many arguments for format%%%*/
-	printf("\tmovl %d(%s),%%edx\n",op,offset+size_of_int,crn);
-/*###1210 [cc] warning: format argument is not a pointer (arg 3)%%%*/
-/*###1210 [cc] warning: too many arguments for format%%%*/
-	printf("\tmovl %d(%s),%%eax\n",op,offset,crn);
+    use_longlong(reg);
+    if((reg==REG_L&&rname[creg]==REG_ESI)||(rname[creg]==REG_EAX)) {
+	printf("\tmovl %d(%s),%s\n",offset+size_of_int,crn,l_edx(reg));
+	printf("\tmovl %d(%s),%s\n",offset,crn,l_edx(reg));
     } else {
-/*###1212 [cc] warning: too many arguments for format%%%*/
-/*###1212 [cc] warning: format argument is not a pointer (arg 3)%%%*/
-	printf("\tmovl %d(%s),%%eax\n",op,offset,crn);
-/*###1213 [cc] warning: format argument is not a pointer (arg 3)%%%*/
-/*###1213 [cc] warning: too many arguments for format%%%*/
-	printf("\tmovl %d(%s),%%edx\n",op,offset+size_of_int,crn);
+	printf("\tmovl %d(%s),%s\n",offset,crn,l_eax(reg));
+	printf("\tmovl %d(%s),%s\n",offset+size_of_int,crn,l_eax(reg));
     }
 }
 
 int
 code_lrindirect(int e1, int reg, int offset, int us)
 {
-/*###1220 [cc] warning: unused variable `crn'%%%*/
-    char *crn;
     g_expr(e1);
-/*###1222 [cc] warning: implicit declaration of function `use_longlong'%%%*/
+    regv[creg]=1;
     use_longlong(reg);
-    lload(creg,offset);
+    lload(creg,offset,reg);
     return LONGLONG;
 }
 #endif
@@ -1683,6 +1709,9 @@
 code_get_fixed_creg(int reg,int type) {
     if (type==FLOAT||type==DOUBLE) {
 	return 0;
+    } else if (type==LONGLONG||type==ULONGLONG) {
+	use_longlong(reg);
+	return reg;
     } else {
 	use_int(reg);
 	return rname[reg];
@@ -1692,6 +1721,7 @@
 void
 code_set_fixed_creg(int reg,int mode,int type) {
     if (type==FLOAT||type==DOUBLE) {
+    } else if (type==LONGLONG||type==ULONGLONG) {
     } else {
 	use_register(creg,reg,mode);
     }
@@ -1700,6 +1730,7 @@
 void
 code_set_return_register(int mode) {
     if (fnptr->ty==DOUBLE||fnptr->ty==FLOAT) {
+    } else if (fnptr->ty==LONGLONG||fnptr->ty==ULONGLONG) {
     } else {
 	use_register(creg,REG_EAX,mode);
     }
@@ -1724,6 +1755,24 @@
     }
 }
 
+#if LONGLONG_CODE
+static long long ll0 = 1LL;
+
+static int 
+code_l1(long long d)
+{
+    int *i = (int *)&ll0; int *j = (int *)&d;
+    return (i[1] == 1)?j[1]:j[0];
+}
+
+static int 
+code_l2(long long d)
+{
+    int *i = (int *)&ll0; int *j = (int *)&d;
+    return (i[1] == 1)?j[0]:j[1];
+}
+#endif
+
 void
 emit_data(int e, int t, NMTBL *n)
 {
@@ -1732,6 +1781,9 @@
     double d;
     float f;
 #endif
+#if LONGLONG_CODE
+    long long ll;
+#endif
     char *name;
     name = n->nm; 
     if(mode!=GDECL && mode!=STADECL)  { 
@@ -1761,6 +1813,11 @@
 	    printf("\t.long %d\n",cadr(e));
 	    gpc += size_of_int;
 	}
+#if LONGLONG_CODE
+    } else if(t==LONGLONG||t==ULONGLONG) {       
+        ll = lcadr(e);
+        printf("\t.long\t0x%x,0x%x\n",code_l2(ll),code_l1(ll));
+#endif
 #if FLOAT_CODE
     } else if(t==DOUBLE) {       
 	d = dcadr(e);
@@ -1952,9 +2009,9 @@
     printf("\tfchs\n");
 }
 
-void code_d2i()
+void code_d2i(int reg)
 { 
-    use_int0();
+    use_int(reg);
     printf("\tlea -%d(%%esp),%%esp\n",size_of_int*2);
     printf("\tfnstcw  (%%esp)\n");
     printf("\tmovl    (%%esp), %s\n",register_name(creg,0));
@@ -1967,29 +2024,29 @@
     printf("\tpopl    %s\n",register_name(creg,0));
 }
 
-void code_i2d()
+void code_i2d(int reg)
 { 
     printf("\tpushl %s\n",register_name(creg,0));
     printf("\tfildl (%%esp)\n");
     printf("\tlea %d(%%esp),%%esp\n",size_of_int);
 }
 
-void code_d2u()
+void code_d2u(int reg)
 { 
-    use_int0();
+    use_int(reg);
     printf("\tlea -%d(%%esp),%%esp\n",size_of_int*3);
     printf("\tfnstcw  (%%esp)\n");
-    printf("\tmovl    (%%esp), %s\n",register_name(creg,0));
+    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(creg,0));
+    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(creg,0));
+    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()
+void code_u2d(int reg)
 { 
     printf("\tpushl  %s\n",register_name(creg,0));
     printf("\tpushl  %s\n",register_name(creg,0));
@@ -1998,12 +2055,12 @@
     printf("\tlea %d(%%esp),%%esp\n",size_of_int*2);
 }
 
-void code_d2f() { }
-void code_f2d() { }
-void code_f2i() { code_d2i(); }
-void code_f2u() { code_d2u(); }
-void code_i2f() { code_i2d(); }
-void code_u2f() { code_u2d(); }
+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_drgvar(int e2,int d,int freg)
 { 
@@ -2246,17 +2303,14 @@
 
 void lrexpr(int e1, int e2,int l1, int op,int cond)
 {
-    int reg;
     int e3;
     g_expr(e1);
     emit_lpush();
     g_expr(e2);
     e3 = emit_lpop();
-/*###2240 [cc] error: `lreg' undeclared (first use in this function)%%%*/
-    reg = lreg;
+    // reg = use_longlong0(USE_CREG);
 
-/*###2242 [cc] warning: too few arguments for format%%%*/
-    printf("\tsubl %edx,4(%%esp)\n");
+    printf("\tsubl %%edx,4(%%esp)\n");
     switch(op) {
     case LOP+GT:
         pcond(code_gt(cond),l1); break;
@@ -2277,8 +2331,7 @@
     default:
         error(-1);
     }
-/*###2263 [cc] warning: too few arguments for format%%%*/
-    printf("\tsubl %eax,(%%esp)\n");
+    printf("\tsubl %%eax,(%%esp)\n");
     switch(op) {
     case LOP+GT:
         pcond(code_gt(cond),l1); break;
@@ -2310,8 +2363,10 @@
 void code_lregister(int e2,int reg)
 {
     use_longlong(reg);
-    printf("\tmovl %%edx,%%esi\n");
-    printf("\tmovl %%eax,%%edi\n");
+    if (reg!=REG_L) {
+	printf("\tmovl %%esi,%s\n",l_edx(reg));
+	printf("\tmovl %%edi,%s\n",l_edx(reg));
+    }
 }
 
 void code_cmp_lregister(int reg)
@@ -2319,9 +2374,8 @@
     char *crn;
     use_int(reg);
     crn = register_name(reg,0);
-    printf("\tmovl %s,%%esi\n",crn);
-/*###2305 [cc] error: `rcrn' undeclared (first use in this function)%%%*/
-    printf("\torl %s,%%edi\n",rcrn);
+    printf("\tmovl %%esi,%s\n",crn);
+    printf("\torl %%edi,%s\n",crn);
     printf("\ttestl %s,%s\n",crn,crn);
 }
 
@@ -2341,10 +2395,9 @@
     char *crn;
     use_int(e2);
     crn = register_name(e2,0);
-    printf("\tmovl %s,%d(%%dbp)\n",crn,lvar(e1));
-    printf("\trol  %s,%d(%%dbp)\n",crn,lvar(e1)+4);
-/*###2327 [cc] warning: too few arguments for format%%%*/
-    printf("\ttestl %s,%s\n",crn);
+    printf("\tmovl %d(%%ebp),%s\n",lvar(e1),crn);
+    printf("\torl  %d(%%ebp),%s\n",lvar(e1)+4,crn);
+    printf("\ttestl %s,%s\n",crn,crn);
 }
 
 void code_lassign(int e1,int e2)
@@ -2352,108 +2405,85 @@
     char *rn;
     // e1 = e2
     use_longlong(e2);
-/*###2335 [cc] error: too few arguments to function `register_name'%%%*/
-    rn = register_name(e1);
-    printf("\tmovl %%eax,(%s)\n",rn);
-    printf("\tmovl %%edx,4(%s)\n",rn);
+    rn = register_name(e1,0);
+    printf("\tmovl %s,(%s)\n",l_eax(e2),rn);
+    printf("\tmovl %s,4(%s)\n",l_edx(e2),rn);
 }
 
 void code_lassign_gvar(int e1,int e2)
 {
-/*###2342 [cc] warning: unused variable `crn'%%%*/
-    char *n,*crn;
+    char *n;
     n = ((NMTBL*)cadr(e1))->nm;
     use_longlong(e2);
-    printf("\tmovl %%eax,%s\n",n);
-    printf("\tmovl %%edx,%s+4\n",n);
+    printf("\tmovl %s,%s\n",l_eax(e2),n);
+    printf("\tmovl %s,%s+4\n",l_edx(e2),n);
 }
 
 void code_lassign_lvar(int e1,int e2)
 {
     use_longlong(e2);
-    printf("\tmovl %%eax,%d(%%dbp)\n",lvar(e1));
-    printf("\tmovl %%edx,%d(%%dbp)\n",lvar(e1)+4);
+    printf("\tmovl %s,%d(%%ebp)\n",l_eax(e2),lvar(e1));
+    printf("\tmovl %s,%d(%%ebp)\n",l_edx(e2),lvar(e1)+4);
 }
 
 void code_lassign_lregister(int e2,int reg)
 {
+
     use_longlong(reg);
-/*###2359 [cc] error: too few arguments to function `register_name'%%%*/
-/*###2359 [cc] error: `rn' undeclared (first use in this function)%%%*/
-    rn = register_name(e2);
-    printf("\tmovl %%edi,(%s)\n",rn);
-    printf("\tmovl %%esi,4(%s)\n",rn);
-/*###2362 [cc] warning: too many arguments for format%%%*/
-    printf("\tmovl %%edi,%%eax\n",rn);
-/*###2363 [cc] warning: too many arguments for format%%%*/
-    printf("\tmovl %%esi,%%edx\n",rn);
-}
-
-static int 
-code_l1(long long d)
-{
-/*###2369 [cc] error: `ll0' undeclared (first use in this function)%%%*/
-    int *i = (int *)&ll0; int *j = (int *)&d;
-    return (i[1] == 1)?j[1]:j[0];
-}
-
-static int 
-code_l2(long long d)
-{
-/*###2376 [cc] error: `ll0' undeclared (first use in this function)%%%*/
-    int *i = (int *)&ll0; int *j = (int *)&d;
-    return (i[1] == 1)?j[0]:j[1];
+    if (e2!=reg) {
+	printf("\tmovl %s,%s\n",l_eax(e2),l_eax(reg));
+	printf("\tmovl %s,%s\n",l_edx(e2),l_edx(reg));
+    }
 }
 
 void
 code_lconst(int e1,int creg)
 {
     use_longlong(creg);
-    code_const(code_l1(lcadr(e1)),virtual(REG_EAX));
-    code_const(code_l2(lcadr(e1)),virtual(REG_EDX));
+    printf("\tmovl $%d,%s\n",code_l1(lcadr(e1)),l_eax(creg));
+    printf("\tmovl $%d,%s\n",code_l2(lcadr(e1)),l_edx(creg));
 }
 
 void code_lneg(int e1)
 {
-    // use_longlong(creg);
-    printf("\tnegl %%eax\n");
-    printf("\tadcl $0,%%edx\n");
-    printf("\tnegl %%edx\n");
+    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));
 }
 
 void code_lrgvar(int e1,int e2)
 {
-/*###2398 [cc] warning: unused variable `crn'%%%*/
-    char *n,*crn;
+    char *n;
     n = ((NMTBL*)cadr(e1))->nm;
     use_longlong(e2);
-    printf("\tmovl %s,%%eax\n",n);
-    printf("\tmovl %s+4,%%edx\n",n);
+    printf("\tmovl %s,%s\n",n,l_eax(e2));
+    printf("\tmovl %s+4,%s\n",n,l_edx(e2));
 }
 
 void code_lrlvar(int e1,int e2)
 {
     use_longlong(e2);
-    printf("\tmovl %d(%%dbp),%%eax\n",lvar(e1));
-    printf("\tmovl %d(%%dbp),%%edx\n",lvar(e1)+4);
+    printf("\tmovl %d(%%ebp),%s\n",lvar(e1),l_eax(e2));
+    printf("\tmovl %d(%%ebp),%s\n",lvar(e1)+4,l_edx(e2));
 }
 
-void ltosop(int e1,int reg,int e2)
+#define check_lreg() if (reg==REG_L) code_lassign_lregister(REG_LCREG,reg)
+
+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;
 
-/*###2420 [cc] error: `op' undeclared (first use in this function)%%%*/
     switch(op) {
     case LLSHIFT:
     case LULSHIFT:
-/*###2423 [cc] error: parse error before ';' token%%%*/
-	printf("\tmovl %%ecx,4(%%esp)\n";);
-/*###2424 [cc] error: parse error before ';' token%%%*/
-	printf("\tpopl %%ecx\n";);
+	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");
@@ -2462,12 +2492,11 @@
         printf("\txorl %%eax,%%eax\n");
 	fwddef(lb);
 	printf("\tpopl %%ecx\n");
+	check_lreg();
 	return;
     case LRSHIFT:
-/*###2435 [cc] error: parse error before ';' token%%%*/
-	printf("\tmovl %%ecx,4(%%esp)\n";);
-/*###2436 [cc] error: parse error before ';' token%%%*/
-	printf("\tpopl %%ecx\n";);
+	printf("\tmovl %%ecx,4(%%esp)\n");
+	printf("\tpopl %%ecx\n");
         printf("\tshrdl %%eax,%%edx\n");
         printf("\tsarl %%cl,%%eax\n");
         printf("\ttestb $32,%%cl\n");
@@ -2476,12 +2505,11 @@
         printf("\tsarl $31,%%edx\n");
 	fwddef(lb);
 	printf("\tpopl %%ecx\n");
+	check_lreg();
 	return;
     case LURSHIFT:
-/*###2447 [cc] error: parse error before ';' token%%%*/
-	printf("\tmovl %%ecx,4(%%esp)\n";);
-/*###2448 [cc] error: parse error before ';' token%%%*/
-	printf("\tpopl %%ecx\n";);
+	printf("\tmovl %%ecx,4(%%esp)\n");
+	printf("\tpopl %%ecx\n");
         printf("\tshrdl %%eax,%%edx\n");
         printf("\tshrl %%cl,%%eax\n");
         printf("\ttestb $32,%%cl\n");
@@ -2490,22 +2518,20 @@
         printf("\txorl %%edx,%%edx\n");
 	fwddef(lb);
 	printf("\tpopl %%ecx\n");
+	check_lreg();
 	return;
     }
     switch(op) {
-    case LADD: opl="addl";oph="adcl"; break;
-    case LSUB: opl="subl";oph="bbl"; break;
+    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:
-/*###2467 [cc] error: parse error before ';' token%%%*/
-	printf("\tpushl %%edx\n";);
-/*###2468 [cc] error: parse error before ';' token%%%*/
-	printf("\tpushl %%eax\n";);
-/*###2469 [cc] error: parse error before ';' token%%%*/
-	printf("\tpushl %%ecx\n";);
+	printf("\tpushl %%edx\n");
+	printf("\tpushl %%eax\n");
+	printf("\tpushl %%ecx\n");
 	//       4   c_l
 	//       8   c_h
 	//      12   o_l
@@ -2513,15 +2539,12 @@
         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
-/*###2477 [cc] warning: too many arguments for format%%%*/
-/*###2477 [cc] error: `h' undeclared (first use in this function)%%%*/
-        printf("\taddl %%ecx,%%edx\n",h);      //  %edx+%ecx->%edx
+        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
-/*###2480 [cc] warning: too many arguments for format%%%*/
-        printf("\taddl %%ecx,%%edx\n",h);      //  %edx+%ecx->%edx
+        printf("\taddl %%ecx,%%edx\n");        //  %edx+%ecx->%edx
 	printf("\tpopl %%ecx\n");
-	printf("\tladd $16,%%esp\n");
+	printf("\taddl $16,%%esp\n");
 	return;
     case LDIV:  call="__divdi3"; break;
     case LUDIV: call="__udivdi3"; break;
@@ -2531,15 +2554,17 @@
     }
     if (opl) {
 	printf("\t%s (%%esp),%%eax\n\t%s 4(%%esp),%%edx\n",opl,oph);
+	check_lreg();
 	emit_lpop_free(e2);
-/*###2493 [cc] error: parse error before "if"%%%*/
-/*###2493 [cc] error: `eles' undeclared (first use in this function)%%%*/
-    } eles if (call) {
+    } else if (call) {
+	printf("\tpushl %%edx\n");
+	printf("\tpushl %%eax\n");
 	printf("\tcall %s\n",call);
-/*###2495 [cc] warning: too few arguments for format%%%*/
-	printf("\tladd $16,%esp\n");
+	printf("\taddl $16,%%esp\n");
+	check_lreg();
+    } else {
+	error(-1);
     }
-/*###2497 [cc] error: parse error before '}' token%%%*/
 }
 
 int code_lconst_op_p(int op,int e) {
@@ -2552,8 +2577,7 @@
 	return (0<=l&&l<=32);
     case LADD:
     case LSUB:
-    case LBAND
-/*###2510 [cc] error: parse error before "case"%%%*/
+    case LBAND:
     case LEOR:
     case LBOR:
 	return 1;
@@ -2564,8 +2588,6 @@
 
 void loprtc(int op,int reg,int e) {
     char *opl,*oph;
-/*###2520 [cc] warning: unused variable `lb'%%%*/
-    int lb;
     int vl = code_l1(lcadr(e));
     int vh = code_l2(lcadr(e));
 
@@ -2577,27 +2599,29 @@
     case LULSHIFT:
         printf("\tshldl $%d,%%eax,%%edx\n",vl);
         printf("\tsall $%d,%%eax\n",vl);
+	check_lreg();
 	return;
     case LRSHIFT:
         printf("\tshrdl $%d,%%eax,%%edx\n",vl);
         printf("\tsarl $%d,%%eax\n",vl);
+	check_lreg();
 	return;
     case LURSHIFT:
         printf("\tshrdl $%d,%%eax,%%edx\n",vl);
         printf("\tshrl $%d,%%eax\n",vl);
+	check_lreg();
 	return;
     }
     switch(op) {
     case LADD: opl="addl";oph="adcl"; break;
-    case LSUB: opl="subl";oph="bbl"; 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;
     default: error(-1);
     }
-    if (opl) {
-	printf("\t%s $%d,%%eax\n\t%s $%d,%%edx\n",opl,vl,oph,vh);
-    }
+    printf("\t%s $%d,%%eax\n\t%s $%d,%%edx\n",opl,vl,oph,vh);
+    check_lreg();
 }
 
 void emit_lpop_free(int e1)
@@ -2607,68 +2631,61 @@
 
 void emit_lpush()
 {
-/*###2562 [cc] warning: too few arguments for format%%%*/
-    printf("\tpush %edx\n\tpushl %eax\n");
+    printf("\tpush %%edx\n\tpushl %%eax\n");
 }
 
-void code_i2ll()
+void code_i2ll(int reg)
 {
-/*###2567 [cc] warning: unused variable `reg'%%%*/
-    int reg = USE_CREG;
     if (virtual(REG_EAX)!=creg)
 	printf("\tmovl %s,%%eax\n",register_name(creg,0));
-/*###2570 [cc] warning: implicit declaration of function `use_longlong0'%%%*/
-    use_longlong0();
+    use_longlong(reg);
     printf("\tcltd\n");
 }
 
-void code_i2ull()
+void code_i2ull(int reg)
 {
-    code_i2ll();
+    code_i2ll(reg);
 }
 
-void code_u2ll()
+void code_u2ll(int reg)
 {
-/*###2581 [cc] warning: unused variable `reg'%%%*/
-    int reg = USE_CREG;
     if (virtual(REG_EAX)!=creg)
 	printf("\tmovl %s,%%eax\n",register_name(creg,0));
-    use_longlong0();
+    use_longlong(reg);
     printf("\txorl %%edx,%%edx\n");
 }
 
-void code_u2ull()
+void code_u2ull(int reg)
 {
-    code_u2ll();
+    code_u2ll(reg);
 }
 
-void code_ll2i()
+void code_ll2i(int reg)
 {
-    int reg = USE_CREG;
-    reg = use_int0();
+    use_int(reg);
     if (virtual(REG_EAX)!=reg)
 	printf("\tmovl %%eax,%s\n",register_name(creg,0));
 }
 
-void code_ll2u()
+void code_ll2u(int reg)
 {
-    code_ll2i();
+    code_ll2i(reg);
 }
 
-void code_ull2i()
+void code_ull2i(int reg)
 {
-    code_ll2i();
+    code_ll2i(reg);
 }
 
-void code_ull2u()
+void code_ull2u(int reg)
 {
-    code_ll2i();
+    code_ll2i(reg);
 }
 
 #if FLOAT_CODE
-void code_d2ll()
+void code_d2ll(int reg)
 {
-    use_longlong0();
+    use_longlong(reg);
         printf("\tsubl $40,%%esp\n");
         printf("\tfnstcw 2(%%esp)\n");
         printf("\tmovw 2(%%esp),%%ax\n");
@@ -2677,37 +2694,35 @@
         printf("\tfldcw 0(%%esp)\n");
         printf("\tfistpll 12(%%esp)\n");
         printf("\tfldcw 2(%%esp)\n");
-/*###2628 [cc] warning: too few arguments for format%%%*/
-        printf("\tmovl 12(%esp),%%eax\n");
-/*###2629 [cc] warning: too few arguments for format%%%*/
-        printf("\tmovl 16(%esp),%%edx\n");
+        printf("\tmovl 12(%%esp),%%eax\n");
+        printf("\tmovl 16(%%esp),%%edx\n");
         printf("\taddl $40,%%esp\n");
 }
 
-void code_d2ull()
+void code_d2ull(int reg)
 {
-    use_longlong0();
+    use_longlong(reg);
         printf("\tsubl $16,%%esp\n");
         printf("\tfstpl (%%esp)\n");
         printf("\tcall __fixunsdfdi\n");
         printf("\taddl $16,%%esp\n");
 }
 
-void code_f2ll()
+void code_f2ll(int reg)
 {
-    code_d2ll();
+    code_d2ll(reg);
 }
 
-void code_f2ull()
+void code_f2ull(int reg)
 {
-    use_longlong0();
+    use_longlong(reg);
         printf("\tsubl $16,%%esp\n");
         printf("\tfstpl (%%esp)\n");
         printf("\tcall __fixunssfdi\n");
         printf("\taddl $16,%%esp\n");
 }
 
-void code_ll2d()
+void code_ll2d(int reg)
 {
         printf("\tsubl $8,%%esp\n");
         printf("\tmovl %%eax,(%%esp)\n");
@@ -2716,19 +2731,19 @@
         printf("\taddl $8,%%esp\n");
 }
 
-void code_ll2f()
+void code_ll2f(int reg)
 {
-    code_ll2d();
+    code_ll2d(reg);
 }
 
-void code_ull2d()
+void code_ull2d(int reg)
 {
-    code_ll2d();
+    code_ll2d(reg);
 }
 
-void code_ull2f()
+void code_ull2f(int reg)
 {
-    code_ll2d();
+    code_ll2d(reg);
 }
 
 #endif
@@ -2741,19 +2756,19 @@
     char *crn;
     if (car(e2)==LREGISTER) {
         use_longlong(reg);
-        printf("\taddl %%edi,%%edi,%d\n",dir);
-        printf("\tadcl %%esi,%%esi,%d\n",dir);
-	printf("\tmovl %%edi,%%eax\n");
-	printf("\tmovl %%esi,%%edx\n");
+        printf("\taddl $%d,%%esi\n",dir);
+	printf("\tadcl $%d,%%edi\n",dir>0?0:-1);
+	if (reg!=REG_L) {
+	    code_lregister(REG_L,reg);
+	}
         return;
     } 
     g_expr(e2);
     crn = register_name(creg0=creg,0);
     printf("\taddl $%d,(%s)\n",dir,crn);
-/*###2699 [cc] error: parse error before ':' token%%%*/
-    printf("\tadcl $%d,4(%s)\n",dir>0?:0:-1,crn);
+    printf("\tadcl $%d,4(%s)\n",dir>0?0:-1,crn);
     use_longlong(reg);
-    lload(creg0,0);
+    lload(creg0,0,reg);
 }
 
 void code_lpostinc(int e1,int e2,int reg)
@@ -2763,23 +2778,21 @@
     char *crn;
     if (car(e2)==LREGISTER) {
         use_longlong(reg);
-	printf("\tmovl %%edi,%%eax\n");
-	printf("\tmovl %%esi,%%edx\n");
-        printf("\taddl %%edi,%%edi,%d\n",dir);
-        printf("\tadcl %%esi,%%esi,%d\n",dir);
+	if (reg!=REG_L) {
+	    code_lregister(REG_L,reg);
+	}
+        printf("\taddl $%d,%%esi\n",dir);
+	printf("\tadcl $%d,%%edi\n",dir>0?0:-1);
         return;
     } 
     g_expr(e2);
     crn = register_name(creg0=creg,0);
     printf("\taddl $%d,(%s)\n",dir,crn);
-/*###2720 [cc] error: parse error before ':' token%%%*/
-    printf("\tadcl $%d,4(%s)\n",dir>0?:0:-1,crn);
+    printf("\tadcl $%d,4(%s)\n",dir>0?0:-1,crn);
     use_longlong(reg);
-    lload(creg0,0);
-/*###2723 [cc] warning: too many arguments for format%%%*/
-    printf("\taddl $%d,%%eax\n",-dir,crn);
-/*###2724 [cc] error: parse error before ':' token%%%*/
-    printf("\tadcl $%d,%%edx\n",-dir>0?:0:-1,crn);
+    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));
 }
 
 void code_lassop(int op,int reg)
--- a/mc-code-powerpc.c	Fri Apr 30 14:46:09 2004 +0900
+++ b/mc-code-powerpc.c	Mon May 03 19:28:35 2004 +0900
@@ -4025,37 +4025,35 @@
 }
 
 void
-code_i2ll()
+code_i2ll(int reg)
 {
     char *crn,*crn_h,*crn_l;
-    int creg0;
-    use_int0();
-    crn = register_name(creg0 = ireg);
-    use_longlong0();
+    int reg0;
+    crn = register_name(reg0 = ireg);
+    use_longlong(reg);
     crn_h = lregister_name_high(lreg);
     crn_l = lregister_name_low(lreg);
-    if (creg0!=regv_l(lreg))
+    if (reg0!=regv_l(lreg))
 	printf("\tmr %s,%s\n",crn_l,crn);
     printf("\tsrawi %s,%s,31\n",crn_h,crn_l);
 }
 
 void
-code_i2ull()
+code_i2ull(int reg)
 {
-    code_i2ll();
+    code_i2ll(reg);
 }
 
 void
-code_u2ll()
+code_u2ll(int reg)
 {
-    int creg0;
     char *crn,*crn_h,*crn_l;
-    use_int0();
-    crn = register_name(creg0 = ireg);
-    use_longlong0();
+    int reg0;
+    crn = register_name(reg0 = ireg);
+    use_longlong(reg);
     crn_h = lregister_name_high(lreg);
     crn_l = lregister_name_low(lreg);
-    if (creg0!=regv_l(lreg))
+    if (reg0!=regv_l(lreg))
 	printf("\tmr %s,%s\n",crn_l,crn);
     printf("\tli %s,0\n",crn_h);
 }
@@ -4067,14 +4065,13 @@
 }
 
 void
-code_ll2i()
+code_ll2i(int reg)
 {
     char *crn_l;
-    int reg;
-    use_longlong0();
-    crn_l = lregister_name_low(reg=lreg);
-    use_int0();
-    if (ireg!=regv_l(reg))
+    int reg0;
+    crn_l = lregister_name_low(reg0=lreg);
+    use_int(reg);
+    if (ireg!=regv_l(reg0))
 	printf("\tmr %s,%s\n",register_name(ireg),crn_l);
 }
 
@@ -4099,53 +4096,65 @@
 #if FLOAT_CODE
 
 void
-code_d2ll()
+code_d2ll(int reg)
 {
     // fixdfdi$stub
     set_freg(RET_FREGISTER,1);
     extern_conv("__fixdfdi");
     set_lreg(RET_LREGISTER,0);
+    if (reg!=USE_CREG&&reg!=RET_LREGISTER)
+	use_longlong(reg);
 }
 
 void
-code_d2ull()
+code_d2ull(int reg)
 {
     set_freg(RET_FREGISTER,1);
     extern_conv("__fixunsdfdi");
     set_lreg(RET_LREGISTER,0);
+    if (reg!=USE_CREG&&reg!=RET_LREGISTER)
+	use_longlong(reg);
 }
 
 void
-code_f2ll()
+code_f2ll(int reg)
 {
     set_freg(RET_FREGISTER,1);
     extern_conv("__fixdfdi");
     set_lreg(RET_LREGISTER,0);
+    if (reg!=USE_CREG&&reg!=RET_LREGISTER)
+	use_longlong(reg);
 }
 
 void
-code_f2ull()
+code_f2ull(int reg)
 {
     set_freg(RET_FREGISTER,1);
     extern_conv("__fixsfdi");
     set_lreg(RET_LREGISTER,0);
+    if (reg!=USE_CREG&&reg!=RET_LREGISTER)
+	use_longlong(reg);
 }
 
 void
-code_ll2d()
+code_ll2d(int reg)
 {
     set_lreg(RET_LREGISTER,1);
     extern_conv("__floatdidf");
     set_freg(RET_FREGISTER,0);
+    if (reg!=USE_CREG&&reg!=RET_FREGISTER)
+	use_float(1,reg);
 }
 
 
 void
-code_ll2f(int creg)
+code_ll2f(int reg)
 {
     set_lreg(RET_LREGISTER,1);
     extern_conv("__floatdisf");
     set_freg(RET_FREGISTER,0);
+    if (reg!=USE_CREG&&reg!=RET_FREGISTER)
+	use_float(0,reg);
 }
 
 void
--- a/mc-code.h	Fri Apr 30 14:46:09 2004 +0900
+++ b/mc-code.h	Mon May 03 19:28:35 2004 +0900
@@ -174,23 +174,23 @@
 extern void emit_lpush();
 extern int code_lconst_op_p(int op,int e); 
 extern void loprtc(int op,int reg, int e);
-extern void code_i2ll();
-extern void code_i2ull();
-extern void code_u2ll();
-extern void code_u2ull();
-extern void code_ll2i();
-extern void code_ll2u();
-extern void code_ull2i();
-extern void code_ull2u();
+extern void code_i2ll(int reg);
+extern void code_i2ull(int reg);
+extern void code_u2ll(int reg);
+extern void code_u2ull(int reg);
+extern void code_ll2i(int reg);
+extern void code_ll2u(int reg);
+extern void code_ull2i(int reg);
+extern void code_ull2u(int reg);
 #if FLOAT_CODE
-extern void code_d2ll();
-extern void code_d2ull();
-extern void code_f2ll();
-extern void code_f2ull();
-extern void code_ll2d();
-extern void code_ll2f();
-extern void code_ull2d();
-extern void code_ull2f();
+extern void code_d2ll(int reg);
+extern void code_d2ull(int reg);
+extern void code_f2ll(int reg);
+extern void code_f2ull(int reg);
+extern void code_ll2d(int reg);
+extern void code_ll2f(int reg);
+extern void code_ull2d(int reg);
+extern void code_ull2f(int reg);
 #endif
 
 
--- a/mc-codegen.c	Fri Apr 30 14:46:09 2004 +0900
+++ b/mc-codegen.c	Mon May 03 19:28:35 2004 +0900
@@ -1493,11 +1493,12 @@
 	t = long_sign(op);
 	if (car(e2)==LREGISTER||car(e2)==LVAR||car(e2)==GVAR) {
 	    g_expr(assign_expr0(e2,list3(op,rvalue_t(e2,t),e3),t,t));
+	    return;
 	}
 	/*  new = &e2 */
 	/*  *new = *new op e3 */
 	n = list2(LVAR,new_lvar(size_of_int));
-	g_expr(assign_expr0(n,list2(ADDRESS,e2),INT,INT));
+	g_expr_u(assign_expr0(n,list2(ADDRESS,e2),INT,INT));
 	g_expr(assign_expr0(list2(INDIRECT,n),list3(op,n,e3),t,t));
 	free_lvar(cadr(n));
 	return;