# HG changeset patch # User kono # Date 1046792379 -32400 # Node ID 25654dc29eccd4ab81a777d9d190d4418e75718b # Parent f94ca1168520b72ecdefba36af03fdc88199a6a5 First Floating Point coding done. diff -r f94ca1168520 -r 25654dc29ecc Changes --- 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の場合はいるんじゃないの? + diff -r f94ca1168520 -r 25654dc29ecc Makefile --- 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 : diff -r f94ca1168520 -r 25654dc29ecc conv/c.c --- 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); diff -r f94ca1168520 -r 25654dc29ecc conv/c.h --- 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_, + ®ister_, + &return_, + &return_end_, + &return_type_, + &rpar_, + &sm_, + &static_, + &switch_, + &switch_body_, + &switch_end_, + &typedef_, + &while_, + &while_body_, + &while_end_, + &decl_data_, + &break_, + &continue_, + &sdecl_, +}; diff -r f94ca1168520 -r 25654dc29ecc conv/null.c --- 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) +{ } + diff -r f94ca1168520 -r 25654dc29ecc conv/null.h --- 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_, + ®ister_, + &return_, + &return_end_, + &return_type_, + &rpar_, + &sm_, + &static_, + &switch_, + &switch_body_, + &switch_end_, + &typedef_, + &while_, + &while_body_, + &while_end_, + &decl_data_, + &break_, + &continue_, + &sdecl_, +}; diff -r f94ca1168520 -r 25654dc29ecc mc-code-ia32.c --- 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 */ diff -r f94ca1168520 -r 25654dc29ecc mc-code.h --- 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(); diff -r f94ca1168520 -r 25654dc29ecc mc-codegen.c --- 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; } diff -r f94ca1168520 -r 25654dc29ecc mc-parse.c --- 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>e2;break; case LSHIFT: 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(); diff -r f94ca1168520 -r 25654dc29ecc mc.h --- 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); diff -r f94ca1168520 -r 25654dc29ecc test/float.c --- 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; } -