Mercurial > hg > CbC > old > device
changeset 96:7d8de41390d8
*** empty log message ***
author | kono |
---|---|
date | Thu, 13 Mar 2003 22:48:57 +0900 |
parents | 185d2cc6a3a9 |
children | 6d42fcac07af |
files | Changes mc-code-ia32.c mc-code-powerpc.c test/basic.c test/float.c |
diffstat | 5 files changed, 288 insertions(+), 76 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Thu Mar 13 14:41:48 2003 +0900 +++ b/Changes Thu Mar 13 22:48:57 2003 +0900 @@ -2114,3 +2114,21 @@ Wed Mar 12 12:58:47 JST 2003 比較で入れ換えるとの否定は若干違うよね。 + +Thu Mar 13 19:39:48 JST 2003 + +そういえば、doif で条件が定数だったときとかの最適化は +してないんだね。やさしいけど。chk を使えば良いので。 + + f(g(1,2,3),g(1,2,3),g(1,2,3)) + +とかだと、結局、g の返り値は一旦メモリに入れないとだめじゃん。 +なんだけど、実際は、r29-r22 を使っているようですね。 + +ってことは、function call の時に、r3-r10 が前の引数かどうかを +チェックして、引数だったらr29-r22に移す作業がいるわけだよね。 +いったんr3とかに入れてしまった後だと、重複してしまうが... +前もって関数呼出しがあるかどうかは、調べることができるから、 +関数呼び出しがあったら、そうするようにする? + +いろいろめんどくさいなぁ... (いったい、いつなったらできるんだ?)
--- a/mc-code-ia32.c Thu Mar 13 14:41:48 2003 +0900 +++ b/mc-code-ia32.c Thu Mar 13 22:48:57 2003 +0900 @@ -1759,7 +1759,7 @@ error(-1); } -int dpop_register() +int pop_dregister() { if (freg_sp<0) { error(-1); return -1;} printf("# fpop: %d\n",freg_sp-1); @@ -1770,7 +1770,7 @@ emit_dpop(int type) { int xreg; - if ((xreg=dpop_register())==-1) { + if ((xreg=pop_dregister())==-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
--- a/mc-code-powerpc.c Thu Mar 13 14:41:48 2003 +0900 +++ b/mc-code-powerpc.c Thu Mar 13 22:48:57 2003 +0900 @@ -55,20 +55,32 @@ int size_of_double = 8; int size_of_longlong = 8; int endian = 0; -int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ -#define REAL_MAX_REGISTER 32 /* PowerPCのレジスタが32ということ*/ -#define REAL_MAX_FREGISTER 32 /* PowerPCのレジスタが32ということ*/ -int MAX_REGISTGER_VAR=30-10; -int MAX_FREGISTER=30; #define REG_fp 1 #define REG_sp 30 -#define REG_VAR_BASE 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 + +#define PTRC_REG 3 +#define INPUT_REG 2 +#define USING_REG 1 + +#define FREG_VAR_BASE 31 +#define FREG_VAR_MIN 22 #define FREG_ARG_BASE 1 #define FREG_ARG_MAX 13 +int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ +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 powerpc_regs[REAL_MAX_REGISTER]; int powerpc_regv[REAL_MAX_REGISTER]; @@ -105,6 +117,7 @@ void code_save_registers(); void code_save_stacks(); void regist_extern_function(); +void clear_ptr_cache_reg(int r); void code_init(void) @@ -116,24 +129,47 @@ endian = 1; } -#define register_name(i) reg_name[i] +#define register_name(i) reg_name[i] +#define dregister_name(i) freg_name[i] void gexpr_code_init(void){ regv[creg]=0; + fregv[freg]=0; +} + +int +replace_arg_var(int n) +{ + fnptr->dsp; } int get_register(void) { /* 使われていないレジスタを調べる */ - int i; - for(i=0;i<MAX_REGISTER;i++) { + int i,n; + for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { if (! regs[i]) { /* 使われていないなら */ - regs[i]=1; /* そのレジスタを使うことを宣言し */ - return i; /* その場所を表す番号を返す */ + } else if (regs[i]==INPUT_REG) { + code_assign_lvar(lvar(replace_arg_var(i)),0); + } else if (regs[i]==PTRPC_REG) { + clear_ptr_cache_r(i); + } else + continue; + regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ + return i; /* その場所を表す番号を返す */ + } + /* search register stack */ + for(i=0;i<reg_sp;i++) { + if (reg_stack[i]>=0) { + code_assign_lvar( + lvar(reg_stack[i]=new_lvar(size_of_int)),0); + reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; + return i; } } - return -1; /* 空いている場所がないなら、それを表す -1 を返す */ + /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ + error(REG_ERR); } int @@ -142,6 +178,39 @@ return reg_stack[--reg_sp]; } +int +get_dregister(void) +{ /* 使われていないレジスタを調べる */ + int i,n; + for(i=MAX_TMP_FREG;i>MIN_TMP_FREG;i--) { + if (! fregs[i]) { /* 使われていないなら */ + } else if (fregs[i]==INPUT_REG) { + code_dassign_lvar(lvar(replace_arg_dvar(i)),0); + } else + continue; + fregs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ + return i; /* その場所を表す番号を返す */ + } + /* search register stack */ + for(i=0;i<freg_sp;i++) { + if (freg_stack[i]>=0) { + code_dassign_lvar( + lvar(freg_stack[i]=new_lvar(size_of_double)),1); + freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET; + return i; + } + } + /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ + error(REG_ERR); +} + + +int +pop_dregister(void) +{ /* レジスタから値を取り出す */ + return freg_stack[--freg_sp]; +} + int stack_used(void) { return reg_stack[--reg_sp]<0; @@ -158,6 +227,11 @@ regv[i]=regs[i]=0; } +void +free_dregister(int i) { /* いらなくなったレジスタを開放 */ + fregv[i]=fregs[i]=0; +} + int register_full(void) { @@ -189,7 +263,7 @@ regs[i]=regv[i]=0; } creg = get_register(); - freg = get_register(); + freg = get_dregister(); return; } @@ -214,7 +288,12 @@ error(-1); return; } use_register_var(n->dsp); /* it has now value in it */ - } + } else if(n->sc==DREGISTER) { + if ((n->dsp = get_dregister_var()) <0) { + error(-1); return; + } + use_dregister_var(n->dsp); /* it has now value in it */ + } code_arg_register(cadr(args)); } } @@ -277,12 +356,33 @@ { int i; for(i=0;i<MAX_REGISTGER_VAR;i++) { - if (REG_VAR_BASE-i<=REG_ARG_MAX) + if (REG_VAR_BASE-i<=REG_VAR_MIN) return -1; - if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ - regs[REG_VAR_BASE-i]=1; /* そのレジスタを使うことを宣言し */ + if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ + regs[REG_VAR_BASE-i]=USING_REG; /* そのレジスタを使うことを宣言し */ regv[REG_VAR_BASE-i]=0; - return i; /* その場所を表す番号を返す */ + return i; /* その場所を表す番号を返す */ + } + } + return -1; +} + +int +dregister_var(int r) { + return FREG_VAR_BASE-r; +} + +int +get_dregister_var(void) +{ + int i; + for(i=0;i<MAX_FREGISTGER_VAR;i++) { + if (FREG_VAR_BASE-i<=FREG_VAR_MIN) + return -1; + if (! regs[FREG_VAR_BASE-i]) { /* 使われていないなら */ + regs[FREG_VAR_BASE-i]=USING_REG; /* そのレジスタを使うことを宣言し */ + regv[FREG_VAR_BASE-i]=0; + return i; /* その場所を表す番号を返す */ } } return -1; @@ -337,6 +437,21 @@ } void +clear_ptr_cache_reg(int r) +{ + int ptcptr=ptr_cache; + while(ptcptr) { + if(car(ptcptr)&&caddr(ptcptr)==r) { + car(ptcptr)=0; + caddr(ptcptr)=0; + free_register(caddr(ptcptr)); + retrun; + } + ptcptr=cadr(ptcptr); + } +} + +void clear_ptr_cache() { int ptcptr=ptr_cache; @@ -368,10 +483,10 @@ cadr(p) = ptr_cache; /* connect current queue to the last one */ ptr_cache = p; /* now the last one is the top */ if (!caddr(p)) { - if((r=get_register())) - caddr(p)=r; - else - r=creg; + if((r=get_register())) { + caddr(p)=r; regs[r]=PTRC_REG; + } else + r=creg; /* this can't happen */ } rrn = register_name(r); printf("\taddis %s,r31,ha16(L_%s$non_lazy_ptr-%s)\n", @@ -882,7 +997,7 @@ int function(int e1) { - int e2,e3,e4,e5,nargs,t; + int e2,e3,e4,e5,nargs,t,i; int reg_arg,freg_arg; NMTBL *n; int jmp; @@ -899,10 +1014,11 @@ n=(NMTBL *)(e5=(cadr(e4 = car(e3)))); if(scalar(t)) { g_expr(e4); - if (reg_arg<REG_ARG_MAX) + if (reg_arg<REG_ARG_MAX) { printf("\tmr %s,%s\n",register_name(reg_arg), register_name(creg)); - else { + regs[reg_arg]=1; + } else { printf("\tstw %s,%d(r1)\n",register_name(creg), arg_offset_v(nargs)); } @@ -940,6 +1056,7 @@ regv[creg]=1; } + clear_ptr_cache(); if (car(e2) == FNAME) { printf("\tbl\tL_%s$stub\n",n->nm); } else { @@ -951,8 +1068,17 @@ printf("\tbctrl\n"); free_register(jmp); } - regv[creg]=1; - clear_ptr_cache(); + for(;reg_argv>=REG_ARG_BASE;reg_argv--) + regs[reg_argv]=regv[reg_argv]=0; + for(;freg_argv>=FREG_ARG_BASE;freg_argv--) + fregs[freg_argv]=fregv[freg_argv]=0; + 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; } @@ -990,7 +1116,7 @@ switch (car(e1)) { case FRINDIRECT: case DRINDIRECT: printf("\t%s %s,(%s)\n",fload(car(e1)==DRINDIRECT), - register_name(freg),crn); + dregister_name(freg),crn); regv[creg]=0; regv[freg]=1; return DOUBLE; case CRINDIRECT: @@ -1195,13 +1321,6 @@ } void -code_closing() -{ - global_table(); - printf("\t.ident \"Micro-C compiled\"\n"); -} - -void rexpr(int e1, int l1, char *s,int t) { g_expr(list3(CMP,cadr(e1),caddr(e1))); @@ -1481,6 +1600,17 @@ /* floating point */ +static int float_one_lib_used=0; +static char *float_one_lib[] = { +".data", +".literal8", +" .align 3", +"__float_one:", +" .long 1065353216", +".text", +0 +}; + char * fstore(int d) @@ -1508,17 +1638,17 @@ { int r; r = get_ptr_cache((char*)caddr(e2)); - printf("\t%s %s,(%s)\n",fstore(d),register_name(freg),register_name(r)); + printf("\t%s %s,(%s)\n",fstore(d),dregister_name(freg),register_name(r)); } void code_dassign_lvar(int e2,int d) { - printf("\t%s %s,%d(r1)\n",fstore(d),register_name(creg),e2); + printf("\t%s %s,%d(r1)\n",fstore(d),dregister_name(freg),e2); } void code_dassign(int e2,int d) { - printf("\t%s %s,(%s)\n",fstore(d),register_name(creg),register_name(e2)); + printf("\t%s %s,(%s)\n",fstore(d),dregister_name(freg),register_name(e2)); } static double d0 = 1.0; @@ -1543,7 +1673,7 @@ double d = dcadr(e2); int r; char *rrn; - rrn = register_name((r=get_register())); + rrn = dregister_name((r=get_dregister())); if (d==0.0) { printf("\tfldz\n"); return; @@ -1562,19 +1692,19 @@ } printf("\taddis %s,r31,ha16(_%d-%s)\n",rrn,lb,code_base); printf("\tla %s,lo16(_%d-%s)(%s)\n",rrn,lb,code_base,rrn); - printf("\tlfd %s,(%s)\n",register_name(freg),rrn); + printf("\tlfd %s,(%s)\n",dregister_name(freg),rrn); free_register(r); } void code_dneg() { - char *frn = register_name(freg); + char *frn = dregister_name(freg); printf("\tfneg %s,%s\n",frn,frn); } void code_d2i() { - char *frn = register_name(freg); + char *frn = dregister_name(freg); char *crn = register_name(creg); disp-=size_of_double; printf("\tfctiwz %s,%s\n",frn,frn); @@ -1615,7 +1745,7 @@ void code_i2d() { i2d_lib_used = 1; - char *frn = register_name(freg); + char *frn = dregister_name(freg); char *crn = register_name(creg); printf("\tmr r3,%s\n",crn); printf("\tbl i2d_\n"); @@ -1663,7 +1793,7 @@ void code_d2u() { d2u_lib_used=1; - char *frn = register_name(freg); + char *frn = dregister_name(freg); char *crn = register_name(creg); printf("\tfmr f1,%s\n",frn); printf("\tbl d2u\n"); @@ -1702,7 +1832,7 @@ void code_u2d() { u2d_lib_used = 1; - char *frn = register_name(freg); + char *frn = dregister_name(freg); char *crn = register_name(creg); printf("\tmr r3,%s\n",crn); printf("\tbl u2d\n"); @@ -1715,21 +1845,21 @@ { int r; r = get_ptr_cache((char*)caddr(e2)); - printf("\t%s %s,(%s)\n",fload(d),register_name(freg),register_name(r)); + printf("\t%s %s,(%s)\n",fload(d),dregister_name(freg),register_name(r)); } void code_drlvar(int e2,int d) { - printf("\t%s %s,%d(r1)\n",fload(d),register_name(freg),e2); + printf("\t%s %s,%d(r1)\n",fload(d),dregister_name(freg),e2); } void code_cmp_drgvar(int e2) { int r; - char *frn=register_name(freg); - int g=get_register(); - char *grn=register_name(g); + char *frn=dregister_name(freg); + int g=get_dregister(); + char *grn=dregister_name(g); r = get_ptr_cache((char*)caddr(e2)); printf("\t%s %s,(%s)\n",fload(1),grn,register_name(r)); printf("\tfcmpu cr0,%s,%s\n",frn,grn); @@ -1739,9 +1869,9 @@ void code_cmp_drlvar(int e2) { printf("\tfcmpu %d(%%ebp)\n",e2); - char *frn=register_name(freg); - int g=get_register(); - char *grn=register_name(g); + char *frn=dregister_name(freg); + int g=get_dregister(); + char *grn=dregister_name(g); printf("\t%s %s,%d(r1)\n",fload(1),grn,e2); printf("\tfcmpu cr0,%s,%s\n",frn,grn); free_register(g); @@ -1750,8 +1880,8 @@ void dtosop(int op,int e1) { char *opn; - char *frn=register_name(freg); - char *grn=register_name(e1); + char *frn=dregister_name(freg); + char *grn=dregister_name(e1); switch(op) { case DADD: opn="fadd"; break; case DSUB: opn="fadd"; break; @@ -1773,9 +1903,9 @@ void code_dassop(int op,int d) { /* we have lvalue in creg, applied floating value is in freg */ - char *frn=register_name(freg); - int e1=get_register(); - char *grn=register_name(e1); + char *frn=dregister_name(freg); + int e1=get_dregister(); + char *grn=dregister_name(e1); char *crn=register_name(creg); printf("\t%s %s,(%s)\n",fload(d),grn,crn); @@ -1783,7 +1913,6 @@ printf("\t%s %s,(%s)\n",fstore(d),frn,crn); } -static int use_float_one=0; void code_dpreinc(int e1,int e2,int d) { @@ -1792,15 +1921,15 @@ int g; char *grn,*drn; int r; - r = get_ptr_cache("float_one"); - use_float_one=1; + r = get_ptr_cache("_float_one"); + float_one_lib_used=1; g_expr(e2); crn=register_name(creg); - frn=register_name(freg); + frn=dregister_name(freg); drn=register_name(r); - grn=register_name(g); + grn=dregister_name(g=get_dregister()); printf("\t%s %s,(%s)\n",fload(d),frn,crn); printf("\tfls %s,(%s)\n",grn,drn); @@ -1809,6 +1938,7 @@ else printf("\tfsub %s,%s,%s\n",frn,frn,grn); printf("\t%s %s,(%s)\n",fstore(d),frn,crn); + free_dregister(g); } void @@ -1818,15 +1948,15 @@ int g; char *grn,*drn; int r; - r = get_ptr_cache("float_one"); - use_float_one=1; + r = get_ptr_cache("_float_one"); + float_one_lib_used=1; g_expr(e2); crn=register_name(creg); - frn=register_name(freg); + frn=dregister_name(freg); drn=register_name(r); - grn=register_name(g); + grn=dregister_name(g=get_dregister()); printf("\t%s %s,(%s)\n",fload(d),frn,crn); printf("\tfls %s,(%s)\n",grn,drn); @@ -1835,6 +1965,7 @@ else printf("\tfsub %s,%s,%s\n",grn,frn,grn); printf("\t%s %s,(%s)\n",fstore(d),grn,crn); + free_dregister(g); } void @@ -1858,18 +1989,20 @@ } } -int dpop_register() -{ - return 1; -} - int emit_dpop(int e1) { - return 1; + int xreg; + if ((xreg=pop_dregister())==-1) { + } else if (xreg<= -REG_LVAR_OFFSET) { + xreg = get_dregister(); + code_drlvar(lvar(REG_LVAR_OFFSET+xreg),1); + } + return xreg; } void emit_dpop_free(int e1) { + free_dregister(e1); } void emit_dpush() @@ -1887,8 +2020,27 @@ } void -regist_extern_function(bcopy) +regist_extern_function(int f) +{ +} + +void +emit_lib(char *p[]) { + while(p++) { + printf("%s\n",p); + } +} + +void +code_closing() +{ + global_table(); + printf("\t.ident \"Micro-C compiled\"\n"); + if (d2u_lib_used) emit_lib(d2u_lib); + if (u2d_lib_used) emit_lib(u2d_lib); + if (float_one_lib_used) emit_lib(float_one_lib); + if (i2d_lib_used) emit_lib(i2d_lib); } /* end */
--- a/test/basic.c Thu Mar 13 14:41:48 2003 +0900 +++ b/test/basic.c Thu Mar 13 22:48:57 2003 +0900 @@ -26,9 +26,50 @@ printf("%d\n",i); } +int +g( +int a0,int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8 +) +{ + printf("g: %d\n", +a0+a1+a2+a3+a4+a5+a6+a7+a8 + ); + return a8; +} + +double +f( +double a0,double a1,double a2,double a3,double a4,double a5,double a6,double a7,double a8 +) +{ + printf("g: %g\n", +a0+a1+a2+a3+a4+a5+a6+a7+a8 + ); + return a8; +} + void tmp1 () { +g(g(0,1,2,3,4,5,6,7,0), + g(0,1,2,3,4,5,6,7,1), + g(0,1,2,3,4,5,6,7,2), + g(0,1,2,3,4,5,6,7,3), + g(0,1,2,3,4,5,6,7,4), + g(0,1,2,3,4,5,6,7,5), + g(0,1,2,3,4,5,6,7,6), + g(0,1,2,3,4,5,6,7,6), + g(0,1,2,3,4,5,6,7,7)); +f(f(0,1,2,3,4,5,6,7,0), + f(0,1,2,3,4,5,6,7,1), + f(0,1,2,3,4,5,6,7,2), + f(0,1,2,3,4,5,6,7,3), + f(0,1,2,3,4,5,6,7,4), + f(0,1,2,3,4,5,6,7,5), + f(0,1,2,3,4,5,6,7,6), + f(0,1,2,3,4,5,6,7,6), + f(0,1,2,3,4,5,6,7,7)); + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d \n", 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49 );