changeset 111:7aa449aff3e6

floating point
author kono
date Wed, 19 Mar 2003 18:33:25 +0900
parents fb502a0071f8
children fc7de4faedfd
files .gdbinit .gdbinit.powerpc Changes mc-code-ia32.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-parse.c test/macro.c
diffstat 9 files changed, 172 insertions(+), 78 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Wed Mar 19 04:25:43 2003 +0900
+++ b/.gdbinit	Wed Mar 19 18:33:25 2003 +0900
@@ -1,7 +1,12 @@
 tb main
+r -s mc-code-powerpc.c
 define regs 
-printf "r0=%08x r1=%08x r2=%08x r3=%08x\n",$r0,$r1,$r2,$r3
-printf "lr=%08x pc=%08x r4=%08x r5=%08x\n",$lr,$pc,$r4,$r5
+printf "lr =%08x pc =%08x r0 =%08x r1 =%08x r3= %08x r4= %08x\n",$lr,$pc,$r0,$r1,$r3,$r4
+printf "r10=%08x r11=%08x r12=%08x r13=%08x r14=%08x r15=%08x\n",$r10,$r11,$r12,$r13,$r14,$r15
+end
+define fregs 
+printf "f1=%g f2=%g f3=%g f4=%g f5=%g f6=%g\n",$f1,$f2,$f3,$f4,$f5,$f6
+printf "f10=%g f11=%g f12=%g f13=%g f14=%g f15=%g\n",$f10,$f11,$f12,$f13,$f14,$f15
 end
 define si
 stepi
@@ -14,4 +19,3 @@
 x/1i $pc
 end
 b errmsg
-r -s mc-code-powerpc.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.gdbinit.powerpc	Wed Mar 19 18:33:25 2003 +0900
@@ -0,0 +1,21 @@
+tb main
+r -s mc-code-powerpc.c
+define regs 
+printf "lr =%08x pc =%08x r0 =%08x r1 =%08x r3= %08x r4= %08x\n",$lr,$pc,$r0,$r1,$r3,$r4
+printf "r10=%08x r11=%08x r12=%08x r13=%08x r14=%08x r15=%08x\n",$r10,$r11,$r12,$r13,$r14,$r15
+end
+define fregs 
+printf "f1=%g f2=%g f3=%g f4=%g f5=%g f6=%g\n",$f1,$f2,$f3,$f4,$f5,$f6
+printf "f10=%g f11=%g f12=%g f13=%g f14=%g f15=%g\n",$f10,$f11,$f12,$f13,$f14,$f15
+end
+define si
+stepi
+regs
+x/1i $pc
+end
+define ni
+nexti
+regs
+x/1i $pc
+end
+b errmsg
--- a/Changes	Wed Mar 19 04:25:43 2003 +0900
+++ b/Changes	Wed Mar 19 18:33:25 2003 +0900
@@ -2320,4 +2320,30 @@
 Wed Mar 19 02:22:51 JST 2003
 
 なんだか、struct のtag listが、int a,b,c; のようになっているのを
-一つと数えているらしい。困ったものだ。
+一つと数えているらしい。困ったものだ。前に言ったのをちゃんと
+実装しよう。
+
+macro のバグも見つけちゃったよ... むぅ。
+
+でも、とりあえず、a.out は動きました。
+
+Wed Mar 19 12:59:01 JST 2003
+
+なんか、浮動小数点をprintfに引き渡すときは、rnレジスタにも
+値をいれていて、しかも、そっちを見るみたいね。これは、
+めんどくさい....
+   r4,r5   ... f1
+   r6,r7   ... f2
+   r8,r9   ... f3
+   f4 からは単独
+(あぁ、なんか、これは異常にめんどくさいぞ... こんなことするなら
+f0 から r0 にコピーさせてよ...)
+
+40(r1)とかをprintfは、派手にぶっこわすようですね。いったい
+どれだけ取れば良いんだろう?
+
+-112 ぐらい? 今は-72程度か。
+
+(なんか風邪ひいた... 家内がくるというのに...)
+
+浮動小数点のバグも順調に取れています。
--- a/mc-code-ia32.c	Wed Mar 19 04:25:43 2003 +0900
+++ b/mc-code-ia32.c	Wed Mar 19 18:33:25 2003 +0900
@@ -1062,7 +1062,7 @@
 }
 
 void
-code_assign_register(int e2,int byte) {
+code_assign_register(int e2,int byte,int creg) {
     printf("\tmovl %s,%s\n",register_name(creg,0),register_name(e2,0));
 }
 
@@ -1617,6 +1617,11 @@
     printf("\t%s %d(%%ebp)\n",fstore(d),e2);
 }
 
+void code_dassign_fregister(int e,int d,int freg)
+{
+    error(-1);
+}
+
 void code_dassign(int e2,int freg,int d)
 { 
     printf("\t%s (%s)\n",fstore(d),register_name(e2,0));
--- a/mc-code-powerpc.c	Wed Mar 19 04:25:43 2003 +0900
+++ b/mc-code-powerpc.c	Wed Mar 19 18:33:25 2003 +0900
@@ -20,6 +20,9 @@
 static int data_alignment = 0;
 
 static int code_disp_label;
+static int code_setup;
+static int func_disp_label;
+
 
 /*
                                            -16  -8 local2   <-- r30
@@ -48,17 +51,28 @@
      f1-r8  input register
      f24-f31 saved register variable
  */
-int arg_offset = 56;
-int disp_offset = 0;
-int func_disp_offset = 0;
+int arg_offset = 40;
+int disp_offset = -32;
+int func_disp_offset = -40;
 int code_disp_offset = 0;
 int jump_offset = 0;
 
+/*
+    printf(".set L_%d,%d\n",func_disp_label,
+	-(disp+func_disp_offset+disp_offset+reg_save));
+    lvar(int l)
+	if (fnptr->sc==CODE) { return l+code_disp_offset;
+	} else if (l<0) {      return l+disp_offset;
+	} else {               return l+arg_offset;
+	}
+
+ */
+
 int size_of_int = 4;
 int size_of_float = 4;
 int size_of_double = 8;
 int size_of_longlong = 8;
-int endian = 0;
+int endian = 1;
 
 #define REG_fp   1
 #define REG_sp   30
@@ -104,7 +118,6 @@
 
 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",
@@ -139,11 +152,6 @@
 void
 code_init(void)
 {
-    arg_offset = 8;
-    func_disp_offset = -12;
-    disp_offset = -12;
-    size_of_int = 4;
-    endian = 1;
     init_ptr_cache();
 }
 
@@ -578,7 +586,7 @@
 void
 code_lvar(int e2,int creg) {
     printf("\tla %s,lo16(%d+L_%d)(r1)\n",register_name(creg),
-	e2,lvar_offset);
+	e2,func_disp_label);
     regv[creg]=1;
 }
 
@@ -594,14 +602,14 @@
 void
 code_rlvar(int e2,int reg) {
     printf("\tlwz %s,lo16(%d+L_%d)(r1)\n",register_name(reg),
-	e2,lvar_offset);
+	e2,func_disp_label);
     regv[creg]=1;
 }
 
 
 void
 code_crlvar(int e2,int reg) {
-    printf("\tlbz %s,lo16(%d+L_%d)(r1)\n",register_name(reg),e2,lvar_offset);
+    printf("\tlbz %s,lo16(%d+L_%d)(r1)\n",register_name(reg),e2,func_disp_label);
     printf("\textsb %s,%s\n",register_name(reg),register_name(reg));
     regv[reg]=1;
 }
@@ -884,7 +892,7 @@
 void
 code_cmp_crlvar(int e1) {
     char *crn = register_name(creg);
-    printf("\tlbz %s,lo16(%d+L_%d)(r1)\n",crn,e1,lvar_offset);
+    printf("\tlbz %s,lo16(%d+L_%d)(r1)\n",crn,e1,func_disp_label);
     code_cmp_register(creg);
     regv[creg]=0;
 }
@@ -904,7 +912,7 @@
 void
 code_cmp_rlvar(int e1) {
     char *crn = register_name(creg);
-    printf("\tlwz %s,lo16(%d+L_%d)(r1)\n",crn,e1,lvar_offset);
+    printf("\tlwz %s,lo16(%d+L_%d)(r1)\n",crn,e1,func_disp_label);
     code_cmp_register(creg);
     regv[creg]=0;
 }
@@ -1067,6 +1075,7 @@
 set_creg(int reg,int mode)
 {
     if (reg!=creg) {
+	clear_ptr_cache_reg(reg);
 	if (mode) 
 	    printf("\tmr %s,%s\n",register_name(reg),register_name(creg));
 	free_register(creg);
@@ -1143,16 +1152,18 @@
     ;
 }
 
+
 int
 function(int e1)
 {
-    int e2,e3,e4,e5,nargs,t;
+    int e2,e3,e4,e5,nargs,t,r0,r1;
     int arg,reg_arg,freg_arg,arg_assign;
-    int reg_arg_list=0,ret_type;
-    NMTBL *n,*fn;
+    int reg_arg_list=0,ret_type,special_lvar;
+    NMTBL *fn;
     int jmp = 0;
     char *jrn;
 
+    special_lvar = -1;
     ret_type = cadddr(e1);
 
     e2 = cadr(e1);
@@ -1173,7 +1184,7 @@
     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))));
+	e4 = car(e3);
 	if(scalar(t)) {
 	    if (reg_arg>MAX_INPUT_REGISTER_VAR) { 
 		arg = list2(LVAR,arg_offset_v(nargs));
@@ -1191,12 +1202,32 @@
 	    nargs ++ ; reg_arg++;
 	    continue;
 	} else if (t==DOUBLE||t==FLOAT) {
+	    if (reg_arg<MAX_INPUT_REGISTER_VAR-1) {
+		/* sigh... */
+		if (car(e4)==DRLVAR) {
+		    special_lvar = cadr(e4);
+		    e5 = list2(LVAR,special_lvar);
+		} else {
+		    special_lvar = new_lvar(size_of_double);
+		    g_expr_u(assign_expr0((e5=list2(LVAR,special_lvar)),e4,t,t));
+		    e4 = e5;
+		}
+		r0=get_input_register_var(reg_arg,0);
+		r1=get_input_register_var(reg_arg+1,0);
+		reg_arg_list = list2(r0,reg_arg_list);
+		reg_arg_list = list2(r1,reg_arg_list);
+		arg_assign = list2( assign_expr0(r0,e5,INT,INT), arg_assign);
+		arg_assign = list2( assign_expr0(r1,
+			list2(LVAR,special_lvar+size_of_int),
+			INT,INT), arg_assign);
+		reg_arg += 2;
+	    }
 	    if (freg_arg>MAX_INPUT_DREGISTER_VAR) {
 		arg = list2(LVAR,arg_offset_v(nargs));
 	    } 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),
+		    assign_expr0(get_input_fregister_var(reg_arg,0),arg,t,t),
 		    arg_assign);
 	    } else {
 		arg = get_input_fregister_var(freg_arg,0); 
@@ -1310,20 +1341,14 @@
     char *crn;
     crn=register_name(creg);
     if (byte) {
-	printf("\tstb %s,lo16(%d+L_%d)(r1)\n",crn,e2,lvar_offset);
+	printf("\tstb %s,lo16(%d+L_%d)(r1)\n",crn,e2,func_disp_label);
     } else {
-	printf("\tstw %s,lo16(%d+L_%d)(r1)\n",crn,e2,lvar_offset);
+	printf("\tstw %s,lo16(%d+L_%d)(r1)\n",crn,e2,func_disp_label);
     }
 }
 
 void
-code_assign_register(int e2,int byte) {
-    if (e2!=creg)
-	printf("\tmr %s,%s\n",register_name(e2),register_name(creg));
-}
-
-void
-code_assign_fregister(int e2,int byte) {
+code_assign_register(int e2,int byte,int creg) {
     if (e2!=creg)
 	printf("\tmr %s,%s\n",register_name(e2),register_name(creg));
 }
@@ -1568,9 +1593,6 @@
     free_all_register();
 }
 
-static int code_setup;
-static int func_disp_label;
-
 void
 enter(char *name)
 {
@@ -1588,9 +1610,9 @@
     printf("\tmflr r0\n");
     printf("\tbl L_%d\n",code_setup);
     code_base=fwdlabel();
-    lvar_offset = fwdlabel();
+    fwddef(code_base);
     func_disp_label = fwdlabel();
-    printf("\tstwu r1,lo16(L_%d)(r1)\n",func_disp_label);
+    printf("\tstwu r1,lo16(-L_%d)(r1)\n",func_disp_label);
     printf("\tmr r30,r1\n");
     printf("\tmflr r31\n");
 }
@@ -1614,17 +1636,22 @@
 void
 leave(int control, char *name)
 {
+    int reg_save;
+    int freg_save;
+
     if (control) {
 	code_set_return_register(1);
     }
     if (retcont) fwddef(retcont);
     fwddef(retlabel);
     printf("\tlwz r1,0(r1)\n");
+    reg_save = reg_save_offset();
     if (max_freg_var>=0) {
 	printf("\tlmw r%d,%d(r1)\n",
-			REG_VAR_BASE-max_reg_var,reg_save_offset());
+			REG_VAR_BASE-max_reg_var,reg_save);
+	freg_save = 72-(REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*4;
 	printf("\tb restFP+%d ; restore f%d-f31\n",
-			68-(31-FREG_VAR_BASE-max_freg_var)*4,
+			freg_save,
 			FREG_VAR_BASE-max_freg_var);
     } else {
 	printf("\tlwz r0,8(r1)\n");
@@ -1636,21 +1663,20 @@
 
     disp &= -size_of_int;
     fwddef(code_setup);
-    fwddef(code_base);
     printf("\tstmw r%d,%d(r1)\n",
 		    REG_VAR_BASE-max_reg_var,reg_save_offset());
     printf("\tstw r0,8(r1)\n");
     if (max_freg_var>=0)
 	printf("\tb saveFP+%d ; save f%d-f31\n",
-			68-(31-FREG_VAR_BASE-max_freg_var)*4,
+			freg_save,
 			FREG_VAR_BASE-max_freg_var);
     else {
 	printf("\tblr\n");
     }
 
-    printf(".set L_%d,%d\n",func_disp_label,disp+disp_offset+reg_save_offset());
-    printf(".set L_%d,%d\n",lvar_offset,
-	arg_offset+disp+disp_offset+reg_save_offset());
+    printf("## disp %d arg_offset=%d disp_offset=%d reg_save=%d\n",disp,arg_offset,disp_offset,reg_save); 
+    printf(".set L_%d,%d\n",func_disp_label,
+	-(disp+func_disp_offset+disp_offset+reg_save));
 /*
     printf("L_%d:\n",labelno);
     printf("\t.size\t%s,L_%d-%s\n",name,labelno,name);
@@ -1663,7 +1689,7 @@
 
 void
 code_set_return_register(int mode) {
-    if (fnptr->ty==DOUBLE||fnptr->ty==FLOAT) {
+    if (cadr(fnptr->ty)==DOUBLE||cadr(fnptr->ty)==FLOAT) {
 	set_freg(RET_FREGISTER,mode);
     } else {
 	set_creg(RET_REGISTER,mode);
@@ -1835,7 +1861,7 @@
 		text_mode();
 printf("\t.set L_%s$stub,_%s\n",extrn,extrn);
 		data_mode(0);
-printf("L_%s$non_lazy_ptr:\n\t.long\t_%s\n\n",extrn,extrn);
+printf("L_%s$non_lazy_ptr:\n\t.long\t_%s\n",extrn,extrn);
 	    } 
 	}
     }
@@ -1992,7 +2018,7 @@
 void code_dassign_lvar(int e2,int freg,int d)
 { 
     printf("\t%s %s,lo16(%d+L_%d)(r1)\n",fstore(d),fregister_name(freg),
-	e2,lvar_offset);
+	e2,func_disp_label);
     fregv[freg]=1;
 }
 
@@ -2002,6 +2028,12 @@
     fregv[freg]=1;
 }
 
+void
+code_dassign_fregister(int e2,int d,int freg) {
+    if (e2!=freg)
+	printf("\tfmr %s,%s\n",fregister_name(e2),fregister_name(freg));
+}
+
 static double d0 = 1.0;
 
 int
@@ -2068,9 +2100,9 @@
     char *crn = register_name(creg);
     int d = new_lvar(size_of_double);
     printf("\tfctiwz  %s,%s\n",frn,frn);
-    printf("\tstfd  %s,lo16(%d+L_%d)(r1)\n",frn,d,lvar_offset);
+    printf("\tstfd  %s,lo16(%d+L_%d)(r1)\n",frn,d,func_disp_label);
     printf("\tlwz %s,lo16(%d+L_%d)(r1)\n",crn,
-	d+size_of_double-size_of_int,lvar_offset);
+	d+size_of_double-size_of_int,func_disp_label);
     fregs[freg]=0;
     regs[creg]=1;
 }
@@ -2085,7 +2117,7 @@
 "        .long   -2147483648",
 ".text",
 "        .align 2",
-"i2d:",
+"i2d_:",
 "        mflr r0",
 "        bcl 20,31,__i2dL1$pb",
 "__i2dL1$pb:",
@@ -2100,7 +2132,6 @@
 "        lfd f1,lo16(__i2dLC0-__i2dL1$pb)(r9)",
 "        fsub f1,f0,f1",
 "        blr",
-/* ".set L_i2d$non_lazy_ptr,i2d", */
 0
 };
 
@@ -2123,7 +2154,7 @@
 "        .long   0",
 ".text",
 "        .align 2",
-"d2u:",
+"d2u_:",
 "        mflr r0",
 "        bcl 20,31,__d2uL1$pb",
 "__d2uL1$pb:",
@@ -2147,7 +2178,6 @@
 "        lwz r3,-20(r1)",
 "        xoris r3,r3,0x8000",
 "        blr",
-/* ".set L_d2u$non_lazy_ptr,d2u", */
 0
 };
 
@@ -2155,7 +2185,7 @@
 { 
     d2u_lib_used=1;
     set_freg(RET_FREGISTER,1);
-    printf("\tbl d2u\n");
+    printf("\tbl d2u_\n");
     set_creg(RET_REGISTER,0);
     fregs[freg]=1;
     regs[creg]=0;
@@ -2171,7 +2201,7 @@
 "        .long   0",
 ".text",
 "        .align 2",
-"u2d:",
+"u2d_:",
 "        mflr r0",
 "        bcl 20,31,__u2dL2$pb",
 "__u2dL2$pb:",
@@ -2185,7 +2215,6 @@
 "        lfd f1,lo16(__u2dLC1-__u2dL2$pb)(r9)",
 "        fsub f1,f0,f1",
 "        blr",
-/* ".set L_u2d$non_lazy_ptr,u2d", */
 0
 };
 
@@ -2195,7 +2224,7 @@
     char *frn = fregister_name(freg);
     char *crn = register_name(creg);
     printf("\tmr r3,%s\n",crn);
-    printf("\tbl u2d\n");
+    printf("\tbl u2d_\n");
     printf("\tfmr %s,f1\n",frn);
     fregs[freg]=1;
     regs[creg]=0;
@@ -2213,7 +2242,7 @@
 void code_drlvar(int e2,int d,int freg)
 { 
     printf("\t%s %s,lo16(%d+L_%d)(r1)\n",fload(d),fregister_name(freg),
-	e2,lvar_offset);
+	e2,func_disp_label);
     fregv[freg]=1;
 }
 
@@ -2237,7 +2266,7 @@
     char *grn=fregister_name(g);
 
     printf("\t%s %s,lo16(%d+L_%d)(r1)\n",fload(1),grn,
-	e2,lvar_offset);
+	e2,func_disp_label);
     printf("\tfcmpu cr0,%s,%s\n",frn,grn);
     free_fregister(g);
     fregv[freg]=0;
@@ -2345,16 +2374,16 @@
     switch(op) {
 	case DOP+GE:
 	    printf("\tcror 2,29,30\n");
-	    printf("\tbeq\tcr0,L_%d\n",l1);
+	    printf("\tbne\tcr0,L_%d\n",l1);
 	    break;
 	case DOP+GT:
-	    printf("\tbgt\tcr0,L_%d\n",l1);
+	    printf("\tble\tcr0,L_%d\n",l1);
 	    break;
 	case DOP+EQ:
-	    printf("\tbeq\tcr0,L_%d\n",l1);
+	    printf("\tbne\tcr0,L_%d\n",l1);
 	    break;
 	case DOP+NEQ:
-	    printf("\tbne\tcr0,L_%d\n",l1);
+	    printf("\tbeq\tcr0,L_%d\n",l1);
 	    break;
     }
 }
--- a/mc-code.h	Wed Mar 19 04:25:43 2003 +0900
+++ b/mc-code.h	Wed Mar 19 18:33:25 2003 +0900
@@ -72,7 +72,7 @@
 extern int rindirect(int e1);
 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);
+extern void code_assign_register(int e2,int byte,int reg);
 extern void code_assign(int e2,int byte);
 extern void code_register_assop(int e2,int op,int byte);
 extern void code_assop(int op,int byte);
@@ -102,6 +102,7 @@
 extern void code_dassign(int,int,int);
 extern void code_dassign_gvar(int,int,int);
 extern void code_dassign_lvar(int,int,int);
+extern void code_dassign_fregister(int e2,int d,int reg);
 extern void code_dconst(int,int);
 extern void code_dneg(int);
 extern void code_drgvar(int,int,int);
--- a/mc-codegen.c	Wed Mar 19 04:25:43 2003 +0900
+++ b/mc-codegen.c	Wed Mar 19 18:33:25 2003 +0900
@@ -939,7 +939,7 @@
     case REGISTER:
             g_expr(e4);
 	    if (creg!=cadr(e2))
-		code_assign_register(cadr(e2),byte);
+		code_assign_register(cadr(e2),byte,creg);
             return;
     }
     g_expr(e2);
@@ -971,6 +971,11 @@
             g_expr(e4);
 	    code_dassign_lvar(lvar(cadr(e2)),freg,d);
             return;
+    case DREGISTER:
+            g_expr(e4);
+	    if (freg!=cadr(e2))
+		code_dassign_fregister(cadr(e2),d,freg);
+            return;
     }
     g_expr(e2);
     emit_push();
--- a/mc-parse.c	Wed Mar 19 04:25:43 2003 +0900
+++ b/mc-parse.c	Wed Mar 19 18:33:25 2003 +0900
@@ -515,7 +515,7 @@
 decl1(void)
 {
     NMTBL *n;
-    int i,t;
+    int i,t,sstmode;
 
     if(sym==LPAR) {
 	getsym();
@@ -551,25 +551,24 @@
 	    } else
 		getsym();
 	    n->dsp=0;
+	    if(stmode==EXTRN) n->sc=EXTRN;
 	    if (type==CODE) {
 		n->ty=CODE;
-		/* n->sc=EMPTY; */
 		if(sym==RPAR) {
 		    getsym();t=0;
 		} else {
-		    stmode=REGISTER;
+		    sstmode=stmode; stmode=REGISTER;
 		    t=adecl(n);
-		    stmode=0;
+		    stmode=sstmode;
 		}
 		type=glist3(CODE,CODE,t);
 	    } else {
-		/* n->sc=EMPTY; */
 		if(sym==RPAR) {
 		    getsym();t=0;
 		} else {
-		    stmode=REGISTER;
+		    sstmode=stmode; stmode=REGISTER;
 		    t=adecl(n);
-		    stmode=0;
+		    stmode=sstmode;
 		}
 		type=glist3(FUNCTION,type,t);
 		n->ty=type;
@@ -1106,10 +1105,10 @@
     } else
 	fnptr->dsp=reverse0(fnptr->dsp);
     fdecl_struct(fnptr->ty);
+    disp=0;
     arg_register(fnptr);
     typedefed=0;
     conv->function_(fnptr,sd); conv->lc_();
-    disp=0;
     init_vars=0;
     /* local variable declaration */
     stmode=0;
@@ -1823,7 +1822,7 @@
 	}
 	if(type==FLOAT||type==DOUBLE||t==FLOAT||t==DOUBLE) {
 	    e2=float_value(e2,t);
-	    e3=float_value(e2,type);
+	    e3=float_value(e3,type);
 	    t=type=DOUBLE;
 	    return(list4(DCOND,e1,e2,e3));
 	}
@@ -2143,7 +2142,7 @@
 {
     int e1;
     e1=list2(FNAME,(int)nptr);
-    type=list3(car(nptr->ty),nptr->ty,nptr->dsp);
+    type=list3(car(nptr->ty),cadr(nptr->ty),nptr->dsp);
     getsym();
     extrn_use(nptr);
     return expr16(e1);
--- a/test/macro.c	Wed Mar 19 04:25:43 2003 +0900
+++ b/test/macro.c	Wed Mar 19 18:33:25 2003 +0900
@@ -20,6 +20,10 @@
       b);
    /* 3,5 expected */
 #endif
-   car(cadr(e));
+   e=50; heap[51]=3; heap[3]=4;
+   /* 5,4 expected */
+#if 0
+   g(car(cadr(e)),cadr(e));
+#endif
 }