Mercurial > hg > CbC > old > device
changeset 83:f3f75911d62c
*** empty log message ***
author | kono |
---|---|
date | Wed, 05 Mar 2003 03:41:08 +0900 |
parents | 25654dc29ecc |
children | 1a723130a2c7 |
files | mc-code-ia32.c mc-code.h mc-codegen.c mc-codegen.h mc-parse.c mc.h |
diffstat | 6 files changed, 199 insertions(+), 94 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-code-ia32.c Wed Mar 05 00:39:39 2003 +0900 +++ b/mc-code-ia32.c Wed Mar 05 03:41:08 2003 +0900 @@ -43,16 +43,12 @@ int size_of_double = 8; int size_of_longlong = 8; int endian = 0; -int MAX_REGISTER=6; /* intel386のレジスタを4つまで使う*/ +int MAX_REGISTER=6; /* intel386のレジスタを6つまで使う*/ int REAL_MAX_REGISTER=8; /* intel386のレジスタが8つということ*/ int MAX_DATA_REG=4; int MAX_POINTER=3; int MAX_REGISTGER_VAR=2; - -EXTERN int creg; /* current register */ -EXTERN int dreg; /* temporary register */ -EXTERN int freg; /* current floating point register */ -EXTERN int reg_sp; /* REGister Stack-Pointer */ +int MAX_FREGISTER=1; #define REG_EAX 0 @@ -71,17 +67,6 @@ static char *reg_name_l[4]; static char *reg_name_w[4]; -extern int creg; /* current register */ -extern int dreg; /* temporary register */ -extern int reg_sp; /* REGister Stack-Pointer */ - -#define MAX_MAX 10 -int rname[MAX_MAX]; -int regs[MAX_MAX]; /* 使われているレジスタを示すフラグ */ -int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ -int regv[MAX_MAX]; /* 値が入っているかどうか */ - - void use_register(int virt, int real, int move); void code_preinc(int e1,int e2) ; void code_cmp_register(int e2) ; @@ -167,13 +152,10 @@ } } -extern int creg_regvar; - void gexpr_code_init(void){ use_register(creg,REG_EAX,0); regv[dreg]=0; - creg_regvar = -1; } int @@ -250,6 +232,7 @@ int new_reg; new_reg = get_register(); if(new_reg<0) { /* もうレジスタがない */ + if (reg_sp>=MAX_MAX) error(-1); reg_stack[reg_sp++] = -1; printf("\tpushl %s\n",register_name(creg,0)); /* creg is used soon, don't regv[creg]=0 */ @@ -734,13 +717,13 @@ } else if (t==DOUBLE) { g_expr(e4); printf("\tleal\t-8(%%esp),%%esp\n\tfstpl\t(%%esp)\n"); - regv[freg]=0; + fregv[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; + fregv[freg]=0; nargs += size_of_float/size_of_int; continue; } else if (car(t)==STRUCT||car(t)==UNION) { @@ -781,7 +764,7 @@ } regv[save]=0; regv[creg]=1; - regv[freg]=1; /* return type はどこ? fnptr にはあるけど... */ + fregv[freg]=1; /* return type はどこ? fnptr にはあるけど... */ } void @@ -1174,7 +1157,7 @@ fwddef(retlabel); /* use_register(creg,REG_EAX,0); too late */ /* if(disp) printf("\taddl $%d,%%esp\n",-disp); */ - disp&= -size_of_int; + disp &= -size_of_int; printf("\tlea %d(%%ebp),%%esp\n",disp_offset); printf("\tpopl %%edi\n"); @@ -1363,6 +1346,15 @@ char * fstore(int d) { + return use? + (d?"fstl":"fsts"): + (d?"fstpl":"fstps") + ; +} + +char * +fstore_u(int d) +{ return d?"fstpl":"fstps"; } @@ -1490,6 +1482,42 @@ } } +void +code_dassop(int op,int d) { + /* we have lvalue in creg, applied floating value is in %st(0) */ + printf("\t%s (%s)\n",fload(d),register_name(creg,0)); + dtosop(op,0); + printf("\t%s (%s)\n",fstore(d),register_name(creg,0)); +} + +void +code_dpreinc(int e1,int e2,int d) { + g_expr(e2); + printf("\t%s (%s)\n",fload(d),register_name(creg,0)); + printf("\tfld1\n"); + if (e2>0) + printf("\tfaddp %%st,%%st(1)\n"); + else + printf("\tfsubrp %%st,%%st(1)\n"); + printf("\t%s (%s)\n",fstore(d),register_name(creg,0)); +} + +void +code_dpostinc(int e1,int e2,int d) { + g_expr(e2); + printf("\t%s (%s)\n",fload(d),register_name(creg,0)); + if (use) + /* dup */; + printf("\tfld1\n"); + if (e2>0) + printf("\tfaddp %%st,%%st(1)\n"); + else + printf("\tfsubrp %%st,%%st(1)\n"); + printf("\t%s (%s)\n",fstore_u(d),register_name(creg,0)); + if (use) + /* pop */; +} + int dpop_register() { return 1;
--- a/mc-code.h Wed Mar 05 00:39:39 2003 +0900 +++ b/mc-code.h Wed Mar 05 03:41:08 2003 +0900 @@ -2,6 +2,15 @@ mc-code-*.c have to provied these */ +extern int size_of_int; +extern int size_of_float; +extern int size_of_double; +extern int size_of_longlong; +extern int endian; +extern int MAX_REGISTER; +extern int MAX_REGISTGER_VAR; +extern int MAX_FREGISTER; + extern char *register_name(int i,int byte); extern void gexpr_code_init(void); extern int register_var(int r); @@ -87,3 +96,6 @@ extern void code_i2d(); extern void code_d2i(); +extern void code_dpreinc(int e1,int e2,int d); +extern void code_dpostinc(int e1,int e2,int d); +extern void code_dassop(int op,int d);
--- a/mc-codegen.c Wed Mar 05 00:39:39 2003 +0900 +++ b/mc-codegen.c Wed Mar 05 03:41:08 2003 +0900 @@ -10,7 +10,23 @@ int dreg; /* temporary register */ int reg_sp; /* REGister Stack-Pointer */ +int rname[MAX_MAX]; +int regs[MAX_MAX]; /* 使われているレジスタを示すフラグ */ +int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ +int regv[MAX_MAX]; /* 値が入っているかどうか */ + +/* floating point registers */ + int freg; /* current floating point register */ +int greg; /* current floating point register */ +int freg_sp; /* floating point REGister Stack-Pointer */ + +int frname[MAX_MAX]; +int fregs[MAX_MAX]; /* 使われているレジスタを示すフラグ */ +int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ +int fregv[MAX_MAX]; /* 値が入っているかどうか */ + +int use; /* generated value will be used */ /* creg currrent virtual register @@ -23,6 +39,9 @@ regv[] value in virtual register flag reg_name[rname[creg]] + + freg current floating point register + fregv calue in floating point register */ void remove0(int *parent,int e) ; @@ -33,6 +52,7 @@ void sassign(int e1); void assign(int e1); void assop(int e1); +void g_expr0(int e1); int get_register(void) @@ -119,24 +139,6 @@ arg_register0(fnptr->dsp); } - -int creg_regvar = -1; -static int creg_regvar_back; -static int creg_back; - -void -creg_destroy() { - creg_back = creg; creg_regvar_back = creg_regvar; - if (creg_regvar>=0) - creg = creg_regvar; - creg_regvar=-1; -} - -void -creg_un_destroy() { - creg = creg_back; creg_regvar = creg_regvar_back; -} - void register_usage(char *s) { @@ -219,17 +221,18 @@ } void -gexpr(int e1) +gexpr(int e1,int use0) { if (chk) return; gexpr_init(); + use = use0; #if 0 if(lineno==2862) { - g_expr(e1); /*break here*/ + g_expr0(e1); /*break here*/ return; } #endif - g_expr(e1); + g_expr0(e1); } int @@ -239,9 +242,25 @@ } void +g_expr_u(int e1) +{ + int suse = use; use=0; + g_expr0(e1); + use=suse; +} + +void g_expr(int e1) { - int e2,e3/*,e4*/; + int suse = use; use=1; + g_expr0(e1); + use=suse; +} + +void +g_expr0(int e1) +{ + int e2,e3; NMTBL *n; e2 = cadr(e1); @@ -279,19 +298,19 @@ return; case FRLVAR: code_drlvar(lvar(e2),0); - regv[freg]=1; + fregv[freg]=1; return; case FRGVAR: code_drgvar(e1,0); - regv[freg]=1; + fregv[freg]=1; return; case DRLVAR: code_drlvar(lvar(e2),1); - regv[freg]=1; + fregv[freg]=1; return; case DRGVAR: code_drgvar(e1,1); - regv[freg]=1; + fregv[freg]=1; return; case FNAME: code_fname(((NMTBL *)(e2))->nm); @@ -303,7 +322,7 @@ return; case DCONST: code_dconst(e1); - regv[freg]=1; + fregv[freg]=1; return; case STRING: string(e1); @@ -317,37 +336,37 @@ jump(e2,caddr(e1)); return; case INDIRECT: - g_expr(e2); + g_expr0(e2); return; case RINDIRECT: case CRINDIRECT: case DRINDIRECT: case FRINDIRECT: rindirect(e1); return; case ADDRESS: - g_expr(e2); + g_expr0(e2); return; case MINUS: /* レジスタに対し、neglを実行すれば実現可能 */ - g_expr(e2); + g_expr0(e2); code_neg(); return; case DMINUS: - g_expr(e2); + g_expr0(e2); code_dneg(); return; case I2D: - g_expr(e2); + g_expr0(e2); code_i2d(); return; case D2I: - g_expr(e2); + g_expr0(e2); code_d2i(); return; case BNOT: /* ~ */ - g_expr(e2); + g_expr0(e2); code_not(); return; case LNOT: /* ! */ - g_expr(e2); + g_expr0(e2); code_lnot(); return; case PREINC: @@ -356,6 +375,18 @@ case POSTINC: code_postinc(e1,e2); return; + case DPREINC: + code_dpreinc(e1,e2,1); + return; + case DPOSTINC: + code_dpostinc(e1,e2,1); + return; + case FPREINC: + code_dpreinc(e1,e2,0); + return; + case FPOSTINC: + code_dpostinc(e1,e2,0); + return; case CPOSTINC: /* char *p; *p++ */ code_cpostinc(e1,e2); @@ -385,13 +416,13 @@ e2=fwdlabel(); b_expr(cadr(e1),0,e2,0); code_set_fixed_creg(0); - g_expr(caddr(e1)); + g_expr0(caddr(e1)); /* e4 = rname[creg]; this is a bad idea */ code_set_fixed_creg(1); jmp(e3=fwdlabel()); fwddef(e2); code_set_fixed_creg(0); - g_expr(cadddr(e1)); + g_expr0(cadddr(e1)); code_set_fixed_creg(1); fwddef(e3); return; @@ -411,11 +442,11 @@ dassop(e1); return; case RSTRUCT: - g_expr(e2); + g_expr0(e2); return; case COMMA: - g_expr(e2); - g_expr(caddr(e1)); + g_expr_u(e2); + g_expr0(caddr(e1)); return; case RETURN: n = (NMTBL *)e2; @@ -546,10 +577,9 @@ if((dcadr(e2)!=0.0)^cond) jmp(l1); return; default: - /* type ? */ if(err) { error(-1); return; /* recursive g_expr/b_expr */ - } + } /* type ? */ g_expr(e1); code_cmp_register(creg); jcond(l1,cond); @@ -611,11 +641,11 @@ if (sz==size_of_int && (e1=get_register())!=-1) { *use=list3(t,*use,e1); e1=list2(REGISTER,e1); - g_expr(assign_expr0(e1,s,ty,ty)); + g_expr_u(assign_expr0(e1,s,ty,ty)); *target = append4(*target,t,ty,e1); } else { disp-=sz; - g_expr(assign_expr0((e1=list2(LVAR,disp)),s,ty,ty)); + g_expr_u(assign_expr0((e1=list2(LVAR,disp)),s,ty,ty)); *target = append4(*target,t,ty,e1); } } @@ -667,7 +697,7 @@ #if DEBUG_PARALLEL_ASSIGN printf("# normal assign %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); #endif - g_expr(assign_expr0(t,s,ty,ty)); + g_expr_u(assign_expr0(t,s,ty,ty)); remove_target(target,t,use); remove0(source,s); } else { if(circular_dependency(t,s1,target,source)) { @@ -791,7 +821,7 @@ } if (!is_simple(car(s0))) { disp-=sz; - g_expr(assign_expr0((e4=list2(LVAR,disp)),s0,ty,ty)); + g_expr_u(assign_expr0((e4=list2(LVAR,disp)),s0,ty,ty)); cadddr(e2)=e4; s0=e4; } else if (is_same_type(t0,s0)) { @@ -884,7 +914,7 @@ g_expr(e2); dtosop(car(e1),(e2=dpop_register())); emit_dpop_free(e2); - regv[freg]=1; + fregv[freg]=1; return; } @@ -1014,11 +1044,21 @@ void dassop(int e1) { -} + int e2,e3,op,d; -void -fassop(int e1) -{ + /* e2 op= e3 */ + d = (car(e1) == DASSOP); + e2 = cadr(e1); + if (car(e2)==INDIRECT) e2=cadr(e2); + e3 = caddr(e1); + op = cadddr(e1); + + g_expr(e3); + emit_dpush(); + g_expr(e2); + code_dassop(op,d); + regv[creg]=1; + return; } int
--- a/mc-codegen.h Wed Mar 05 00:39:39 2003 +0900 +++ b/mc-codegen.h Wed Mar 05 03:41:08 2003 +0900 @@ -1,19 +1,31 @@ + +/* max stack in an expression (for each int, float ) */ +#define MAX_MAX 10 extern int creg; /* current register */ extern int dreg; /* temporary register */ extern int reg_sp; /* REGister Stack-Pointer */ -extern int rname[]; -extern int regs[]; /* 使われているレジスタを示すフラグ */ -extern int reg_stack[]; /* 実際のレジスタの領域 */ -extern int regv[]; /* 値が入っているかどうか */ -extern int MAX_REGISTER; +extern int rname[MAX_MAX]; +extern int regs[MAX_MAX]; /* 使われているレジスタを示すフラグ */ +extern int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ +extern int regv[MAX_MAX]; /* 値が入っているかどうか */ + +/* floating point registers */ -extern int creg_regvar; +extern int freg; /* current floating point register */ +extern int greg; /* current floating point register */ +extern int freg_sp; /* floating point REGister Stack-Pointer */ + +extern int frname[MAX_MAX]; +extern int fregs[MAX_MAX]; /* 使われているレジスタを示すフラグ */ +extern int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ +extern int fregv[MAX_MAX]; /* 値が入っているかどうか */ + +extern int use; /* generated value will be used */ /* function provided by mc-codegen.c */ - extern void def_label(int cslabel, int dlabel); extern int backdef(void); extern int csvalue(); @@ -47,7 +59,7 @@ 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); +extern void 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 Wed Mar 05 00:39:39 2003 +0900 +++ b/mc-parse.c Wed Mar 05 03:41:08 2003 +0900 @@ -850,7 +850,7 @@ if (!init_vars) return; init_vars = reverse0(init_vars); while(init_vars) { - gexpr(car(init_vars)); + gexpr(car(init_vars),0); init_vars = cadr(init_vars); } } @@ -1287,7 +1287,7 @@ statement(); } else { slfree=lfree; - gexpr(expr(0)); + gexpr(expr(0),0); lfree=slfree; conv->sm_(); checksym(SM); @@ -1400,7 +1400,7 @@ checksym(LPAR); slfree=lfree; if(sym!=SM) { - gexpr(expr(0)); + gexpr(expr(0),0); checksym(SM); conv->for1_(); } else { @@ -1432,7 +1432,7 @@ statement(); checkret(); fwddef(clabel); - gexpr(e); + gexpr(e,0); lfree=slfree; } conv->for_end_(); @@ -1457,7 +1457,7 @@ checksym(LPAR); slfree=lfree; svalue=csvalue1; /* save parents switch value */ - gexpr(expr(0)); + gexpr(expr(0),1); csvalue1=csvalue() ; lfree=slfree; checksym(RPAR); @@ -1547,20 +1547,21 @@ if ((car(type)==STRUCT || car(type)==UNION)&& size(type)==cadr(struct_return)) { if(car(e)==RSTRUCT && car(cadr(e))==FUNCTION) { + /* pass the return pointer to the called function */ replace_return_struct(cadr(e), rvalue_t(car(struct_return),caddr(struct_return))); - gexpr(cadr(e)); + gexpr(cadr(e),0); } else { e = rvalue(e); type = caddr(struct_return); e1 = rvalue_t(cadr(struct_return),INT); /* size */ - gexpr(list4(SASS,rvalue(car(struct_return)),e,e1)); + gexpr(list4(SASS,rvalue(car(struct_return)),e,e1),0); } } else { error(TYERR); /* should check compatible */ } } else { - gexpr(expr(0)); + gexpr(expr(0),1); } lfree=slfree; conv->return_end_(); @@ -1616,7 +1617,7 @@ nptr0=(NMTBL *)cadr(e2); nptr0->sc = CODE; } - gexpr(list3(CODE,e1,env)); + gexpr(list3(CODE,e1,env),0); control=0; conv->sm_(); checksym(SM); @@ -1976,6 +1977,10 @@ } if(integral(type)) return(list3(PREINC,e,op==INC?1:-1)); + if(type==FLOAT) + return(list3(FPREINC,e,op==INC?1:-1)); + if(type==DOUBLE) + return(list3(DPREINC,e,op==INC?1:-1)); if(car(type)!=POINTER) error(TYERR); return(list3(PREINC,e, @@ -2043,7 +2048,7 @@ if(sym==INC||sym==DEC) { getsym(); if(type==CHAR) type=INT; - else if(!scalar(type)) + else if(!scalar(type)&&type!=FLOAT&&type!=DOUBLE) error(TYERR); } } @@ -2064,6 +2069,10 @@ } if(integral(type)) return(list3(POSTINC,e,op==INC?1:-1)); + if(type==FLOAT) + return(list3(FPOSTINC,e,op==INC?1:-1)); + if(type==DOUBLE) + return(list3(DPOSTINC,e,op==INC?1:-1)); if(car(type)!=POINTER) error(TYERR); return (list3(POSTINC,e,
--- a/mc.h Wed Mar 05 00:39:39 2003 +0900 +++ b/mc.h Wed Mar 05 03:41:08 2003 +0900 @@ -178,10 +178,14 @@ #define I2D 97 #define D2I 98 +#define FPOSTINC 99 +#define DPOSTINC 100 +#define FPREINC 101 +#define DPREINC 102 #define US 1 #define AS 200 -#define DOP 300 +#define DOP 400 #define FILERR 1 #define DCERR 2