Mercurial > hg > CbC > old > device
changeset 94:1ad7045741a7 dbinop
float dbinop fix
author | kono |
---|---|
date | Wed, 12 Mar 2003 15:28:44 +0900 |
parents | 8f5d61239b93 |
children | 185d2cc6a3a9 |
files | Changes Makefile mc-code-ia32.c mc-code.h mc-codegen.c mc-codegen.h mc-parse.c mc.h test/call.c test/float.c |
diffstat | 10 files changed, 577 insertions(+), 362 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Sun Mar 09 18:31:00 2003 +0900 +++ b/Changes Wed Mar 12 15:28:44 2003 +0900 @@ -2066,3 +2066,51 @@ でも、結局、引数は関数呼び出しの前にセーブするのね。だったら、 そんなことしないで、セーブすれば良いのか。 +Mon Mar 10 11:42:40 JST 2003 + +で、レジスタのセーブなんだけど、mc-codegen.c を変更しない +とすれば、引数のリストを使って変更していくのが良い。 +関数呼び出しは基本的には並列代入になる。並列代入でき +てもできなくても、セーブする必要はある。今の並列代入 +ルーチンのできは良くないので、「同じかどうか」だけ +判断するのが良いのではないか? + +関数呼び出しの前に式用にレジスタに積まれた値はセーブした +方が良い。セーブした後はlvarとしてアクセスすることになる。 +スタックでもいいけど。 +そうすると、stack 配列には、 + + レジスタ レジスタ番号 (>0) + スタック -1 + lvar lvar番号 + +の三種類が入ることになる。それに合わせてtosop/assopを書き直 +す必要がある。emit_pop だけでいいかも。スタックを止めちまう +のも手ではあるが、ia32の方で効率が悪い。やっぱり三種類サポー +トするのが良いだろう。 + +(けっこういろいろあるなぁ... どこから手を付けるか...) + +Tue Mar 11 14:23:57 JST 2003 + +save_stacks すると、レジスタはほとんど使われなくなって +しまう。が、コードの見通しは良くなる。 + +定数を右辺に持って行くとsave_stacksでsaveする量が減る。が以 +外にめんどくさいね。反射律が成り立たない演算子に関しては。tosop +の定数版とか作ることになるので... あとスタックに積む順序が逆 +になってしまう。まぁ、もとの版では行われていたことだが... +CMPではrexpr で反転して論理を逆転させる方が簡単か。SUBでは、 +ADD + (-CONST) にする方が良いね。 + + je _xxx +したあと、current register のregv[]が残ってしまう。これは、 +変だよね。gexpr_init で regv が残るのは、case 文の比較だけ。 +あとは全部0にして良い。(まぁ、害は無いんだけど) + +(case 文のjumpは、switch 文が終る時に処理すれば、index jump +にすることができるね) + +Wed Mar 12 12:58:47 JST 2003 + +比較で入れ換えるとの否定は若干違うよね。
--- a/Makefile Sun Mar 09 18:31:00 2003 +0900 +++ b/Makefile Wed Mar 12 15:28:44 2003 +0900 @@ -7,15 +7,20 @@ PRINTF= # printf.c CONVERTER=conv/c.o conv/null.o # conv/c2cbc.o conv/cbc2c.o - +COMPLIB = mc-parse.o mc-codegen.o mc-tree.o # CODE=mc-code-ia32.o CODE=mc-code-powerpc.o -all: mc +all: mc mc-ia32 mc-powerpc + +mc: mc-powerpc + cp mc-powerpc mc -mc : mc-parse.o mc-codegen.o $(CODE) mc-tree.o $(CONVERTER) - $(CC) -g mc-parse.o mc-codegen.o $(CODE) \ - mc-tree.o $(CONVERTER) -o $@ +mc-powerpc : mc-code-powerpc.o $(COMPLIB) $(CONVERTER) + $(CC) -g mc-code-powerpc.o $(COMPLIB) $(CONVERTER) -o $@ + +mc-ia32 : mc-code-ia32.o $(COMPLIB) $(CONVERTER) + $(CC) -g mc-code-ia32.o $(COMPLIB) $(CONVERTER) -o $@ conv/conv.h: conv_func.tbl conv_func.pl perl conv_func.pl @@ -36,14 +41,14 @@ mc-code-powerpc.c clean : - -rm -f *.bak *.s *.o *.cc mc mc1 a.out *~ core* */*.o *.bak test/*.s test/*.cc test/*.o test/*.bak test/*~ conv/*.s conv/*.cc conv/*.o conv/*.bak conv/*~ + -rm -f mc mc-ia32 mc-powerpc *.bak *.s *.o *.cc mc mc1 a.out *~ core* */*.o *.bak test/*.s test/*.cc test/*.o test/*.bak test/*~ conv/*.s conv/*.cc conv/*.o conv/*.bak conv/*~ mc1 : b00.s b01.s mc-codegen.o mc-tree.o $(CONVERTER) $(CC) -g -o $@ $(PRINTF) b00.s b01.s mc-codegen.o mc-tree.o $(CONVERTER) -b00.s : mc-parse.c mc - ./mc -s -ob00.s mc-parse.c -b01.s : mc-code-ia32.c mc - ./mc -s -ob01.s mc-code-ia32.c +b00.s : mc-parse.c $(MC) + ./$(MC) -s -ob00.s mc-parse.c +b01.s : mc-code-ia32.c $(MC) + ./$(MC) -s -ob01.s mc-code-ia32.c b10.s : mc-parse.c mc1 ./mc1 -s -ob10.s mc-parse.c b11.s : mc-code-ia32.c $(PRINTF) mc1
--- a/mc-code-ia32.c Sun Mar 09 18:31:00 2003 +0900 +++ b/mc-code-ia32.c Wed Mar 12 15:28:44 2003 +0900 @@ -6,6 +6,8 @@ #include "mc-codegen.h" #include "mc-code.h" +#define SAVE_STACKS 1 + #define TEXT_EMIT_MODE 0 #define DATA_EMIT_MODE 1 #define RODATA_EMIT_MODE 2 @@ -80,6 +82,7 @@ static char * fload(int d); static int code_d1(double d); static int code_d2(double d); +static void code_save_stacks(); void code_init(void) @@ -130,6 +133,7 @@ void gexpr_code_init(void){ use_register(creg,REG_EAX,0); + regv[creg]=0; regv[dreg]=0; } @@ -199,10 +203,6 @@ } void -set_register_var() { -} - -void code_arg_register(int args) { NMTBL *n; @@ -241,6 +241,7 @@ printf(" %s",register_name(reg_stack[i],0)); } #endif + printf(" f:%d",freg_sp); printf("\n"); } @@ -248,8 +249,10 @@ gexpr_init(void) { while(reg_sp > 0) { - free_register(reg_stack[--reg_sp]); + if (reg_stack[--reg_sp]>=0) + free_register(reg_stack[reg_sp]); } + freg_sp = 0; text_mode(); gexpr_code_init(); register_usage("gexpr_init"); @@ -263,6 +266,7 @@ for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; regv[i]=0;rname[i]=i;} free_all_register(); reg_sp = 0; + freg_sp = 0; text_mode(); } @@ -286,11 +290,6 @@ return reg_stack[--reg_sp]; } -int -stack_used(void) { - return reg_stack[--reg_sp]<0; -} - void emit_pop_free(int xreg) { @@ -393,11 +392,16 @@ use_data_reg(dreg,0); if (regv[dreg]) { printf("# emit_pop dreg conflict\n"); + error(-1); } printf("\tpopl %s\n",register_name(dreg,0)); - xreg = dreg; - regv[xreg]=1; - } + regv[dreg]=1; + return dreg; + } else if (xreg<= -REG_LVAR_OFFSET) { + code_rlvar(lvar(xreg+REG_LVAR_OFFSET),dreg); + regv[dreg]=1; + return dreg; + } return xreg; } @@ -437,14 +441,14 @@ void -code_rlvar(int e2) { - printf("\tmovl %d(%%ebp),%s\n",e2,register_name(creg,0)); +code_rlvar(int e2,int reg) { + printf("\tmovl %d(%%ebp),%s\n",e2,register_name(reg,0)); } void -code_crlvar(int e2) { - printf("\tmovsbl %d(%%ebp),%s\n",e2,register_name(creg,0)); +code_crlvar(int e2,int reg) { + printf("\tmovsbl %d(%%ebp),%s\n",e2,register_name(reg,0)); } @@ -838,12 +842,15 @@ return length/size_of_int; } -void +int function(int e1) { int e2,e3,e4,e5,nargs,t; NMTBL *n; int save,saved; +#ifdef SAVE_STACKS + code_save_stacks(); +#endif if (free_register_count()<1) { for(save = 0;save==dreg||save==creg;save++); printf("\tpushl %s\n",register_name(save,0)); @@ -910,8 +917,14 @@ free_register(save); } regv[save]=0; - regv[creg]=1; - fregv[freg]=1; /* return type はどこ? fnptr にはあるけど... */ + if (fnptr->ty==DOUBLE||fnptr->ty==FLOAT) { + fregv[freg]=1; regv[creg]=0; + } else if (fnptr->ty==VOID) { + fregv[freg]=0; regv[creg]=0; + } else { + fregv[freg]=0; regv[creg]=1; + } + return fnptr->ty; } void @@ -937,21 +950,24 @@ printf("\tjmp *%s\n",register_name(e2,0)); } -void +int rindirect(int e1) /* *(p +5 ) */ { char *op; - int e2,e3,byte; + int e2,e3,byte,t; 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)); + t=DOUBLE; 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)); + t=byte?CHAR:INT; } + return t; } char * @@ -1033,6 +1049,10 @@ printf("\tpopl %s\n",register_name(dreg,0)); oreg = dreg; regv[dreg]=1; + } else if (oreg<= -REG_LVAR_OFFSET) { + code_rlvar(lvar(oreg+REG_LVAR_OFFSET),dreg); + oreg = dreg; + regv[dreg]=1; } regv[oreg]=1; regs[oreg]=1; orn = register_name(oreg,0); @@ -1087,6 +1107,7 @@ } if (oreg!=dreg&&oreg>=0) free_register(oreg); + else if (oreg==dreg) regv[dreg]=0; } static int edx_stack=0; @@ -1613,7 +1634,7 @@ } void dtosop(int op,int e1) -{ +{ switch(op) { case DADD: printf("\tfaddp %%st,%%st(1)\n"); break; case DSUB: printf("\tfsubp %%st,%%st(1)\n"); break; @@ -1686,22 +1707,80 @@ } } -int dpop_register() -{ - return 1; +void +code_dregister(int e2) +{ + error(-1); +} + +void +code_cmp_dregister(int r) +{ + error(-1); } -int emit_dpop(int e1) +int dpop_register() { - return 1; + if (freg_sp<0) { error(-1); return -1;} + printf("# fpop: %d\n",freg_sp-1); + return freg_stack[--freg_sp]; } +int +emit_dpop(int type) +{ + int xreg; + if ((xreg=dpop_register())==-1) { + } else if (xreg<= -REG_LVAR_OFFSET) { + code_drlvar(lvar(REG_LVAR_OFFSET+xreg),1); + /* pushed order is reversed. We don't need this for comutable + operator, but it is ok to do this. */ + printf("\tfxch\t%%st(1)\n"); + } + return xreg; +} + + void emit_dpop_free(int e1) { } void emit_dpush() { + if (freg_sp>MAX_MAX) error(-1); + else + freg_stack[freg_sp++]=-1; + printf("# fpush:%d\n",freg_sp); +} + +void +code_save_stacks() +{ + /* temporal registers or stacks in fpu are saved in local variable */ + int xreg,sp,screg; + sp=reg_sp; + while(sp-->0) { + if ((xreg=reg_stack[sp])>=0) { + screg=creg; + if(creg!=xreg) { + if (xreg!=dreg) free_register(xreg); + creg = xreg; + } + code_assign_lvar( + lvar(reg_stack[sp]=new_lvar(size_of_int)),0); + reg_stack[sp]= reg_stack[sp]-REG_LVAR_OFFSET; + regv[xreg]=0; + creg=screg; + } + } + sp=freg_sp; + while(sp-->0) { + if ((xreg=freg_stack[sp])==-1) { + code_dassign_lvar( + lvar(freg_stack[sp]=new_lvar(size_of_double)),1); + freg_stack[sp]= freg_stack[sp]-REG_LVAR_OFFSET; + } + } } /* end */
--- a/mc-code.h Sun Mar 09 18:31:00 2003 +0900 +++ b/mc-code.h Wed Mar 12 15:28:44 2003 +0900 @@ -10,6 +10,7 @@ extern int MAX_REGISTER; extern int MAX_REGISTGER_VAR; extern int MAX_FREGISTER; +#define REG_LVAR_OFFSET 2 extern char *register_name(int i,int byte); extern void gexpr_code_init(void); @@ -25,8 +26,8 @@ extern void code_crgvar(int e1); extern void code_lvar(int e2); extern void code_register(int e2); -extern void code_rlvar(int e2); -extern void code_crlvar(int e2); +extern void code_rlvar(int e2,int reg); +extern void code_crlvar(int e2,int reg); extern void code_fname(char *e2); extern void code_const(int e2); extern void code_neg(); @@ -53,12 +54,12 @@ extern void code_cmp_register(int e2); extern void string(int e1); extern void emit_copy(int from,int to,int length,int offset,int value,int det); -extern void function(int e1); +extern int function(int e1); extern void code_frame_pointer(int e3); extern void code_fix_frame_pointer(int disp_offset); extern void code_jmp(char *s); extern void code_indirect_jmp(int e2); -extern void rindirect(int e1); +extern int rindirect(int e1); extern void code_assign_gvar(int e2,int byte); extern void code_assign_lvar(int e2,int byte); extern void code_assign_register(int e2,int byte); @@ -83,6 +84,8 @@ extern int dpop_register(); extern int emit_dpop(int); +extern void code_dregister(int e2); +extern void code_cmp_dregister(int); extern void code_cmp_drgvar(int); extern void code_cmp_drlvar(int); extern void code_dassign(int,int);
--- a/mc-codegen.c Sun Mar 09 18:31:00 2003 +0900 +++ b/mc-codegen.c Wed Mar 12 15:28:44 2003 +0900 @@ -52,21 +52,20 @@ void sassign(int e1); void assign(int e1); void assop(int e1); -void g_expr0(int e1); +int g_expr0(int e1); -void +int gexpr(int e1,int use0) { - if (chk) return; + if (chk) return INT; gexpr_init(); use = use0; #if 0 if(lineno==2862) { - g_expr0(e1); /*break here*/ - return; + return g_expr0(e1); /*break here*/ } #endif - g_expr0(e1); + return g_expr0(e1); } int @@ -75,26 +74,30 @@ return rname[creg]; /* for switch value */ } -void +int g_expr_u(int e1) { + int t; int suse = use; use=0; - g_expr0(e1); + t=g_expr0(e1); use=suse; + return t; } -void +int g_expr(int e1) { + int t; int suse = use; use=1; - g_expr0(e1); + t=g_expr0(e1); use=suse; + return t; } -void +int g_expr0(int e1) { - int e2,e3; + int e2,e3,t; NMTBL *n; e2 = cadr(e1); @@ -102,150 +105,154 @@ case GVAR: code_gvar(e1); regv[creg]=1; - return; + return ADDRESS; case RGVAR: code_rgvar(e1); regv[creg]=1; - return; + return INT; case CRGVAR: code_crgvar(e1); regv[creg]=1; - return; + return CHAR; case LVAR: code_lvar(lvar(e2)); regv[creg]=1; - return; + return ADDRESS; case REGISTER: /* this is of course redundant... */ /* we can use rname for this? */ /* or why not creg=e2? */ code_register(e2); regv[creg]=1; - return; + return INT; + case DREGISTER: + /* this is of course redundant... */ + /* we can use rname for this? */ + /* or why not creg=e2? */ + code_dregister(e2); + fregv[freg]=1; + return DOUBLE; case RLVAR: - code_rlvar(lvar(e2)); + code_rlvar(lvar(e2),creg); regv[creg]=1; - return; + return INT; case CRLVAR: - code_crlvar(lvar(e2)); + code_crlvar(lvar(e2),creg); regv[creg]=1; - return; + return CHAR; case FRLVAR: code_drlvar(lvar(e2),0); fregv[freg]=1; - return; + return FLOAT; case FRGVAR: code_drgvar(e1,0); fregv[freg]=1; - return; + return FLOAT; case DRLVAR: code_drlvar(lvar(e2),1); fregv[freg]=1; - return; + return DOUBLE; case DRGVAR: code_drgvar(e1,1); fregv[freg]=1; - return; + return DOUBLE; case FNAME: code_fname(((NMTBL *)(e2))->nm); regv[creg]=1; - return; + return ADDRESS; case CONST: /* 代入する値が0でも特別な処理はしない */ code_const(e2); regv[creg]=1; - return; + return INT; case DCONST: code_dconst(e1); fregv[freg]=1; - return; + return DOUBLE; case STRING: string(e1); regv[creg]=1; - return; + return ADDRESS; case FUNCTION: - function(e1); + t = function(e1); regv[creg]=1; - return; + return t; case CODE: jump(e2,caddr(e1)); - return; + return VOID; case INDIRECT: - g_expr0(e2); - return; + return g_expr0(e2); case RINDIRECT: case CRINDIRECT: case DRINDIRECT: case FRINDIRECT: - rindirect(e1); - return; + return rindirect(e1); case ADDRESS: - g_expr0(e2); - return; + return g_expr0(e2); case MINUS: /* レジスタに対し、neglを実行すれば実現可能 */ g_expr0(e2); code_neg(); - return; + return INT; case DMINUS: g_expr0(e2); code_dneg(); - return; + return DOUBLE; case I2D: g_expr0(e2); code_i2d(); - return; + return DOUBLE; case D2I: g_expr0(e2); code_d2i(); - return; + return INT; case U2D: g_expr0(e2); code_u2d(); - return; + return DOUBLE; case D2U: g_expr0(e2); code_d2u(); - return; + return UNSIGNED; case BNOT: /* ~ */ g_expr0(e2); code_not(); - return; + return INT; case LNOT: /* ! */ g_expr0(e2); code_lnot(); - return; + return INT; case PREINC: code_preinc(e1,e2); - return; + return INT; case POSTINC: code_postinc(e1,e2); - return; + return INT; case DPREINC: code_dpreinc(e1,e2,1); - return; + return DOUBLE; case DPOSTINC: code_dpostinc(e1,e2,1); - return; + return DOUBLE; case FPREINC: code_dpreinc(e1,e2,0); - return; + return FLOAT; case FPOSTINC: code_dpostinc(e1,e2,0); - return; + return FLOAT; case CPOSTINC: /* char *p; *p++ */ code_cpostinc(e1,e2); - return; + return CHAR; case CPREINC: code_cpreinc(e1,e2); - return; + return CHAR; case CPOSTDEC: code_cpostdec(e1,e2); - return; + return CHAR; case CPREDEC: code_cpredec(e1,e2); - return; + return CHAR; case MUL: case UMUL: case DIV: case UDIV: case MOD: case UMOD: case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT: - case ADD: case SUB: case BAND: case EOR: case BOR: + case ADD: case SUB: case BAND: case EOR: case BOR: case CMP: machinop(e1); - return; + return INT; case DMUL: case DDIV: case DADD: case DSUB: case DCMP: case DCMPGE: dmachinop(e1); - return; + return DOUBLE; case COND: e2=fwdlabel(); b_expr(cadr(e1),0,e2,0); @@ -256,61 +263,89 @@ jmp(e3=fwdlabel()); fwddef(e2); code_set_fixed_creg(0); - g_expr0(cadddr(e1)); + t = g_expr0(cadddr(e1)); code_set_fixed_creg(1); fwddef(e3); - return; + return t; case SASS: sassign(e1); - return; + return RSTRUCT; case ASS: case CASS: assign(e1); - return; + return INT; case FASS: case DASS: case LASS: dassign(e1); - return; + return DOUBLE; case ASSOP: case CASSOP: assop(e1); - return; + return INT; case DASSOP: case FASSOP: dassop(e1); - return; + return DOUBLE; case RSTRUCT: g_expr0(e2); - return; + return RSTRUCT; case COMMA: g_expr_u(e2); - g_expr0(caddr(e1)); - return; + return g_expr0(caddr(e1)); case RETURN: n = (NMTBL *)e2; if (retcont==0) retcont=fwdlabel(); code_return(creg); regv[creg]=1; - return; + return VOID; case ENVIRONMENT: code_environment(creg); regv[creg]=1; - return; + return ADDRESS; default: - code_bool(e1); + code_bool(e1); /* type? */ regv[creg]=1; + return INT; } } +#define dual_ops(op) \ + (op==GT|| op==UGT|| op==GE|| op==UGE|| op==LT|| \ + op==ULT|| op==LE|| op==ULE|| \ + op==DOP+GT|| op==DOP+GE|| op==DOP+LT|| op==DOP+LE || \ + op==EQ|| op==NEQ|| op==DOP+EQ|| op==DOP+NEQ) + +int +rop_dual(op) +{ + if (op==GT) return LT; + if (op==UGT) return ULT; + if (op==GE) return LE; + if (op==UGE) return ULE; + if (op==LT) return GT; + if (op==ULT) return UGT; + if (op==LE) return GE; + if (op==ULE) return UGE; + if (op==DOP+GT) return DOP+LT; + if (op==DOP+GE) return DOP+LE; + if (op==DOP+LT) return DOP+GT; + if (op==DOP+LE) return DOP+GE; + return op; +} + void bexpr(int e1, char cond, int l1) { + int op = car(e1); if (chk) return; gexpr_init(); - b_expr(e1,cond,l1,0); + if (dual_ops(op) && (car(caddr(e1))==CONST||(car(caddr(e1))==DCONST))) + b_expr(list3(rop_dual(op),caddr(e1),cadr(e1)),cond,l1,0); + else + b_expr(e1,cond,l1,0); } void b_expr(int e1, char cond, int l1,int err) { - int e2,l2; + int e2,l2,t; e2=cadr(e1); switch(car(e1)) { case LNOT: @@ -404,6 +439,10 @@ code_cmp_register(e2); jcond(l1,cond); return; + case DREGISTER: + code_cmp_dregister(e2); + jcond(l1,cond); + return; case CONST: if((cond&&e2)||(!cond&&!e2)) jmp(l1); return; @@ -413,9 +452,12 @@ default: if(err) { error(-1); return; /* recursive g_expr/b_expr */ - } /* type ? */ - g_expr(e1); - code_cmp_register(creg); + } + t=g_expr(e1); + if(t==FLOAT||t==DOUBLE) + code_cmp_dregister(freg); + else + code_cmp_register(creg); jcond(l1,cond); return; } @@ -484,8 +526,7 @@ g_expr_u(assign_expr0(e1,s,ty,ty)); *target = append4(*target,t,ty,e1); } else { - disp-=sz; - g_expr_u(assign_expr0((e1=list2(LVAR,disp)),s,ty,ty)); + g_expr_u(assign_expr0((e1=list2(LVAR,new_lvar(sz))),s,ty,ty)); *target = append4(*target,t,ty,e1); } } @@ -660,8 +701,7 @@ arg_size-=sz; } if (!is_simple(car(s0))) { - disp-=sz; - g_expr_u(assign_expr0((e4=list2(LVAR,disp)),s0,ty,ty)); + g_expr_u(assign_expr0((e4=list2(LVAR,new_lvar(sz))),s0,ty,ty)); cadddr(e2)=e4; s0=e4; } else if (is_same_type(t0,s0)) { @@ -752,7 +792,7 @@ g_expr(e3); emit_dpush(); g_expr(e2); - dtosop(car(e1),(e2=dpop_register())); + dtosop(car(e1),(e2=emit_dpop(1))); emit_dpop_free(e2); fregv[freg]=1; return;
--- a/mc-codegen.h Sun Mar 09 18:31:00 2003 +0900 +++ b/mc-codegen.h Wed Mar 12 15:28:44 2003 +0900 @@ -47,11 +47,11 @@ extern void emit_init(void); extern void enter(char *name); extern void enter1(); -extern void g_expr(int e1); +extern int g_expr(int e1); extern void gen_comment(char *s); extern void gen_gdecl(char *n, int gpc); extern void gen_source(char *s); -extern void gexpr(int e1,int use); +extern int gexpr(int e1,int use); extern void gexpr_init(void); extern void jcond(int l, char cond); extern void jmp(int l);
--- a/mc-parse.c Sun Mar 09 18:31:00 2003 +0900 +++ b/mc-parse.c Wed Mar 12 15:28:44 2003 +0900 @@ -137,7 +137,7 @@ if (!chk && ccout) if ( (freopen(ccout,"w",stdout)) == NULL ) error(FILERR); init(); - while(1) { + while(1) { for (nptr = &ntable[GSYMS],i=LSYMS; i--;) { (nptr++)->sc = 0; } @@ -157,17 +157,17 @@ error(int n) { if(n == EOFERR) { - if(filep!=filestack) { + if(filep!=filestack) { fclose(filep->fcb); lineno=filep->ln; --filep; return; - } else if(ac2!=ac) { + } else if(ac2!=ac) { fclose(filep->fcb); newfile(); return; - } else if(mode == TOP) { - if (chk) { + } else if(mode == TOP) { + if (chk) { fprintf(stderr, "Total internal labels : %u.\n",labelno-1); fprintf(stderr, "Total global variables: %u bytes.\n",gpc); } @@ -224,13 +224,13 @@ { char *p; - if (sym != s) { + if (sym != s) { p=(s==RPAR) ? "')'": (s==RBRA) ? "']'": (s==SM) ? "';'": (s==LPAR) ? "'('": (s==WHILE) ? "'while'": (s==COLON) ? "':'": "Identifier"; fprintf(stderr,"%d:%s expected.\n",lineno,p); errmsg(); - } else + } else getsym(); } @@ -362,19 +362,19 @@ if (mode==GDECL) { typedefed=0; } if(sym==STATIC) { - if(mode==LDECL) { + if(mode==LDECL) { getsym(); conv->static_(); mode=STADECL; stmode=LDECL; - } else if(mode==GDECL) { + } else if(mode==GDECL) { getsym(); conv->static_(); stmode=STATIC; - } else + } else error(DCERR); } else if(sym==REGISTER) { - if(mode!=LDECL) + if(mode!=LDECL) error(DCERR); stmode=REGISTER; getsym(); @@ -384,15 +384,15 @@ conv->extern_(); stmode=EXTRN; } else if(sym==TYPEDEF) { - if(mode==GDECL) { + if(mode==GDECL) { getsym(); conv->typedef_(); mode=GTDECL; - } else if(mode==LDECL) { + } else if(mode==LDECL) { getsym(); conv->typedef_(); mode=LTDECL; - } else + } else error(DCERR); } if((t=typespec())==0) return; @@ -417,22 +417,22 @@ } conv->return_type_(type,n,sd); def(n); - while(sym==COMMA) { + while(sym==COMMA) { conv->comma_(); getsym(); type=t; n=decl0(); reverse(t); - if(n == &null_nptr) error(DCERR); + if(n == &null_nptr) error(DCERR); /* if(args) error(DCERR); */ conv->return_type_(type,n,1); def(n); } if(sym!=SM) error(DCERR); conv->sm_(); - if(mode==GTDECL) + if(mode==GTDECL) mode=GDECL; - if(mode==STADECL||mode==LTDECL) + if(mode==STADECL||mode==LTDECL) mode=LDECL; } @@ -470,7 +470,7 @@ case LONG: t=INT; getsym(); - if(sym==LONG) { + if(sym==LONG) { getsym(); t=LONGLONG; } @@ -478,12 +478,12 @@ break; default: if(sym==IDENT) { - if(nptr->sc==TYPE) { + if(nptr->sc==TYPE) { t=nptr->ty; typedefed=glist2((int)nptr,typedefed); getsym(); break; - } else if(nptr->sc==EMPTY && gnptr->sc==TYPE) { + } else if(nptr->sc==EMPTY && gnptr->sc==TYPE) { getsym(); break; } @@ -504,7 +504,7 @@ decl0(void) { NMTBL *n; - if(sym==MUL) { + if(sym==MUL) { getsym(); n=decl0(); type=list2(POINTER,type); @@ -520,11 +520,11 @@ NMTBL *n; int i,t; - if(sym==LPAR) { + if(sym==LPAR) { getsym(); n=decl0(); checksym(RPAR); - } else if (sym == IDENT) { + } else if (sym == IDENT) { n=nptr; getsym(); } else { @@ -533,7 +533,7 @@ } while(1) { if(sym==LBRA) { - if(getsym()==RBRA) { + if(getsym()==RBRA) { getsym(); if(mode==ADECL) { type=list2(POINTER,type); @@ -542,16 +542,16 @@ } else { error(DCERR); } - } else { + } else { t=type; i=cexpr(expr(1)); checksym(RBRA); type=list3(ARRAY,t,i); } - } else if(sym==LPAR) { + } else if(sym==LPAR) { if(mode==GDECL) { mode=ADECL;getsym();mode=GDECL; /* ??? */ - } else + } else getsym(); n->dsp=0; if (type==CODE) { @@ -577,9 +577,9 @@ /* in GDECL mode dsp contains real parameter, if not, it contains arg type list. Real parameter list is compatible with arg type list. See def/ADECL */ - if (mode!=GDECL) + if (mode!=GDECL) n->dsp=t; - } else + } else return n; } /* NOT REACHED */ @@ -606,7 +606,7 @@ mode=ADECL; args = 0; n->dsp=0; - for(;;) { + for(;;) { if(sym==IDENT && nptr->sc!=TYPE) { type=INT; /* naked argument, old K&R C */ def(nptr); @@ -617,7 +617,7 @@ argtypes=list2(DOTS,argtypes); getsym(); break; - } + } if((t=typespec())==0) { error(DCERR); break; @@ -629,15 +629,15 @@ arg=decl0(); args = sargs; reverse(t); - if (arg != &null_nptr) { - if (smode==GDECL) + if (arg != &null_nptr) { + if (smode==GDECL) def(arg); - } + } argtypes=list2(type,argtypes); } if(sym==RPAR) break; - } - if (sym!=COMMA) error(DCERR); + } + if (sym!=COMMA) error(DCERR); getsym(); } argtypes=reverse0(argtypes); @@ -651,13 +651,13 @@ return argtypes; } -static void +static void reverse(int t1) { int t2,t3; t2=t1; - while(type!=t1) { + while(type!=t1) { t3=cadr(type); rplacad(type,t2); t2=type; @@ -666,13 +666,13 @@ type = t2; } -int +int reverse0(int t1) { int t2,t3; t2=0; - while(t1) { + while(t1) { t3=cadr(t1); rplacad(t1,t2); t2=t1; @@ -691,21 +691,27 @@ if(t==FLOAT) return size_of_float; if(t==DOUBLE) return size_of_double; if(t==LONGLONG) return size_of_longlong; - if(car(t)==STRUCT||car(t)==UNION) { + if(car(t)==STRUCT||car(t)==UNION) { if(cadr(t)==-1) error(DCERR); return(cadr(t)); } - if(car(t)==ARRAY) + if(car(t)==ARRAY) return(size(cadr(t))*caddr(t)); - else if(car(t)==CODE) + else if(car(t)==CODE) return size_of_int; - else if(car(t)==FUNCTION) + else if(car(t)==FUNCTION) return size_of_int; - else + else error(DCERR); return 0; } +int +new_lvar(int sz) +{ + return disp -= sz; +} + static NMTBL * def(NMTBL *n) { @@ -717,13 +723,13 @@ n->nm = "_"; } nsc=ndsp=0; - if(car(type)==FUNCTION) { + if(type>0&&(car(type)==FUNCTION || car(type)==CODE)) { if (n->sc==EXTRN || (mode==GDECL)) { fcheck(n); return n; } } - if (n->sc!=EMPTY && + if (n->sc!=EMPTY && !(n->sc==GVAR&&n->dsp==EXTRN) && !(n->sc==FUNCTION&&n->dsp==EXTRN) && (mode!=ADECL || n->sc!=LVAR || n->ty!=INT) && @@ -753,12 +759,12 @@ } *cheapp++ = 0; } - if(sym==ASS) { + if(sym==ASS) { conv->op_(sym); decl_data(type,n,0); emit_data_closing(n); /* gpc is incremented by emit_data */ - } else + } else gpc +=sz; return n; case GSDECL: @@ -792,7 +798,7 @@ if(type==CHAR) { if (n->dsp==0) { n->dsp = args; - if (endian) + if (endian) n->dsp += size_of_int-1; } args += size_of_int; @@ -818,11 +824,11 @@ error(-1); } else { nsc = LVAR; - ndsp = (disp -= sz); + ndsp = new_lvar(sz); } n->sc = nsc; n->dsp = ndsp; - if(sym==ASS) { + if(sym==ASS) { conv->op_(sym); decl_data(type,n,0); } @@ -914,8 +920,8 @@ for(i=0;;i++) { if (sym!=RC) offset=decl_data(t1,n,offset); /* array of some thing */ - if (sym==COMMA) { - conv->comma_(); + if (sym==COMMA) { + conv->comma_(); continue; } else if (sym==RC) { conv->decl_data_end_(); @@ -942,7 +948,7 @@ } else if (caddr(t)!=size(type)) { /* size match? */ error(TYERR); } - } else + } else error(DCERR); } else if (t1==STRUCT) { if (sym==LC) { @@ -956,10 +962,10 @@ if ( t1 && sym==COMMA) { conv->comma_(); continue; } if (!t1 && sym!=RC) error(DCERR); } - conv->decl_data_end_(); conv->rc_(); + conv->decl_data_end_(); conv->rc_(); getsym(); return offset; - } else + } else error(DCERR); } else { mode = mode_save; @@ -978,16 +984,16 @@ smode=mode; if (mode==GDECL || mode==GSDECL || mode==GUDECL || mode==GTDECL) mode=(s==STRUCT?GSDECL:GUDECL); - else + else mode=(s==STRUCT?LSDECL:LUDECL); sdisp=disp; disp=0; if (sdecl_f) conv->sdecl_(s); - if (getsym() == IDENT) { + if (getsym() == IDENT) { nptr0 = nptr; gnptr0 = gnptr; if (sdecl_f) conv->id_(sym,nptr); - if (getsym() == LC) { + if (getsym() == LC) { if (sdecl_f) conv->lc_(); if (nptr0->sc != EMPTY) error(DCERR); nptr0->sc = TAG; @@ -1002,7 +1008,7 @@ tags=reverse0(tags); heap[nptr0->ty+2]=tags; rplacad(type0 = nptr0->ty,disp); - } else { + } else { /* struct tag name */ if(nptr0->sc == EMPTY) nptr0=gnptr0; if(nptr0->sc == EMPTY) error(UDERR); @@ -1012,7 +1018,7 @@ conv->comment_(' '); } type0 = list4(s,disp,tags,(int)nptr0); - } else if(sym==LC) { + } else if(sym==LC) { if (sdecl_f) conv->lc_(); tags = 0; while(getsym() != RC) { @@ -1041,7 +1047,7 @@ fnptr=n; disp = -args; mode=ADECL; - if (sym!=LC) { + if (sym!=LC) { stmode=REGISTER; reg_var=0; args=0; fnptr->dsp=0; @@ -1065,7 +1071,7 @@ stmode=0; mode=STAT; init_vars=0; - while (typeid(getsym()) || sym==STATIC || sym==EXTRN || sym==TYPEDEF) { + while (typeid(getsym()) || sym==STATIC || sym==EXTRN || sym==TYPEDEF) { mode=LDECL; decl(); mode=STAT; @@ -1098,7 +1104,7 @@ reg_var=0; fcheck(n); mode=ADECL; - if (sym!=LC) { + if (sym!=LC) { args=0; fnptr->dsp=0; while (sym!=LC) { /* argument declaration !ANSI */ stmode=0; @@ -1114,8 +1120,8 @@ init_vars=0; /* local variable declaration */ mode=STAT; - while (typeid(getsym()) || sym==STATIC || sym==EXTRN - || sym==REGISTER || sym==TYPEDEF) { + while (typeid(getsym()) || sym==STATIC || sym==EXTRN + || sym==REGISTER || sym==TYPEDEF) { mode=LDECL; stmode=0; decl(); @@ -1140,7 +1146,7 @@ /* If function has structure return value, it has extra argument for where to write the structure. It have to be - a first argument. We add it here and we have to fix all arguments' + a first argument. We add it here and we have to fix all arguments' offset. If it is the last value, we don't have to fix, but gcc has a first argument convention. */ @@ -1185,10 +1191,12 @@ void fcheck(NMTBL *n) { - if(!(mode==GDECL||mode==ADECL)||car(type)!=FUNCTION) error(DCERR); + if(!(mode==GDECL||mode==ADECL)|| + (car(type)!=FUNCTION&&car(type)!=CODE)) error(DCERR); if(n->sc==FUNCTION) compatible(n->ty,cadr(type)); + else if(n->sc==CODE) compatible(n->ty,cadr(type)); else { - if(n->sc!=EMPTY) + if(n->sc!=EMPTY) error(DCERR); else { n->sc=FUNCTION; @@ -1200,10 +1208,10 @@ static void compatible(int t1, int t2) { - if(integral(t1)) { + if(integral(t1)) { if(t1!=t2) error(TYERR); } - else if(car(t1)!=car(t2)) + else if(car(t1)!=car(t2)) error(TYERR); else if((car(t1)==STRUCT || car(t1)==UNION) && cadr(t1)!=cadr(t2)) error(TYERR); @@ -1238,9 +1246,9 @@ { int slfree; - if(sym==SM) { + if(sym==SM) { conv->sm_(); - getsym(); return; + getsym(); return; } checkret(); switch(sym) { @@ -1289,10 +1297,10 @@ dogoto(); return; default: - if(sym==IDENT&&skipspc()==':') { + if(sym==IDENT&&skipspc()==':') { dolabel(); statement(); - } else { + } else { slfree=lfree; gexpr(expr(0),0); lfree=slfree; @@ -1316,9 +1324,9 @@ checksym(RPAR); statement(); checkret(); - if(sym==ELSE) { + if(sym==ELSE) { conv->if_else_(); - if ((l2 = control)) + if ((l2 = control)) jmp(l2=fwdlabel()); fwddef(l1); getsym(); @@ -1346,12 +1354,12 @@ e=expr(0); checksym(RPAR); conv->while_body_(); - if(sym==SM) { + if(sym==SM) { bexpr(e,1,clabel); lfree=slfree; conv->sm_(); getsym(); - } else { + } else { bexpr(e,0,blabel); lfree=slfree; statement(); @@ -1406,7 +1414,7 @@ getsym(); checksym(LPAR); slfree=lfree; - if(sym!=SM) { + if(sym!=SM) { gexpr(expr(0),0); checksym(SM); conv->for1_(); @@ -1416,7 +1424,7 @@ } lfree=slfree; l=backdef(); - if(sym!=SM) { + if(sym!=SM) { bexpr(expr(0),0,blabel); checksym(SM); conv->for2_(); @@ -1425,13 +1433,13 @@ getsym(); } lfree=slfree; - if(sym==RPAR) { + if(sym==RPAR) { clabel=l; conv->for_body_(); getsym(); statement(); checkret(); - } else { + } else { clabel=fwdlabel(); e=expr(0); conv->for_body_(); @@ -1500,7 +1508,7 @@ c=0; slfree=lfree; - while(sym==CASE) { + while(sym==CASE) { conv->case_begin_(c,0); getsym(); c=list2(cexpr(expr(1)),c); @@ -1508,12 +1516,12 @@ checksym(COLON); } l=fwdlabel(); - if (control) { + if (control) { control=0; jmp(l); } if (cslabel) fwddef(cslabel); - while(cadr(c)) { + while(cadr(c)) { cmpdimm(car(c),csvalue1); jcond(l,0); c=cadr(c); @@ -1540,7 +1548,7 @@ { int slfree,e,e1; - if(getsym()==SM) { + if(getsym()==SM) { conv->return_(); conv->return_end_(); getsym(); @@ -1609,7 +1617,7 @@ checksym(SM); conv->goto_label_(nptr0); return; - } + } if (t==COMMA) { env = caddr(e1); e1 = cadr(e1); @@ -1620,7 +1628,7 @@ if (t==FUNCTION) { conv->jump_(env); e2 = cadr(e1); - if (car(e2) == FNAME) { + if (car(e2) == FNAME) { nptr0=(NMTBL *)cadr(e2); nptr0->sc = CODE; } @@ -1637,9 +1645,9 @@ static void dolabel(void) { - if(nptr->sc == FLABEL) + if(nptr->sc == FLABEL) fwddef(nptr->dsp); - else if(nptr->sc != EMPTY) + else if(nptr->sc != EMPTY) error(TYERR); nptr->sc = BLABEL; nptr->dsp = backdef(); @@ -1653,8 +1661,8 @@ { if (car(e2)==CONST) return dlist2(DCONST,(double)cadr(e2)); if(type==FLOAT||type==DOUBLE) return e2; - if(type==UNSIGNED) return list2(U2D,e2); - if(integral(type)) return list2(I2D,e2); + if(type==UNSIGNED) return list2(U2D,rvalue_t(e2,type)); + if(integral(type)) return list2(I2D,rvalue_t(e2,type)); error(TYERR); return dlist2(DCONST,1.0); } @@ -1663,7 +1671,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,e2); + if(type==FLOAT||type==DOUBLE) return list2(D2I,rvalue_t(e2,type)); error(TYERR); return list2(CONST,1); } @@ -1671,7 +1679,7 @@ unsigned_value(int e2,int type) { if(scalar(type)) return e2; - if(type==FLOAT||type==DOUBLE) return list2(D2U,e2); + if(type==FLOAT||type==DOUBLE) return list2(D2U,rvalue_t(e2,type)); error(TYERR); return e2; } @@ -1774,7 +1782,7 @@ if((t==UNSIGNED||type==UNSIGNED)&& (op==MUL||op==DIV||op==MOD||op==RSHIFT||op==LSHIFT)) op=op+US; - if(t==CHAR) { + if(t==CHAR) { type= INT; return(list4(CASSOP,e1,e2,op)); } @@ -1796,7 +1804,7 @@ int e1,e2,e3,t; e1=expr3(); - if(sym==COND) { + if(sym==COND) { conv->cond_(); e1=rvalue(e1); getsym(); @@ -1810,10 +1818,10 @@ if(car(e1)==CONST) { if(cadr(e1)) { type=t;return e2; - } else + } else return e3; } - if(type==INT||(t!=INT&&type==UNSIGNED)) + if(type==INT||(t!=INT&&type==UNSIGNED)) type=t; return(list4(COND,e1,e2,e3)); } @@ -1826,7 +1834,7 @@ int e; e=expr4(); - while(sym==LOR) { + while(sym==LOR) { conv->op_(sym); e=rvalue(e); getsym(); @@ -1842,7 +1850,7 @@ int e; e=expr5(); - while(sym==LAND) { + while(sym==LAND) { conv->op_(sym); e=rvalue(e); getsym(); @@ -1858,7 +1866,7 @@ int e1,e2,t; e1=expr6(); - while(sym==BOR) { + while(sym==BOR) { conv->op_(sym); e1=rvalue(e1); t=type; @@ -1875,7 +1883,7 @@ int e1,e2,t; e1=expr7(); - while(sym==EOR) { + while(sym==EOR) { conv->op_(sym); e1=rvalue(e1); t=type; @@ -1892,7 +1900,7 @@ int e1,e2,t; e1=expr8(); - while(sym==BAND) { + while(sym==BAND) { conv->op_(sym); e1=rvalue(e1); t=type; @@ -1909,7 +1917,7 @@ int e1,e2,op,t; e1=expr9(); - while((op=sym)==EQ||op==NEQ) { + while((op=sym)==EQ||op==NEQ) { conv->op_(sym); e1=rvalue(e1); t=type; @@ -1927,19 +1935,19 @@ int e1,e2,t,op; e1=expr10(); - while((op=sym)==GT||op==GE||op==LT||op==LE) { + while((op=sym)==GT||op==GE||op==LT||op==LE) { conv->op_(sym); e1=rvalue(e1); t=type; getsym(); e2=rvalue(expr10()); - if(t==INT&&type==INT) + if(t==INT&&type==INT) e1=binop(op,e1,e2,t,type); else if(t==DOUBLE||type==DOUBLE|| - t==FLOAT||type==FLOAT) + t==FLOAT||type==FLOAT) /* binop will handle op+DOP */ e1=binop(op,e1,e2,t,type); - else + else e1=binop(op+US,e1,e2,t,type); type= INT; } @@ -1952,7 +1960,7 @@ int e1,e2,t,op; e1=expr11(); - while((op=sym)==RSHIFT||op==LSHIFT) { + while((op=sym)==RSHIFT||op==LSHIFT) { conv->op_(sym); e1=rvalue(e1); t=type; @@ -1969,7 +1977,7 @@ int e1,e2,t,op; e1=expr12(); - while((op=sym)==ADD||op==SUB) { + while((op=sym)==ADD||op==SUB) { conv->op_(sym); e1=rvalue(e1); t=type; @@ -1986,7 +1994,7 @@ int e1,e2,t,op; e1=expr13(); - while((op=sym)==MUL||op==DIV||op==MOD) { + while((op=sym)==MUL||op==DIV||op==MOD) { conv->op_(sym); e1=rvalue(e1); t=type; @@ -2007,7 +2015,7 @@ conv->prefix_(sym); getsym(); lcheck(e=expr13()); - if(type==CHAR) { + if(type==CHAR) { type= INT; return(list2(op==INC?CPREINC:CPREDEC,e)); } @@ -2017,7 +2025,7 @@ return(list3(FPREINC,e,op==INC?1:-1)); if(type==DOUBLE) return(list3(DPREINC,e,op==INC?1:-1)); - if(car(type)!=POINTER) + if(car(type)!=POINTER) error(TYERR); return(list3(PREINC,e, op==INC?size(cadr(type)):-size(cadr(type)) )); @@ -2047,59 +2055,59 @@ conv->prefix_(sym); getsym(); e=rvalue(expr13()); - if(type==FLOAT||type==DOUBLE) + if(type==FLOAT||type==DOUBLE) return list2(DMINUS,e); - if(!integral(type)) + if(!integral(type)) error(TYERR); return(car(e)==CONST?list2(CONST,-cadr(e)):list2(MINUS,e)); case BNOT: conv->prefix_(sym); getsym(); e=rvalue(expr13()); - if(!integral(type)) + if(!integral(type)) error(TYERR); return(car(e)==CONST?list2(CONST,~cadr(e)):list2(BNOT,e)); case LNOT: conv->prefix_(sym); getsym(); e=rvalue(expr13()); - if(type==FLOAT||type==DOUBLE) + if(type==FLOAT||type==DOUBLE) return(car(e)==DCONST?list2(CONST,!dcadr(e)): list3(DOP+NEQ,list2(CONST,0),e)); - if(!scalar(type)) + if(!scalar(type)) error(TYERR); return(car(e)==CONST?list2(CONST,!cadr(e)):list2(LNOT,e)); case SIZEOF: conv->prefix_(sym); if(getsym()==LPAR) { - if(typeid(getsym())) { + if(typeid(getsym())) { e=list2(CONST,size(typename())); type=INT; checksym(RPAR); return e; - } else { + } else { e=expr0(); checksym(RPAR); expr16(e); - if(sym==INC||sym==DEC) { + if(sym==INC||sym==DEC) { getsym(); if(type==CHAR) type=INT; else if(!scalar(type)&&type!=FLOAT&&type!=DOUBLE) error(TYERR); } } - } else + } else expr13(); e=list2(CONST,size(type)); type=INT; return e; } e=expr14(); - if((op=sym)==INC||op==DEC) { + if((op=sym)==INC||op==DEC) { conv->postfix_(sym); lcheck(e); getsym(); - if(type==CHAR) { + if(type==CHAR) { type= INT; return(list2(op==INC?CPOSTINC:CPOSTDEC,e)); } @@ -2109,7 +2117,7 @@ return(list3(FPOSTINC,e,op==INC?1:-1)); if(type==DOUBLE) return(list3(DPOSTINC,e,op==INC?1:-1)); - if(car(type)!=POINTER) + if(car(type)!=POINTER) error(TYERR); return (list3(POSTINC,e, op == INC ? size(cadr(type)): -size(cadr(type)) )); @@ -2148,7 +2156,7 @@ getsym(); break; case EMPTY: - if(getsym()==LPAR) { + if(getsym()==LPAR) { nptr->sc = FUNCTION; nptr->ty= INT; type= list3(FUNCTION,INT,0); @@ -2181,7 +2189,7 @@ getsym(); break; case RETURN: - conv-> return_f_(); + conv-> return_f_(); if (fnptr->sc != FUNCTION) { error(STERR); } @@ -2201,14 +2209,14 @@ checksym(RPAR); break; case ENVIRONMENT: - conv-> environment_(); + conv-> environment_(); type=list2(POINTER,VOID); e1=list2(ENVIRONMENT,0); getsym(); break; case LPAR: conv->lpar_(); - if(typeid(getsym())) { + if(typeid(getsym())) { t=typename(); conv->return_type_(t,0,0); conv->rpar_(); @@ -2238,7 +2246,7 @@ int e2,t; while(1) { - if(sym==LBRA) { + if(sym==LBRA) { conv->lbra_(sym); e1=rvalue(e1); t=type; @@ -2263,7 +2271,7 @@ rvalue(int e) { int t; - if(type==CHAR) { + if(type==CHAR) { type= INT; switch(car(e)) { case GVAR: @@ -2275,7 +2283,7 @@ default:return(e); } } - if(type==FLOAT) { + if(type==FLOAT) { switch(car(e)) { case GVAR: return(list3(FRGVAR,cadr(e),caddr(e))); @@ -2286,7 +2294,7 @@ default:return(e); } } - if(type==DOUBLE) { + if(type==DOUBLE) { switch(car(e)) { case GVAR: return(list3(DRGVAR,cadr(e),caddr(e))); @@ -2297,7 +2305,7 @@ default:return(e); } } - if(type==LONGLONG) { + if(type==LONGLONG) { switch(car(e)) { case GVAR: return(list3(LRGVAR,cadr(e),caddr(e))); @@ -2311,11 +2319,11 @@ if(!integral(type)&&type!=VOID) { if(type==CODE) { return e; - } if((t=car(type))==ARRAY) { + } if((t=car(type))==ARRAY) { type=list2(POINTER,cadr(type)); if(car(e)==INDIRECT) return cadr(e); return list2(ADDRESS,e); - } else if(t==STRUCT || t==UNION) { + } else if(t==STRUCT || t==UNION) { t = cadr(type); /* size */ return list3(RSTRUCT,e,t); } else if(t==FUNCTION) { @@ -2364,9 +2372,9 @@ else if(car(type)==CODE || car(type)==FUNCTION) type=type; else error(TYERR); - } else + } else type= CHAR; - if(car(e)==ADDRESS) + if(car(e)==ADDRESS) return(cadr(e)); return(list2(INDIRECT,e)); } @@ -2384,7 +2392,7 @@ switch(car(e)) { case GVAR: e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp))); - break; + break; case LVAR: e=list2(LVAR,cadr(e) + nptr->dsp); break; @@ -2410,6 +2418,7 @@ dbinop(int op, int e1, int e2, int t1, int t2) { double d1,d2,d; + int b; type= DOUBLE; if (integral(t1)) { e1=float_value(e1,t1); t1=DOUBLE; } @@ -2423,23 +2432,36 @@ case MUL: d=d1*d2;break; case DIV: if(!d2) error(EXERR);d=d1/d2;break; - case GT: - d=(d1>d2);break; - case GE: - d=(d1>=d2);break; - case LT: - d=(d1<d2);break; - case LE: - d=(d1<=d2);break; - case EQ: - d=(d1==d2);break; - case NEQ: - d=(d1!=d2);break; + default: + switch(op) { + case GT: b=(d1>d2);break; + case GE: b=(d1>=d2);break; + case LT: b=(d1<d2);break; + case LE: b=(d1<=d2);break; + case EQ: b=(d1==d2);break; + case NEQ: b=(d1!=d2);break; + default: error(EXERR); + } + type = INT; + return list2(CONST,b); } return dlist2(DCONST,d); } - if(op==GT||op==GE||op==LT||op==LE||op==EQ||op==NEQ|| - ADD||SUB||MUL||DIV) + if(car(e2)==DCONST) { + if (op==SUB) { + op=ADD; dcadr(e2) = -dcadr(e2); + } else if(op==DIV) { + if(dcadr(e2)==0.0) error(EXERR); + op=MUL; dcadr(e2)=1/dcadr(e2); + } + } + if (car(e1)==DCONST && (op==ADD||op==MUL)) { + return(list3(op+DOP,e2,e1)); + } + if(op==GT||op==GE||op==LT||op==LE||op==EQ||op==NEQ) { + type=INT; + return(list3(op+DOP,e1,e2)); + } else if(ADD||SUB||MUL||DIV) return(list3(op+DOP,e1,e2)); else error(-1); @@ -2450,7 +2472,7 @@ { int e; - if(t1==DOUBLE||t2==DOUBLE||t1==FLOAT||t2==FLOAT) + 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); @@ -2464,15 +2486,15 @@ case BAND: e=e1&e2;break; case ADD: - if(integral(t1)) { + if(integral(t1)) { if(integral(t2)) { e=e1+e2; - } else { + } else { if(car(t2)!=POINTER) error(TYERR); e=size(cadr(t2))*e1+e2; type=t2; } - } else { + } else { if(car(t1)!=POINTER) error(TYERR); e=e1+size(cadr(t1))*e2; type=t1; @@ -2481,7 +2503,7 @@ case SUB: if(integral(t1)) { e=e1-e2; - } else { + } else { if(car(t1)!=POINTER) error(TYERR); e=e1-size(cadr(t1))*e2; type=t1; @@ -2525,14 +2547,15 @@ op==EQ||op==NEQ ) return(list3(op,e1,e2)); + if(op==SUB&&car(e2)==CONST) { op=ADD; cadr(e2)=-cadr(e2); } if((op==ADD||op==MUL||op==BOR||op==EOR||op==BAND)&& (car(e1)==CONST||(car(e2)!=CONST&& (car(e1)==RGVAR||car(e1)==RLVAR)))) { e=e1;e1=e2;e2=e;e=t1;t1=t2;t2=e; } - if(op==ADD) { - if(integral(t1)) { - if(integral(t2)) { + if(op==ADD) { + if(integral(t1)) { + if(integral(t2)) { if(t1==INT) type=t2;else type=t1; return(list3(ADD,e1,e2)); } @@ -2551,14 +2574,14 @@ cadr(cadr(e1))+cadr(e)))); return(list3(ADD,e1,e)); } - if(op==SUB) { - if(integral(t1)) { + if(op==SUB) { + if(integral(t1)) { if(!integral(t2)) error(TYERR); if(t1==INT) type=t2;else type=t1; return(list3(SUB,e1,e2)); } if(car(t1)!=POINTER) error(TYERR); - if(integral(t2)) { + if(integral(t2)) { e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT); type=t1; return(list3(SUB,e1,e)); @@ -2586,8 +2609,8 @@ if (type==FLOAT && t==DOTS) { type=DOUBLE;} if (type==CHAR && t==DOTS) { type=INT;} if (t==DOTS) return e; - if (t==UNSIGNED) e = unsigned_value(e,type); - else if (integral(t)) e = int_value(e,type); + if (t==UNSIGNED) e = unsigned_value(e,type); + else if (integral(t)) e = int_value(e,type); else if (t==FLOAT||t==DOUBLE) e = float_value(e,type); else if ((t1=car(t))==STRUCT||t1==UNION) { if(size(t)!=size(type)) error(TYERR); @@ -2621,11 +2644,11 @@ } t=type; arglist=0; - while(sym!=RPAR) { + while(sym!=RPAR) { e=rvalue(expr1()); if(argtypes==0) at=DOTS; else if(car(argtypes)==DOTS) at=DOTS; - else { at=car(argtypes); argtypes=cadr(argtypes); } + else { at=car(argtypes); argtypes=cadr(argtypes); } e = function_args(e,at); arglist=list3(e,arglist,type); if(sym!=COMMA) break; @@ -2634,7 +2657,7 @@ } checksym(RPAR); conv->funcall_args_(); - if(car(t)==CODE) + if(car(t)==CODE) return list3(FUNCTION,e1,arglist); type=cadr(t); if(type==CHAR) type=INT; @@ -2669,7 +2692,7 @@ static int typeid(int s) { - return (integral(s) || s==CODE || s==SHORT || + return (integral(s) || s==CODE || s==SHORT || s==LONG || s==STRUCT || s==UNION || s==LONGLONG || s==FLOAT || s==DOUBLE || (s==IDENT && nptr->sc==TYPE)); @@ -2689,7 +2712,7 @@ static int ndecl0(void) { - if(sym==MUL) { + if(sym==MUL) { getsym(); return type=list2(POINTER,ndecl0()); } @@ -2704,23 +2727,23 @@ if(sym==LPAR) { if(getsym()==RPAR) { type=list3(FUNCTION,type,0); getsym(); - } else { + } else { ndecl0(); checksym(RPAR); } } while(1) { - if(sym==LBRA) { + if(sym==LBRA) { getsym(); t=type; i=cexpr(expr(1)); checksym(RBRA); type=list3(ARRAY,t,i); - } else if(sym==LPAR) { + } else if(sym==LPAR) { t = type; getsym(); arglist=0; - while(sym!=RPAR) { + while(sym!=RPAR) { ndecl0(); arglist=list2(type,arglist); if(sym!=COMMA) break; @@ -2735,7 +2758,7 @@ static int cexpr(int e) -{ +{ conv->conv_(); if (car(e) != CONST) error(CNERR); return (cadr(e)); @@ -2753,15 +2776,15 @@ char *scheapp; char c; - if (alpha(skipspc())) { + if (alpha(skipspc())) { i = hash = 0; name = namebuf; - while (alpha(ch) || digit(ch)) { - if (i < LBUFSIZE-1) + while (alpha(ch) || digit(ch)) { + if (i < LBUFSIZE-1) hash=(7*hash ^ (name[i++]=ch)); getch(); } - name[i++] = '\0'; + name[i++] = '\0'; nptrm=msearch(name); if (mode==MDECL) { @@ -2769,7 +2792,7 @@ return (sym==MACRO); } if (mode==IFDEF) { - if (nptrm->sc == MACRO||nptrm->sc==FMACRO) { + if (nptrm->sc == MACRO||nptrm->sc==FMACRO) { return (symval=1); } else { return (symval=0); @@ -2826,14 +2849,14 @@ if (ch=='.') { getch(); return sym=DOTS; - } + } error(CHERR); return getsym(); } else if (!digit(ch)) return sym=PERIOD; d=1; *cheapp++ = '.'; /* .0 case */ - } else if (ch == '0') { + } else if (ch == '0') { if (getch() == 'x' || ch == 'X') { while(1) { if(digit(getch())) @@ -2874,13 +2897,13 @@ dsymval = strtod(scheapp,0); cheapp=scheapp; return sym=DCONST; - } else if(ch=='\'') { + } else if(ch=='\'') { getch(); symval=escape(); if(ch!='\'') error(CHERR); getch(); return sym=CONST; - } else if(ch=='"') { + } else if(ch=='"') { getstring(); return sym= STRING; } @@ -2941,7 +2964,7 @@ case '/': if(ch=='/') { in_comment = 1; - conv->comment_('/'); conv->comment_('/'); + conv->comment_('/'); conv->comment_('/'); while(ch!='\n') { getch(); conv->comment_(ch); } in_comment = 0; getch(); @@ -2949,7 +2972,7 @@ } if(ch!='*') return postequ(DIV,DIV+AS); in_comment = 1; - conv->comment_('/'); conv->comment_('*'); + conv->comment_('/'); conv->comment_('*'); do { c=ch; getch(); conv->comment_(ch); } while(!(c=='*'&&ch=='/')); @@ -2993,8 +3016,8 @@ NMTBL *nptr,*iptr; iptr=nptr= &ntable[hash % GSYMS]; - while(nptr->sc!=0) { - if (++nptr== &ntable[GSYMS]) + while(nptr->sc!=0) { + if (++nptr== &ntable[GSYMS]) nptr=ntable; if (nptr==iptr) error(GSERR); } @@ -3014,8 +3037,8 @@ NMTBL *nptr,*iptr; iptr=nptr= &ntable[hash % GSYMS]; - while(nptr->sc!=0 && neqname(nptr->nm,name)) { - if (++nptr== &ntable[GSYMS]) + while(nptr->sc!=0 && neqname(nptr->nm,name)) { + if (++nptr== &ntable[GSYMS]) nptr=ntable; if (nptr==iptr) error(GSERR); } @@ -3032,8 +3055,8 @@ NMTBL *nptr,*iptr; iptr=nptr= &ntable[hash%LSYMS+GSYMS]; - while(nptr->sc!=0 && neqname(nptr->nm,name)) { - if (++nptr== &ntable[LSYMS+GSYMS]) + while(nptr->sc!=0 && neqname(nptr->nm,name)) { + if (++nptr== &ntable[LSYMS+GSYMS]) nptr= &ntable[GSYMS]; if (nptr==iptr) error(LSERR); } @@ -3051,8 +3074,8 @@ NMTBL *nptr,*iptr; iptr=nptr= &mtable[hash%MSYMS]; - while(nptr->sc!=0 && neqname(nptr->nm,name)) { - if (++nptr== &mtable[MSYMS]) + while(nptr->sc!=0 && neqname(nptr->nm,name)) { + if (++nptr== &mtable[MSYMS]) nptr= &mtable[0]; if (nptr==iptr) error(MSERR); } @@ -3077,7 +3100,7 @@ } iptr=nptr= &mtable[hash%MSYMS]; while(nptr->sc!=0 && neqname(nptr->nm,name)) { - if (++nptr== &mtable[MSYMS]) + if (++nptr== &mtable[MSYMS]) nptr= &mtable[0]; if (nptr==iptr) error(MSERR); } @@ -3103,7 +3126,7 @@ { if (!p) return 0; - while(*p && *p!='.') + while(*p && *p!='.') if(*p++ != *q++) return 1; return (*q!=0); } @@ -3114,7 +3137,7 @@ getch(); symval = 0; sptr = cheapp; - while (ch != '"') { + while (ch != '"') { *cheapp++ = escape(); symval++; if (cheapp >= cheap+CHEAPSIZE) error(STRERR); @@ -3155,14 +3178,14 @@ return getch(); } -char +char escape(void) { char c; - if ((c=ch) == '\\') { - if (digit(c=getch())) { + if ((c=ch) == '\\') { + if (digit(c=getch())) { c = ch-'0'; - if (digit(getch())) { + if (digit(getch())) { c = c*8+ch-'0'; if (digit(getch())) { c=c*8+ch-'0';getch(); @@ -3231,14 +3254,14 @@ i=0; while ((*chptr++ = c = getc(filep->fcb)) != '\n') { if (++i > LBUFSIZE-2) error(LNERR); - if (c==EOF) { + if (c==EOF) { error(EOFERR); --chptr; } } *chptr = '\0'; if (lsrc && !asmf && !macro_if_skip) gen_comment(linebuf); - if (*(chptr = linebuf) == '#' && !in_comment) { + if (*(chptr = linebuf) == '#' && !in_comment) { macro_processing(); } } while(macro_if_skip || linebuf[0] == '#'); @@ -3264,7 +3287,7 @@ macro_if_skip = (!i)^c; } return; - } else if (macroeq("if")) { + } else if (macroeq("if")) { macro_if_current++; if (!macro_if_skip) { for(c=0;chptr[c];c++); @@ -3276,15 +3299,15 @@ macro_if_skip = !i; } return; - } else if (macroeq("else")) { + } else if (macroeq("else")) { if (macro_if_current==0) { error(MCERR); /* extra #else */ return; } - if (macro_if_current == macro_if_depth) + if (macro_if_current == macro_if_depth) macro_if_skip = !macro_if_skip; return; - } else if (macroeq("endif")) { + } else if (macroeq("endif")) { if (macro_if_current == macro_if_depth) { macro_if_skip = 0; macro_if_depth = --macro_if_current; @@ -3298,38 +3321,38 @@ return; } if (macro_if_skip) return; - if (macroeq("define")) { + if (macroeq("define")) { macro_define0(); *(chptr = linebuf) = '\0'; - } else if (macroeq("undef")) { + } else if (macroeq("undef")) { i=mode; mode=LDECL; ch= *chptr; - if (getsym() == IDENT) { - if (nptr->sc == MACRO) { + if (getsym() == IDENT) { + if (nptr->sc == MACRO) { nptr->sc = EMPTY; - } else if (nptr->sc == FMACRO) { + } else if (nptr->sc == FMACRO) { nptr->sc = EMPTY; /* we cannot reclaim it's arg */ } else error(MCERR); } mode=i; - } else if (macroeq("include")) { + } else if (macroeq("include")) { if(filep+1 >= filestack + FILES) error(FILERR); if ( ((filep+1)->fcb=getfname()) == NULL) error(FILERR); (filep+1)->ln=lineno; lineno=0; ++filep; *(chptr = linebuf) = '\0'; - } else if (macroeq("asm")) { + } else if (macroeq("asm")) { if (asmf) error(MCERR); asmf = 1; getline(); - while (asmf) { + while (asmf) { gen_source(linebuf); getline(); } - } else if (macroeq("endasm")) { + } else if (macroeq("endasm")) { if (!asmf) error(MCERR); asmf = 0; } else if (macroeq(" ")) @@ -3378,7 +3401,7 @@ args = macro_args(&cheapp,cheap+CHEAPSIZE,&chptr); } else { nptr->sc = MACRO; - nptr->ty = -1; + nptr->ty = -1; } nptr->dsp = list2((int)cheapp,args); /* macro body */ while ((*cheapp++ = c = *chptr++) @@ -3395,7 +3418,7 @@ mode=i; } -static int +static int macro_args(char **pcheapp,char *maxcheap,char **pchptr) { int c; @@ -3514,9 +3537,9 @@ { NMTBL *nptr0; nptr0 = msearch0(macro); - nptr0->ty=list3(nptr0->sc,nptr0->ty,nptr0->dsp); - nptr0->sc=MACRO; - nptr0->dsp=list2((int)value,0); + nptr0->ty=list3(nptr0->sc,nptr0->ty,nptr0->dsp); + nptr0->sc=MACRO; + nptr0->dsp=list2((int)value,0); } static void @@ -3526,9 +3549,9 @@ int save; nptr0 = msearch0(macro); save = nptr0->ty; - nptr0->sc=car(save); - nptr0->dsp=caddr(save); - nptr0->ty=cadr(save); + nptr0->sc=car(save); + nptr0->dsp=caddr(save); + nptr0->ty=cadr(save); } static int @@ -3730,11 +3753,11 @@ void display_ntable(NMTBL *n, char *s) { - fprintf(stderr,"\n%s %0x %0x ",s,(int)n,(int)ntable); - fprintf(stderr,"nptr->sc %d ",n->sc); - fprintf(stderr,"nptr->dsp %d ",n->dsp); - fprintf(stderr,"nptr->ty %d ",n->ty); - fprintf(stderr,"nptr->nm %s\n",n->nm); + fprintf(stderr,"\n%s %0x %0x ",s,(int)n,(int)ntable); + fprintf(stderr,"nptr->sc %d ",n->sc); + fprintf(stderr,"nptr->dsp %d ",n->dsp); + fprintf(stderr,"nptr->ty %d ",n->ty); + fprintf(stderr,"nptr->nm %s\n",n->nm); } int c0(int d) { fprintf(stderr,"heap[%d]=",d);return car(d); }
--- a/mc.h Sun Mar 09 18:31:00 2003 +0900 +++ b/mc.h Wed Mar 12 15:28:44 2003 +0900 @@ -60,7 +60,8 @@ #define FLOAT (-46) #define DOUBLE (-47) -#define LONGLONG (-48) +#define DREGISTER (-48) +#define LONGLONG (-49) #define TOP 0 #define GDECL 1 @@ -318,5 +319,7 @@ EXTERN void display_ntable(NMTBL *n, char *s); EXTERN void exit(int l); EXTERN void fwddef(int l); +EXTERN int new_lvar(int size); + /* end */
--- a/test/call.c Sun Mar 09 18:31:00 2003 +0900 +++ b/test/call.c Wed Mar 12 15:28:44 2003 +0900 @@ -1,4 +1,6 @@ +int +a0(int i); int (*conv)(int);
--- a/test/float.c Sun Mar 09 18:31:00 2003 +0900 +++ b/test/float.c Wed Mar 12 15:28:44 2003 +0900 @@ -1,11 +1,11 @@ #include "stdio.h" -void test2(double); void test1(); void print(double d); extern double sin(double); // extern float fsin(float); +double test2(double f,int i); float f = 0.3; double d = 0.3; @@ -64,7 +64,7 @@ i = f; f = i; printf("\n%d %g %f",i,d,f); - f = g = d = g = d = f; + f = g = d = d1 = d2 = f; printf(" %d %g %f %g\n",i,d,f,g); d = 4204967294.4234; f=4204967294.4234; @@ -80,6 +80,7 @@ print(1.234e-10); test1(); + printf("nested call: %g\n",test2(test2(test2(test2(-0.333,3),5),6),7)); return 0; } @@ -298,3 +299,14 @@ return; } + +double +test2(double f,int i) +{ + double g,h; + + if (i<=0) return f; + g = f*2; + h = f-0.5; + return h/3-(3.0-(g+3)*test2(f*0.5,i-1)/(h-1)); +}