changeset 221:ceae585186d9

*** empty log message ***
author kono
date Mon, 26 Apr 2004 05:35:33 +0900
parents 97246ddfe8ab
children 3d214303bae9
files Changes Makefile mc-code-powerpc.c mc-code.h mc-codegen.c mc-codegen.h mc-parse.c
diffstat 7 files changed, 714 insertions(+), 569 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Sun Apr 25 19:03:04 2004 +0900
+++ b/Changes	Mon Apr 26 05:35:33 2004 +0900
@@ -3995,3 +3995,57 @@
 use_int とかは、codegen でやったんじゃいけなくて、
 もっとも下のcode生成部分でやらないといけないんじゃない?
 それでいいのか?
+
+あ、そうか、
+
+creg に対する操作ばっかりじゃないので、code_xxxx(xxxx,creg)
+というようになっている。そうすると、creg をその外で
+creg = use_int(creg) する必要がある。だね。
+
+    void
+    code_lvar(int e2,int reg) {
+	creg = use_int(creg);
+	lvar_intro(e2);
+	printf("\tla %s,",register_name(reg));
+	lvar(e2);
+    }
+
+だと、reg が間に合わない。手遅れ。
+
+reg にcreg 以外が入るのは、基本的には assign_opt 系ですね。
+これを creg に直せば。。。。
+
+    void
+    code_lvar(int e2,int reg) {
+	if (reg==-1) {
+	    creg = use_int(creg);
+	    reg = creg;
+	}
+	lvar_intro(e2);
+	printf("\tla %s,",register_name(reg));
+	lvar(e2);
+    }
+
+みたいな?
+
+    #define use_int(reg) if (reg==-1) reg = use_int0(reg)
+    void
+    code_lvar(int e2,int reg) {
+	use_int(reg);
+	lvar_intro(e2);
+	printf("\tla %s,",register_name(reg));
+	lvar(e2);
+    }
+    use_int0(int reg) {
+	creg = ireg;
+	return creg;
+    }
+
+かな。 #define で? ま、どっちでもおんなじようなものか。
+
+でも、これは変更多いなぁ。
+
+Mon Apr 26 05:35:24 JST 2004
+
+一応、no long long は通ったみたいだが。。
+
--- a/Makefile	Sun Apr 25 19:03:04 2004 +0900
+++ b/Makefile	Mon Apr 26 05:35:33 2004 +0900
@@ -69,6 +69,8 @@
 	make check TARGET=test/tmp9
 	make check TARGET=test/enum
 	make check TARGET=test/obsf
+	make check TARGET=test/long
+	make check TARGET=test/code-gen-all
 #MK =-make
 MK=
 check-all-code:
@@ -94,7 +96,7 @@
 check: $(MC)
 	-gcc $(TARGET).c -o b.out $(MLIB)
 	-./b.out > $(TARGET).gcc.out
-	-./$(MC) -s $(TARGET).c
+	-./$(MC) -Itest/ -s $(TARGET).c
 	-gcc $(TARGET).s $(MLIB)
 	-./a.out > $(TARGET).$(MC).out
 	-diff  $(TARGET).gcc.out $(TARGET).$(MC).out
--- a/mc-code-powerpc.c	Sun Apr 25 19:03:04 2004 +0900
+++ b/mc-code-powerpc.c	Mon Apr 26 05:35:33 2004 +0900
@@ -17,11 +17,13 @@
 
 static void data_mode(char *name);
 static void init_ptr_cache();
-static void ld_indexx(int byte, int n, int xreg,int sign);
+static void ld_indexx(int byte, int n, int xreg,int reg,int sign);
 static void local_table(void);
-static void shift(char *op, int reg);
+static void shift(char *op, int creg,int reg);
 static int struct_push(int e4,int t,int arg);
 
+static int creg;
+
 static int output_mode = TEXT_EMIT_MODE;
 static int data_alignment = 0;
 
@@ -121,23 +123,35 @@
 #define lregister_name_low(i) reg_name[regv_l(i)]
 #define lregister_name_high(i) reg_name[regv_h(i)]
 
+char *r(i) { return register_name(i); }
+char *f(i) { return fregister_name(i); }
+char *ll(i) { return lregister_name_low(i); }
+char *lh(i) { return lregister_name_high(i); }
+
 #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_longlong_reg(i)  (LREG_OFFSET<=i&&i<LREG_OFFSET+REAL_MAX_LREGISTER)
 
-
-int use_int(int i) { 
+#define  use_int(reg) if (reg==USE_CREG) reg=use_int0()
+static
+int use_int0() { 
+    int i = creg;
     if (!is_int_reg(i)) {
-	if (lreg) { free_register(lreg); lreg = 0; }
 	if (!ireg) ireg = get_register();
 	else if (ireg!=i) free_register(i);
+	if (lreg) { free_register(lreg); lreg = 0; }
 	i = ireg;
     }
     if (!regs[i]) regs[i]=USING_REG;
+    creg = i;
     return i;
 }
 
-int use_float(int i) { 
+#if FLOAT_CODE
+#define  use_float(d,reg) if (reg==USE_CREG) reg=d?use_double0():use_float0()
+static
+int use_float0() { 
+    int i = creg;
     if (!is_float_reg(i)) {
 	if (lreg) { free_register(lreg); lreg = 0; }
 	if (!freg) freg = get_dregister(0);
@@ -145,10 +159,12 @@
 	i = freg;
     }
     if (!regs[i]) regs[i]=USING_REG;
+    creg = i;
     return i;
 }
-
-int use_double(int i) { 
+static
+int use_double0() { 
+    int i = creg;
     if (!is_float_reg(i)) {
 	if (lreg) { free_register(lreg); lreg = 0; }
 	if (!freg) freg = get_dregister(1);
@@ -156,20 +172,30 @@
 	i = freg;
     }
     if (!regs[i]) regs[i]=USING_REG;
+    creg = i;
     return i;
 }
-
-int use_longlong(int i) {
+#endif
+
+#if LONGLONG_CODE
+#define  use_longlong(reg) if (reg==USE_CREG) reg=use_longlong0()
+
+static
+int use_longlong0() {
+    int i = creg;
     if (!is_longlong_reg(i)) {
 	if (!lreg) lreg = get_lregister();
 	else if (lreg!=i) free_register(i);
+	if (ireg) { free_register(ireg); ireg=0; }
 	i = lreg;
     }
     if (!regs[i]) regs[i]=USING_REG;
     if (!regs[regv_l(i)]) regs[regv_l(i)]=USING_REG;
     if (!regs[regv_h(i)]) regs[regv_h(i)]=USING_REG;
+    creg = i;
     return i;
 }
+#endif
 
 
 #if FLOAT_CODE
@@ -341,9 +367,10 @@
 #define lvar(i) if (LARGE_LVAR) lvar16lo(i); else lvar8(i)
 
 void
-code_lvar(int e2,int creg) {
+code_lvar(int e2,int reg) {
+    use_int(reg);
     lvar_intro(e2);
-    printf("\tla %s,",register_name(creg));
+    printf("\tla %s,",register_name(reg));
     lvar(e2);
 }
 
@@ -807,6 +834,7 @@
     while(lreg_sp > 0) {
 	free_register(lreg_stack[--lreg_sp]);
     }
+    use_int0();
     text_mode();
     gexpr_code_init();
     register_usage("gexpr_init");
@@ -862,8 +890,9 @@
 emit_push()
 {
     int new_reg;
+    if (!is_int_reg(creg)) error(-1);
     if (reg_sp>MAX_MAX) error(-1);
-    new_reg = get_register();
+    new_reg = get_register();       /* 絶対に取れる */
     reg_stack[reg_sp++] = creg;     /* push するかわりにレジスタを使う */
     ireg = creg = new_reg;
 }
@@ -982,24 +1011,27 @@
 }
 
 void
-code_gvar(int e1,int creg) {
+code_gvar(int e1,int reg) {
     int r;
+    use_int(reg);
     r = get_ptr_cache((NMTBL*)cadr(e1));
-    if(r!=creg)
-	printf("\tmr %s,%s\n",register_name(creg),register_name(r));
+    if(r!=reg)
+	printf("\tmr %s,%s\n",register_name(reg),register_name(r));
     return;
 }
 
 void
-code_rgvar(int e1,int creg) {
-    if (!is_int_reg(creg)) error(-1);
-    printf("\tlwz %s,0(%s)\n",register_name(creg),
+code_rgvar(int e1,int reg) {
+    use_int(reg);
+    printf("\tlwz %s,0(%s)\n",register_name(reg),
                              register_name(get_ptr_cache((NMTBL*)cadr(e1))));
 }
 
 void
-code_crgvar(int e1,int creg,int sign,int sz){
-    char *crn = register_name(creg);
+code_crgvar(int e1,int reg,int sign,int sz){
+    char *crn;
+    use_int(reg);
+    crn = register_name(reg);
     printf("\t%s %s,0(%s)\n",cload(sz),crn,
                              register_name(get_ptr_cache((NMTBL*)cadr(e1))));
     if (sign)
@@ -1009,22 +1041,24 @@
 
 
 void
-code_register(int e2,int creg) {
-    if (creg!=e2)
-	printf("\tmr %s,%s\n",register_name(creg),register_name(e2));
+code_register(int e2,int reg) {
+    use_int(reg);
+    if (reg!=e2)
+	printf("\tmr %s,%s\n",register_name(reg),register_name(e2));
 }
 
 
 void
 code_rlvar(int e2,int reg) {
+    use_int(reg);
     lvar_intro(e2);
-    if (!is_int_reg(reg)) error(-1);
     printf("\tlwz %s,",register_name(reg));
     lvar(e2);
 }
 
 void
 code_crlvar(int e2,int reg,int sign,int sz) {
+    use_int(reg);
     lvar_intro(e2);
     printf("\t%s %s,",cload(sz),register_name(reg));
     lvar(e2);
@@ -1037,18 +1071,21 @@
 
 
 void
-code_fname(NMTBL *n,int creg) {
+code_fname(NMTBL *n,int reg) {
     int r;
+    use_int(reg);
     r = get_ptr_cache(n);
-    if(r!=creg)
-	printf("\tmr %s,%s\n",register_name(creg),register_name(r));
+    if(r!=reg)
+	printf("\tmr %s,%s\n",register_name(reg),register_name(r));
     return;
 }
 
 
 void
-code_const(int e2,int creg) {
-    char *crn = register_name(creg);
+code_const(int e2,int reg) {
+    char *crn;
+    use_int(reg);
+    crn = register_name(reg);
     if (-32768<e2&&e2<32768)
 	printf("\tli %s,%d\n",crn,e2);
     else {
@@ -1060,12 +1097,14 @@
 
 void
 code_neg(int creg) {
+    use_int(creg);
     printf("\tneg %s,%s\n", register_name(creg), register_name(creg));
 }
 
 
 void
 code_not(int creg) {
+    use_int(creg);
     printf("\tnor %s,%s,%s\n", 
 	register_name(creg), register_name(creg),register_name(creg));
 }
@@ -1073,6 +1112,7 @@
 
 void
 code_lnot(int creg) {
+    use_int(creg);
     printf("\tsubfic r0,%s,0\n", register_name(creg));
     printf("\tadde %s,r0,%s\n", register_name(creg),register_name(creg));
 }
@@ -1080,8 +1120,9 @@
 void
 code_preinc(int e1,int e2,int dir,int sign,int sz,int reg) {
     char *xrn,*drn;
-    int i,dreg;
+    int dreg;
     if (car(e2)==REGISTER) {
+	use_int(reg);
 	printf("\taddi %s,%s,%d\n", 
 		register_name(cadr(e2)),register_name(cadr(e2)), dir);
 	if (cadr(reg)!=e2)
@@ -1089,51 +1130,60 @@
 	return;
     } 
     g_expr(e2);
+    if (!is_int_reg(creg)) error(-1);
     xrn = register_name(creg);
-    dreg=get_register(); if (!dreg) error(-1);
-    drn = register_name(dreg);
+    if (reg==USE_CREG) {
+	dreg=get_register(); if (!dreg) error(-1);
+	drn = register_name(dreg);
+	set_ireg(dreg,0);
+    } else {
+	drn = register_name(reg);
+    }
     printf("\t%s %s,0(%s)\n",cload(sz),drn,xrn);
     if (use && sign && sz!=size_of_int) 
 	printf("\t%s %s,%s\n",cext(sz),drn,drn);
     printf("\taddi %s,%s,%d\n",drn,drn,dir);
     printf("\t%s %s,0(%s)\n",cstore(sz),drn,xrn);
-    i=creg;creg=dreg;dreg=i;
-    ireg=creg;
-    free_register(dreg);
 }
 
 
 void
 code_postinc(int e1,int e2,int dir,int sign,int sz,int reg) {
     char *xrn,*crn,*nrn;
-    int dreg,nreg,i;
+    int dreg,nreg;
     if (car(e2)==REGISTER) {
+	use_int(reg);
 	printf("\tmr %s,%s\n",register_name(reg),register_name(cadr(e2)));
 	printf("\taddi %s,%s,%d\n", 
 	    register_name(cadr(e2)),register_name(cadr(e2)),dir);
 	return;
     } 
     g_expr(e2);
+    if (!is_int_reg(creg)) error(-1);
     crn = register_name(creg);
-    dreg=get_register(); if (!dreg) error(-1);
-    xrn = register_name(dreg);
     nreg=get_register(); if (!nreg) error(-1);
     nrn = register_name(nreg);
+    if (reg==USE_CREG) {
+	dreg=get_register(); if (!dreg) error(-1);
+	xrn = register_name(dreg);
+	set_ireg(dreg,0);
+    } else {
+	xrn = register_name(reg);
+    }
     printf("\t%s %s,0(%s)\n",cload(sz),xrn,crn);
     if (use && sign && sz!=size_of_int) 
 	printf("\t%s %s,%s\n",cext(sz),xrn,xrn);
     printf("\taddi %s,%s,%d\n",nrn,xrn,dir);
     printf("\t%s %s,0(%s)\n",cstore(sz),nrn,crn);
-    i=creg;creg=dreg;dreg=i; 
     free_register(nreg);
-    free_register(dreg);
-    ireg=creg;
 }
 
 
 void
 code_return(int creg) {
-    char *crn = register_name(creg);
+    char *crn;
+    use_int(creg);
+    crn = register_name(creg);
     printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",crn,retcont,code_base);
     printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",crn,retcont,code_base,crn);
 }
@@ -1143,6 +1193,7 @@
 void
 code_environment(int creg) {
     /* save frame pointer */
+    use_int(creg);
 #if R1SAVE
     printf("\tlwz %s,0(r1)\n",register_name(creg));
 #else
@@ -1153,12 +1204,12 @@
 }
 
 void
-code_bool(int e1) {
+code_bool(int e1,int reg) {
     char *xrn;
     int e2,e3;
     b_expr(e1,1,e2=fwdlabel(),1);  /* including > < ... */
-    creg = use_int(creg);
-    xrn = register_name(creg);
+    use_int(reg);
+    xrn = register_name(reg);
     printf("\tli %s,0\n",xrn);
     jmp(e3=fwdlabel());
     fwddef(e2);
@@ -1192,9 +1243,11 @@
 }
 
 void
-code_cmp_crgvar(int e1,int sz) {
+code_cmp_crgvar(int e1,int reg,int sz) {
     int r;
-    char *crn = register_name(creg);
+    char *crn;
+    use_int(reg);
+    crn = register_name(reg);
     r = get_ptr_cache((NMTBL*)cadr(e1));
     printf("\t%s %s,0(%s)\n",cload(sz),crn,register_name(r));
     printf("\tcmpwi cr0,%s,0\n",crn);
@@ -1202,38 +1255,44 @@
 
 
 void
-code_cmp_crlvar(int e2,int sz) {
-    char *crn = register_name(creg);
+code_cmp_crlvar(int e2,int reg, int sz) {
+    char *crn;
+    use_int(reg);
+    crn = register_name(reg);
     lvar_intro(e2);
     printf("\t%s %s,",cload(sz),crn);
     lvar(e2);
-    code_cmp_register(creg);
+    code_cmp_register(reg);
 }
 
 
 void
-code_cmp_rgvar(int e1) {
+code_cmp_rgvar(int e1,int reg) {
     int r;
-    char *crn = register_name(creg);
-    if (!is_int_reg(creg)) error(-1);
+    char *crn;
+    use_int(reg);
+    crn = register_name(reg);
     r = get_ptr_cache((NMTBL*)cadr(e1));
     printf("\tlwz %s,0(%s)\n",crn,register_name(r));
-    code_cmp_register(creg);
+    code_cmp_register(reg);
 }
 
 
 void
-code_cmp_rlvar(int e2) {
-    char *crn = register_name(creg);
+code_cmp_rlvar(int e2,int reg) {
+    char *crn;
+    use_int(reg);
+    crn = register_name(reg);
     lvar_intro(e2);
     printf("\tlwz %s,",crn);
     lvar(e2);
-    code_cmp_register(creg);
+    code_cmp_register(reg);
 }
 
 
 void
 code_cmp_register(int e2) {
+    use_int(e2);
     printf("\tcmpwi cr0,%s,0\n",register_name(e2));
 }
 
@@ -1263,7 +1322,9 @@
 {
     char *s,*crn;
     int lb;
-    crn=register_name(creg);
+
+    use_int(creg);
+    crn = register_name(creg);
 
     s=(char *)cadr(e1);
     printf(".data\t\n.cstring\n\t.align 2\n");
@@ -1285,13 +1346,18 @@
 
 emit_copy(int from,int  to,int length,int offset,int value,int det)
 {
-    char *frn =	register_name(from);
-    char *trn =	register_name(to);
+    char *frn;
+    char *trn;
     char *drn;
     int fix = 0;
     char *memmove = "memmove";
     int dreg = get_register(); if (!dreg) error(-1);
+
     drn	 = register_name(dreg);
+    use_int(from);
+    use_int(to);
+    frn =	register_name(from);
+    trn =	register_name(to);
 
     /* length <0 means upward direction copy */
     switch (length) {
@@ -1347,7 +1413,7 @@
     /* otherwise we don't need this */
 	if (fix) printf("\taddi %s,%s,%d\n",trn,trn,fix);
 	if(creg!=to) {
-	    free_register(creg); creg=to;
+	    free_register(creg); creg=to; ireg=to;
 	}
     }
     free_register(dreg);
@@ -1359,6 +1425,7 @@
     int length,count;
     int dreg,sreg; char *drn,*crn,*srn;
     g_expr(e4);
+    if (!is_int_reg(creg)) error(-1);
     length=size(t); 
     if(length%size_of_int) {
 	length += size_of_int - (length%size_of_int);
@@ -1427,6 +1494,8 @@
 set_lreg(int reg,int mode)
 {
     if (!is_longlong_reg(reg)) error(-1);
+    if (regv_l(reg)==0) regv_l(reg)=get_register();
+    if (regv_h(reg)==0) regv_h(reg)=get_register();
     if (reg!=creg) {
 	if (reg!=lreg) {
 	    free_register(lreg);
@@ -1530,6 +1599,7 @@
 	!contains_in_list(e3,CONV) &&
 	!contains_in_list(e3,RSTRUCT) &&
 	!contains_in_list(e3,STASS)
+        // and more?
     ;
 }
 
@@ -1572,6 +1642,7 @@
 	if (car(jmp)!=REGISTER) error(-1);
 	reg_arg_list = list2(jmp,reg_arg_list);
 	g_expr(e2);
+	if (!is_int_reg(creg)) error(-1);
 	code_register(creg,cadr(jmp));
         /* g_expr(assign_expr0(jmp,e2,INT,INT)); functions are lvalue */
     }
@@ -1579,8 +1650,8 @@
     /* now all input register vars are free */
     code_save_stacks();
     set_lreg(LREG_LREGISTER,0);
+    set_freg(FREG_FREGISTER,0);
     set_ireg(CREG_REGISTER,0);
-    set_freg(FREG_FREGISTER,0);
 
     nargs = reg_arg = freg_arg = arg_assign = 0;
     for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {	
@@ -1726,6 +1797,7 @@
 
 void
 code_frame_pointer(int e3) {
+    use_int(e3);
 #if R1SAVE
     printf("\tmr r1,%s\n",register_name(e3));
 #else
@@ -1753,76 +1825,89 @@
 code_indirect_jmp(int e2) {
     max_reg_var = REG_VAR_BASE-REG_VAR_MIN;
     max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN;
+    use_int(e2);
     printf("\tmtctr %s\n",register_name(e2));
     printf("\tbctr\n");
 }
 
 int
-code_rindirect(int e1, int offset, int us)
+code_rindirect(int e1, int reg,int offset, int us)
 {
-    char *crn;
+    char *crn,*rrn;
     g_expr(e1);
+    if (!is_int_reg(creg)) error(-1);
     crn=register_name(creg);
-    printf("\tlwz %s,%d(%s)\n",crn,offset,crn);
+    use_int(reg);
+    rrn=register_name(reg);
+    printf("\tlwz %s,%d(%s)\n",rrn,offset,crn);
     return us?UNSIGNED:INT;
 }
 
 int
-code_crindirect(int e1, int offset, int us)
+code_crindirect(int e1, int reg,int offset, int us)
 {
-    char *crn;
+    char *crn,*rrn;
     g_expr(e1);
+    if (!is_int_reg(creg)) error(-1);
     crn=register_name(creg);
+    use_int(reg);
+    rrn=register_name(reg);
+    
     if (us) {
-	printf("\tlbz %s,%d(%s)\n",crn,offset,crn);
+	printf("\tlbz %s,%d(%s)\n",rrn,offset,crn);
 	return UCHAR;
     } else {
-	printf("\tlbz %s,%d(%s)\n",crn,offset,crn);
-	printf("\textsb %s,%s\n",crn,crn);
+	printf("\tlbz %s,%d(%s)\n",rrn,offset,crn);
+	printf("\textsb %s,%s\n",rrn,rrn);
 	return CHAR;
     }
 }
 
 int
-code_srindirect(int e1, int offset, int us)
+code_srindirect(int e1, int reg,int offset, int us)
 {
-    char *crn;
+    char *crn,*rrn;
     g_expr(e1);
+    if (!is_int_reg(creg)) error(-1);
     crn=register_name(creg);
+    use_int(reg);
+    rrn = register_name(reg);
     if (us) {
-	printf("\tlhz %s,%d(%s)\n",crn,offset,crn);
+	printf("\tlhz %s,%d(%s)\n",rrn,offset,crn);
 	return USHORT;
     } else {
-	printf("\tlhz %s,%d(%s)\n",crn,offset,crn);
-	printf("\textsh %s,%s\n",crn,crn);
+	printf("\tlhz %s,%d(%s)\n",rrn,offset,crn);
+	printf("\textsh %s,%s\n",rrn,rrn);
 	return SHORT;
     }
 }
 
 #if FLOAT_CODE
 int
-code_drindirect(int e1, int offset, int d)
+code_drindirect(int e1, int reg,int offset, int d)
 {
     char *crn;
     g_expr(e1);
+    if (!is_int_reg(creg)) error(-1);
     crn=register_name(creg);
-    creg = d?use_double(creg):use_float(creg);
+    use_float(d,reg);
     printf("\t%s %s,%d(%s)\n",fload(d),
-	fregister_name(freg),offset,crn);
+	fregister_name(reg),offset,crn);
     return d?DOUBLE:FLOAT;
 }
 #endif
 
 #if LONGLONG_CODE
 int
-code_lrindirect(int e1, int offset, int us)
+code_lrindirect(int e1, int reg, int offset, int us)
 {
     char *crn;
     g_expr(e1);
+    if (!is_int_reg(creg)) error(-1);
     crn=register_name(creg);
-    creg = use_longlong(creg);
-    printf("\tlwz %s,%d(%s)\n",crn,offset,lregister_name_low(lreg));
-    printf("\tlwz %s,%d(%s)\n",crn,offset+size_of_int,lregister_name_high(lreg));
+    use_longlong(reg);
+    printf("\tlwz %s,%d(%s)\n",lregister_name_low(reg),offset,crn);
+    printf("\tlwz %s,%d(%s)\n",lregister_name_high(reg),offset+size_of_int,crn);
     return us?ULONGLONG:LONGLONG;
 }
 #endif
@@ -1831,6 +1916,7 @@
 void
 code_assign_gvar(int e2,int creg,int byte) {
     int r;
+    use_int(creg);
     r = get_ptr_cache((NMTBL*)cadr(e2));
     code_assign(r,byte,creg);
 }
@@ -1838,6 +1924,7 @@
 void
 code_assign_lvar(int e2,int creg,int byte) {
     char *crn;
+    use_int(creg);
     crn=register_name(creg);
     lvar_intro(e2);
     if (byte==1) {
@@ -1852,6 +1939,7 @@
 
 void
 code_assign_register(int e2,int byte,int creg) {
+    use_int(creg);
     if (e2!=creg)
 	printf("\tmr %s,%s\n",register_name(e2),register_name(creg));
 }
@@ -1859,7 +1947,9 @@
 void
 code_assign(int e2,int byte,int creg) {
     char *drn=register_name(e2);
-    char *crn=register_name(creg);
+    char *crn;
+    use_int(creg);
+    crn=register_name(creg);
 
     if (byte==1) {
 	printf("\tstb %s,0(%s)\n",crn,drn);
@@ -1872,26 +1962,24 @@
 
 
 void
-code_register_assop(int e2,int op,int byte) {
-    int reg;
-    int xreg = creg;
-    creg = reg = e2;
-    tosop(op,xreg);
-    creg = xreg;
-    if (creg!=reg)
-	printf("\tmr %s,%s\n",register_name(creg),register_name(reg));
+code_register_assop(int e2,int reg, int op,int byte) {
+    //  reg <= reg(e2) op=reg
+    use_int(reg);
+    tosop(op,e2,reg);
 }
 
-
 void
-code_assop(int op,int byte,int sign) {
+code_assop(int op,int creg, int byte,int sign) {
     char *xrn,*crn,*drn;
     int xreg;
     int edx = get_register(); if(!edx) error(-1);
+    //  (*creg) op = pop()
+
+    use_int(creg);
     xrn = register_name(xreg = emit_pop(0));       /* pop e3 value */
     printf("# assop\n\tmr %s,%s\n",register_name(edx),register_name(creg));
-    ld_indexx(byte,0,edx,sign);
-    tosop(op,xreg);
+    ld_indexx(byte,0,edx,creg,sign);
+    tosop(op,creg,xreg);
     crn = register_name(creg);
     drn = register_name(edx);
     if (byte==1) {
@@ -1907,11 +1995,13 @@
 
 
 void
-tosop(int op,int oreg)
+tosop(int op,int creg,int oreg)
 {
-    int dx;
+    int dx = -1;
     char *orn,*crn,*drn;
-
+    // creg = creg op oreg
+
+    use_int(creg);
     if(oreg==-1) {
 	error(-1);
     } else if (oreg<= -REG_LVAR_OFFSET) {
@@ -1923,13 +2013,13 @@
     switch(op) {
     case LSHIFT:
     case ULSHIFT:
-	shift("slw",oreg);
+	shift("slw",creg,oreg);
 	return;
     case RSHIFT:
-	shift("sraw",oreg);
+	shift("sraw",creg,oreg);
 	return;
     case URSHIFT:
-	shift("srw",oreg);
+	shift("srw",creg,oreg);
 	return;
     }
     orn = register_name(oreg);
@@ -1971,7 +2061,6 @@
 	printf("\tdivw %s,%s,%s\n",drn,crn,orn);
 	printf("\tmullw %s,%s,%s\n",drn,drn,orn);
 	printf("\tsubf %s,%s,%s\n",crn,drn,crn);
-	free_register(dx);
 	break;
     case UMOD:
 	dx=get_register();
@@ -1979,12 +2068,11 @@
 	printf("\tdivwu %s,%s,%s\n",drn,crn,orn);
 	printf("\tmullw %s,%s,%s\n",drn,drn,orn);
 	printf("\tsubf %s,%s,%s\n",crn,drn,crn);
-	free_register(dx);
 	break;
     default:
 	error(-1);
     }
-    if(oreg!=creg) free_register(oreg);
+    if(dx!=-1) free_register(dx);
 }
 
 int 
@@ -1995,10 +2083,12 @@
 }
 
 void
-oprtc(int op,int v)
+oprtc(int op,int creg, int v)
 {
-    char *crn = register_name(creg);
-
+    char *crn;
+    use_int(creg);
+    crn = register_name(creg);
+    
     switch(op) {
     case LSHIFT:
     case ULSHIFT:
@@ -2014,7 +2104,7 @@
 	printf("\taddi %s,%s,lo16(%d)\n",crn,crn,v);
 	break;
     case SUB:
-	printf("\tsubi %s,%s,lo16(%d)\n",crn,crn,v);
+	printf("\taddi %s,%s,lo16(-%d)\n",crn,crn,v);
 	break;
     case CMP:
 	printf("\tcmpwi cr0,%s,lo16(%d)\n",crn,v);
@@ -2037,17 +2127,21 @@
 }
 
 void
-shift(char *op, int reg)
+shift(char *op, int creg, int reg)
 {
-    char *crn = register_name(creg);
+    char *crn;
     char *rrn = register_name(reg);
+    use_int(creg);
+    crn = register_name(creg);
     printf("\t%s %s,%s,%s\n",op,crn,crn,rrn);
 }
 
 void
-ld_indexx(int byte, int n, int xreg,int sign)
+ld_indexx(int byte, int n, int xreg,int creg, int sign)
 {	
-    char *crn = register_name(creg);
+    char *crn;
+    use_int(creg);
+    crn = register_name(creg);
     if (byte==1) {
 	printf("\tlbz %s,%d(%s)\n",register_name(creg),n,
 	    register_name(xreg));
@@ -2584,6 +2678,7 @@
     char *frn,*rrn,*grn;
     int greg,r;
     grn =  register_name(greg = get_dregister(d));
+    use_float(d,e2);
     frn = register_name(e2);
     float_zero_lib_used=1;
     r = get_ptr_cache(&float_zero);
@@ -2597,6 +2692,7 @@
 void
 code_dregister(int e2,int freg,int d)
 {
+    use_float(d,freg);
     if (freg!=e2) {
 	if (is_int_reg(e2)) error(-1);
 	printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2));
@@ -2607,16 +2703,16 @@
 code_dassign_gvar(int e2,int freg,int d)
 { 
     int r;
+    use_float(d,freg);
     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));
 }
 
 void
 code_dassign_lvar(int e2,int freg,int d)
 { 
+    use_float(d,freg);
     lvar_intro(e2);
-    if (!is_float_reg(freg)) error(-1);
     printf("\t%s %s,",fstore(d),fregister_name(freg));
     lvar(e2);
 }
@@ -2624,14 +2720,14 @@
 void
 code_dassign(int e2,int freg,int d)
 { 
-    if (!is_float_reg(freg)) error(-1);
+    use_float(d,freg);
     printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(e2));
 }
 
 void
 code_dassign_dregister(int e2,int d,int freg) {
+    use_float(d,freg);
     if (e2!=freg) {
-	if (is_int_reg(freg)) error(-1);
 	printf("\tfmr %s,%s\n",fregister_name(e2),fregister_name(freg));
     }
 }
@@ -2668,6 +2764,8 @@
     double value = dcadr(e2);
     int r;
     char *rrn,*frn;
+
+    use_float(d,freg);
     frn = fregister_name(freg);
     if (value==0.0) {
 	float_zero_lib_used=1;
@@ -2711,24 +2809,24 @@
 void
 code_dneg(int freg,int d)
 { 
-    char *frn = fregister_name(freg);
-    if (is_int_reg(freg)) error(-1);
+    char *frn;
+    use_float(d,freg);
+    frn = fregister_name(freg);
     printf("\tfneg %s,%s\n",frn,frn);
 }
 
 void
-code_d2i(int freg0)
+code_d2i()
 { 
     char *frn;
     char *crn;
     int e2 = new_lvar(size_of_double);
 
-    freg0 = use_double(freg0);
-    frn = fregister_name(freg0);
-    creg = use_int(creg);
+    use_double0();
+    frn = fregister_name(freg);
+    use_int0();
     crn = register_name(creg);
 
-    freg = freg0;
     free_lvar(e2);
     printf("\tfctiwz  %s,%s\n",frn,frn);
     lvar_intro(e2);
@@ -2766,7 +2864,7 @@
 };
 
 void
-code_i2d(int creg0)
+code_i2d()
 { 
     i2d_lib_used = 1;
     clear_ptr_cache();
@@ -2813,7 +2911,7 @@
 };
 
 void
-code_d2u(int freg0)
+code_d2u()
 { 
     code_save_stacks();
     clear_ptr_cache();
@@ -2851,7 +2949,7 @@
 };
 
 void
-code_u2d(int creg0)
+code_u2d()
 { 
     code_save_stacks();
     clear_ptr_cache();
@@ -2862,23 +2960,24 @@
 }
 
 void
-code_d2f(int freg) { }
+code_d2f() { }
 void
-code_f2d(int freg) { }
+code_f2d() { }
 void
-code_f2i(int freg) { code_d2i(freg); }
+code_f2i() { code_d2i(); }
 void
-code_f2u(int freg) { code_d2u(freg); }
+code_f2u() { code_d2u(); }
 void
-code_i2f(int creg) { code_i2d(creg); }
+code_i2f() { code_i2d(); }
 void
-code_u2f(int creg) { code_u2d(creg); }
+code_u2f() { code_u2d(); }
 
 void
 code_drgvar(int e2,int d,int freg)
 { 
     int r;
     r = get_ptr_cache((NMTBL*)cadr(e2));
+    use_float(d,freg);
     printf("\t%s %s,0(%s)\n",fload(d),fregister_name(freg),register_name(r));
 }
 
@@ -2886,17 +2985,22 @@
 void
 code_drlvar(int e2,int d,int freg)
 { 
+    use_float(d,freg);
     lvar_intro(e2);
     printf("\t%s %s,",fload(d),fregister_name(freg)); lvar(e2);
 }
 
 void
-code_cmp_drgvar(int e2,int d)
+code_cmp_drgvar(int e2,int reg,int d)
 { 
     int r;
-    char *frn=fregister_name(freg);
+    char *frn;
     int g=get_dregister(d);
     char *grn=fregister_name(g);
+
+    use_float(d,reg);
+    frn=fregister_name(reg);
+
     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);
@@ -2904,12 +3008,15 @@
 }
 
 void
-code_cmp_drlvar(int e2,int d)
+code_cmp_drlvar(int e2,int reg,int d)
 { 
-    char *frn=fregister_name(freg);
+    char *frn;
     int g=get_dregister(d);
     char *grn=fregister_name(g);
 
+    use_float(d,reg);
+    frn=fregister_name(reg);
+
     lvar_intro(e2);
     printf("\t%s %s,",fload(1),grn); lvar(e2);
     printf("\tfcmpu cr0,%s,%s\n",frn,grn);
@@ -2917,11 +3024,14 @@
 }
 
 void
-dtosop(int op,int e1)
+dtosop(int op,int reg,int e1)
 { 
     char *opn="";
-    char *frn=fregister_name(freg);
+    char *frn;
     char *grn=fregister_name(e1);
+
+    use_float(1,reg);
+    frn=fregister_name(reg);
     switch(op) {
     case FADD:
     case DADD: opn="fadd"; break;
@@ -2945,37 +3055,32 @@
 	error(-1); return;
     }
     printf("\t%s %s,%s,%s\n",opn,frn,frn,grn);
-    free_register(e1);
 }
 
 void
-code_dassop(int op,int d) {
+code_dassop(int op,int reg,int d) {
     /* we have lvalue in creg, applied floating value is in freg */
+    //  (*creg) op = pop()
     int  xreg=emit_dpop(d);
-    char *crn=register_name(creg);
+    char *crn;
     char *frn;
-    creg = d?use_double(creg):use_float(creg);
-    frn  =fregister_name(freg);
+
+    crn=register_name(ireg);
+    use_float(d,reg);
+    frn  =fregister_name(reg);
 
     printf("\t%s %s,0(%s)\n",fload(d),frn,crn);
-    dtosop(op,xreg);
+    dtosop(op,reg,xreg);
     printf("\t%s %s,0(%s)\n",fstore(d),frn,crn);
     emit_dpop_free(xreg,d);
 }
 
 void
 code_register_dassop(int reg,int op,int d) {
+    // reg op= dpop()
     int  xreg=emit_dpop(d);
-    set_freg(reg,0);
-    dtosop(op,xreg);
-    if (creg==reg) {
-	printf("\tfmr %s,%s\n",fregister_name(xreg),fregister_name(freg));
-	free_register(freg);
-	freg = creg = xreg;
-    } else {
-	printf("\tfmr %s,%s\n",fregister_name(reg),fregister_name(freg));
-	emit_dpop_free(xreg,d);
-    }
+    dtosop(op,reg,xreg);
+    emit_dpop_free(xreg,d);
 }   
 
 void
@@ -2987,30 +3092,32 @@
     int r;
 
     if (car(e2)==DREGISTER||car(e2)==FREGISTER) {
-	error(-1); /* unspported now */
+	crn=register_name(cadr(e2));
+    } else {
+	g_expr(e2);
+	if (!is_int_reg(creg)) error(-1);
+	crn=register_name(ireg);
     }
-    g_expr(e2);
 
     float_one_lib_used=1;
     r = get_ptr_cache(&float_one);
     drn=register_name(r);
 
-    crn=register_name(creg);
-
-    creg = d?use_double(creg):use_float(creg);
-    frn=fregister_name(freg);
+    use_float(d,reg);
+
+    frn=fregister_name(reg);
     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",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);
+
+    if (car(e2)==DREGISTER||car(e2)==FREGISTER) {
+	printf("\tfmr %s,%s\n",crn,frn);
+	printf("\t%s %s,%s,%s\n",(caddr(e1)>0)?"fadd":"fsub",crn,frn,grn);
+    } else {
+	printf("\t%s %s,0(%s)\n",fload(d),frn,crn);
+	printf("\t%s %s,%s,%s\n",(caddr(e1)>0)?"fadd":"fsub",frn,frn,grn);
+	printf("\t%s %s,0(%s)\n",fstore(d),frn,crn);
+    }
     free_register(g);
-    creg = freg;
 }
 
 void
@@ -3022,30 +3129,32 @@
     int r;
 
     if (car(e2)==DREGISTER||car(e2)==FREGISTER) {
-	error(-1); /* unspported now */
+	crn=register_name(cadr(e2));
+    } else {
+	g_expr(e2);
+	if (!is_int_reg(creg)) error(-1);
+	crn=register_name(creg);
     }
-    g_expr(e2);
-
-    crn=register_name(creg);
 
     float_one_lib_used=1;
     r = get_ptr_cache(&float_one);
     drn=register_name(r);
 
-    creg = d?use_double(creg):use_float(creg);
-    frn=fregister_name(freg);
+    use_float(d,reg);
+
+    frn=fregister_name(reg);
     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);
+
+    if (car(e2)==DREGISTER||car(e2)==FREGISTER) {
+	printf("\t%s %s,%s,%s\n",(caddr(e1)>0)?"fadd":"fsub",frn,crn,grn);
+	printf("\tfmr %s,%s\n",frn,crn);
+    } else {
+	printf("\t%s %s,0(%s)\n",fload(d),frn,crn);
+	printf("\t%s %s,%s,%s\n",(caddr(e1)>0)?"fadd":"fsub",grn,frn,grn);
+	printf("\t%s %s,0(%s)\n",fstore(d),grn,crn);
+    }
     free_register(g);
-    creg = freg;
 }
 
 void
@@ -3096,8 +3205,9 @@
 emit_dpush(int d)
 { 
     int new_reg;
+    if (!is_float_reg(creg)) error(-1);
     if (freg_sp>MAX_MAX) error(-1);
-    new_reg = get_dregister(1);
+    new_reg = get_dregister(1);       /* 絶対に取れる */
     freg_stack[freg_sp++] = freg;     /* push するかわりにレジスタを使う */
     creg = freg = new_reg;
 }
@@ -3124,15 +3234,16 @@
 void
 lrexpr(int e1, int e2,int l1, int op)
 {
-    int creg_save;
+    int reg;
     int e3;
     g_expr(e1);
     emit_lpush();
     g_expr(e2);
     e3 = emit_lpop();
-
-    creg = regv_h(creg_save = creg);
-    tosop(CMP,regv_h(e3));
+    if (!is_longlong_reg(creg)) error(-1);
+    reg = lreg;
+
+    tosop(CMP,regv_h(reg),regv_h(e3));
     switch(op) {
     case LOP+GT:
     	cond(code_gt(1),l1); break;
@@ -3153,8 +3264,7 @@
     default:
 	error(-1);
     }
-    creg = regv_l(creg_save);
-    tosop(CMP,regv_l(e3));
+    tosop(CMP,regv_l(reg),regv_l(e3));
     switch(op) {
     case LOP+GT:
     	cond(code_gt(1),l1); break;
@@ -3201,14 +3311,16 @@
 void
 code_lregister(int e2,int reg)
 {
-    if (creg!=e2) {
-	lmove(creg,e2);
+    use_longlong(reg);
+    if (reg!=e2) {
+	lmove(reg,e2);
     }
 }
 
 void
 code_cmp_lregister(int reg)
 {
+    use_longlong(reg);
     printf("\tor %s,%s,%s\n",
 		lregister_name_low(reg),
 		lregister_name_low(reg),
@@ -3219,6 +3331,7 @@
 void
 code_cmp_lrgvar(int e1,int creg)
 {
+    use_longlong(creg);
     code_lrgvar(e1,creg);
     code_cmp_lregister(creg);
 }
@@ -3226,6 +3339,7 @@
 void
 code_cmp_lrlvar(int e1,int creg)
 {
+    use_longlong(creg);
     code_lrlvar(e1,creg);
     code_cmp_lregister(creg);
 }
@@ -3234,8 +3348,12 @@
 code_lassign(int e2,int creg)
 {
     char *drn = register_name(e2);
-    char *crn_h = lregister_name_high(creg);
-    char *crn_l = lregister_name_low(creg);
+    char *crn_h;
+    char *crn_l;
+
+    use_longlong(creg);
+    crn_h = lregister_name_high(creg);
+    crn_l = lregister_name_low(creg);
 
     printf("\tstw %s,0(%s)\n",crn_h,drn);
     printf("\tstw %s,%d(%s)\n",crn_l,size_of_int,drn);
@@ -3245,7 +3363,6 @@
 code_lassign_gvar(int e2,int creg)
 {
     int r;
-    if (!is_longlong_reg(creg)) error(-1);
     r = get_ptr_cache((NMTBL*)cadr(e2));
     code_lassign(r,creg);
 }
@@ -3253,8 +3370,12 @@
 void
 code_lassign_lvar(int e2,int creg)
 {
-    char *crn_h = lregister_name_high(creg);
-    char *crn_l = lregister_name_low(creg);
+    char *crn_h;
+    char *crn_l;
+
+    use_longlong(creg);
+    crn_h = lregister_name_high(creg);
+    crn_l = lregister_name_low(creg);
     lvar_intro(e2);
     printf("\tstw %s,",crn_h);lvar(e2);
     printf("\tstw %s,",crn_l);lvar(e2+size_of_int);
@@ -3263,6 +3384,7 @@
 void
 code_lassign_lregister(int e2,int reg)
 {
+    use_longlong(reg);
     if (e2!=reg) {
 	lmove(e2,reg);
     }
@@ -3287,6 +3409,7 @@
 void
 code_lconst(int e1,int creg)
 {
+    use_longlong(creg);
     code_const(code_l1(lcadr(e1)),regv_l(creg));
     code_const(code_l2(lcadr(e1)),regv_h(creg));
 }
@@ -3294,19 +3417,22 @@
 void
 code_lneg(int creg)
 {
+    use_longlong(creg);
     printf("\tsubfic %s,%s,0\n",
 	lregister_name_low(creg),lregister_name_low(creg));
-    printf("\tsubfze %s,%s,0\n",
+    printf("\tsubfze %s,%s\n",
 	lregister_name_high(creg),lregister_name_high(creg));
 }
 
 void
-code_lrgvar(int e1,int e2)
+code_lrgvar(int e1,int creg)
 {
     int r;
-    char *crn_h = lregister_name_high(creg);
-    char *crn_l = lregister_name_low(creg);
-    if (!is_longlong_reg(creg)) error(-1);
+    char *crn_h;
+    char *crn_l;
+    use_longlong(creg);
+    crn_h = lregister_name_high(creg);
+    crn_l = lregister_name_low(creg);
     r = get_ptr_cache((NMTBL*)cadr(e1));
     printf("\tlwz %s,0(%s)\n",crn_h,register_name(r));
     printf("\tlwz %s,%d(%s)\n",crn_l,size_of_int,register_name(r));
@@ -3315,13 +3441,17 @@
 void
 code_lrlvar(int e1,int creg)
 {
-    char *crn_h = lregister_name_high(creg);
-    char *crn_l = lregister_name_low(creg);
+    char *crn_h;
+    char *crn_l;
+    use_longlong(creg);
+    crn_h = lregister_name_high(creg);
+    crn_l = lregister_name_low(creg);
     lvar_intro(e1);
     printf("\tlwz %s,",crn_h); lvar(e1);
     printf("\tlwz %s,",crn_l); lvar(e1+size_of_int);
 }
 
+#if 0
 static int lumod_lib_used=0;
 static char *lumod_lib[] = {
 };
@@ -3337,6 +3467,7 @@
 static int ldiv_lib_used=0;
 static char *ldiv_lib[] = {
 };
+#endif
 
 static int lsrd_lib_used=0;
 static char *lsrd_lib[] = {
@@ -3479,7 +3610,7 @@
     asld_lib_used = 1;
     set_lreg(RET_LREGISTER,1);
     set_lreg_operand(oreg,1);
-    printf("\tbl asld_\n");
+    printf("\tbl asld__\n");
 }
 
 static void
@@ -3490,7 +3621,7 @@
     asrd_lib_used = 1;
     set_lreg(RET_LREGISTER,1);
     set_lreg_operand(oreg,1);
-    printf("\tbl asrd_\n");
+    printf("\tbl asrd__\n");
 }
 
 static void
@@ -3501,48 +3632,52 @@
     lsrd_lib_used = 1;
     set_lreg(RET_LREGISTER,1);
     set_lreg_operand(oreg,1);
-    printf("\tbl lsrd_\n");
+    printf("\tbl lsrd__\n");
 }
 
 static void
 code_ldiv_lib(int oreg) // ___divdi3$stub
 {
+    set_lreg(RET_LREGISTER,1);
     set_lreg_operand(oreg,1);
-    set_lreg(RET_LREGISTER,1);
     extern_conv("__divdi3");
 }
 
 static void
 code_ludiv_lib(int oreg) // ___udivdi3$stub
 {
+    set_lreg(RET_LREGISTER,1);
     set_lreg_operand(oreg,1);
-    set_lreg(RET_LREGISTER,1);
     extern_conv("__udivdi3");
 }
 
 static void
 code_lmod_lib(int oreg) // ___moddi3$stub
 {
+    set_lreg(RET_LREGISTER,1);
     set_lreg_operand(oreg,1);
-    set_lreg(RET_LREGISTER,1);
     extern_conv("__moddi3");
 }
 
 static void
 code_lumod_lib(int oreg) // ___umoddi3$stub
 {
+    set_lreg(RET_LREGISTER,1);
     set_lreg_operand(oreg,1);
-    set_lreg(RET_LREGISTER,1);
     extern_conv("__umoddi3");
 }
 
+#define check_lreg(reg) if (reg!=lreg) { lmove(reg,lreg); }
+
 void
-ltosop(int op,int oreg)
+ltosop(int op,int reg,int oreg)
 {
-    int dx;
+    int dx = -1;
     char *orn_h,*crn_h,*drn_h;
     char *orn_l,*crn_l,*drn_l;
-
+    // creg = creg op oreg
+
+    use_longlong(reg);
     if(oreg==-1) {
 	error(-1);
     } else if (oreg<= -REG_LVAR_OFFSET) {
@@ -3555,18 +3690,21 @@
     case LLSHIFT:
     case LULSHIFT:
 	code_asld_lib(oreg); // ___ashldi3$stub
+	check_lreg(reg);
 	return;
     case LRSHIFT:
 	code_asrd_lib(oreg); // ___ashrdi3$stub
+	check_lreg(reg);
 	return;
     case LURSHIFT:
 	code_lsrd_lib(oreg); // ___lshrdi3$stub
+	check_lreg(reg);
 	return;
     }
     orn_h = lregister_name_high(oreg);
     orn_l = lregister_name_low(oreg);
-    crn_h = lregister_name_high(creg);
-    crn_l = lregister_name_low(creg);
+    crn_h = lregister_name_high(reg);
+    crn_l = lregister_name_low(reg);
     switch(op) {
     case LADD:
 	printf("\taddc %s,%s,%s\n",crn_l,crn_l,orn_l);
@@ -3615,20 +3753,24 @@
 	break;
     case LDIV:
 	code_ldiv_lib(oreg); // ___divdi3$stub
+	check_lreg(reg);
 	break;
     case LUDIV:
 	code_ludiv_lib(oreg); // ___udivdi3$stub
+	check_lreg(reg);
 	break;
     case LMOD:
 	code_lmod_lib(oreg); // ___moddi3$stub
+	check_lreg(reg);
 	break;
     case LUMOD:
 	code_lumod_lib(oreg); // ___umoddi3$stub
+	check_lreg(reg);
 	break;
     default:
 	error(-1);
     }
-    if(oreg!=creg) free_register(oreg);
+    if(dx!=-1) free_register(dx);
 }
 
 int
@@ -3660,14 +3802,18 @@
 }
 
 void
-loprtc(int op,int e)
+loprtc(int op,int creg,int e)
 {
-    char *crn_h = lregister_name_high(creg);
-    char *crn_l = lregister_name_low(creg);
+    char *crn_h;
+    char *crn_l;
     char *grn;
     int v;
     int greg;
 
+    use_longlong(creg);
+    crn_h = lregister_name_high(creg);
+    crn_l = lregister_name_low(creg);
+
     if (car(e)==LCONST) v = lcaddr(e);
     else if (car(e)==CONST) v = caddr(e);
 
@@ -3700,13 +3846,12 @@
 	printf("\tsrwi %s,%s,%d\n",crn_l,crn_l,v);
 	free_register(greg);
 	return;
-	return;
     case LADD:
 	printf("\taddi %s,%s,lo16(%d)\n",crn_l,crn_l,v);
 	printf("\taddze %s,%s\n",crn_h,crn_h);
 	break;
     case LSUB:
-	printf("\tsubi %s,%s,lo16(%d)\n",crn_l,crn_l,v);
+	printf("\taddi %s,%s,lo16(-%d)\n",crn_l,crn_l,v);
 	printf("\taddme %s,%s\n",crn_h,crn_h);
 	break;
     case LBOR:
@@ -3731,41 +3876,43 @@
     int new_reg;
     if (!is_longlong_reg(creg)) error(-1);
     if (lreg_sp>MAX_MAX) error(-1);
-    new_reg = get_lregister();
+    new_reg = get_lregister();        /* 絶対に取れる(?) */
     lreg_stack[lreg_sp++] = creg;     /* push するかわりにレジスタを使う */
     lreg = creg = new_reg;
 }
 
 void
-code_i2ll(int reg)
+code_i2ll()
 {
     char *crn,*crn_h,*crn_l;
     int creg0;
-    crn = register_name(reg);
-    creg = use_longlong(creg0=creg);
-    crn_h = lregister_name_high(creg);
-    crn_l = lregister_name_low(creg);
-    if (creg0!=regv_l(reg))
+    use_int0();
+    crn = register_name(creg0 = ireg);
+    use_longlong0();
+    crn_h = lregister_name_high(lreg);
+    crn_l = lregister_name_low(lreg);
+    if (creg0!=regv_l(lreg))
 	printf("\tmr %s,%s\n",crn_l,crn);
     printf("\tsrawi %s,%s,31\n",crn_h,crn_l);
 }
 
 void
-code_i2ull(int creg)
+code_i2ull()
 {
-    code_i2ll(creg);
+    code_i2ll();
 }
 
 void
-code_u2ll(int reg)
+code_u2ll()
 {
     int creg0;
     char *crn,*crn_h,*crn_l;
-    crn = register_name(reg);
-    creg = use_longlong(creg0=creg);
-    crn_h = lregister_name_high(creg);
-    crn_l = lregister_name_low(creg);
-    if (creg0!=regv_l(reg))
+    use_int0();
+    crn = register_name(creg0 = ireg);
+    use_longlong0();
+    crn_h = lregister_name_high(lreg);
+    crn_l = lregister_name_low(lreg);
+    if (creg0!=regv_l(lreg))
 	printf("\tmr %s,%s\n",crn_l,crn);
     printf("\tli %s,0\n",crn_h);
 }
@@ -3777,14 +3924,15 @@
 }
 
 void
-code_ll2i(int reg)
+code_ll2i()
 {
     char *crn_l;
-    if (!is_longlong_reg(reg)) { error(-1); return; }
-    crn_l = lregister_name_low(reg);
-    creg = use_int(creg);
-    if (creg!=regv_l(reg))
-	printf("\tmr %s,%s\n",register_name(creg),crn_l);
+    int reg;
+    use_longlong0();
+    crn_l = lregister_name_low(reg=lreg);
+    use_int0();
+    if (ireg!=regv_l(reg))
+	printf("\tmr %s,%s\n",register_name(ireg),crn_l);
 }
 
 void
@@ -3808,43 +3956,43 @@
 #if FLOAT_CODE
 
 void
-code_d2ll(int creg)
+code_d2ll()
 {
     // fixdfdi$stub
     set_freg(RET_FREGISTER,1);
-    extern_conv("_fixdfdi");
+    extern_conv("__fixdfdi");
     set_lreg(RET_LREGISTER,0);
 }
 
 void
-code_d2ull(int creg)
+code_d2ull()
 {
     set_freg(RET_FREGISTER,1);
-    extern_conv("_fixunsdfdi");
+    extern_conv("__fixunsdfdi");
     set_lreg(RET_LREGISTER,0);
 }
 
 void
-code_f2ll(int creg)
+code_f2ll()
 {
     set_freg(RET_FREGISTER,1);
-    extern_conv("_fixdfdi");
+    extern_conv("__fixdfdi");
     set_lreg(RET_LREGISTER,0);
 }
 
 void
-code_f2ull(int creg)
+code_f2ull()
 {
     set_freg(RET_FREGISTER,1);
-    extern_conv("_fixsfdi");
+    extern_conv("__fixsfdi");
     set_lreg(RET_LREGISTER,0);
 }
 
 void
-code_ll2d(int creg)
+code_ll2d()
 {
     set_lreg(RET_LREGISTER,1);
-    extern_conv("_floatdidf");
+    extern_conv("__floatdidf");
     set_freg(RET_FREGISTER,0);
 }
 
@@ -3853,7 +4001,7 @@
 code_ll2f(int creg)
 {
     set_lreg(RET_LREGISTER,1);
-    extern_conv("_floatdisf");
+    extern_conv("__floatdisf");
     set_freg(RET_FREGISTER,0);
 }
 
@@ -3871,6 +4019,11 @@
 
 #endif
 
+static char *
+addze(int dir)
+{
+    return dir>0?"ze":"me";
+}
 
 void
 code_lpreinc(int e1,int e2,int reg)
@@ -3879,9 +4032,10 @@
     int dreg;
     int dir=caddr(e1);
     if (car(e2)==LREGISTER) {
-        printf("\taddci %s,%s,%d\n", 
+	use_longlong(reg);
+        printf("\taddic %s,%s,%d\n", 
                 lregister_name_low(cadr(e2)),lregister_name_low(cadr(e2)), dir);
-        printf("\taddei %s,%s,0\n", 
+        printf("\tadd%s %s,%s\n", addze(dir),
                 lregister_name_high(cadr(e2)),lregister_name_high(cadr(e2)));
         if (cadr(reg)!=cadr(e2)) {
 	    lmove(cadr(reg),cadr(e2));
@@ -3889,17 +4043,23 @@
         return;
     } 
     g_expr(e2);
+    if(!is_int_reg(creg)) error(-1);
     xrn = register_name(creg);
-    dreg=get_lregister(); if (!dreg) error(-1);
-    drn_h = lregister_name_high(dreg);
-    drn_l = lregister_name_low(dreg);
-    printf("\tlzw %s,%d(%s)\n",drn_l,size_of_int,xrn);
-    printf("\tlzw %s,0(%s)\n",drn_h,xrn);
-    printf("\taddci %s,%s,%d\n",drn_l,drn_l,dir);
-    printf("\taddei %s,%s,0\n",drn_h,drn_h);
+    if (reg==USE_CREG) {
+	dreg=get_lregister(); if (!dreg) error(-1);
+	drn_h = lregister_name_high(dreg);
+	drn_l = lregister_name_low(dreg);
+	set_lreg(dreg,0);  // free old lreg==creg
+    } else {
+	drn_h = lregister_name_high(reg);
+	drn_l = lregister_name_low(reg);
+    }
+    printf("\tlwz %s,%d(%s)\n",drn_l,size_of_int,xrn);
+    printf("\tlwz %s,0(%s)\n",drn_h,xrn);
+    printf("\taddic %s,%s,%d\n",drn_l,drn_l,dir);
+    printf("\tadd%s %s,%s\n",addze(dir),drn_h,drn_h);
     printf("\tstw %s,%d(%s)\n",drn_l,size_of_int,xrn);
     printf("\tstw %s,0(%s)\n",drn_h,xrn);
-    set_lreg(dreg,0);
 }
 
 void
@@ -3910,72 +4070,76 @@
     int dreg,nreg;
     int dir=caddr(e1);
     if (car(e2)==LREGISTER) {
+	use_longlong(reg);
 	lmove(cadr(reg),cadr(e2));
-        printf("\taddci %s,%s,%d\n", 
+        printf("\taddic %s,%s,%d\n", 
                 lregister_name_low(cadr(e2)),lregister_name_low(cadr(e2)), dir);
-        printf("\taddei %s,%s,0\n", 
+        printf("\tadd%s %s,%s\n", addze(dir),
                 lregister_name_high(cadr(e2)),lregister_name_high(cadr(e2)));
         return;
     } 
     g_expr(e2);
+    if(!is_int_reg(creg)) error(-1);
     xrn = register_name(creg);
-    dreg=get_lregister(); if (!dreg) error(-1);
-    nreg=get_lregister(); if (!dreg) error(-1);
-    drn_h = lregister_name_high(dreg);
-    drn_l = lregister_name_low(dreg);
+    nreg=get_lregister(); if (!nreg) error(-1);
     nrn_h = lregister_name_high(nreg);
     nrn_l = lregister_name_low(nreg);
-    printf("\tlzw %s,%d(%s)\n",drn_l,size_of_int,xrn);
-    printf("\tlzw %s,0(%s)\n",drn_h,xrn);
-    printf("\taddci %s,%s,%d\n",nrn_l,drn_l,dir);
-    printf("\taddei %s,%s,0\n",nrn_h,drn_h);
+    if (reg==USE_CREG) {
+	dreg=get_lregister(); if (!dreg) error(-1);
+	drn_h = lregister_name_high(dreg);
+	drn_l = lregister_name_low(dreg);
+	set_lreg(dreg,0);  // free old lreg==creg
+    } else {
+	drn_h = lregister_name_high(reg);
+	drn_l = lregister_name_low(reg);
+    }
+    printf("\tlwz %s,%d(%s)\n",drn_l,size_of_int,xrn);
+    printf("\tlwz %s,0(%s)\n",drn_h,xrn);
+    printf("\taddic %s,%s,%d\n",nrn_l,drn_l,dir);
+    printf("\tadd%s %s,%s\n",addze(dir),nrn_h,drn_h);
     printf("\tstw %s,%d(%s)\n",nrn_l,size_of_int,xrn);
     printf("\tstw %s,0(%s)\n",nrn_h,xrn);
     free_register(nreg);
-    set_lreg(dreg,0);
 }
 
 void
-code_lassop(int op)
+code_lassop(int op,int reg)
 {
     int xreg;
     int edx,edx0=-1;
+    char *crn;
+
+    // (*creg) op = pop()
     xreg = emit_lpop(0);       /* pop e3 value */
     if (!is_int_reg(creg)) error(-1);
-    edx = creg;
-    creg = use_longlong(creg);
-    if (regv_l(creg)==edx || regv_h(creg)==edx) {
+    edx = ireg;
+    use_longlong(reg);
+    if (regv_l(lreg)==edx || regv_h(lreg)==edx) {
 	edx0 = get_register(); if(!edx0) error(-1);
 	printf("# lassop\n\tmr %s,%s\n",register_name(edx0),register_name(edx));
 	edx = edx0;
     }
+    crn=register_name(edx);
     use_reg(edx);
-    printf("\tlwz %s,0(%s)\n",lregister_name_high(creg),
+    printf("\tlwz %s,0(%s)\n",lregister_name_high(reg),
 	register_name(edx));
-    printf("\tlwz %s,%d(%s)\n",lregister_name_low(creg),
-	size_of_int,register_name(edx));
-    ltosop(op,xreg);
-    printf("\tstw %s,0(%s)\n",lregister_name_high(creg),
+    printf("\tlwz %s,%d(%s)\n",lregister_name_low(reg),
+	size_of_int,crn);
+    ltosop(op,reg,xreg);
+    printf("\tstw %s,0(%s)\n",lregister_name_high(reg),
 	register_name(edx));
-    printf("\tstw %s,%d(%s)\n",lregister_name_low(creg),
-	size_of_int,register_name(edx));
+    printf("\tstw %s,%d(%s)\n",lregister_name_low(reg),
+	size_of_int,crn);
     free_register(edx);
     emit_lpop_free(xreg);
 }
 
 void
 code_register_lassop(int reg,int op) {
+    // reg op = pop()
     int  xreg=emit_lpop();
-    set_lreg(reg,0);
-    ltosop(op,xreg);
-    if (creg==reg) {
-	free_register(lreg);
-	lmove(xreg,lreg);
-	lreg = creg = xreg;
-    } else {
-	lmove(reg,lreg);
-	emit_lpop_free(xreg);
-    }
+    ltosop(op,reg,xreg);
+    emit_lpop_free(xreg);
 }   
 
 
@@ -4032,12 +4196,14 @@
 #endif
 #if LONGLONG_CODE
     if (asld_lib_used) emit_lib(asld_lib);
+    if (lsrd_lib_used) emit_lib(lsrd_lib);
+    if (asrd_lib_used) emit_lib(asrd_lib);
+#if 0
     if (lumod_lib_used) emit_lib(lumod_lib);
     if (lmod_lib_used) emit_lib(lmod_lib);
     if (ludiv_lib_used) emit_lib(ludiv_lib);
     if (ldiv_lib_used) emit_lib(ldiv_lib);
-    if (lsrd_lib_used) emit_lib(lsrd_lib);
-    if (asrd_lib_used) emit_lib(asrd_lib);
+#endif
 #if FLOAT_CODE
 #if 0
     if (dl2ll_lib_used) emit_lib(dl2ll_lib);
--- a/mc-code.h	Sun Apr 25 19:03:04 2004 +0900
+++ b/mc-code.h	Mon Apr 26 05:35:33 2004 +0900
@@ -57,16 +57,16 @@
 extern void code_postinc(int e1,int e2,int dir,int sign,int sz,int reg);
 extern void code_return(int reg);
 extern void code_environment(int reg);
-extern void code_bool(int e1);
+extern void code_bool(int e1,int reg);
 extern char *code_gt(int cond);
 extern char *code_ugt(int cond);
 extern char *code_ge(int cond);
 extern char *code_uge(int cond);
 extern char *code_eq(int cond);
-extern void code_cmp_crgvar(int e1,int sz);
-extern void code_cmp_crlvar(int e1,int sz);
-extern void code_cmp_rgvar(int e1);
-extern void code_cmp_rlvar(int e1);
+extern void code_cmp_crgvar(int e1,int reg,int sz);
+extern void code_cmp_crlvar(int e1,int reg,int sz);
+extern void code_cmp_rgvar(int e1,int reg);
+extern void code_cmp_rlvar(int e1,int reg);
 extern void code_cmp_register(int e2);
 extern void code_string(int e1,int reg);
 extern void emit_copy(int from,int  to,int length,int offset,int value,int det);
@@ -76,23 +76,23 @@
 extern void code_jmp(char *s);
 extern void code_indirect_jmp(int e2);
 
-extern int code_rindirect(int e1, int offset, int us);
-extern int code_crindirect(int e1, int offset, int us);
-extern int code_srindirect(int e1, int offset, int us);
+extern int code_rindirect(int e1, int reg,int offset, int us);
+extern int code_crindirect(int e1, int reg,int offset, int us);
+extern int code_srindirect(int e1, int reg,int offset, int us);
 #if FLOAT_CODE
-extern int code_drindirect(int e1, int offset, int d);
+extern int code_drindirect(int e1, int reg,int offset, int d);
 #endif
 #if LONGLONG_CODE
-extern int code_lrindirect(int e1, int offset, int us);
+extern int code_lrindirect(int e1, int reg,int offset, int us);
 #endif
 
 extern void code_assign_gvar(int e2,int reg,int byte);
 extern void code_assign_lvar(int e2,int reg,int byte);
 extern void code_assign_register(int e2,int byte,int reg);
 extern void code_assign(int e2,int byte,int reg);
-extern void code_register_assop(int e2,int op,int byte);
-extern void code_assop(int op,int byte,int sign);
-extern void tosop(int op,int oreg);
+extern void code_register_assop(int e2,int reg,int op,int byte);
+extern void code_assop(int op,int reg,int byte,int sign);
+extern void tosop(int op,int reg,int oreg);
 extern void code_opening(char *filename);
 extern void code_closing();
 extern void rexpr(int e1, int l1, char *s,int t);
@@ -106,7 +106,7 @@
 extern void code_label(int labelno);
 
 extern int code_const_op_p(int op,int v); 
-extern void oprtc(int op,int v);
+extern void oprtc(int op,int reg,int v);
 
 
 #if FLOAT_CODE
@@ -117,8 +117,8 @@
 extern int emit_dpop(int);
 extern void code_dregister(int e2,int reg,int d);
 extern void code_cmp_dregister(int,int);
-extern void code_cmp_drgvar(int,int);
-extern void code_cmp_drlvar(int,int);
+extern void code_cmp_drgvar(int,int,int);
+extern void code_cmp_drlvar(int,int,int);
 extern void code_dassign(int,int,int);
 extern void code_dassign_gvar(int,int,int);
 extern void code_dassign_lvar(int,int,int);
@@ -127,24 +127,24 @@
 extern void code_dneg(int,int);
 extern void code_drgvar(int,int,int);
 extern void code_drlvar(int,int,int);
-extern void dtosop(int,int);
+extern void dtosop(int,int,int);
 extern void emit_dpop_free(int,int);
 extern void emit_dpush(int);
-extern void code_i2d(int);
-extern void code_d2i(int);
-extern void code_u2d(int);
-extern void code_d2u(int);
-extern void code_d2f(int freg);
-extern void code_f2d(int freg);
-extern void code_f2i(int freg);
-extern void code_f2u(int freg);
-extern void code_i2f(int creg);
-extern void code_u2f(int creg);
+extern void code_i2d();
+extern void code_d2i();
+extern void code_u2d();
+extern void code_d2u();
+extern void code_d2f();
+extern void code_f2d();
+extern void code_f2i();
+extern void code_f2u();
+extern void code_i2f();
+extern void code_u2f();
 
 
 extern void code_dpreinc(int e1,int e2,int d,int reg);
 extern void code_dpostinc(int e1,int e2,int d,int reg);
-extern void code_dassop(int op,int d);
+extern void code_dassop(int op,int reg,int d);
 extern void code_register_dassop(int reg,int op,int d);
 
 #endif
@@ -167,28 +167,28 @@
 extern void code_lneg(int);
 extern void code_lrgvar(int,int);
 extern void code_lrlvar(int,int);
-extern void ltosop(int,int);
+extern void ltosop(int,int,int);
 extern void emit_lpop_free(int);
 extern void emit_lpush();
 extern int code_lconst_op_p(int op,int e); 
-extern void loprtc(int op,int e);
-extern void code_i2ll(int creg);
-extern void code_i2ull(int creg);
-extern void code_u2ll(int creg);
-extern void code_u2ull(int creg);
-extern void code_ll2i(int creg);
-extern void code_ll2u(int creg);
-extern void code_ull2i(int creg);
-extern void code_ull2u(int creg);
+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();
 #if FLOAT_CODE
-extern void code_d2ll(int creg);
-extern void code_d2ull(int creg);
-extern void code_f2ll(int creg);
-extern void code_f2ull(int creg);
-extern void code_ll2d(int creg);
-extern void code_ll2f(int creg);
-extern void code_ull2d(int creg);
-extern void code_ull2f(int creg);
+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();
 #endif
 
 
@@ -196,7 +196,7 @@
 
 extern void code_lpreinc(int e1,int e2,int reg);
 extern void code_lpostinc(int e1,int e2,int reg);
-extern void code_lassop(int op);
+extern void code_lassop(int op,int reg);
 extern void code_register_lassop(int reg,int op);
 
 #endif
@@ -210,9 +210,9 @@
 extern int pop_register(void);
 extern void emit_pop_free(int xreg);
 
-extern int use_int(int);
-extern int use_float(int);
-extern int use_double(int);
-extern int use_longlong(int);
+// extern int use_int(int);
+// extern int use_float(int);
+// extern int use_double(int);
+// extern int use_longlong(int);
 
 /* */
--- a/mc-codegen.c	Sun Apr 25 19:03:04 2004 +0900
+++ b/mc-codegen.c	Mon Apr 26 05:35:33 2004 +0900
@@ -6,14 +6,8 @@
 #include "mc-codegen.h"
 #include "mc-code.h"
 
-int  creg;     /* current register */
-
 int use;       /* generated value will be used */
 
-/*
-    creg   currrent virtual register
- */
-
 static void remove0(int *parent,int e) ;
 /* static void remove0_all(int *parent,int e) ; */
 static int is_same_type(int e1,int e2);
@@ -102,136 +96,106 @@
     e2 = cadr(e1);
     switch (car(e1)){
     case GVAR:   
-	creg=use_int(creg);
-	code_gvar(e1,creg);
+	code_gvar(e1,USE_CREG);
 	return ADDRESS;
     case RGVAR:
-	creg=use_int(creg);
-	code_rgvar(e1,creg);
+	code_rgvar(e1,USE_CREG);
 	return INT;
     case CRGVAR:
-	creg=use_int(creg);
-	code_crgvar(e1,creg,1,1);
+	code_crgvar(e1,USE_CREG,1,1);
 	return CHAR;
     case CURGVAR:
-	creg=use_int(creg);
-	code_crgvar(e1,creg,0,1);
+	code_crgvar(e1,USE_CREG,0,1);
 	return UCHAR;
     case SRGVAR:
-	creg=use_int(creg);
-	code_crgvar(e1,creg,1,size_of_short);
+	code_crgvar(e1,USE_CREG,1,size_of_short);
 	return CHAR;
     case SURGVAR:
-	creg=use_int(creg);
-	code_crgvar(e1,creg,0,size_of_short);
+	code_crgvar(e1,USE_CREG,0,size_of_short);
 	return UCHAR;
     case LVAR:
-	creg=use_int(creg);
-	code_lvar(e2,creg);
+	code_lvar(e2,USE_CREG);
 	return ADDRESS;
     case REGISTER:
-	creg=use_int(creg);
-	code_register(e2,creg);
+	code_register(e2,USE_CREG);
 	return INT;
 #if FLOAT_CODE
     case DREGISTER:
-	creg=use_double(creg);
-	code_dregister(e2,creg,1);
+	code_dregister(e2,USE_CREG,1);
 	return DOUBLE;
     case FREGISTER:
-	creg=use_float(creg);
-	code_dregister(e2,creg,0);
+	code_dregister(e2,USE_CREG,0);
 	return FLOAT;
 #endif
 #if LONGLONG_CODE
     case LREGISTER:
-	creg=use_longlong(creg);
-	code_lregister(e2,creg);
+	code_lregister(e2,USE_CREG);
 	return LONGLONG;
 #endif
     case RLVAR:
-	creg=use_int(creg);
-	code_rlvar(e2,creg);
+	code_rlvar(e2,USE_CREG);
 	return INT;
     case CRLVAR:
-	creg=use_int(creg);
-	code_crlvar(e2,creg,1,1);
+	code_crlvar(e2,USE_CREG,1,1);
 	return CHAR;
     case CURLVAR:
-	creg=use_int(creg);
-	code_crlvar(e2,creg,0,1);
+	code_crlvar(e2,USE_CREG,0,1);
 	return UCHAR;
     case SRLVAR:
-	creg=use_int(creg);
-	code_crlvar(e2,creg,1,size_of_short);
+	code_crlvar(e2,USE_CREG,1,size_of_short);
 	return CHAR;
     case SURLVAR:
-	creg=use_int(creg);
-	code_crlvar(e2,creg,0,size_of_short);
+	code_crlvar(e2,USE_CREG,0,size_of_short);
 	return UCHAR;
 #if FLOAT_CODE
     case FRLVAR:
-	creg=use_float(creg);
-	code_drlvar(e2,0,creg);
+	code_drlvar(e2,0,USE_CREG);
 	return FLOAT;
     case FRGVAR:
-	creg=use_float(creg);
-	code_drgvar(e1,0,creg);
+	code_drgvar(e1,0,USE_CREG);
 	return FLOAT;
     case DRLVAR:
-	creg=use_double(creg);
-	code_drlvar(e2,1,creg);
+	code_drlvar(e2,1,USE_CREG);
 	return DOUBLE;
     case DRGVAR:
-	creg=use_double(creg);
-	code_drgvar(e1,1,creg);
+	code_drgvar(e1,1,USE_CREG);
 	return DOUBLE;
 #endif
 #if LONGLONG_CODE
     case LRLVAR:
-	creg=use_longlong(creg);
-	code_lrlvar(e2,creg);
+	code_lrlvar(e2,USE_CREG);
 	return LONGLONG;
     case LRGVAR:
-	creg=use_longlong(creg);
-	code_lrgvar(e1,creg);
+	code_lrgvar(e1,USE_CREG);
 	return LONGLONG;
     case LURLVAR:
-	creg=use_longlong(creg);
-	code_lrlvar(e2,creg);
+	code_lrlvar(e2,USE_CREG);
 	return ULONGLONG;
     case LURGVAR:
-	creg=use_longlong(creg);
-	code_lrgvar(e1,creg);
+	code_lrgvar(e1,USE_CREG);
 	return ULONGLONG;
 #endif
     case FNAME:
-	creg=use_int(creg);
-	code_fname((NMTBL *)(e2),creg);
+	code_fname((NMTBL *)(e2),USE_CREG);
 	return ADDRESS;
     case CONST:  /* 代入する値が0でも特別な処理はしない */
-	creg=use_int(creg);
-	code_const(e2,creg);
+	code_const(e2,USE_CREG);
 	return INT;
 #if FLOAT_CODE
     case DCONST:
-	creg=use_double(creg);
-	code_dconst(e1,creg,1);
+	code_dconst(e1,USE_CREG,1);
 	return DOUBLE;
     case FCONST:
-	creg=use_float(creg);
-	code_dconst(e1,creg,0);
+	code_dconst(e1,USE_CREG,0);
 	return FLOAT;
 #endif
 #if LONGLONG_CODE
     case LCONST:
-	creg=use_longlong(creg);
-	code_lconst(e1,creg);
+	code_lconst(e1,USE_CREG);
 	return LONGLONG;
 #endif
     case STRING:
-	creg=use_int(creg);
-	code_string(e1,creg);
+	code_string(e1,USE_CREG);
 	return ADDRESS;
     case FUNCTION:
 	t = function(e1);
@@ -242,28 +206,28 @@
     case INDIRECT:
 	return g_expr0(e2);
     case RINDIRECT:  
-	return code_rindirect(e2,caddr(e1),0);
+	return code_rindirect(e2,USE_CREG,caddr(e1),0);
     case URINDIRECT:  
-	return code_rindirect(e2,caddr(e1),1);
+	return code_rindirect(e2,USE_CREG,caddr(e1),1);
     case CRINDIRECT: 
-	return code_crindirect(e2,caddr(e1),0);
+	return code_crindirect(e2,USE_CREG,caddr(e1),0);
     case CURINDIRECT:
-	return code_crindirect(e2,caddr(e1),1);
+	return code_crindirect(e2,USE_CREG,caddr(e1),1);
     case SRINDIRECT: 
-	return code_srindirect(e2,caddr(e1),0);
+	return code_srindirect(e2,USE_CREG,caddr(e1),0);
     case SURINDIRECT:
-	return code_srindirect(e2,caddr(e1),1);
+	return code_srindirect(e2,USE_CREG,caddr(e1),1);
 #if FLOAT_CODE
     case FRINDIRECT:
-	return code_drindirect(e2,caddr(e1),0);
+	return code_drindirect(e2,USE_CREG,caddr(e1),0);
     case DRINDIRECT: 
-	return code_drindirect(e2,caddr(e1),1);
+	return code_drindirect(e2,USE_CREG,caddr(e1),1);
 #endif
 #if LONGLONG_CODE
     case LRINDIRECT: 
-	return code_lrindirect(e2,caddr(e1),0);
+	return code_lrindirect(e2,USE_CREG,caddr(e1),0);
     case LURINDIRECT:
-	return code_lrindirect(e2,caddr(e1),1);
+	return code_lrindirect(e2,USE_CREG,caddr(e1),1);
 #endif
     case ADDRESS:
 	if (car(e2)==REGISTER||car(e2)==DREGISTER||car(e2)==FREGISTER)
@@ -271,54 +235,54 @@
 	else
 	    return g_expr0(e2);
     case MINUS:  /* レジスタに対し、neglを実行すれば実現可能 */
-	g_expr0(e2); code_neg(creg);
+	g_expr0(e2); code_neg(USE_CREG);
 	return INT;
 #if LONGLONG_CODE
     case LMINUS: 
-	g_expr0(e2); code_lneg(creg);
+	g_expr0(e2); code_lneg(USE_CREG);
 	return LONGLONG;
 #endif
 #if FLOAT_CODE
     case DMINUS: 
-	g_expr0(e2); code_dneg(creg,1);
+	g_expr0(e2); code_dneg(USE_CREG,1);
 	return DOUBLE;
     case FMINUS: 
-	g_expr0(e2); code_dneg(creg,0);
+	g_expr0(e2); code_dneg(USE_CREG,0);
 	return FLOAT;
 #endif
     case CONV: 
 	g_expr0(e2); 
 	switch(caddr(e1)) {
 #if FLOAT_CODE
-	case I2D: code_i2d(creg); return DOUBLE;
-	case D2I: code_d2i(creg); return INT;
-	case U2D: code_u2d(creg); return DOUBLE;
-	case F2U: code_f2u(creg); return UNSIGNED;
-	case I2F: code_i2f(creg); return FLOAT;
-	case F2I: code_f2i(creg); return INT;
-	case U2F: code_u2f(creg); return FLOAT;
-	case D2U: code_d2u(creg); return UNSIGNED;
-	case D2F: code_d2f(creg); return FLOAT;
-	case F2D: code_f2d(creg); return DOUBLE;
+	case I2D: code_i2d(USE_CREG); return DOUBLE;
+	case D2I: code_d2i(USE_CREG); return INT;
+	case U2D: code_u2d(USE_CREG); return DOUBLE;
+	case F2U: code_f2u(USE_CREG); return UNSIGNED;
+	case I2F: code_i2f(USE_CREG); return FLOAT;
+	case F2I: code_f2i(USE_CREG); return INT;
+	case U2F: code_u2f(USE_CREG); return FLOAT;
+	case D2U: code_d2u(USE_CREG); return UNSIGNED;
+	case D2F: code_d2f(USE_CREG); return FLOAT;
+	case F2D: code_f2d(USE_CREG); return DOUBLE;
 #endif
 #if LONGLONG_CODE
-	case  I2LL: code_i2ll(creg); return LONGLONG;
-	case  I2ULL: code_i2ull(creg); return ULONGLONG;
-	case  U2LL: code_u2ll(creg); return LONGLONG;
-	case  U2ULL: code_u2ull(creg); return ULONGLONG;
-	case  LL2I: code_ll2i(creg); return INT;
-	case  LL2U: code_ll2u(creg); return UNSIGNED;
-	case  ULL2I: code_ull2i(creg); return INT;
-	case  ULL2U: code_ull2u(creg); return UNSIGNED;
+	case  I2LL: code_i2ll(USE_CREG); return LONGLONG;
+	case  I2ULL: code_i2ull(USE_CREG); return ULONGLONG;
+	case  U2LL: code_u2ll(USE_CREG); return LONGLONG;
+	case  U2ULL: code_u2ull(USE_CREG); return ULONGLONG;
+	case  LL2I: code_ll2i(USE_CREG); return INT;
+	case  LL2U: code_ll2u(USE_CREG); return UNSIGNED;
+	case  ULL2I: code_ull2i(USE_CREG); return INT;
+	case  ULL2U: code_ull2u(USE_CREG); return UNSIGNED;
 #if FLOAT_CODE
-	case  D2LL: code_d2ll(creg); return LONGLONG;
-	case  D2ULL: code_d2ull(creg); return ULONGLONG;
-	case  F2LL: code_f2ll(creg); return LONGLONG;
-	case  F2ULL: code_f2ull(creg); return ULONGLONG;
-	case  LL2D: code_ll2d(creg); return DOUBLE;
-	case  LL2F: code_ll2f(creg); return FLOAT;
-	case  ULL2D: code_ull2d(creg); return DOUBLE;
-	case  ULL2F: code_ull2f(creg); return FLOAT;
+	case  D2LL: code_d2ll(USE_CREG); return LONGLONG;
+	case  D2ULL: code_d2ull(USE_CREG); return ULONGLONG;
+	case  F2LL: code_f2ll(USE_CREG); return LONGLONG;
+	case  F2ULL: code_f2ull(USE_CREG); return ULONGLONG;
+	case  LL2D: code_ll2d(USE_CREG); return DOUBLE;
+	case  LL2F: code_ll2f(USE_CREG); return FLOAT;
+	case  ULL2D: code_ull2d(USE_CREG); return DOUBLE;
+	case  ULL2F: code_ull2f(USE_CREG); return FLOAT;
 #endif
 #endif
 
@@ -326,61 +290,49 @@
 	    error(-1); return INT;
 	}
     case BNOT:   /* ~ */
-	g_expr0(e2); code_not(creg);
+	g_expr0(e2); code_not(USE_CREG);
 	return INT;
     case LNOT:   /* !  */
-	g_expr0(e2); code_lnot(creg);
+	g_expr0(e2); code_lnot(USE_CREG);
 	return INT;
     case PREINC:
-	creg=use_int(creg);
-	code_preinc(e1,e2,caddr(e1),1,cadddr(e1),creg);
+	code_preinc(e1,e2,caddr(e1),1,cadddr(e1),USE_CREG);
 	return INT;
     case UPREINC:
-	creg=use_int(creg);
-	code_preinc(e1,e2,caddr(e1),0,cadddr(e1),creg);
+	code_preinc(e1,e2,caddr(e1),0,cadddr(e1),USE_CREG);
 	return INT;
     case POSTINC:
-	creg=use_int(creg);
-	code_postinc(e1,e2,caddr(e1),1,cadddr(e1),creg);
+	code_postinc(e1,e2,caddr(e1),1,cadddr(e1),USE_CREG);
 	return INT;
     case UPOSTINC:
-	creg=use_int(creg);
-	code_postinc(e1,e2,caddr(e1),0,cadddr(e1),creg);
+	code_postinc(e1,e2,caddr(e1),0,cadddr(e1),USE_CREG);
 	return INT;
 #if FLOAT_CODE
     case DPREINC:   /* ++d */
-	creg=use_double(creg);
-	code_dpreinc(e1,e2,1,creg);
+	code_dpreinc(e1,e2,1,USE_CREG);
 	return DOUBLE;
     case DPOSTINC:  /* d++ */
-	creg=use_double(creg);
-	code_dpostinc(e1,e2,1,creg);
+	code_dpostinc(e1,e2,1,USE_CREG);
 	return DOUBLE;
     case FPREINC:   /* ++f */
-	creg=use_float(creg);
-	code_dpreinc(e1,e2,0,creg);
+	code_dpreinc(e1,e2,0,USE_CREG);
 	return FLOAT;
     case FPOSTINC:  /* f++ */
-	creg=use_float(creg);
-	code_dpostinc(e1,e2,0,creg);
+	code_dpostinc(e1,e2,0,USE_CREG);
 	return FLOAT;
 #endif
 #if LONGLONG_CODE
     case LPREINC:   /* ++d */
-	creg=use_longlong(creg);
-	code_lpreinc(e1,e2,creg);
+	code_lpreinc(e1,e2,USE_CREG);
 	return LONGLONG;
     case LPOSTINC:  /* d++ */
-	creg=use_longlong(creg);
-	code_lpostinc(e1,e2,creg);
+	code_lpostinc(e1,e2,USE_CREG);
 	return LONGLONG;
     case LUPREINC:   /* ++d */
-	creg=use_longlong(creg);
-	code_lpreinc(e1,e2,creg);
+	code_lpreinc(e1,e2,USE_CREG);
 	return ULONGLONG;
     case LUPOSTINC:  /* d++ */
-	creg=use_longlong(creg);
-	code_lpostinc(e1,e2,creg);
+	code_lpostinc(e1,e2,USE_CREG);
 	return ULONGLONG;
 #endif
     case MUL: case UMUL:
@@ -388,20 +340,17 @@
     case MOD: case UMOD:
     case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT:
     case ADD: case SUB: case BAND: case EOR: case BOR: case CMP:
-	creg=use_int(creg);
 	machinop(e1);
 	return INT;
 #if FLOAT_CODE
     case DMUL: case DDIV:
     case DADD: case DSUB:
     case DCMP: case DCMPGE:
-	creg=use_double(creg);
 	dmachinop(e1,1);
 	return DOUBLE;
     case FMUL: case FDIV:
     case FADD: case FSUB:
     case FCMP: case FCMPGE:
-	creg=use_float(creg);
 	dmachinop(e1,0);
 	return FLOAT;
     case DCOND:
@@ -413,7 +362,6 @@
     case LMOD: case LUMOD:
     case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT:
     case LADD: case LSUB: case LBAND: case LEOR: case LBOR: case LCMP:
-	creg=use_longlong(creg);
 	lmachinop(e1);
 	return INT;
 #endif
@@ -423,7 +371,7 @@
 	e2=fwdlabel();
 	b_expr(cadr(e1),0,e2,0);
         g_expr0(caddr(e1));
-	t = code_get_fixed_creg(creg,d);
+	t = code_get_fixed_creg(USE_CREG,d);
 	jmp(e3=fwdlabel());
 	fwddef(e2);
         t1=g_expr0(cadddr(e1));
@@ -462,18 +410,16 @@
 	g_expr_u(e2);
 	return g_expr0(caddr(e1));
     case RETURN:
-	creg = use_int(creg);
 	n = (NMTBL *)e2;
 	if (retcont==0)
 	    retcont=fwdlabel();
-	code_return(creg);
+	code_return(USE_CREG);
 	return VOID;
     case ENVIRONMENT:
-	creg = use_int(creg);
-	code_environment(creg);
+	code_environment(USE_CREG);
 	return ADDRESS;
     default:
-	code_bool(e1); /* type? */
+	code_bool(e1,USE_CREG); /* type? */
 	return INT;
     }
 }
@@ -631,63 +577,51 @@
 	if(!cond) fwddef(l2);
 	return;
     case CRGVAR: case CURGVAR:
-	creg=use_int(creg);
-	code_cmp_crgvar(e1,1);
+	code_cmp_crgvar(e1,USE_CREG,1);
 	jcond(l1,cond);
 	return;
     case SRGVAR: case SURGVAR:
-	creg=use_int(creg);
-	code_cmp_crgvar(e1,size_of_short);
+	code_cmp_crgvar(e1,USE_CREG,size_of_short);
 	jcond(l1,cond);
 	return;
     case CRLVAR: case CURLVAR:
-	creg=use_int(creg);
-	code_cmp_crlvar(e2,1);
+	code_cmp_crlvar(e2,USE_CREG,1);
 	jcond(l1,cond);
 	return;
     case SRLVAR: case SURLVAR:
-	creg=use_int(creg);
-	code_cmp_crlvar(e2,size_of_short);
+	code_cmp_crlvar(e2,USE_CREG,size_of_short);
 	jcond(l1,cond);
 	return;
     case RGVAR:
-	creg=use_int(creg);
-	code_cmp_rgvar(e1);
+	code_cmp_rgvar(e1,USE_CREG);
 	jcond(l1,cond);
 	return;
     case RLVAR:
-	creg=use_int(creg);
-	code_cmp_rlvar(e2);
+	code_cmp_rlvar(e2,USE_CREG);
 	jcond(l1,cond);
 	return;
 #if FLOATC_DOE
     case DRLVAR:
-	creg=use_double(creg);
-	code_cmp_drlvar(e2,1);
+	code_cmp_drlvar(e2,USE_CREG,1);
 	jcond(l1,cond);
 	return;
     case FRLVAR:
-	creg=use_float(creg);
-	code_cmp_drlvar(e2,0);
+	code_cmp_drlvar(e2,USE_CREG,0);
 	jcond(l1,cond);
 	return;
     case DRGVAR:
-	creg=use_double(creg);
-	code_cmp_drgvar(e2,1);
+	code_cmp_drgvar(e2,USE_CREG,1);
 	jcond(l1,cond);
 	return;
     case FRGVAR:
-	creg=use_float(creg);
-	code_cmp_drgvar(e2,0);
+	code_cmp_drgvar(e2,USE_CREG,0);
 	jcond(l1,cond);
 	return;
     case FREGISTER:
-	creg=use_float(creg);
 	code_cmp_dregister(e2,0);
 	jcond(l1,cond);
 	return;
     case DREGISTER:
-	creg=use_double(creg);
 	code_cmp_dregister(e2,1);
 	jcond(l1,cond);
 	return;
@@ -698,17 +632,14 @@
 #endif
 #if LONGLONG_DOE
     case LRLVAR:
-	creg=use_longlong(creg);
 	code_cmp_lrlvar(e2,1);
 	jcond(l1,cond);
 	return;
     case LRGVAR:
-	creg=use_longlong(creg);
 	code_cmp_lrgvar(e2,1);
 	jcond(l1,cond);
 	return;
     case LREGISTER:
-	creg=use_longlong(creg);
 	code_cmp_lregister(e2,1);
 	jcond(l1,cond);
 	return;
@@ -717,7 +648,6 @@
 	return;
 #endif
     case REGISTER:
-	creg=use_int(creg);
 	code_cmp_register(e2);
 	jcond(l1,cond);
 	return;
@@ -732,16 +662,16 @@
 	if (0) ;
 #if FLOAT_CODE
 	else if(t==FLOAT)
-	    code_cmp_dregister(creg,0);
+	    code_cmp_dregister(USE_CREG,0);
 	else if(t==DOUBLE)
-	    code_cmp_dregister(creg,1);
+	    code_cmp_dregister(USE_CREG,1);
 #endif
 #if LONGLONG_CODE
 	else if(t==LONGLONG||t==ULONGLONG)
-	    code_cmp_lregister(creg);
+	    code_cmp_lregister(USE_CREG);
 #endif
 	else
-	    code_cmp_register(creg);
+	    code_cmp_register(USE_CREG);
 	jcond(l1,cond);
 	return;
     }
@@ -1157,13 +1087,13 @@
     e3 = caddr(e1);
     if (car(e3)==CONST && code_const_op_p(op,v=cadr(e3))) {
 	g_expr(e2);
-	oprtc(op,v);
+	oprtc(op,USE_CREG,v);
 	return;
     }
     g_expr(e3);
     emit_push();
     g_expr(e2);
-    tosop(op,(e2=pop_register()));
+    tosop(op,USE_CREG,(e2=pop_register()));
     emit_pop_free(e2);
     return;
 }
@@ -1180,7 +1110,7 @@
     g_expr(e3);
     emit_dpush(d);
     g_expr(e2);
-    dtosop(car(e1),(e2=emit_dpop(d)));
+    dtosop(car(e1),USE_CREG,(e2=emit_dpop(d)));
     emit_dpop_free(e2,d);
     return;
 }
@@ -1197,13 +1127,13 @@
     e3 = caddr(e1);
     if (code_lconst_op_p(op,e3)) {
 	g_expr(e2);
-	loprtc(op,e3);
+	loprtc(op,USE_CREG,e3);
 	return;
     }
     g_expr(e3);
     emit_lpush();
     g_expr(e2);
-    ltosop(car(e1),(e2=emit_lpop()));
+    ltosop(car(e1),USE_CREG,(e2=emit_lpop()));
     emit_lpop_free(e2);
     return;
 }
@@ -1232,7 +1162,7 @@
     } else {
 	det = 0;
     }
-    emit_copy(xreg,creg,sz,0,1,det);
+    emit_copy(xreg,USE_CREG,sz,0,1,det);
     emit_pop_free(xreg);
     return;
 }
@@ -1250,7 +1180,7 @@
 	case REGISTER: code_assign_register(cadr(e2),byte,reg); return;
 	}
 	g_expr(e2);
-	code_assign(creg,byte,reg);
+	code_assign(reg,byte,USE_CREG);
 	return;
     }
     /* e2 is register now */
@@ -1299,30 +1229,28 @@
 		e5== CONST ||  e5== FNAME || e5== STRING ||
 		(e5==ADDRESS&&car(cadr(e4))==STRING) ||
 		(e5==ADDRESS&&car(cadr(e4))==GVAR) )))) {
-	creg = use_int(creg);
 	assign_opt(e5,e2,e4,byte);
 	return;
     }
     switch(car(e2)) {
     case GVAR:      /*   i=3 */
             g_expr(e4);
-	    code_assign_gvar(e2,creg,byte);
+	    code_assign_gvar(e2,USE_CREG,byte);
             return;
     case LVAR:
             g_expr(e4);
-	    code_assign_lvar(cadr(e2),creg,byte);
+	    code_assign_lvar(cadr(e2),USE_CREG,byte);
             return;
     case REGISTER:
             g_expr(e4);
-	    if (creg!=cadr(e2))
-		code_assign_register(cadr(e2),byte,creg);
+	    code_assign_register(cadr(e2),byte,USE_CREG);
             return;
     }
     g_expr(e2);
     emit_push();
     g_expr(e4);
     e2 = emit_pop(0);
-    code_assign(e2,byte,creg);
+    code_assign(e2,byte,USE_CREG);
     emit_pop_free(e2);
     return;
 }
@@ -1382,36 +1310,29 @@
 	    (car(e2)==DREGISTER&&(e5==DRGVAR||e5==DRLVAR||e5==DCONST))||
 	    (car(e2)==DREGISTER&&(e5==FRGVAR||e5==FRLVAR||e5==FCONST))
 	)) {
-	creg = d?use_double(creg):use_float(creg);
 	dassign_opt(e5,e2,e4,d);
 	return;
     }
     switch(car(e2)) {
     case GVAR:
             g_expr(e4);
-	    creg = d?use_double(creg):use_float(creg);
-	    code_dassign_gvar(e2,creg,d);
+	    code_dassign_gvar(e2,USE_CREG,d);
             return;
     case LVAR:
             g_expr(e4);
-	    creg = d?use_double(creg):use_float(creg);
-	    code_dassign_lvar(cadr(e2),creg,d);
+	    code_dassign_lvar(cadr(e2),USE_CREG,d);
             return;
     case DREGISTER:
     case FREGISTER:
-	    if (d) creg = use_double(creg); else creg = use_float(creg);
             g_expr(e4);
-	    if (creg!=cadr(e2)) {
-		code_dassign_dregister(cadr(e2),d,creg);
-	    }
+	    code_dassign_dregister(cadr(e2),d,USE_CREG);
             return;
     }
     g_expr(e2);
     emit_push();
-    if (d) creg = use_double(creg); else creg = use_float(creg);
     g_expr(e4);
     e2 = emit_pop(0);
-    code_dassign(e2,creg,d);
+    code_dassign(e2,USE_CREG,d);
     emit_pop_free(e2);
     return;
 }
@@ -1467,35 +1388,28 @@
 	    (e5==LREGISTER) ||
 	    (car(e2)==LREGISTER&&(e5==LRGVAR||e5==LRLVAR||e5==LCONST))
 	)) {
-	creg = use_longlong(creg);
 	lassign_opt(e5,e2,e4);
 	return;
     }
     switch(car(e2)) {
     case GVAR:
             g_expr(e4);
-	    creg = use_longlong(creg);
-	    code_lassign_gvar(e2,creg);
+	    code_lassign_gvar(e2,USE_CREG);
             return;
     case LVAR:
             g_expr(e4);
-	    creg = use_longlong(creg);
-	    code_lassign_lvar(cadr(e2),creg);
+	    code_lassign_lvar(cadr(e2),USE_CREG);
             return;
     case LREGISTER:
-	    creg = use_longlong(creg);
             g_expr(e4);
-	    if (creg!=cadr(e2)) {
-		code_lassign_lregister(cadr(e2),creg);
-	    }
+	    code_lassign_lregister(cadr(e2),USE_CREG);
             return;
     }
     g_expr(e2);
     emit_push();
-    creg = use_longlong(creg);
     g_expr(e4);
     e2 = emit_pop(0);
-    code_lassign(e2,creg);
+    code_lassign(e2,USE_CREG);
     emit_pop_free(e2);
     return;
 }
@@ -1524,15 +1438,16 @@
     e3 = caddr(e1);
     op = cadddr(e1);
 
-    creg = use_int(creg);
     g_expr(e3);
     if (car(e2)==REGISTER) {
-	code_register_assop(cadr(e2),op,byte);
+	code_register_assop(cadr(e2),USE_CREG,op,byte);
+	if (use)
+	    code_register(cadr(e2),USE_CREG);
 	return;
     }
     emit_push();
     g_expr(e2);
-    code_assop(op,byte,sign);
+    code_assop(op,USE_CREG,byte,sign);
     return;
 }
 
@@ -1550,15 +1465,16 @@
     e3 = caddr(e1);
     op = cadddr(e1);
 
-    creg = d?use_double(creg):use_float(creg);
     g_expr(e3);
     emit_dpush(d);
     g_expr(e2);
     if (car(e2)==DREGISTER||car(e2)==FREGISTER) {
 	code_register_dassop(cadr(e2),op,d);
+	if (use)
+	    code_dregister(cadr(e2),USE_CREG,d);
 	return;
     }
-    code_dassop(op,d);
+    code_dassop(op,USE_CREG,d);
     return;
 }
 
@@ -1577,15 +1493,16 @@
     e3 = caddr(e1);
     op = cadddr(e1);
 
-    creg = use_longlong(creg);
     g_expr(e3);
     emit_lpush();
     g_expr(e2);
     if (car(e2)==LREGISTER) {
 	code_register_lassop(cadr(e2),op);
+	if (use)
+	    code_lregister(cadr(e2),USE_CREG);
 	return;
     }
-    code_lassop(op);
+    code_lassop(op,USE_CREG);
     return;
 }
 
--- a/mc-codegen.h	Sun Apr 25 19:03:04 2004 +0900
+++ b/mc-codegen.h	Mon Apr 26 05:35:33 2004 +0900
@@ -1,8 +1,8 @@
 /* for mc-codegen.c */
 
-extern int  creg;       /* current register */
+extern int use;         /* generated value will be used in gexpr */
 
-extern int use;         /* generated value will be used in gexpr */
+#define USE_CREG (-1)
 
 /* function provided by mc-code-*.c */
 
--- a/mc-parse.c	Sun Apr 25 19:03:04 2004 +0900
+++ b/mc-parse.c	Mon Apr 26 05:35:33 2004 +0900
@@ -2981,7 +2981,12 @@
     int t;
     if(!(scalar(type)||type==DOUBLE||type==FLOAT||
 	type==LONGLONG||type==ULONGLONG)||
-	(car(e)!=GVAR&&car(e)!=LVAR&&car(e)!=INDIRECT&&car(e)!=REGISTER))
+	(car(e)!=GVAR&&car(e)!=LVAR&&car(e)!=INDIRECT
+		&& car(e)!=REGISTER
+		&& car(e)!=DREGISTER
+		&& car(e)!=FREGISTER
+		&& car(e)!=LREGISTER)
+	)
 	if ((t=car(type))<0 && t!=STRUCT && t!=UNION)
 	    error(LVERR);
 }
@@ -3778,6 +3783,7 @@
 		cheapp=scheapp;
 		return sym=LCONST;
 #else
+		error(CHERR);
 		symval = 0;
 		return sym=CONST;
 #endif