Mercurial > hg > CbC > old > device
changeset 99:53899975154c
*** empty log message ***
author | kono |
---|---|
date | Fri, 14 Mar 2003 21:33:03 +0900 |
parents | 07c2554e1cfa |
children | a9e6f2a2946f |
files | Changes mc-code-ia32.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-codegen.h |
diffstat | 6 files changed, 221 insertions(+), 69 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Fri Mar 14 12:34:47 2003 +0900 +++ b/Changes Fri Mar 14 21:33:03 2003 +0900 @@ -2141,3 +2141,15 @@ なんか、emit_pop_free のxregがLVARの時のバグを取るのに苦労した... gdb は top level でのwhile を受け付けなくて、define してやなんないと だめみたいね。 + +Fri Mar 14 15:50:28 JST 2003 + +なぁ... 書いても書いても書いても、終らん! + +Fri Mar 14 19:43:44 JST 2003 + +jump の中で input register を割り振るときに floating point register の +ことを考えてなかった。これは register_var とは異なるので異なる +仕組みで割り振る必要がある。ってことは、get_input_register_var +が要るってこと? +
--- a/mc-code-ia32.c Fri Mar 14 12:34:47 2003 +0900 +++ b/mc-code-ia32.c Fri Mar 14 21:33:03 2003 +0900 @@ -53,6 +53,9 @@ int MAX_REGISTGER_VAR=2; int MAX_FREGISTER=1; +int max_input_register_var = 2; +int max_input_fregister_var = 0; + /* creg currrent virtual register dreg spare virtual register @@ -193,6 +196,30 @@ regv[i]=regs[i]=0; } +int +get_input_register_var(int i) +{ + return virtual(i+REG_ESI); +} +int + +get_input_fregister_var(int i) +{ + error(-1); + return -1; +} + +int +get_fregister(void) +{ + return -1; +} + +void +free_fregister(int i) { + error(-1); +} + int register_full(void) {
--- a/mc-code-powerpc.c Fri Mar 14 12:34:47 2003 +0900 +++ b/mc-code-powerpc.c Fri Mar 14 21:33:03 2003 +0900 @@ -66,8 +66,6 @@ #define REG_sp 30 #define REG_VAR_BASE 29 #define REG_VAR_MIN 22 -#define REG_ARG_BASE 3 -#define REG_ARG_MAX 10 #define MIN_TMP_REG 3 #define MAX_TMP_REG 12 @@ -77,8 +75,6 @@ #define FREG_VAR_BASE 31 #define FREG_VAR_MIN 24 -#define FREG_ARG_BASE 1 -#define FREG_ARG_MAX 13 #define MIN_TMP_FREG 1 #define MAX_TMP_FREG 12 @@ -86,8 +82,9 @@ int MAX_FREGISTER=30; #define REAL_MAX_REGISTER 32 /* PowerPCのレジスタが32ということ*/ #define REAL_MAX_FREGISTER 32 /* PowerPCのレジスタが32ということ*/ -int MAX_REGISTGER_VAR=REG_VAR_BASE-REG_VAR_MIN; -int MAX_FREGISTGER_VAR=FREG_VAR_BASE-FREG_VAR_MIN; + +int max_input_register_var = MAX_TMP_REG-MIN_TMP_REG; +int max_input_fregister_var = MAX_TMP_FREG-MIN_TMP_FREG; int powerpc_regs[REAL_MAX_REGISTER]; int powerpc_regv[REAL_MAX_REGISTER]; @@ -127,6 +124,7 @@ int fregister_var(int r); int get_fregister_var(void); void use_fregister_var(int r); +int arg_offset_v(int arg); void code_init(void) @@ -148,9 +146,24 @@ } int -replace_arg_var(int n,int type) +replace_arg_var(int reg,int type) { - fnptr->dsp; + int arglist=fnptr->dsp; + int nargs=0; + int lvar; + NMTBL *n; + while(arglist) { + n = (NMTBL*)caddr(arglist); + if (n->sc==REGISTER && n->dsp==reg) { + if (n->ty!=type) error(-1); + lvar = arg_offset_v(nargs); + n->sc=LVAR; n->dsp = lvar; + return lvar; + } + nargs++; + } + error(-1); + return 0; } int @@ -237,6 +250,18 @@ } int +get_input_fregister_var(int i) +{ + return i+MIN_TMP_FREG; +} + +int +get_input_register_var(int i) +{ + return i+MIN_TMP_REG; +} + +int register_full(void) { int i; @@ -270,27 +295,21 @@ } void -set_register_var() { -} - -void -set_fregister_var() { -} - -void code_arg_register(int args) { NMTBL *n; + /* all registers are freed at this time */ + /* set up input regsiters */ if (args) { /* process in reverse order */ n = (NMTBL*)caddr(args); if(n->sc==REGISTER) { - if ((n->dsp = get_register_var()) <0) { + if ((n->dsp = get_register()) <0) { error(-1); return; } use_register_var(n->dsp); /* it has now value in it */ } else if(n->sc==DREGISTER) { - if ((n->dsp = get_fregister_var()) <0) { + if ((n->dsp = get_fregister()) <0) { error(-1); return; } use_fregister_var(n->dsp); /* it has now value in it */ @@ -348,7 +367,7 @@ int register_var(int r) { - return REG_VAR_BASE-r; + return r; } @@ -356,7 +375,7 @@ get_register_var(void) { int i; - for(i=0;i<MAX_REGISTGER_VAR;i++) { + for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ regs[REG_VAR_BASE-i]=USING_REG; /* そのレジスタを使うことを宣言し */ regv[REG_VAR_BASE-i]=0; @@ -369,14 +388,14 @@ int fregister_var(int r) { - return FREG_VAR_BASE-r; + return r; } int get_fregister_var(void) { int i; - for(i=0;i<MAX_FREGISTGER_VAR;i++) { + for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) { if (! regs[FREG_VAR_BASE-i]) { /* 使われていないなら */ regs[FREG_VAR_BASE-i]=USING_REG; /* そのレジスタを使うことを宣言し */ regv[FREG_VAR_BASE-i]=0; @@ -980,54 +999,51 @@ int arg_offset_v(int arg) { - return arg; + return arg*size_of_int+0; } int function(int e1) { int e2,e3,e4,e5,nargs,t; - int reg_arg,freg_arg; + int arg,reg_arg,freg_arg; + int reg_arg_list; NMTBL *n; int jmp; char *jrn,*crn; code_save_stacks(); code_save_registers(); + /* now all input register vars are free */ e2 = cadr(e1); - nargs = 0; - reg_arg = REG_ARG_BASE; - freg_arg = FREG_ARG_BASE; + reg_arg_list = nargs = reg_arg = freg_arg = 0; for (e3 = caddr(e1); e3; e3 = cadr(e3)) { t=caddr(e3); n=(NMTBL *)(e5=(cadr(e4 = car(e3)))); if(scalar(t)) { - g_expr(e4); - if (reg_arg<REG_ARG_MAX) { - printf("\tmr %s,%s\n",register_name(reg_arg), - register_name(creg)); - regs[reg_arg]=1; + if (reg_arg<max_input_register_var) { + arg = list2(LVAR,arg_offset_v(nargs)); + } else if (contains(e3,FUNCTION)) { + arg = list2(REGISTER,get_register_var()); regv[cadr(arg)]=1; } else { - printf("\tstw %s,%d(r1)\n",register_name(creg), - arg_offset_v(nargs)); + arg = list2(REGISTER,get_register()); regv[cadr(arg)]=1; } + reg_arg_list = list2(arg,reg_arg_list); + g_expr_u(assign_expr0(arg,e4,t,t)); nargs ++ ; reg_arg++; + continue; } else if (t==DOUBLE||t==FLOAT) { - g_expr(e4); + if (freg_arg<max_input_fregister_var) { + arg = list2(LVAR,arg_offset_v(nargs)); + } else if (contains(e3,FUNCTION)) { + arg = list2(DREGISTER,get_fregister_var()); fregv[cadr(arg)]=1; + } else { + arg = list2(DREGISTER,get_fregister()); fregv[cadr(arg)]=1; + } + reg_arg_list = list2(arg,reg_arg_list); + g_expr_u(assign_expr0(arg,e4,t,t)); + freg_arg++; nargs += size_of_double/size_of_int; - if (freg_arg<FREG_ARG_MAX) - printf("\tmr %s,%s\n",register_name(reg_arg++), - register_name(freg)); - else if(t==DOUBLE) { - printf("\tstfd %s,%d(r1)\n",register_name(freg), - arg_offset_v(nargs)); - nargs+=size_of_double/size_of_int; - } else { - printf("\tstfs %s,%d(r1)\n",register_name(freg), - arg_offset_v(nargs)); - nargs+=size_of_float/size_of_int; - } - freg_arg++; continue; } else if (car(t)==STRUCT||car(t)==UNION) { nargs += struct_push(e4,t); @@ -1057,10 +1073,11 @@ printf("\tbctrl\n"); free_register(jmp); } - for(;reg_arg>=REG_ARG_BASE;reg_arg--) - regs[reg_arg]=regv[reg_arg]=0; - for(;freg_arg>=FREG_ARG_BASE;freg_arg--) - fregs[freg_arg]=fregv[freg_arg]=0; + for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) { + if (car(reg_arg_list)==DREGISTER) free_fregister(cadr(reg_arg_list)); + else if (car(reg_arg_list)==REGISTER) free_register(cadr(reg_arg_list)); + } + if (fnptr->ty==DOUBLE||fnptr->ty==FLOAT) { fregv[freg]=1; regv[creg]=0; } else if (fnptr->ty==VOID) { @@ -1423,16 +1440,14 @@ void code_set_fixed_creg(int mode) { - creg=11; + creg=0; } void gen_gdecl(char *n, int gpc) { - /* if (stmode!=STATIC) - printf(".globl %s\n",n); - */ + printf(".globl _%s\n",n); } void @@ -1482,7 +1497,7 @@ } } else if(t==DOUBLE) { d = dcadr(e); - printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d)); + printf("\t.long\t0x%x,0x%x\n",code_d2(d),code_d1(d)); } else if(t==FLOAT) { f = dcadr(e); printf("\t.long\t0x%x\n",*(int *)&f); @@ -1666,11 +1681,23 @@ void code_cmp_fregister(int e2) { + char *frn,*rrn,*grn; + int greg,r; + grn = register_name(greg = get_fregister()); + frn = register_name(freg); + float_zero_lib_used=1; + r = get_ptr_cache("_float_zero"); + rrn = register_name(r); + printf("\tfls %s,(%s)\n",grn,rrn); + printf("\tfcmpu cr0,%s,%s\n",grn,frn); + free_fregister(greg); + return; } void code_fregister(int e2) { + printf("\tfmr %s,%s\n",register_name(freg),register_name(e2)); } void code_dassign_gvar(int e2,int d) @@ -1696,14 +1723,14 @@ code_d1(double d) { int *i = (int *)&d0; int *j = (int *)&d; - return (i[1] == 0x3ff00000)?j[1]:j[0]; + 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[0]:j[1]; + return (i[1] == 0x3ff00000)?j[1]:j[0]; } void code_dconst(int e2) @@ -1731,7 +1758,7 @@ 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)); + printf("\t.long\t0x%x,0x%x\n",code_d2(d),code_d1(d)); if (output_mode==TEXT_EMIT_MODE) { printf(".text\n"); } else {
--- a/mc-code.h Fri Mar 14 12:34:47 2003 +0900 +++ b/mc-code.h Fri Mar 14 21:33:03 2003 +0900 @@ -10,12 +10,17 @@ extern int MAX_REGISTER; extern int MAX_REGISTGER_VAR; extern int MAX_FREGISTER; +extern int max_input_register_var; +extern int max_input_fregister_var; + #define REG_LVAR_OFFSET 2 extern char *register_name(int i,int byte); extern void gexpr_code_init(void); extern int register_var(int r); extern int get_register_var(void); +extern int get_input_register_var(int); +extern int get_input_fregister_var(int); extern void emit_push(void); extern void emit_push_x(int xreg); extern int emit_pop(int type); @@ -111,7 +116,9 @@ extern void code_arg_register(int); extern int get_register(void); +extern int get_fregister(void); extern void free_register(int i) ; +extern void free_fregister(int i) ; extern int pop_register(void); extern void emit_pop_free(int xreg);
--- a/mc-codegen.c Fri Mar 14 12:34:47 2003 +0900 +++ b/mc-codegen.c Fri Mar 14 21:33:03 2003 +0900 @@ -480,7 +480,10 @@ int use0=*use; while(use0) { if (car(use0)==t) { - free_register(caddr(use0)); + if (car(caddr(use0))==REGISTER) + free_register(cadr(caddr(use0))); + else if (car(caddr(use0))==DREGISTER) + free_fregister(cadr(caddr(use0))); break; } use0 = cadr(use0); @@ -494,8 +497,13 @@ int e1; /*新しいレジスタ(or スタック)を取得する*/ if (sz==size_of_int && (e1=get_register())!=-1) { + e1=list2(REGISTER,e1); *use=list3(t,*use,e1); - e1=list2(REGISTER,e1); + g_expr_u(assign_expr0(e1,s,ty,ty)); + *target = append4(*target,t,ty,e1); + } else if (sz==size_of_double && (e1=get_fregister())!=-1) { + e1=list2(DREGISTER,e1); + *use=list3(t,*use,e1); g_expr_u(assign_expr0(e1,s,ty,ty)); *target = append4(*target,t,ty,e1); } else { @@ -597,7 +605,7 @@ is_simple(int e1) { return ( - e1==CONST || e1==FNAME || e1==LVAR || e1==REGISTER || + e1==CONST || e1==FNAME || e1==LVAR || e1==REGISTER ||e1==DREGISTER || e1==GVAR || e1==RGVAR || e1==RLVAR || e1==CRLVAR || e1==CRGVAR || e1==DRLVAR || e1==FRLVAR ); @@ -623,7 +631,7 @@ return ( ce1==LVAR ||ce1==RLVAR||ce1==CRLVAR || ce1==DRLVAR || ce1==GVAR ||ce1==RGVAR||ce1==CRGVAR || ce1==DRGVAR || - ce1==REGISTER + ce1==REGISTER|| ce1==DREGISTER ); } @@ -645,7 +653,7 @@ void jump(int e1, int env) { - int e2,e3,e4,sz,arg_size,ty,max_regs,regs; + int e2,e3,e4,sz,arg_size,ty,regs,fregs; int t0,s0; NMTBL *code0; int target = 0; @@ -655,11 +663,16 @@ /* まず、サイズを計算しながら、決まった形に落す。 */ - arg_size = 0; regs = 0; max_regs = MAX_REGISTER_VAR-1; + arg_size = 0; regs = 0; + fregs = 0; for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { e2 = car(e3); sz = size(ty=caddr(e3)); - if (regs <= max_regs&&sz==size_of_int) { - target=list4(list2(REGISTER,register_var(regs++)), target,ty,e2); + if (scalar(ty) && regs < max_input_register_var&&sz==size_of_int) { + target=list4(list2(REGISTER,get_input_register_var(regs++)), + target,ty,e2); + } else if ((ty==DOUBLE||ty==FLOAT) && fregs < max_input_fregister_var) { + target=list4(list2(DREGISTER,get_input_fregister_var(fregs++)), + target,ty,e2); } else { target=list4(list2(LVAR,0), target,ty,e2); arg_size += sz; @@ -730,7 +743,11 @@ parallel_assign(&target,&source,&processing,&use); while (use) { - free_register(caddr(use)); use=cadr(use); + if (car(caddr(use))==REGISTER) + free_register(cadr(caddr(use))); + else if (car(caddr(use))==DREGISTER) + free_fregister(cadr(caddr(use))); + use=cadr(use); } if(target) error(-1); @@ -1005,4 +1022,63 @@ code_closing(); } +int +contains_in_list(int e,int type) +{ + while(e) { + if(contains(car(e),type)) return 1; + e = cadr(e); + } + return 0; +} + +int +contains(int e,int type) +{ + while(e) { + if (car(e)==type) return 1; + switch (car(e)){ + /* list arguments */ + case FUNCTION: case CODE: + return contains_in_list(caddr(e),type); + /* unary operators */ + case INDIRECT: case RINDIRECT: case CRINDIRECT: + case DRINDIRECT: case FRINDIRECT: case ADDRESS: case MINUS: case DMINUS: + case I2D: case D2I: case U2D: case D2U: case BNOT: case LNOT: + case PREINC: case POSTINC: case DPREINC: case DPOSTINC: + case FPREINC: case FPOSTINC: case CPOSTINC: + case CPREINC: case CPOSTDEC: case CPREDEC: + case RSTRUCT: + e = cadr(e); + continue; + /* biary operators */ + 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 CMP: + case DMUL: case DDIV: case DADD: case DSUB: case DCMP: case DCMPGE: + case SASS: case ASS: case CASS: case FASS: case DASS: case LASS: + case ASSOP: case CASSOP: case DASSOP: case FASSOP: case COMMA: + if (contains(cadr(e),type)) return 1; + e = caddr(e); + continue; + /* tarary operators */ + case COND: + if (contains(cadr(e), type)) return 1; + if (contains(caddr(e),type)) return 1; + e = cadddr(e); + continue; + default: + /* nullary operators + case GVAR: case RGVAR: case CRGVAR: case LVAR: + case REGISTER: case DREGISTER: + case RLVAR: case CRLVAR: case FRLVAR: case FRGVAR: + case DRLVAR: case DRGVAR: + case FNAME: case CONST: case DCONST: case STRING: + case RETURN: case ENVIRONMENT: */ + return 0; + } + } + return 0; +} + /* end */
--- a/mc-codegen.h Fri Mar 14 12:34:47 2003 +0900 +++ b/mc-codegen.h Fri Mar 14 21:33:03 2003 +0900 @@ -46,6 +46,7 @@ extern void enter(char *name); extern void enter1(); extern int g_expr(int e1); +extern int g_expr_u(int e1); extern void gen_comment(char *s); extern void gen_gdecl(char *n, int gpc); extern void gen_source(char *s); @@ -62,6 +63,8 @@ extern void creg_destroy(); extern void arg_register(NMTBL *fnptr); +extern int contains(int e,int type); + /* floating point */ extern void dassop(int e1);