changeset 108:69e2e763cce5 powerpc-asm-first-try

object assemble first try.
author kono
date Tue, 18 Mar 2003 20:50:37 +0900
parents 06f72222d6b5
children e09f9de6f5d3
files Changes mc-code-ia32.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-codegen.h mc-parse.c mc.h test/basic.c test/float.c
diffstat 10 files changed, 286 insertions(+), 142 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Tue Mar 18 12:41:32 2003 +0900
+++ b/Changes	Tue Mar 18 20:50:37 2003 +0900
@@ -2281,3 +2281,39 @@
 
 やっぱり、関数全体を構文木に落してからgexprするべきだよね。
 それ自体は、そんなに難しくないが。
+
+Tue Mar 18 12:41:42 JST 2003
+
+COND(三項演算子)で使うレジスタが関数の引数を破壊してしまう。
+input register にならない値を使えば良いんだけど。r15
+を使っているんだけど、それでいいの?
+
+virtual を使っていたときは、use_register で何も破壊されなかった
+んだけど、使わないとすると、結構破壊されてしまう。なので、
+ちょっと奥の深い問題かもね。三項演算子の型はチェックしてなかったし。
+
+まぁ、それは、一時レジスタを使えば良いとして...
+
+時々呼び出す、u2d とか bcopy とかで破壊されるinput レジスタ
+はどうする? これは、予測は困難だよね。使う分だけsaveするって
+言う手もあるけど。うー、どうしよう... 検出できるようにするっ
+ていう手もある。(と、思ったら、get_register_var が間違ってい
+るみたいね) 検出はちょっと重いか。二乗のアルゴリズムは、あま
+り使いたくない。といっても、定数乗になるだけか。呼出側でsave
+する? bcopy がどれくらい使うか割りと曖昧。
+
+もっと積極的にget_register_var するっていう手もあるよね。そ
+うすれば、あまり気にすること無く library call できる。(ちょ
+っと、書き換えが多いが...) その方が筋かな。使うレジスタを減
+らそうと思うと、それは検出するのと、それほど差はないわけか。
+
+このあたりも構文木を全部持っていれば解決できるんだよな。
+
+うーん、まだまだ、だな。
+
+関数が関数呼び出しで決まる場合の input register の破壊を考えて
+ませんでした。これも、どうすればいいんだ... まぁ、get_register_var
+するのが簡単だよね。
+
+
+save register が狂っているようだね。max_register_var あたり?
--- a/mc-code-ia32.c	Tue Mar 18 12:41:32 2003 +0900
+++ b/mc-code-ia32.c	Tue Mar 18 20:50:37 2003 +0900
@@ -1370,7 +1370,7 @@
 leave(int control, char *name)
 {
     if (control)
-	use_register(creg,REG_EAX,1);
+        code_set_return_register(1);
     if (retcont) {
 	if (control)
 	    jmp(retlabel);
@@ -1400,8 +1400,10 @@
 
 
 void
-code_set_fixed_creg(int mode) {
-    use_register(creg,REG_EAX,mode);
+code_set_fixed_creg(int mode,int type) {
+    if (type==FLOAT||type==DOUBLE) {
+    } else
+	use_register(creg,REG_EAX,mode);
 }
 
 void
--- a/mc-code-powerpc.c	Tue Mar 18 12:41:32 2003 +0900
+++ b/mc-code-powerpc.c	Tue Mar 18 20:50:37 2003 +0900
@@ -48,9 +48,9 @@
      f1-r8  input register
      f24-f31 saved register variable
  */
-int arg_offset = 8;
-int disp_offset = -12;
-int func_disp_offset = -12;
+int arg_offset = 56;
+int disp_offset = 0;
+int func_disp_offset = 0;
 int code_disp_offset = 0;
 int jump_offset = 0;
 
@@ -103,6 +103,8 @@
 int *fregs = powerpc_fregs;
 
 static int max_reg_var, max_freg_var;
+static int cond_reg=-1,cond_freg=-1;
+static int lvar_offset;
 
 static char *reg_name[] = {
     "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9",
@@ -356,6 +358,14 @@
     while(reg_sp > 0) {
 	free_register(reg_stack[--reg_sp]);
     }
+    if (cond_freg!=-1) { 
+	if(car(cond_freg)==DREGISTER) free_fregister(cadr(cond_freg)); 
+	cond_freg=-1; 
+    }
+    if (cond_reg!=-1)  { 
+	if(car(cond_reg)==REGISTER) free_register(cadr(cond_reg)); 
+	cond_reg=-1;  
+    }
     text_mode();
     gexpr_code_init();
     register_usage("gexpr_init");
@@ -386,7 +396,8 @@
             regs[REG_VAR_BASE-i]=USING_REG; /* そのレジスタを使うことを宣言し */
             regv[REG_VAR_BASE-i]=0;
 	    if (i>max_reg_var) max_reg_var=i;
-            return list3(REGISTER,i,(int)n); /* その場所を表す番号を返す */
+		/* その場所を表す番号を返す */
+            return list3(REGISTER,REG_VAR_BASE-i,(int)n); 
         }
     }
     return list2(LVAR,new_lvar(size_of_int));
@@ -507,7 +518,7 @@
     rrn = register_name(r);
     printf("\taddis %s,r31,ha16(L_%s$non_lazy_ptr-L_%d)\n",
 	     rrn,(char *)g,code_base);
-    printf("\tlzw %s,lo16(L_%s$non_lazy_ptr-L_%d)(%s)\n",
+    printf("\tla %s,lo16(L_%s$non_lazy_ptr-L_%d)(%s)\n",
 	     rrn,(char *)g,code_base,rrn);
     return r;
 }
@@ -531,7 +542,7 @@
 
 void
 code_rgvar(int e1,int creg) {
-    printf("\tlwz %s,(%s)\n",register_name(creg),
+    printf("\tlwz %s,0(%s)\n",register_name(creg),
                              register_name(get_ptr_cache((char*)caddr(e1))));
     regv[creg]=1;
 }
@@ -539,7 +550,7 @@
 void
 code_crgvar(int e1,int creg){
     char *crn = register_name(creg);
-    printf("\tlbz %s,(%s)\n",crn,
+    printf("\tlbz %s,0(%s)\n",crn,
                              register_name(get_ptr_cache((char*)caddr(e1))));
     printf("\textsb %s,%s\n",crn,crn);
     regv[creg]=1;
@@ -547,7 +558,8 @@
 
 void
 code_lvar(int e2,int creg) {
-    printf("\tla %s,%d(r1)\n",register_name(creg),e2);
+    printf("\tla %s,lo16(%d+L_%d)(r1)\n",register_name(creg),
+	e2,lvar_offset);
     regv[creg]=1;
 }
 
@@ -562,14 +574,15 @@
 
 void
 code_rlvar(int e2,int reg) {
-    printf("\tlwz %s,%d(r1)\n",register_name(reg),e2);
+    printf("\tlwz %s,lo16(%d+L_%d)(r1)\n",register_name(reg),
+	e2,lvar_offset);
     regv[creg]=1;
 }
 
 
 void
 code_crlvar(int e2,int reg) {
-    printf("\tlbz %s,%d(r1)\n",register_name(reg),e2);
+    printf("\tlbz %s,lo16(%d+L_%d)(r1)\n",register_name(reg),e2,lvar_offset);
     printf("\textsb %s,%s\n",register_name(reg),register_name(reg));
     regv[reg]=1;
 }
@@ -633,9 +646,9 @@
     xrn = register_name(creg);
     dreg=get_register(); if (!dreg) error(-1);
     drn = register_name(dreg);
-    printf("\tlwz %s,(%s)\n",drn,xrn);
+    printf("\tlwz %s,0(%s)\n",drn,xrn);
     printf("\taddi %s,%s,%d\n",drn,drn,caddr(e1));
-    printf("\tstw %s,(%s)\n",drn,xrn);
+    printf("\tstw %s,0(%s)\n",drn,xrn);
     i=creg;creg=dreg;dreg=i;
     regv[creg]=1;
     free_register(dreg);
@@ -659,9 +672,9 @@
     xrn = register_name(dreg);
     nreg=get_register(); if (!nreg) error(-1);
     nrn = register_name(nreg);
-    printf("\tlwz %s,(%s)\n",xrn,crn);
+    printf("\tlwz %s,0(%s)\n",xrn,crn);
     printf("\taddi %s,%s,%d\n",nrn,xrn,caddr(e1));
-    printf("\tstw %s,(%s)\n",nrn,crn);
+    printf("\tstw %s,0(%s)\n",nrn,crn);
     i=creg;creg=dreg;dreg=i; 
     free_register(nreg);
     free_register(dreg);
@@ -674,7 +687,7 @@
     char *xrn,*crn,*nrn;
     int i,nreg,dreg;
     if (car(e2)==REGISTER) {
-	printf("\tlbz %s,(%s)\n",register_name(reg),register_name(cadr(e2)));
+	printf("\tlbz %s,0(%s)\n",register_name(reg),register_name(cadr(e2)));
 	printf("\textsb %s,%s\n",register_name(reg),register_name(reg));
 	printf("\taddi %s,%s,%d\n", 
 	    register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1));
@@ -687,11 +700,11 @@
     xrn = register_name(dreg);
     nreg=get_register(); if (!nreg) error(-1);
     nrn = register_name(nreg);
-    printf("\tlwz %s,(%s)\n",xrn,crn);
-    printf("\tlbz %s,(%s)\n",nrn,xrn);
+    printf("\tlwz %s,0(%s)\n",xrn,crn);
+    printf("\tlbz %s,0(%s)\n",nrn,xrn);
     printf("\textsb %s,%s\n",nrn,nrn);
     printf("\taddi %s,%s,%d\n", xrn,xrn,caddr(e1));
-    printf("\tstw %s,(%s)\n",xrn,crn);
+    printf("\tstw %s,0(%s)\n",xrn,crn);
     i=creg;creg=nreg;nreg=i; 
     free_register(nreg);
     free_register(dreg);
@@ -715,9 +728,9 @@
     xrn = register_name(dreg);
     nreg=get_register(); if (!nreg) error(-1);
     nrn = register_name(nreg);
-    printf("\tlwz %s,(%s)\n",xrn,crn);
+    printf("\tlwz %s,0(%s)\n",xrn,crn);
     printf("\tlbzu %s,%d(%s)\n",nrn,caddr(e1),xrn);
-    printf("\tstw %s,(%s)\n",xrn,crn);
+    printf("\tstw %s,0(%s)\n",xrn,crn);
     printf("\textsb %s,%s\n",nrn,nrn);
     i=creg;creg=nreg;nreg=i; 
     free_register(nreg);
@@ -733,7 +746,7 @@
     if (car(e2)==REGISTER) {
 	crn=register_name(reg);
 	xrn=register_name(cadr(e2));
-	printf("\tlbz %s,(%s)\n",crn,xrn);
+	printf("\tlbz %s,0(%s)\n",crn,xrn);
 	printf("\taddi %s,%s,%d\n",xrn,xrn,caddr(e1));
 	printf("\textsb %s,%s\n",crn,crn);
 	regv[reg]=1;
@@ -745,10 +758,10 @@
     xrn = register_name(dreg);
     nreg=get_register(); if (!nreg) error(-1);
     nrn = register_name(nreg);
-    printf("\tlwz %s,(%s)\n",xrn,crn);
-    printf("\tlbz %s,(%s)\n",nrn,xrn);
+    printf("\tlwz %s,0(%s)\n",xrn,crn);
+    printf("\tlbz %s,0(%s)\n",nrn,xrn);
     printf("\taddi %s,%s,%d\n",xrn,xrn,caddr(e1));
-    printf("\tstw %s,(%s)\n",xrn,crn);
+    printf("\tstw %s,0(%s)\n",xrn,crn);
     printf("\textsb %s,%s\n",nrn,nrn);
     i=creg;creg=nreg;nreg=i; 
     free_register(nreg);
@@ -775,9 +788,9 @@
     xrn = register_name(dreg);
     nreg=get_register(); if (!nreg) error(-1);
     nrn = register_name(nreg);
-    printf("\tlwz %s,(%s)\n",xrn,crn);
+    printf("\tlwz %s,0(%s)\n",xrn,crn);
     printf("\tlbzu %s,%d(%s)\n",nrn,caddr(e1),xrn);
-    printf("\tstw %s,(%s)\n",xrn,crn);
+    printf("\tstw %s,0(%s)\n",xrn,crn);
     printf("\textsb %s,%s\n",nrn,nrn);
     i=creg;creg=nreg;nreg=i; 
     free_register(nreg);
@@ -843,7 +856,7 @@
     int r;
     char *crn = register_name(creg);
     r = get_ptr_cache((char *)caddr(e1));
-    printf("\tlbz %s,(%s)\n",crn,register_name(r));
+    printf("\tlbz %s,0(%s)\n",crn,register_name(r));
     printf("\tcmpwi cr0,%s,0\n",crn);
     regv[creg]=0;
 }
@@ -852,7 +865,7 @@
 void
 code_cmp_crlvar(int e1) {
     char *crn = register_name(creg);
-    printf("\tlbz %s,%d(r1)\n",crn,e1);
+    printf("\tlbz %s,lo16(%d+L_%d)(r1)\n",crn,e1,lvar_offset);
     code_cmp_register(creg);
     regv[creg]=0;
 }
@@ -863,7 +876,7 @@
     int r;
     char *crn = register_name(creg);
     r = get_ptr_cache((char *)caddr(e1));
-    printf("\tlwz %s,(%s)\n",crn,register_name(r));
+    printf("\tlwz %s,0(%s)\n",crn,register_name(r));
     code_cmp_register(creg);
     regv[creg]=0;
 }
@@ -872,7 +885,7 @@
 void
 code_cmp_rlvar(int e1) {
     char *crn = register_name(creg);
-    printf("\tlwz %s,%d(r1)\n",crn,e1);
+    printf("\tlwz %s,lo16(%d+L_%d)(r1)\n",crn,e1,lvar_offset);
     code_cmp_register(creg);
     regv[creg]=0;
 }
@@ -899,7 +912,7 @@
 	    printf("%c",*s);
 	s++;
     }
-    printf("\\0%c\n",34);
+    printf("\\0%c\n\t.align 2\n",34);
 }
 
 void
@@ -1102,29 +1115,50 @@
 }
 
 int
+simple_args(int e3)
+{
+    return 
+	!contains_in_list(e3,FUNCTION) &&
+	!contains_in_list(e3,CONV) &&
+	!contains_in_list(e3,SASS)
+    ;
+}
+
+int
 function(int e1)
 {
     int e2,e3,e4,e5,nargs,t;
     int arg,reg_arg,freg_arg,arg_assign;
-    int reg_arg_list,ret_type;
-    NMTBL *n;
-    int jmp;
-    char *jrn,*crn;
+    int reg_arg_list=0,ret_type;
+    NMTBL *n,*fn;
+    int jmp = 0;
+    char *jrn;
 
     ret_type = cadddr(e1);
-    void code_save_stacks();
+
+    e2 = cadr(e1);
+    if (car(e2) == FNAME) {	
+	fn=(NMTBL *)cadr(e2);
+    } else {	
+	jmp = get_register_var(0);
+	if (car(jmp)!=REGISTER) error(-1);
+	reg_arg_list = list2(jmp,reg_arg_list);
+	g_expr(assign_expr0(jmp,e2,INT,INT));
+    }
+
     /* now all input register vars are free */
+    code_save_stacks();
     set_creg(CREG_REGISTER,0);
     set_freg(FREG_FREGISTER,0);
-    e2 = cadr(e1);
-    reg_arg_list = nargs = reg_arg = freg_arg = arg_assign = 0;
+
+    nargs = reg_arg = freg_arg = arg_assign = 0;
     for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {	
 	t=caddr(e3);
 	n=(NMTBL *)(e5=(cadr(e4 = car(e3))));
 	if(scalar(t)) {
 	    if (reg_arg>MAX_INPUT_REGISTER_VAR) { 
 		arg = list2(LVAR,arg_offset_v(nargs));
-	    } else if (contains_in_list(e3,FUNCTION)) {
+	    } else if (!simple_args(e3)) {
 		arg = get_register_var(0); 
 		arg_assign = list2(
 		    assign_expr0(get_input_register_var(reg_arg,0),arg,t,t),
@@ -1140,7 +1174,7 @@
 	} else if (t==DOUBLE||t==FLOAT) {
 	    if (freg_arg>MAX_INPUT_DREGISTER_VAR) {
 		arg = list2(LVAR,arg_offset_v(nargs));
-	    } else if (contains_in_list(e3,FUNCTION)) {
+	    } else if (!simple_args(e3)) {
 		arg = get_fregister_var(0); 
 		arg_assign = list2(
 		    assign_expr0(get_input_register_var(reg_arg,0),arg,t,t),
@@ -1162,32 +1196,21 @@
 	}
 	++nargs;
     }
-    if (car(e2) == FNAME) {	
-	n=(NMTBL *)cadr(e2);
-	regv[creg]=0;
-    } else {	
-	g_expr(e2);
-	regv[creg]=1;
-    }
-
     for(;arg_assign;arg_assign=cadr(arg_assign)) {
 	g_expr_u(car(arg_assign));
     }
     clear_ptr_cache();
     if (car(e2) == FNAME) {	
-	printf("\tbl\tL_%s$stub\n",n->nm);
+	printf("\tbl\tL_%s$stub\n",fn->nm);
     } else {
-	jmp=get_register();
-        jrn = register_name(jmp);
-	crn = register_name(creg);
-	printf("\tmr %s,%s\n",jrn,crn);
+        jrn = register_name(cadr(jmp));
         printf("\tmtctr %s\n",jrn);
         printf("\tbctrl\n");
-	free_register(jmp);
     }
     for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) {
-	if (car(reg_arg_list)==DREGISTER) free_fregister(cadr(reg_arg_list));
-	else if (car(reg_arg_list)==REGISTER) free_register(cadr(reg_arg_list));
+	arg = car(reg_arg_list);
+	if (car(arg)==DREGISTER) free_fregister(cadr(arg));
+	else if (car(arg)==REGISTER) free_register(cadr(arg));
     }
     if (ret_type==DOUBLE||ret_type==FLOAT) {
 	set_freg(RET_FREGISTER,0);
@@ -1234,16 +1257,16 @@
     crn=register_name(creg);
     switch (car(e1)) {
     case FRINDIRECT: case DRINDIRECT:
-	printf("\t%s %s,(%s)\n",fload(car(e1)==DRINDIRECT),
+	printf("\t%s %s,0(%s)\n",fload(car(e1)==DRINDIRECT),
 	    fregister_name(freg),crn);
 	regv[creg]=0; regv[freg]=1;
 	return DOUBLE;
     case CRINDIRECT: 
-	printf("\tlbz %s,(%s)\n",crn,crn);
+	printf("\tlbz %s,0(%s)\n",crn,crn);
 	printf("\textsb %s,%s\n",crn,crn);
 	return CHAR;
     case RINDIRECT:
-	printf("\tlwz %s,(%s)\n",crn,crn);
+	printf("\tlwz %s,0(%s)\n",crn,crn);
 	return INT;
     }
     error(-1); return INT;
@@ -1257,9 +1280,9 @@
     rrn=register_name(r);
     crn=register_name(creg);
     if (byte) {
-	printf("\tstb %s,(%s)\n",crn,rrn);
+	printf("\tstb %s,0(%s)\n",crn,rrn);
     } else {
-	printf("\tstw %s,(%s)\n",crn,rrn);
+	printf("\tstw %s,0(%s)\n",crn,rrn);
     }
 }
 
@@ -1268,9 +1291,9 @@
     char *crn;
     crn=register_name(creg);
     if (byte) {
-	printf("\tstb %s,%d(r1)\n",crn,e2);
+	printf("\tstb %s,lo16(%d+L_%d)(r1)\n",crn,e2,lvar_offset);
     } else {
-	printf("\tstw %s,%d(r1)\n",crn,e2);
+	printf("\tstw %s,lo16(%d+L_%d)(r1)\n",crn,e2,lvar_offset);
     }
 }
 
@@ -1292,9 +1315,9 @@
     char *crn=register_name(creg);
 
     if (byte) {
-	printf("\tstb %s,(%s)\n",crn,drn);
+	printf("\tstb %s,0(%s)\n",crn,drn);
     } else {
-	printf("\tstw %s,(%s)\n",crn,drn);
+	printf("\tstw %s,0(%s)\n",crn,drn);
     }
 }
 
@@ -1318,16 +1341,16 @@
     int edx = get_register(); if(!edx) error(-1);
     xrn = register_name(xreg = emit_pop(0));       /* pop e3 value */
     regv[xreg]=regs[xreg]=1;
-    printf("\tmr %s,%s  # assop \n",register_name(creg),register_name(edx));
+    printf("# assop\n\tmr %s,%s\n",register_name(creg),register_name(edx));
     regv[edx]=1;
     ld_indexx(byte,0,edx);
     tosop(op,xreg);
     crn = register_name(creg);
     drn = register_name(edx);
     if (byte) {
-	printf("\tstb %s,(%s)\n",crn,drn);
+	printf("\tstb %s,0(%s)\n",crn,drn);
     } else {
-	printf("\tstw %s,(%s)\n",crn,drn);
+	printf("\tstw %s,0(%s)\n",crn,drn);
     }
     free_register(edx);
     emit_pop_free(xreg);
@@ -1377,7 +1400,7 @@
 	printf("\txor %s,%s,%s\n",crn,orn,crn);
 	break;
     case BOR:
-	printf("\torl %s,%s,%s\n",crn,orn,crn);
+	printf("\tor %s,%s,%s\n",crn,orn,crn);
 	break;
     case MUL:
     case UMUL:
@@ -1444,14 +1467,14 @@
 {
     /* used in dosiwtch() */
     if(chk) return;
-    printf("\tcmpw cr0,%s,%d\n",register_name(csreg),e);
+    printf("\tcmpwi cr0,%s,%d\n",register_name(csreg),e);
 }
 
 void
 code_opening(char *filename)
 {
     printf("\t.file \"%s\"\n",filename);
-    printf("\t.version\t\"01.01\"\n");
+    /* printf("\t.version\t\"01.01\"\n"); */
     /* printf("gcc2_compiled.:\n"); */
     printf(".text\n");
 }
@@ -1494,10 +1517,12 @@
     if (output_mode!=TEXT_EMIT_MODE) 
 	text_mode();
     else
-	printf("\t.align 4\n");
+	printf("\t.align 2\n");
     if (stmode!=STATIC)
 	printf(".globl _%s\n",name);
+/*
     printf("\t.type\t%s,@function\n",name);
+ */
     printf("_%s:\n",name);
     code_disp_label=fwdlabel();
     printf("\tla r30,L_%d(r1)\n",code_disp_label);
@@ -1532,15 +1557,18 @@
     if (output_mode!=TEXT_EMIT_MODE) 
 	text_mode();
     else
-	printf("\t.align 4\n");
+	printf("\t.align 2\n");
     if (stmode!=STATIC)
 	printf(".globl _%s\n",name);
+/*
     printf("\t.type\t%s,@function\n",name);
+ */
     printf("_%s:\n",name);
     code_setup=fwdlabel();
     printf("\tmflr r0\n");
     printf("\tbl L_%d\n",code_setup);
     code_base=fwdlabel();
+    lvar_offset = fwdlabel();
     printf("\tmr r30,r1\n");
     printf("\tmflr r31\n");
 }
@@ -1556,16 +1584,17 @@
 int
 reg_save_offset()
 {
-    return (REG_VAR_BASE-max_reg_var)*size_of_int+
-           (FREG_VAR_BASE-max_freg_var)*size_of_double+
-	    20;
+    return -(
+	(REAL_MAX_REGISTER-(REG_VAR_BASE-max_reg_var))*size_of_int+
+	(REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*size_of_double
+	);
 }
 
 void
 leave(int control, char *name)
 {
     if (control) {
-	code_set_fixed_creg(0);
+	code_set_return_register(1);
     }
     if (retcont) fwddef(retcont);
     fwddef(retlabel);
@@ -1592,7 +1621,7 @@
     if (max_reg_var>0)
 	printf("\tstmw r%d,%d(r1)\n",
 			REG_VAR_BASE-max_reg_var,reg_save_offset());
-    printf("\tstwu r1,%d(r1)\n",disp+disp_offset);
+    printf("\tstwu r1,%d(r1)\n",disp+disp_offset+reg_save_offset());
     if (max_freg_var>0)
 	printf("\tb saveFP+%d ; save f%d-f31\n",
 			68-(31-FREG_VAR_BASE-max_freg_var)*4,
@@ -1600,8 +1629,12 @@
     else
 	printf("\tblr\n");
 
+    printf(".set L_%d,%d\n",lvar_offset,
+	arg_offset+disp+disp_offset+reg_save_offset());
+/*
     printf("L_%d:\n",labelno);
     printf("\t.size\t%s,L_%d-%s\n",name,labelno,name);
+ */
     local_table();
     labelno++;
     free_all_register();
@@ -1618,8 +1651,20 @@
 }
 
 void
-code_set_fixed_creg(int mode) {
-    set_creg(RET_REGISTER,mode);
+code_set_fixed_creg(int mode,int type) {
+    if (type==FLOAT||type==DOUBLE) {
+	if (cond_freg== -1) {
+	    cond_freg = get_fregister_var(0);
+	    if(car(cond_freg)!=DREGISTER) error(-1);
+	}
+	set_freg(cadr(cond_freg),mode);
+    } else {
+	if (cond_reg== -1) {
+	    cond_reg = get_register_var(0);
+	    if(car(cond_reg)!=REGISTER) error(-1);
+	}
+	set_creg(cadr(cond_reg),mode);
+    }
 }
 
 void
@@ -1692,7 +1737,7 @@
 	    if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) {
 		l = fwdlabel();
 		printf("\t.long L_%d\n",l);
-		printf(".section\t.rodata\n");
+		printf(".cstring\n\t.align 2\n");
 		printf("L_%d:\n",l);
 		output_mode = RODATA_EMIT_MODE;
 	    }
@@ -1704,13 +1749,17 @@
 void
 emit_data_closing(NMTBL *n)
 {
+/*
     int lb;
+ */
     if (chk) return;
     if (mode==GDECL) {
 	data_mode(0);
+/*
 	lb=fwdlabel();
 	printf("L_%d:\n",lb);
 	printf("\t.size\t%s,L_%d-%s\n",n->nm,lb,n->nm);
+ */
     }
 }
 
@@ -1756,7 +1805,8 @@
 	    } else if (n->sc==FUNCTION||n->sc==CODE) {
 		text_mode();
 printf("\t.set L_%s$stub,_%s\n",extrn,extrn);
-	    }
+printf("\t.set L_%s$non_lazy_ptr,_%s\n",extrn,extrn);
+	    } 
 	}
     }
     init = 0;
@@ -1809,8 +1859,10 @@
 	printf(".data\n");
 	output_mode = DATA_EMIT_MODE;
     }
+/*
     if (name)
 	printf("\t.type\t%s,@object\n",name);
+ */
 }
 
 int
@@ -1830,21 +1882,23 @@
 static int float_one_lib_used=0;
 static char *float_one_lib[] = {
 ".data",
-".literal8",
+/* ".literal8", */
 "        .align 3",
 "__float_one:",
 "        .long   1065353216",
 ".text",
+".set L__float_one$non_lazy_ptr,__float_one",
 0
 };
 static int float_zero_lib_used=0;
 static char *float_zero_lib[] = {
 ".data",
-".literal8",
+/* ".literal8", */
 "        .align 3",
 "__float_zero:",
 "        .long   0",
 ".text",
+".set L__float_zero$non_lazy_ptr,__float_zero",
 0
 };
 
@@ -1872,7 +1926,7 @@
     float_zero_lib_used=1;
     r = get_ptr_cache("_float_zero");
     rrn = register_name(r);
-    printf("\tfls %s,(%s)\n",grn,rrn);
+    printf("\tlfs %s,0(%s)\n",grn,rrn);
     printf("\tfcmpu cr0,%s,%s\n",grn,frn);
     free_fregister(greg);
     fregv[freg]=0;
@@ -1883,7 +1937,7 @@
 code_fregister(int e2,int freg)
 {
     if (freg!=e2)
-	printf("\tfmr %s,%s\n",register_name(freg),register_name(e2));
+	printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2));
     fregv[freg]=1;
 }
 
@@ -1891,19 +1945,20 @@
 { 
     int r;
     r = get_ptr_cache((char*)caddr(e2));
-    printf("\t%s %s,(%s)\n",fstore(d),fregister_name(freg),register_name(r));
+    printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(r));
     fregv[freg]=1;
 }
 
 void code_dassign_lvar(int e2,int freg,int d)
 { 
-    printf("\t%s %s,%d(r1)\n",fstore(d),fregister_name(freg),e2);
+    printf("\t%s %s,lo16(%d+L_%d)(r1)\n",fstore(d),fregister_name(freg),
+	e2,lvar_offset);
     fregv[freg]=1;
 }
 
 void code_dassign(int e2,int freg,int d)
 { 
-    printf("\t%s %s,(%s)\n",fstore(d),fregister_name(freg),register_name(e2));
+    printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(e2));
     fregv[freg]=1;
 }
 
@@ -1934,18 +1989,18 @@
 	float_zero_lib_used=1;
 	r = get_ptr_cache("_float_zero");
 	rrn = register_name(r);
-	printf("\tfls %s,(%s)\n",frn,rrn);
+	printf("\tlfs %s,0(%s)\n",frn,rrn);
 	return;
     }
     if (d==1.0) {
 	float_one_lib_used=1;
 	r = get_ptr_cache("_float_one");
 	rrn = register_name(r);
-	printf("\tfls %s,(%s)\n",frn,rrn);
+	printf("\tlfs %s,0(%s)\n",frn,rrn);
 	return;
     }
     rrn = register_name((r=get_register()));
-    printf(" \t.section\t.rodata\n\t.align 8\n");
+    printf(" \t.data\n\t.align 3\n");
     lb=fwdlabel();
     printf("L_%d:\n",lb);
     printf("\t.long\t0x%x,0x%x\n",code_d2(d),code_d1(d));
@@ -1956,7 +2011,7 @@
     }
     printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",rrn,lb,code_base);
     printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",rrn,lb,code_base,rrn);
-    printf("\tlfd %s,(%s)\n",frn,rrn);
+    printf("\tlfd %s,0(%s)\n",frn,rrn);
     free_register(r);
     fregv[freg]=1;
 }
@@ -1971,10 +2026,11 @@
 { 
     char *frn = fregister_name(freg);
     char *crn = register_name(creg);
-    disp-=size_of_double;
+    int d = new_lvar(size_of_double);
     printf("\tfctiwz  %s,%s\n",frn,frn);
-    printf("\tstfd  %s,%d(r1)\n",frn,disp);
-    printf("\tlwz  %s,%d(r1)\n",crn,disp+size_of_double-size_of_int);
+    printf("\tstfd  %s,lo16(%d+L_%d)(r1)\n",frn,d,lvar_offset);
+    printf("\tlwz %s,lo16(%d+L_%d)(r1)\n",crn,
+	d+size_of_double-size_of_int,lvar_offset);
     fregs[freg]=0;
     regs[creg]=1;
 }
@@ -1982,7 +2038,7 @@
 static int i2d_lib_used=0;
 static char *i2d_lib[] = {
 ".data",
-".literal8",
+/* ".literal8", */
 "        .align 3",
 "__i2dLC0:",
 "        .long   1127219200",
@@ -2004,6 +2060,7 @@
 "        lfd f1,lo16(__i2dLC0-__i2dL1$pb)(r9)",
 "        fsub f1,f0,f1",
 "        blr",
+".set L_i2d$non_lazy_ptr,i2d",
 0
 };
 
@@ -2019,7 +2076,7 @@
 
 static int d2u_lib_used=0;
 static char *d2u_lib[] = {
-".literal8",
+/* ".literal8", */
 "        .align 3",
 "__d2uLC0:",
 "        .long   1105199104",
@@ -2050,6 +2107,7 @@
 "        lwz r3,-20(r1)",
 "        xoris r3,r3,0x8000",
 "        blr",
+".set L_d2u$non_lazy_ptr,d2u",
 0
 };
 
@@ -2066,7 +2124,7 @@
 static int u2d_lib_used=0;
 static char *u2d_lib[] = {
 ".data",
-".literal8",
+/* ".literal8", */
 "        .align 3",
 "__u2dLC1:",
 "        .long   1127219200",
@@ -2087,6 +2145,7 @@
 "        lfd f1,lo16(__u2dLC1-__u2dL2$pb)(r9)",
 "        fsub f1,f0,f1",
 "        blr",
+".set L_u2d$non_lazy_ptr,u2d",
 0
 };
 
@@ -2106,14 +2165,15 @@
 { 
     int r;
     r = get_ptr_cache((char*)caddr(e2));
-    printf("\t%s %s,(%s)\n",fload(d),fregister_name(freg),register_name(r));
+    printf("\t%s %s,0(%s)\n",fload(d),fregister_name(freg),register_name(r));
     fregv[freg]=1;
 }
 
 
 void code_drlvar(int e2,int d,int freg)
 { 
-    printf("\t%s %s,%d(r1)\n",fload(d),fregister_name(freg),e2);
+    printf("\t%s %s,lo16(%d+L_%d)(r1)\n",fload(d),fregister_name(freg),
+	e2,lvar_offset);
     fregv[freg]=1;
 }
 
@@ -2124,7 +2184,7 @@
     int g=get_fregister();
     char *grn=fregister_name(g);
     r = get_ptr_cache((char*)caddr(e2));
-    printf("\t%s %s,(%s)\n",fload(1),grn,register_name(r));
+    printf("\t%s %s,0(%s)\n",fload(1),grn,register_name(r));
     printf("\tfcmpu cr0,%s,%s\n",frn,grn);
     free_fregister(g);
     fregv[freg]=0;
@@ -2132,11 +2192,12 @@
 
 void code_cmp_drlvar(int e2)
 { 
-    printf("\tfcmpu %d(%%ebp)\n",e2);
     char *frn=fregister_name(freg);
     int g=get_fregister();
     char *grn=fregister_name(g);
-    printf("\t%s %s,%d(r1)\n",fload(1),grn,e2);
+
+    printf("\t%s %s,lo16(%d+L_%d)(r1)\n",fload(1),grn,
+	e2,lvar_offset);
     printf("\tfcmpu cr0,%s,%s\n",frn,grn);
     free_fregister(g);
     fregv[freg]=0;
@@ -2154,11 +2215,11 @@
     case DDIV: opn="fdiv"; break;
     case DMUL: opn="fmul"; break;
     case DCMP: 
-	printf("\tfcompu cr0,%s,%s\n",frn,grn);
+	printf("\tfcmpu cr0,%s,%s\n",frn,grn);
 	free_fregister(e1);
 	return;
     case DCMPGE: 
-	printf("\tfcompu cr7,%s,%s\n",frn,grn);
+	printf("\tfcmpu cr7,%s,%s\n",frn,grn);
 	free_fregister(e1);
 	return;
     }
@@ -2173,9 +2234,9 @@
     int  xreg=emit_dpop(0);
     char *crn=register_name(creg);
 
-    printf("\t%s %s,(%s)\n",fload(d),frn,crn);
+    printf("\t%s %s,0(%s)\n",fload(d),frn,crn);
     dtosop(op,xreg);
-    printf("\t%s %s,(%s)\n",fstore(d),frn,crn);
+    printf("\t%s %s,0(%s)\n",fstore(d),frn,crn);
     emit_dpop_free(xreg);
     fregv[freg]=1;
 }
@@ -2198,13 +2259,13 @@
     drn=register_name(r);
     grn=fregister_name(g=get_fregister());
 
-    printf("\t%s %s,(%s)\n",fload(d),frn,crn);
-    printf("\tfls %s,(%s)\n",grn,drn);
+    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);
-    printf("\t%s %s,(%s)\n",fstore(d),frn,crn);
+    printf("\t%s %s,0(%s)\n",fstore(d),frn,crn);
     free_fregister(g);
     fregv[freg]=1;
 }
@@ -2226,13 +2287,13 @@
     drn=register_name(r);
     grn=fregister_name(g=get_fregister());
 
-    printf("\t%s %s,(%s)\n",fload(d),frn,crn);
-    printf("\tfls %s,(%s)\n",grn,drn);
+    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);
-    printf("\t%s %s,(%s)\n",fstore(d),grn,crn);
+    printf("\t%s %s,0(%s)\n",fstore(d),grn,crn);
     free_fregister(g);
     fregv[freg]=1;
 }
@@ -2322,7 +2383,7 @@
     if (float_zero_lib_used) emit_lib(float_zero_lib);
     if (i2d_lib_used) emit_lib(i2d_lib);
     global_table();
-    printf("\t.ident \"Micro-C compiled\"\n");
+    /* printf("\t.ident \"Micro-C compiled\"\n"); */
 }
 
 /* end */
--- a/mc-code.h	Tue Mar 18 12:41:32 2003 +0900
+++ b/mc-code.h	Tue Mar 18 20:50:37 2003 +0900
@@ -83,7 +83,7 @@
 extern void drexpr(int e1, int e2,int l1, int op);
 extern void jcond(int l, char cond);
 extern void jmp(int l);
-extern void code_set_fixed_creg(int mode);
+extern void code_set_fixed_creg(int mode,int type);
 extern void code_set_return_register(int mode);
 extern void text_mode(void);
 extern void global_table(void);
--- a/mc-codegen.c	Tue Mar 18 12:41:32 2003 +0900
+++ b/mc-codegen.c	Tue Mar 18 20:50:37 2003 +0900
@@ -155,18 +155,24 @@
     case DMINUS: 
 	g_expr0(e2); code_dneg(freg);
 	return DOUBLE;
-    case I2D: 
-	g_expr0(e2); code_i2d(creg,freg);
-	return DOUBLE;
-    case D2I: 
-	g_expr0(e2); code_d2i(freg,creg);
-	return INT;
-    case U2D: 
-	g_expr0(e2); code_u2d(creg,freg);
-	return DOUBLE;
-    case D2U: 
-	g_expr0(e2); code_d2u(freg,creg);
-	return UNSIGNED;
+    case CONV: 
+	g_expr0(e2); 
+	switch(caddr(e1)) {
+	case I2D: 
+	    code_i2d(creg,freg);
+	    return DOUBLE;
+	case D2I: 
+	    code_d2i(freg,creg);
+	    return INT;
+	case U2D: 
+	    code_u2d(creg,freg);
+	    return DOUBLE;
+	case D2U: 
+	    code_d2u(freg,creg);
+	    return UNSIGNED;
+	default:
+	    error(-1); return INT;
+	}
     case BNOT:   /* ~ */
 	g_expr0(e2); code_not(creg);
 	return INT;
@@ -219,14 +225,27 @@
     case COND:
 	e2=fwdlabel();
 	b_expr(cadr(e1),0,e2,0);
-	code_set_fixed_creg(0);
-	g_expr0(caddr(e1));
-	code_set_fixed_creg(1);
+	code_set_fixed_creg(0,INT);
+	t = g_expr0(caddr(e1));
+	code_set_fixed_creg(1,t);
 	jmp(e3=fwdlabel());
 	fwddef(e2);
-	code_set_fixed_creg(0);
+	code_set_fixed_creg(0,INT);
 	t = g_expr0(cadddr(e1));
-	code_set_fixed_creg(1);
+	code_set_fixed_creg(1,t);
+	fwddef(e3);
+	return t;
+    case DCOND:
+	e2=fwdlabel();
+	b_expr(cadr(e1),0,e2,0);
+	code_set_fixed_creg(0,DOUBLE);
+	t = g_expr0(caddr(e1));
+	code_set_fixed_creg(1,t);
+	jmp(e3=fwdlabel());
+	fwddef(e2);
+	code_set_fixed_creg(0,DOUBLE);
+	t = g_expr0(cadddr(e1));
+	code_set_fixed_creg(1,t);
 	fwddef(e3);
 	return t;
     case SASS: 
@@ -455,7 +474,7 @@
                 reg_var++;
                 cadddr(args)=size_of_int; /* why we need this? */
             }
-        } else if ((type==FLOAT||type==DOUBLE)&&stmode==REGISTER) {
+        } else if (type==FLOAT||type==DOUBLE) {
             if(freg_var<max_input_fregister_var) {
                 n->sc = DREGISTER;
 		n->dsp = cadr(get_input_fregister_var(freg_var,n));
--- a/mc-codegen.h	Tue Mar 18 12:41:32 2003 +0900
+++ b/mc-codegen.h	Tue Mar 18 20:50:37 2003 +0900
@@ -1,6 +1,6 @@
 
 /* max stack in an expression (for each int, float ) */
-#define MAX_MAX 10
+#define MAX_MAX 20
 
 /* flag in regs/fregs */
 
--- a/mc-parse.c	Tue Mar 18 12:41:32 2003 +0900
+++ b/mc-parse.c	Tue Mar 18 20:50:37 2003 +0900
@@ -1657,8 +1657,8 @@
 {
     if (car(e2)==CONST)  return dlist2(DCONST,(double)cadr(e2));
     if(type==FLOAT||type==DOUBLE) return e2;
-    if(type==UNSIGNED) return list2(U2D,rvalue_t(e2,type));
-    if(integral(type)) return list2(I2D,rvalue_t(e2,type));
+    if(type==UNSIGNED) return list3(CONV,rvalue_t(e2,type),U2D);
+    if(integral(type)) return list3(CONV,rvalue_t(e2,type),I2D);
     error(TYERR); return dlist2(DCONST,1.0);
 }
 
@@ -1667,7 +1667,7 @@
 {
     if (car(e2)==DCONST||car(e2)==FCONST)  return list2(CONST,(int)dcadr(e2));
     if(scalar(type)||car(type)==ARRAY) return e2;
-    if(type==FLOAT||type==DOUBLE) return list2(D2I,rvalue_t(e2,type));
+    if(type==FLOAT||type==DOUBLE) return list3(CONV,rvalue_t(e2,type),D2I);
     error(TYERR); return list2(CONST,1);
 }
 
@@ -1675,7 +1675,7 @@
 unsigned_value(int e2,int type)
 {
     if(scalar(type)) return e2;
-    if(type==FLOAT||type==DOUBLE) return list2(D2U,rvalue_t(e2,type));
+    if(type==FLOAT||type==DOUBLE) return list3(CONV,rvalue_t(e2,type),D2U);
     error(TYERR); return e2;
 }
 
@@ -1819,8 +1819,15 @@
 	    } else
 		return e3;
 	}
+	if(type==FLOAT||type==DOUBLE||t==FLOAT||t==DOUBLE) {
+	    e2=float_value(e2,t);
+	    e3=float_value(e2,type);
+	    t=type=DOUBLE;
+	    return(list4(DCOND,e1,e2,e3));
+	}
 	if(type==INT||(t!=INT&&type==UNSIGNED))
 	    type=t;
+	/* if (t!=type) error(TYERR); */
 	return(list4(COND,e1,e2,e3));
     }
     return(e1);
--- a/mc.h	Tue Mar 18 12:41:32 2003 +0900
+++ b/mc.h	Tue Mar 18 20:50:37 2003 +0900
@@ -190,6 +190,8 @@
 #define DPOSTINC	103
 #define FPREINC	104
 #define DPREINC	105
+#define DCOND	106
+#define CONV	107
 
 #define US	1
 #define AS	200
--- a/test/basic.c	Tue Mar 18 12:41:32 2003 +0900
+++ b/test/basic.c	Tue Mar 18 20:50:37 2003 +0900
@@ -58,6 +58,19 @@
 }
 
 int 
+g2(
+int a0,int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8,
+int b0,int b1,int b2,int b3,int b4,int b5,int b6,int b7,int b8
+)
+{
+    printf("g: %d\n",
+a0+a1+a2+a3+a4+a5+a6+a7+a8+
+b0+b1+b2+b3+b4+b5+b6+b7+b8
+    );
+    return a8;
+}
+
+int 
 h( int a0,int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8)
 {
 g( a0,a1,a2,a3,a4,a5,a6,a7,a8);
@@ -113,4 +126,5 @@
     print(0.1234);
     print(1.234e10);
     print(1.234e-10);
+    tmp1();
 }
--- a/test/float.c	Tue Mar 18 12:41:32 2003 +0900
+++ b/test/float.c	Tue Mar 18 20:50:37 2003 +0900
@@ -40,6 +40,9 @@
    double g;
    int i;
    unsigned u;
+   double d00 = ac?0.5:3;
+
+   printf("%g\n",d00);
 
    g = 1.0;
    g = -g;