changeset 82:25654dc29ecc

First Floating Point coding done.
author kono
date Wed, 05 Mar 2003 00:39:39 +0900
parents f94ca1168520
children f3f75911d62c
files Changes Makefile conv/c.c conv/c.h conv/null.c conv/null.h mc-code-ia32.c mc-code.h mc-codegen.c mc-parse.c mc.h test/float.c
diffstat 12 files changed, 861 insertions(+), 159 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Mon Mar 03 20:59:51 2003 +0900
+++ b/Changes	Wed Mar 05 00:39:39 2003 +0900
@@ -1856,3 +1856,30 @@
 違うんだろうな。
 
 dreg/creg のfloating versionが必要です。( です? )
+
+Tue Mar  4 14:56:28 JST 2003
+
+double のcurrent register は387のスタックを使う。(?)
+関数呼び出し時に387のスタックが保存されるという
+保証は無いので、emit_dpushでは、%esp に保存する。
+
+でも、そうすると、代入の後などで387のスタックが
+常に残ることになる。こいつをクリアするコードは
+どこにいれる? free_register でもいいんだけど....
+ううーむ、つかいずらいやつ。ld じゃなくて、
+stack top に代入するオペレーションはないの?
+
+(あぁ、でも、なんか、floatは、もうすぐ終っちゃうな... なんか、
+さびし...)
+
+Tue Mar  4 23:58:07 JST 2003
+
+fmulp とかでは、fpp のstackのつじつまはあう。fstl とかだと、
+合わない。fstpl すればいいんだが、そうすると連続代入でまずくなる。
+値を使うかどうかを代入時に知ることができれば良いんだが。
+
+結局、freg は、使わなかったね。0が、入っているので直さないとまずいか。
+fregを見て、stack を直すってのは、やっぱり、まずいよな...
+
+でも、浮動小数点レジスタを持つCPUの場合はいるんじゃないの?
+
--- a/Makefile	Mon Mar 03 20:59:51 2003 +0900
+++ b/Makefile	Wed Mar 05 00:39:39 2003 +0900
@@ -5,8 +5,8 @@
 MFLAGS=$(MFALGS) BASE=$(BASE) STAGE=$(STAGE)
 MC=mc
 PRINTF= # printf.c
-CONVERTER=conv/c.o 
-# conv/c2cbc.o conv/cbc2c.o conv/null.o
+CONVERTER=conv/c.o conv/null.o
+# conv/c2cbc.o conv/cbc2c.o
 
 all: mc 
 
@@ -14,9 +14,11 @@
 	$(CC) -g mc-parse.o mc-codegen.o mc-code-ia32.o \
 		mc-tree.o $(CONVERTER) -o $@
 
-conv/conv.h: conv_func.tbl
+conv/conv.h: conv_func.tbl conv_func.pl
 	perl conv_func.pl
-conv/convdef.h: conv_func.tbl
+conv/convdef.h: conv_func.tbl conv_func.pl
+	perl conv_func.pl
+conv/null.c: conv_func.tbl conv_func.pl
 	perl conv_func.pl
 
 tar :
--- a/conv/c.c	Mon Mar 03 20:59:51 2003 +0900
+++ b/conv/c.c	Wed Mar 05 00:39:39 2003 +0900
@@ -3,6 +3,7 @@
 #include "mc.h"
 
 #include "conv/convdef.h"
+#include "conv/c.h"
 
 extern void type_print(int type,NMTBL *nptr,FILE *out);
 extern void type_print1(int type,NMTBL *nptr,FILE *out,int cont);
--- a/conv/c.h	Mon Mar 03 20:59:51 2003 +0900
+++ b/conv/c.h	Wed Mar 05 00:39:39 2003 +0900
@@ -1,3 +1,81 @@
+/* Do not edit this file. This is automatically generated. */
+
+extern Converter c_converter;
+
 
 
-extern Converter c_converter;
+Converter c_converter = {
+    &conv_,
+    &noconv_,
+    &comment_,
+    &open_,
+    &print_,
+    &close_,
+    &case_,
+    &case_begin_,
+    &code_,
+    &code_end_,
+    &comma_,
+    &cond_,
+    &cond1_,
+    &cond2_,
+    &cond_end_,
+    &decl_data_begin_,
+    &decl_data_end_,
+    &def_,
+    &dowhile_,
+    &dowhile_cond_,
+    &dowhile_end_,
+    &error_,
+    &extern_,
+    &for_,
+    &for1_,
+    &for2_,
+    &for_body_,
+    &for_end_,
+    &funcall_,
+    &funcall_args_,
+    &function_,
+    &function_end_,
+    &goto_,
+    &goto_label_,
+    &id_,
+    &string_,
+    &const_,
+    &return_f_,
+    &defined_,
+    &environment_,
+    &if_,
+    &if_else_,
+    &if_endif_,
+    &if_then_,
+    &jump_,
+    &label_,
+    &lbra_,
+    &lc_,
+    &localvar_end_,
+    &lpar_,
+    &op_,
+    &postfix_,
+    &prefix_,
+    &rbra_,
+    &rc_,
+    &register_,
+    &return_,
+    &return_end_,
+    &return_type_,
+    &rpar_,
+    &sm_,
+    &static_,
+    &switch_,
+    &switch_body_,
+    &switch_end_,
+    &typedef_,
+    &while_,
+    &while_body_,
+    &while_end_,
+    &decl_data_,
+    &break_,
+    &continue_,
+    &sdecl_,
+};
--- a/conv/null.c	Mon Mar 03 20:59:51 2003 +0900
+++ b/conv/null.c	Wed Mar 05 00:39:39 2003 +0900
@@ -1,36 +1,299 @@
+/* Do not edit this file. This is automatically generated. */
 #define EXTERN /**/
+#include "mc.h"
+#include "conv/convdef.h"
+
+#include "conv/null.h"
+
+static void
+conv_()
+{ }
+
+static void
+noconv_(int f)
+{ }
+
+static void
+comment_(int f)
+{ }
+
+static void
+open_(char *s)
+{ }
+
+static void
+print_(char *s)
+{ }
+
+static void
+close_()
+{ }
+
+static void
+case_(int cases,int def)
+{ }
 
-#include "mc.h"
+static void
+case_begin_()
+{ }
+
+static void
+code_(NMTBL *fnptr)
+{ }
+
+static void
+code_end_()
+{ }
+
+static void
+comma_()
+{ }
+
+static void
+cond_()
+{ }
+
+static void
+cond1_()
+{ }
+
+static void
+cond2_()
+{ }
+
+static void
+cond_end_()
+{ }
+
+static void
+decl_data_begin_()
+{ }
 
-static void open(char *);
-static void print(char *);
-static void close();
-static void comment(char *s);
+static void
+decl_data_end_()
+{ }
+
+static void
+def_(NMTBL *n)
+{ }
+
+static void
+dowhile_()
+{ }
+
+static void
+dowhile_cond_()
+{ }
+
+static void
+dowhile_end_()
+{ }
+
+static int
+error_(int n)
+{ return (int)0;}
+
+static void
+extern_()
+{ }
+
+static void
+for_()
+{ }
+
+static void
+for1_()
+{ }
 
-Converter null_converter = {
-    &open,
-    &print,
-    &close,
-    &comment,
-};
+static void
+for2_()
+{ }
+
+static void
+for_body_()
+{ }
+
+static void
+for_end_()
+{ }
+
+static void
+funcall_(int type)
+{ }
+
+static void
+funcall_args_()
+{ }
+
+static void
+function_(NMTBL *n,int cont)
+{ }
+
+static void
+function_end_()
+{ }
+
+static void
+goto_()
+{ }
+
+static void
+goto_label_()
+{ }
+
+static void
+id_(int sy,NMTBL *nptr)
+{ }
 
 static void
-comment(char *s)
-{
-}
+string_(char *s)
+{ }
+
+static void
+const_(int symval)
+{ }
+
+static void
+return_f_()
+{ }
+
+static void
+defined_(char *p)
+{ }
+
+static void
+environment_()
+{ }
+
+static void
+if_()
+{ }
+
+static void
+if_else_()
+{ }
+
+static void
+if_endif_()
+{ }
+
+static void
+if_then_()
+{ }
 
 static void
-open(char *s)
-{
-}
+jump_(int env)
+{ }
+
+static void
+label_()
+{ }
+
+static void
+lbra_(int sym)
+{ }
+
+static void
+lc_()
+{ }
+
+static void
+localvar_end_()
+{ }
+
+static void
+lpar_()
+{ }
+
+static void
+op_(int sym)
+{ }
+
+static void
+postfix_(int sym)
+{ }
+
+static void
+prefix_(int sym)
+{ }
+
+static void
+rbra_(int sym)
+{ }
 
 static void
-print(char *s)
-{
-}
+rc_()
+{ }
+
+static void
+register_()
+{ }
+
+static void
+return_()
+{ }
+
+static void
+return_end_()
+{ }
+
+static void
+return_type_(int t,NMTBL *n,int cont)
+{ }
+
+static void
+rpar_()
+{ }
+
+static void
+sm_()
+{ }
+
+static void
+static_()
+{ }
+
+static void
+switch_()
+{ }
 
 static void
-close()
-{
-}
+switch_body_()
+{ }
+
+static void
+switch_end_()
+{ }
+
+static void
+typedef_()
+{ }
+
+static void
+while_()
+{ }
+
+static void
+while_body_()
+{ }
 
+static void
+while_end_()
+{ }
+
+static void
+decl_data_()
+{ }
+
+static void
+break_()
+{ }
+
+static void
+continue_()
+{ }
+
+static void
+sdecl_(int f)
+{ }
+
--- a/conv/null.h	Mon Mar 03 20:59:51 2003 +0900
+++ b/conv/null.h	Wed Mar 05 00:39:39 2003 +0900
@@ -1,2 +1,81 @@
+/* Do not edit this file. This is automatically generated. */
 
 extern Converter null_converter;
+
+
+
+Converter null_converter = {
+    &conv_,
+    &noconv_,
+    &comment_,
+    &open_,
+    &print_,
+    &close_,
+    &case_,
+    &case_begin_,
+    &code_,
+    &code_end_,
+    &comma_,
+    &cond_,
+    &cond1_,
+    &cond2_,
+    &cond_end_,
+    &decl_data_begin_,
+    &decl_data_end_,
+    &def_,
+    &dowhile_,
+    &dowhile_cond_,
+    &dowhile_end_,
+    &error_,
+    &extern_,
+    &for_,
+    &for1_,
+    &for2_,
+    &for_body_,
+    &for_end_,
+    &funcall_,
+    &funcall_args_,
+    &function_,
+    &function_end_,
+    &goto_,
+    &goto_label_,
+    &id_,
+    &string_,
+    &const_,
+    &return_f_,
+    &defined_,
+    &environment_,
+    &if_,
+    &if_else_,
+    &if_endif_,
+    &if_then_,
+    &jump_,
+    &label_,
+    &lbra_,
+    &lc_,
+    &localvar_end_,
+    &lpar_,
+    &op_,
+    &postfix_,
+    &prefix_,
+    &rbra_,
+    &rc_,
+    &register_,
+    &return_,
+    &return_end_,
+    &return_type_,
+    &rpar_,
+    &sm_,
+    &static_,
+    &switch_,
+    &switch_body_,
+    &switch_end_,
+    &typedef_,
+    &while_,
+    &while_body_,
+    &while_end_,
+    &decl_data_,
+    &break_,
+    &continue_,
+    &sdecl_,
+};
--- a/mc-code-ia32.c	Mon Mar 03 20:59:51 2003 +0900
+++ b/mc-code-ia32.c	Wed Mar 05 00:39:39 2003 +0900
@@ -40,7 +40,7 @@
 
 int size_of_int = 4;
 int size_of_float = 4;
-int size_of_dobule = 8;
+int size_of_double = 8;
 int size_of_longlong = 8;
 int endian = 0;
 int MAX_REGISTER=6;         /* intel386のレジスタを4つまで使う*/
@@ -51,6 +51,7 @@
 
 EXTERN int  creg;     /* current register */
 EXTERN int  dreg;     /* temporary register */
+EXTERN int  freg;     /* current floating point register */
 EXTERN int  reg_sp;   /* REGister Stack-Pointer */
 
 
@@ -115,6 +116,11 @@
 int lvar(int l);
 void global_table(void);
 
+char * fstore(int d);
+char * fload(int d);
+int code_d1(double d);
+int code_d2(double d);
+
 void
 code_init(void)
 {
@@ -725,6 +731,18 @@
 	if(scalar(t)) {
 	    g_expr(e4);
 	    printf("\tpushl %s\n",register_name(creg,0));
+	} else if (t==DOUBLE) {
+	    g_expr(e4);
+	    printf("\tleal\t-8(%%esp),%%esp\n\tfstpl\t(%%esp)\n");
+	    regv[freg]=0;
+	    nargs += size_of_double/size_of_int;
+	    continue;
+	} else if (t==FLOAT) {
+	    g_expr(e4);
+	    printf("\tleal\t-4(%%esp),%%esp\n\tfstps\t(%%esp)\n");
+	    regv[freg]=0;
+	    nargs += size_of_float/size_of_int;
+	    continue;
 	} else if (car(t)==STRUCT||car(t)==UNION) {
 	    nargs += struct_push(e4,t);
 	    continue;
@@ -763,6 +781,7 @@
     }
     regv[save]=0;
     regv[creg]=1;
+    regv[freg]=1; /* return type はどこ? fnptr にはあるけど... */
 }
 
 void
@@ -793,11 +812,16 @@
 {
     char *op;
     int e2,e3,byte;
-
-    op = ((byte = (car(e1) == CRINDIRECT)) ? "movsbl" : "movl");
     e3 = cadr(e2 = cadr(e1));
     g_expr(e2);
+    switch (car(e1)) {
+    case FRINDIRECT: case DRINDIRECT:
+    printf("\t%s (%s)\n",fload(car(e1)==DRINDIRECT),register_name(creg,0));
+    break;
+    case CRINDIRECT: case RINDIRECT:
+    op = ((byte = (car(e1) == CRINDIRECT)) ? "movsbl" : "movl");
     printf("\t%s (%s),%s\n",op,register_name(creg,0),register_name(creg,0));
+    }
 }
 
 char *
@@ -1023,6 +1047,33 @@
 }
 
 void
+drexpr(int e1, int e2,int l1, int op)
+{       
+    g_expr(list3(DCOMP,e1,e2));
+    switch(op) {
+	case DOP+GT:
+	    printf("\ttestb\t$69,%%ah\n");
+	    printf("\tje\t_%d\n",l1);
+	    break;
+	case DOP+GE:
+	    printf("\ttestb\t$5,%%ah\n");
+	    printf("\tje\t_%d\n",l1);
+	    break;
+	case DOP+EQ:
+	    printf("\tandb\t$69,%%ah\n");
+	    printf("\txorb\t$64,%%ah\n");
+	    printf("\tje\t_%d\n",l1);
+	    break;
+	case DOP+NEQ:
+	    printf("\tandb\t$69,%%ah\n");
+	    printf("\txorb\t$64,%%ah\n");
+	    printf("\tjne\t_%d\n",l1);
+	    break;
+    }
+}
+
+
+void
 jcond(int l, char cond)
 {       
     if (chk) return;
@@ -1168,6 +1219,8 @@
 emit_data(int e, int t, NMTBL *n)
 {
     int l;
+    double d;
+    float f;
     char *name;
     name = n->nm; 
     if(mode!=GDECL)  { 
@@ -1189,10 +1242,20 @@
 	    if (data_alignment>0)
 		data_alignment++;
 	    gpc += 1;
+	} else if (t==SHORT) {
+	    printf("\t.word %d\n",cadr(e));
+	    if (data_alignment>0) data_alignment++;
+	    gpc += 2;
 	} else {
 	    printf("\t.long %d\n",cadr(e));
 	    gpc += size_of_int;
 	}
+    } else if(t==DOUBLE) {       
+	d = dcadr(e);
+	printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d));
+    } else if(t==FLOAT) {       
+	f = dcadr(e);
+	printf("\t.long\t0x%x\n",*(int *)&f);
     } else if(t!=CHAR) {       
 	gpc += size_of_int;
 	if(car(e)==ADDRESS&&car(cadr(e))==GVAR) {
@@ -1297,64 +1360,152 @@
 /* floating point */
 
 
-void code_cmp_drgvar(int e)
-{ }
-
-
-void code_cmp_drlvar(int e)
-{ }
-
-
-void code_dassign_gvar(int e2,int byte)
-{ }
-
-
-void code_dassign_lvar(int e,int byte)
-{ }
+char *
+fstore(int d)
+{
+    return d?"fstpl":"fstps";
+}
 
-void code_dassign(int e)
-{ }
-
-
-void code_dconst(int e2)
-{ }
-
-
-void code_dneg()
-{ }
-
-
-void code_drgvar(int e1)
-{ }
+char *
+fload(int d)
+{
+    return d?"fldl":"flds";
+}
 
 
-void code_drlvar(int e1)
-{ }
+void code_dassign_gvar(int e2,int d)
+{ 
+    printf("\t%s %s\n",fstore(d),(char *)caddr(e2)) ;
+}
+
+void code_dassign_lvar(int e2,int d)
+{ 
+    printf("\t%s %d(%%ebp)\n",fstore(d),e2);
+}
+
+void code_dassign(int e2,int d)
+{ 
+    printf("\t%s (%s)\n",fstore(d),register_name(e2,0));
+}
+
+static double d0 = 1.0;
 
+int
+code_d1(double d)
+{
+    int *i = (int *)&d0; int *j = (int *)&d;
+    return (i[1] == 0x3ff00000)?j[0]:j[1];
+}
+
+int
+code_d2(double d)
+{
+    int *i = (int *)&d0; int *j = (int *)&d;
+    return (i[1] == 0x3ff00000)?j[1]:j[0];
+}
+
+void code_dconst(int e2)
+{ 
+    int lb;
+    double d = dcadr(e2);
 
-void code_frgvar(int e1)
-{ }
+    if (d==0.0) {
+	printf("\tfldz\n"); return;
+    }
+    if (d==1.0) {
+	printf("\tfld1\n"); return;
+    }
+    printf(" \t.section\t.rodata\n\t.align 8\n");
+    lb=fwdlabel();
+    printf("_%d:\n",lb);
+    printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d));
+    if (output_mode==TEXT_EMIT_MODE) {
+	printf(".text\n");
+    } else {
+	text_mode();
+    }
+    printf("\tfldl _%d\n",lb);
+}
+
+void code_dneg()
+{ 
+    printf("\tfchs\n");
+}
 
+void code_d2i()
+{ 
+    /* fuck you! */
+    printf("\tlea -%d(%%esp),%%esp\n",size_of_int*2);
+    printf("\tfnstcw  (%%esp)\n");
+    printf("\tmovl    (%%esp), %s\n",register_name(creg,0));
+    printf("\tmovb    $12, 1(%%esp)\n");
+    printf("\tfldcw   (%%esp)\n");
+    printf("\tmovl    %s, (%%ebp)\n",register_name(creg,0));
+    printf("\tfistpl  %d(%%ebp)\n",size_of_int);
+    printf("\tfldcw   (%%ebp)\n");
+    printf("\tpopl    %s\n",register_name(creg,0));
+    printf("\tpopl    %s\n",register_name(creg,0));
+}
 
-void code_frlvar(int e1)
-{ }
+void code_i2d()
+{ 
+    printf("\tpushl %s\n",register_name(creg,0));
+    printf("\tfildl (%%esp)\n");
+    printf("\tlea %d(%%esp),%%esp\n",size_of_int);
+}
+
+void code_drgvar(int e2,int d)
+{ 
+    printf("\t%s %s\n",fload(d),(char *)caddr(e2)) ;
+}
 
 
-void dtosop(int e,int e1)
-{ }
+void code_drlvar(int e2,int d)
+{ 
+    printf("\t%s %d(%%ebp)\n",fload(d),e2);
+}
+
+void code_cmp_drgvar(int e2)
+{ 
+    printf("\tfcomp %s\n",(char *)caddr(e2)) ;
+}
+
+void code_cmp_drlvar(int e2)
+{ 
+    printf("\tfcomp %d(%%ebp)\n",e2);
+}
+
+void dtosop(int op,int e1)
+{ 
+    switch(op) {
+    case DADD: printf("\tfaddp %%st,%%st(1)\n"); break;
+    case DSUB: printf("\tfsubrp %%st,%%st(1)\n"); break;
+    case DDIV: printf("\tfdivrp %%st,%%st(1)\n"); break;
+    case DMUL: printf("\tfmulp %%st,%%st(1)\n"); break;
+    case DCOMP: 
+	printf("\tfxch\t%%st(1)\n");
+	printf("\tfucompp\n");
+	printf("\tfnstsw\t%%ax\n");
+	break;
+    }
+}
 
 int dpop_register()
-{ return 1;}
+{ 
+    return 1;
+}
 
 int emit_dpop(int e1)
-{ return 1;}
+{ 
+    return 1;
+}
 
 void emit_dpop_free(int e1)
-{ }
+{ 
+}
 
 void emit_dpush()
-{ }
-
-
+{ 
+}
 
 /* end */
--- a/mc-code.h	Mon Mar 03 20:59:51 2003 +0900
+++ b/mc-code.h	Wed Mar 05 00:39:39 2003 +0900
@@ -60,6 +60,7 @@
 extern void code_opening(char *filename);
 extern void code_closing();
 extern void rexpr(int e1, int l1, char *s);
+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);
@@ -78,11 +79,11 @@
 extern void code_dassign_lvar(int,int);
 extern void code_dconst(int);
 extern void code_dneg();
-extern void code_drgvar(int);
-extern void code_drlvar(int);
-extern void code_frgvar(int);
-extern void code_frlvar(int);
+extern void code_drgvar(int,int);
+extern void code_drlvar(int,int);
 extern void dtosop(int,int);
 extern void emit_dpop_free(int);
 extern void emit_dpush();
+extern void code_i2d();
+extern void code_d2i();
 
--- a/mc-codegen.c	Mon Mar 03 20:59:51 2003 +0900
+++ b/mc-codegen.c	Wed Mar 05 00:39:39 2003 +0900
@@ -278,20 +278,20 @@
 	regv[creg]=1;
 	return;
     case FRLVAR:
-	code_frlvar(lvar(e2));
-	regv[creg]=1;
+	code_drlvar(lvar(e2),0);
+	regv[freg]=1;
 	return;
     case FRGVAR:
-	code_frgvar(lvar(e2));
-	regv[creg]=1;
+	code_drgvar(e1,0);
+	regv[freg]=1;
 	return;
     case DRLVAR:
-	code_drlvar(lvar(e2));
-	regv[creg]=1;
+	code_drlvar(lvar(e2),1);
+	regv[freg]=1;
 	return;
     case DRGVAR:
-	code_drgvar(lvar(e2));
-	regv[creg]=1;
+	code_drgvar(e1,1);
+	regv[freg]=1;
 	return;
     case FNAME:
 	code_fname(((NMTBL *)(e2))->nm);
@@ -302,8 +302,8 @@
 	regv[creg]=1;
 	return;
     case DCONST:
-	code_dconst(e2);
-	regv[creg]=1;
+	code_dconst(e1);
+	regv[freg]=1;
 	return;
     case STRING:
 	string(e1);
@@ -334,6 +334,14 @@
 	g_expr(e2);
 	code_dneg();
 	return;
+    case I2D: 
+	g_expr(e2);
+	code_i2d();
+	return;
+    case D2I: 
+	g_expr(e2);
+	code_d2i();
+	return;
     case BNOT:   /* ~ */
 	g_expr(e2);
 	code_not();
@@ -370,6 +378,7 @@
 	return;
     case DMUL: case DDIV:
     case DADD: case DSUB:
+    case DCOMP:
 	dmachinop(e1);
 	return;
     case COND:
@@ -389,10 +398,10 @@
     case SASS: 
 	sassign(e1);
 	return;
-    case ASS: case CASS: case FASS:
+    case ASS: case CASS: 
 	assign(e1);
 	return;
-    case DASS: case LASS: 
+    case FASS: case DASS: case LASS: 
 	dassign(e1);
 	return;
     case ASSOP: case CASSOP:
@@ -472,6 +481,26 @@
     case NEQ:
 	rexpr(e1,l1,code_eq(!cond));
 	return;
+
+    case DOP+GT:
+	drexpr(cadr(e1),caddr(e1),l1,DOP+GT);
+	return;
+    case DOP+GE:
+	drexpr(cadr(e1),caddr(e1),l1,DOP+GE);
+	return;
+    case DOP+LT:
+	drexpr(caddr(e1),cadr(e1),l1,DOP+GE);
+	return;
+    case DOP+LE:
+	drexpr(caddr(e1),cadr(e1),l1,DOP+GT);
+	return;
+    case DOP+EQ:
+	drexpr(cadr(e1),caddr(e1),l1,DOP+EQ);
+	return;
+    case DOP+NEQ:
+	drexpr(cadr(e1),caddr(e1),l1,DOP+NEQ);
+	return;
+
     case LAND:
 	b_expr(e2,0,cond?(l2=fwdlabel()):l1,0);
 	b_expr(caddr(e1),cond,l1,0);
@@ -931,28 +960,29 @@
 void
 dassign(int e1)
 {
-    int e2,e3,e4,byte;
+    int e2,e3,e4,d;
 
     /*    e2=e4 */
     e2 = cadr(e1);
     e3 = cadr(e2);
     e4 = caddr(e1);
+    d = (car(e1)==LASS)?2:(car(e1)==DASS)?1:0;
     switch(car(e2)) {
-    case GVAR:      /*   i=3 */
+    case GVAR:
             g_expr(e4);
-	    code_dassign_gvar(e2,byte);
+	    code_dassign_gvar(e2,d);
             return;
     case LVAR:
             g_expr(e4);
-	    code_dassign_lvar(lvar(cadr(e2)),byte);
+	    code_dassign_lvar(lvar(cadr(e2)),d);
             return;
     }
     g_expr(e2);
-    emit_dpush();
+    emit_push();
     g_expr(e4);
-    e2 = emit_dpop(0);
-    code_dassign(e2,byte);
-    emit_dpop_free(e2);
+    e2 = emit_pop(0);
+    code_dassign(e2,d);
+    emit_pop_free(e2);
     return;
 }
 
--- a/mc-parse.c	Mon Mar 03 20:59:51 2003 +0900
+++ b/mc-parse.c	Wed Mar 05 00:39:39 2003 +0900
@@ -95,8 +95,8 @@
 static int sdecl_f = 1;
 static int stypedecl;
 
-/* Converter *conv = &null_converter; */
-Converter *conv = &c_converter;
+Converter *conv = &null_converter;
+/* Converter *conv = &c_converter; */
 
 static char *ccout = 0;
 
@@ -324,9 +324,9 @@
     if (macroeq("c2cbc")) conv=&c2cbc_converter;
     else if (macroeq("cbc2c")) conv=&cbc2c_converter;
     else if (macroeq("c")) conv=&c_converter;
-    else conv=&null_converter;
 #else
     if (macroeq("c")) conv=&c_converter;
+    else conv=&null_converter;
 #endif
 }
 
@@ -864,15 +864,7 @@
  	emit_data(e,t,n);
 	return offset+size(t);
     } else if(mode==LDECL) {
-	if(t==CHAR) {
-	    ass =list3(CASS,list2(LVAR,n->dsp+offset),rvalue(e));
-	} else if (scalar(t)) {
-	    ass = list3(ASS,list2(LVAR,n->dsp+offset),rvalue(e));
-	} else if (car(t)==STRUCT || car(t)==UNION || car(t)==STRING) {
-	    ass = list4(SASS,list2(LVAR,n->dsp+offset),rvalue(e),size(t));
-	} else {
-	    error(DCERR);
-	}
+	ass = assign_expr0(list2(LVAR,n->dsp+offset),e,t,type);
 	init_vars = list2(ass,init_vars);
 	return offset+size(t);
     } else {
@@ -899,6 +891,13 @@
  	type=t;
 	return offset;
     }
+    if (t==FLOAT||t==DOUBLE) {
+ 	e=expr1();
+	mode = mode_save;
+ 	offset = assign_data(e,t,n,offset);
+ 	type=t;
+	return offset;
+    }
     t1 = car(t);
     if (t1==ARRAY) {
 	if (sym==LC) {
@@ -1655,14 +1654,22 @@
     if(t==VOID)
 	error(TYERR);
     if(t==CHAR) {
+	if (type==FLOAT||type==DOUBLE) e2=list2(D2I,e2);
+	else if (!integral(type)) error(TYERR);
 	type= INT;return(list3(CASS,e1,e2));
     } else if(t==DOUBLE) {
 	if(integral(type)) e2=list2(I2D,e2);
-	type= DOUBLE;return(list3(DASS,e1,e2));
+	else if (type!=FLOAT&&type!=DOUBLE) error(TYERR);
+	type= t;return(list3(DASS,e1,e2));
     } else if(t==FLOAT) {
 	if(integral(type)) e2=list2(I2D,e2);
-	type= DOUBLE;return(list3(FASS,e1,e2));
-    } else if(!scalar(t)&&(car(t)==STRUCT||car(t)==UNION)) {
+	else if (type!=FLOAT&&type!=DOUBLE) error(TYERR);
+	type= t;return(list3(FASS,e1,e2));
+    } else if(scalar(t)) {
+	if (type==FLOAT||type==DOUBLE) e2=list2(D2I,e2);
+	type=t;
+	return(list3(ASS,e1,e2));
+    } else if((car(t)==STRUCT||car(t)==UNION)) {
 	if (size(t)!=size(type)) error(TYERR);
 	type=t;
 	if(car(e2)==RSTRUCT && car(cadr(e2))==FUNCTION) {
@@ -1672,8 +1679,7 @@
 	    return (list4(SASS,e1,e2,size(t)));
 	}
     } else {
-	type=t;
-	return(list3(ASS,e1,e2));
+	error(TYERR); return list3(ASS,e1,e2);
     }
 }
 
@@ -1752,9 +1758,9 @@
 {
     int e1,e2,e3,t;
 
-    conv->cond_();
     e1=expr3();
     if(sym==COND) {	
+	conv->cond_();
 	e1=rvalue(e1);
 	getsym();
 	conv->cond1_();
@@ -1863,17 +1869,19 @@
 static int
 expr8(void)
 {
-    int e,op;
+    int e1,e2,op,t;
 
-    e=expr9();
+    e1=expr9();
     while((op=sym)==EQ||op==NEQ) {	
 	conv->op_(sym);
-	e=rvalue(e);
+	e1=rvalue(e1);
+	t=type;
 	getsym();
-	e=list3(op,e,rvalue(expr9()));
+	e2=rvalue(expr9());
+	e1=binop(op,e1,e2,t,type);
 	type= INT;
     }
-    return e;
+    return e1;
 }
 
 static int
@@ -1890,6 +1898,10 @@
 	e2=rvalue(expr10());
 	if(t==INT&&type==INT) 
 	    e1=binop(op,e1,e2,t,type);
+	else if(t==DOUBLE||type==DOUBLE||
+	          t==FLOAT||type==FLOAT) 
+	    /* binop will handle op+DOP */
+	    e1=binop(op,e1,e2,t,type);
 	else 
 	    e1=binop(op+US,e1,e2,t,type);
 	type= INT;
@@ -1994,6 +2006,8 @@
 	conv->prefix_(sym);
 	getsym();
 	e=rvalue(expr13());
+	if(type==FLOAT||type==DOUBLE) 
+	    return list2(DMINUS,e);
 	if(!integral(type)) 
 	    error(TYERR);
 	return(car(e)==CONST?list2(CONST,-cadr(e)):list2(MINUS,e));
@@ -2008,6 +2022,9 @@
 	conv->prefix_(sym);
 	getsym();
 	e=rvalue(expr13());
+	if(type==FLOAT||type==DOUBLE) 
+	    return(car(e)==DCONST?list2(CONST,!dcadr(e)):
+		list3(DOP+NEQ,list2(CONST,0),e));
 	if(!scalar(type)) 
 	    error(TYERR);
 	return(car(e)==CONST?list2(CONST,!cadr(e)):list2(LNOT,e));
@@ -2349,8 +2366,6 @@
     double d1,d2,d;
 
     type= DOUBLE;
-    if(t1==FLOAT) t1=DOUBLE;
-    if(t2==FLOAT) t2=DOUBLE;
     if(car(e1)==DCONST&&car(e2)==DCONST) {
 	if (integral(t1)) { d1=cadr(e1);
 	} else if(t1==DOUBLE) d1=dcadr(e1);
@@ -2372,14 +2387,20 @@
 	    d=(d1<d2);break;
 	case LE:
 	    d=(d1<=d2);break;
+	case EQ:
+	    d=(d1==d2);break;
+	case NEQ:
+	    d=(d1!=d2);break;
 	}
 	return dlist2(DCONST,d);
     }
     if (integral(t1)) e1=list2(I2D,e1);
     if (integral(t2)) e2=list2(I2D,e2);
-    if(op==GT||op==GE||op==LT||op==LE||
+    if(op==GT||op==GE||op==LT||op==LE||op==EQ||op==NEQ||
 	    ADD||SUB||MUL||DIV)
 	return(list3(op+DOP,e1,e2));
+    else
+	error(-1);
 }
 
 static int
@@ -2387,7 +2408,7 @@
 {
     int e;
 
-    if(t1==DOUBLE||t2==DOUBLE) 
+    if(t1==DOUBLE||t2==DOUBLE||t1==FLOAT||t2==FLOAT) 
 	return dbinop(op,e1,e2,t1,t2);
     if(car(e1)==CONST&&car(e2)==CONST) {
 	e1=cadr(e1);
@@ -2434,6 +2455,10 @@
 	    e=e1>>e2;break;
 	case LSHIFT:
 	    e=e1<<e2;break;
+	case EQ:
+	    e=(e1==e2);break;
+	case NEQ:
+	    e=(e1!=e2);break;
 	case GT:
 	    e=(e1>e2);break;
 	case GE:
@@ -2453,7 +2478,10 @@
 	}
 	return list2(CONST,e);
     }
-    if(op==GT||op==GE||op==LT||op==LE||op==UGT||op==UGE||op==ULT||op==ULE)
+    if(op==GT||op==GE||op==LT||op==LE||
+	    op==UGT||op==UGE||op==ULT||op==ULE||
+	    op==EQ||op==NEQ
+	    )
 	return(list3(op,e1,e2));
     if((op==ADD||op==MUL||op==BOR||op==EOR||op==BAND)&&
 	(car(e1)==CONST||(car(e2)!=CONST&&
@@ -2651,7 +2679,7 @@
 getsym(void)
 {
     NMTBL *nptr0,*nptr1,*nptrm;
-    int i,slfree,macrop;
+    int i,slfree,macrop,d;
     char *scheapp;
     char c;
 
@@ -2719,25 +2747,7 @@
 	nptr=nptr1;
 	return sym;
     } else if (digit(ch)||ch=='.') {
-	symval=0;
-	if (ch == '0') {	
-	    if (getch() == 'x' || ch == 'X') {
-		while(1) {
-		    if(digit(getch()))
-			symval=symval*16+ch-'0';
-		    else if('a'<=ch&&ch<='f')
-			symval=symval*16+ch-'a'+10;
-		    else if('A'<=ch&&ch<='F')
-			symval=symval*16+ch-'A'+10;
-		    else break;
-		}
-	    } else {
-		while (digit(ch)) {
-		    symval=symval*8+ch-'0';getch();
-		}
-	    }
-	    return sym=CONST;
-	}
+	symval=0; d=0;
 	scheapp = cheapp;
 	if(ch=='.') {
 	    getch();
@@ -2751,12 +2761,29 @@
 		return getsym();
 	    } else if (!digit(ch))
 		return sym=PERIOD;
-	    *cheapp++ = '.';
-	    *cheapp++ = ch;
-	    getch();
+	    d=1;
+	    *cheapp++ = '.'; /* .0 case */
+	} else if (ch == '0') {	
+	    if (getch() == 'x' || ch == 'X') {
+		while(1) {
+		    if(digit(getch()))
+			symval=symval*16+ch-'0';
+		    else if('a'<=ch&&ch<='f')
+			symval=symval*16+ch-'a'+10;
+		    else if('A'<=ch&&ch<='F')
+			symval=symval*16+ch-'A'+10;
+		    else break;
+		}
+		return sym=CONST;
+	    } else if (ch!='.') {
+		while (digit(ch)) {
+		    symval=symval*8+ch-'0';getch();
+		}
+		return sym=CONST;
+	    }
+	    d=1;
+	    *cheapp++ = '0'; /* 0. case */
 	} else {
-	    *cheapp++ = ch;
-	    getch();
 	    while(digit(ch)) {
 		*cheapp++ = ch;
 		symval=symval*10+ch-'0';getch();
--- a/mc.h	Mon Mar 03 20:59:51 2003 +0900
+++ b/mc.h	Wed Mar 05 00:39:39 2003 +0900
@@ -149,12 +149,12 @@
 
 #define FASSOP	70
 #define DASSOP	71
-
+#define DCOMP	72
 #define DMINUS	73
-#define DMUL	74
-#define DDIV	75
-#define DADD	76
-#define DSUB	77
+#define DMUL	(DOP+MUL)
+#define DDIV	(DOP+DIV)
+#define DADD	(DOP+ADD)
+#define DSUB	(DOP+SUB)
 #define LMUL	78
 #define LDIV	79
 #define LADD	80
@@ -280,16 +280,13 @@
 #define dcaddr(e) (*(double*)&heap[((int)(e))+2])
 
 #include "conv/conv.h"
-#include "conv/c.h"
 /*
 #include "conv/c2cbc.h"
 #include "conv/cbc2c.h"
-#include "conv/null.h"
  */
 
 extern Converter *conv;
 
-
 EXTERN void error(int n);
 EXTERN int append4(int p,int a1,int a2,int a3);
 EXTERN int assign_expr(int e1,int e2,int t,int type);
--- a/test/float.c	Mon Mar 03 20:59:51 2003 +0900
+++ b/test/float.c	Wed Mar 05 00:39:39 2003 +0900
@@ -2,16 +2,63 @@
 
 void test2(double);
 void test1();
+void print(double d);
 
 extern double sin(double);
 extern float fsin(float);
 
+float f = 0.3;
+double d = 0.3;
+float f1 = 0.3;
+double d1 = 0.3;
+
 int
 main(int ac,char *av[]) {
+   double g;
+   int i;
+
+   g = 1.0;
+   g = -g;
+   printf("%g\n",g);
+   if(f==f*1.0) printf("ok\n");
+   if(d==f*1.0) printf("ok\n");
+   if(f==f1) printf("ok\n");
+   if(d==d1) printf("ok\n");
+   if(d>d1) printf("ok\n");
+   if(d>=d1) printf("ok\n");
+   if(d!=d1) printf("ok\n");
+   i = d;
+   d = i;
+   i = f;
+   f = i;
+   f = g = d = g = d = f;
+
+   print(1.0);
+   print(0.1234);
+   print(1.234e10);
+   print(1.234e-10);
+
    test1();
    return 0;
 }
 
+void
+print(double d)
+{
+    float f;
+    int *dd;
+
+    f = d;
+
+    dd = (int*) &d;
+    printf("d %g\n",d);
+    printf("dx %08x %08x\n",*(dd),*(dd+1));
+
+    dd = (int*) &f;
+    printf("f %g\n",f);
+    printf("dx %08x \n",*(dd));
+}
+
 double
 testd(double i,double j)
 {
@@ -57,4 +104,3 @@
     printf("%g %g %g %g\n",g,f,g1,f1);
     return;
 }
-