# HG changeset patch # User kono # Date 1058108366 -32400 # Node ID e0eba2993c37b0b3091b79d2cd3b97ea2b7d4b24 # Parent cb7aa00896812d815048e0bac98ae88c314b8387 MIPS version (incomplete) diff -r cb7aa0089681 -r e0eba2993c37 Changes --- a/Changes Wed Jun 11 12:26:03 2003 +0900 +++ b/Changes Sun Jul 13 23:59:26 2003 +0900 @@ -3084,3 +3084,46 @@ あぁ、なんか乗り切れない。CONV の直前でcregが不定だ。 どっかで use_float を忘れているんだろうな。 + +Wed Jun 11 12:27:58 JST 2003 + +なんか、ようやっと creg/ireg/freg が片付いたよ。 +creg を変更したときに、ireg を変更し忘れることが多かった +みたい。set_creg を必ず使うようにすれば良いだけだと思う +のだが。 + +Thu Jun 12 19:34:48 JST 2003 + +まぁ、MIPS用のレジスタ割り当てを書かないとだめだね。 +ちゃんと書いてもいいんだけどさ。なんか one path に +するのが面白いんでしょ? + +Sun Jul 13 18:26:29 JST 2003 + +また、一カ月なにも書かなかったのか。 mips は、mc-code-power.c +から書き直した方が良さそうだね。 + + regs/regv は、i/f/d のすべてのレジスタに関して一つ + +でないと stack に積むのを統一できないから。そういう意味では、 +reg_stack と freg_stack を区別する意味はないわけね。でもstack +は型付けした方が良いから。でも、区別しておくと、long を増や +した時にも、stack を増やさないとだめなんじゃない? なので区別 +しない方が良い。でも、それに手をつけると、また時間かかるんじ +ゃないの? そのためにはスタックそのものに型付けしないとだめだ +から結局同じか。 + +mips の double を格納するためのregister pairは、regs に +格納する。regs にアクセスには必ずアクセス関数を通す。 +なるほど。 + +get_input_dregister_var なんだけど、dregister pair の +場合は、常にpairが決まった値になる必要があるよね。 +この分はどうする? 前もってとっておくか? + +あ、そうか、任意のregister pairを許さなくても良いよ。input register +に対応する連続したregister pair だけを許そう。そうすれば、あ +まり気にしなくても良くなるから。でも、gcc が奇数pairを許して +いたら気まずくない? + +regv は、register rename がなければいらないんじゃない? diff -r cb7aa0089681 -r e0eba2993c37 mc-code-mips.c --- a/mc-code-mips.c Wed Jun 11 12:26:03 2003 +0900 +++ b/mc-code-mips.c Sun Jul 13 23:59:26 2003 +0900 @@ -11,30 +11,46 @@ #define RODATA_EMIT_MODE 2 static void data_mode(char *name); +static void init_ptr_cache(); static void ld_indexx(int byte, int n, int xreg); static void local_table(void); static void shift(char *op, int reg); static int struct_push(int e4,int t,int arg); -static int code_d1(double d); -static int code_d2(double d); - static int output_mode = TEXT_EMIT_MODE; static int data_alignment = 0; static int code_disp_label; +static int code_setup; static int r1_offset_label; static int lvar_offset_label; static int reg_save; static int freg_save; +static int freg,ireg; + +/* mips requires two registers for compare */ +static int cmpreg = -1; + int size_of_int = 4; int size_of_float = 4; int size_of_double = 8; int size_of_longlong = 8; int endian = 1; +int reg_sp; /* REGister Stack-Pointer */ +int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ + +/* floating point registers */ + +int freg_sp; /* floating point REGister Stack-Pointer */ +int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ + +/* double floating point registers */ + +int dreg_sp; /* floating point REGister Stack-Pointer */ +int dreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ #define REG_fp 1 #define REG_sp 30 @@ -51,76 +67,99 @@ #define MAX_TMP_FREG 14 #define RET_REGISTER 3 -#define RET_FREGISTER 1 +#define RET_FREGISTER (1+FREG_OFFSET) +#define RET_DREGISTER (1+DREG_OFFSET) -int MAX_REGISTER=30; /* MIPSのレジスタを10個まで使う*/ +int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ int MAX_FREGISTER=31; -#define REAL_MAX_REGISTER 32 /* MIPSのレジスタが32ということ*/ -#define REAL_MAX_FREGISTER 32 /* MIPSのレジスタが32ということ*/ +int MAX_DREGISTER=16; +#define REAL_MAX_REGISTER 32 /* PowerPCのレジスタが32ということ*/ +#define REAL_MAX_FREGISTER 32 /* PowerPCのFレジスタが32ということ*/ +#define REAL_MAX_DREGISTER 31 /* PowerPCのDレジスタ番号が31ということ*/ + +#define FREG_OFFSET REAL_MAX_REGISTER +#define DREG_OFFSET (REAL_MAX_REGISTER+REAL_MAX_FREGISTER ) int MAX_INPUT_REGISTER_VAR = 7-MIN_TMP_REG; int MAX_CODE_INPUT_REGISTER_VAR = 7-MIN_TMP_REG; int MAX_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; +int MAX_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; int MAX_CODE_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; +int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; #define CREG_REGISTER MAX_TMP_REG -#define FREG_FREGISTER MAX_TMP_FREG - -int dreg; +#define FREG_FREGISTER (MAX_TMP_FREG+FREG_OFFSET) +#define DREG_DREGISTER (2+DFREG_OFFSET) -int reg_sp; /* REGister Stack-Pointer */ -int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ - -/* floating point registers */ - -int freg_sp; /* floating point REGister Stack-Pointer */ -int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ +int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REL_MAX_DREGISTER]; +int powerpc_regv[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REL_MAX_DREGISTER]; -#define dregister(i,j) (i*32+j) -#define dregister0(i) (i/32) -#define dregister1(i) (i%32) - - -int mips_regs[REAL_MAX_REGISTER]; -int mips_regv[REAL_MAX_REGISTER]; +unsigned char dreg_pair0[REL_MAX_DREGISTER] = { + 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 +}; +unsigned char dreg_pair1[REL_MAX_DREGISTER] = { + 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 +}; -int *regv = mips_regv; -int *regs = mips_regs; - -int mips_fregs[REAL_MAX_FREGISTER]; -int mips_fregv[REAL_MAX_FREGISTER]; - -#define FDREG 40 - -int *fregv = mips_fregv; -int *fregs = mips_fregs; +int *regv = powerpc_regv; +int *regs = powerpc_regs; static int max_reg_var, max_freg_var; -static int cond_reg=-1,cond_freg=-1; +static int cond_reg=-1,cond_freg=-1,cond_dreg=-1; static char *reg_name[] = { "$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" -}; - -static char *freg_name[] = { + "$30","$31", "$f0","$f1","$f2","$f3","$f4","$f5","$f6","$f7","$f8","$f9", "$f10","$f11","$f12","$f13","$f14","$f15","$f16","$f17","$f18","$f19", "$f20","$f21","$f22","$f23","$f24","$f25","$f26","$f27","$f28","$f29", "$f30","$f31" }; -#define register_name(i) reg_name[i] -#define fregister_name(i) freg_name[i] + +#define register_name(i) reg_name0(i) +#define fregister_name(i) reg_name0(i) + +static +reg_name0(int i) +{ + if (i<=REAL_MAX_REGISTER+REAL_MAX_FREGISTER) + return reg_name[i]; + else + error(-1); +} + +#define is_int_reg(i) (0<=i&&isc==CODE) { - if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("%d($fp)\n",CODE_CALLER_ARG); - } else - printf("%d($fp)\n",CODE_LVAR); + if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ + printf("%d($fp)\n",CODE_CALLER_ARG); + } else + printf("%d($fp)\n",CODE_LVAR); } else if (l<0) { /* local variable */ - printf("%d+L_%d($fp)\n",FUNC_LVAR,lvar_offset_label); + printf("%d+L_%d($fp)\n",FUNC_LVAR,lvar_offset_label); } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("%d($fp)\n",CALLER_ARG); + printf("%d($fp)\n",CALLER_ARG); } else { /* callee's arguments */ - printf("%d+L_%d($fp)\n",CALLEE_ARG,r1_offset_label); + printf("%d+L_%d($fp)\n",CALLEE_ARG,r1_offset_label); } } @@ -228,20 +267,19 @@ lvar_address(int l,int creg) { if (fnptr->sc==CODE) { - if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_CALLER_ARG); - } else - printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_LVAR); + if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ + printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_CALLER_ARG); + } else + printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_LVAR); } else if (l<0) { /* local variable */ - printf("\taddu\t%s,$fp,%d+L_%d\n",register_name(creg),FUNC_LVAR,lvar_offset_label); + printf("\taddu\t%s,$fp,%d+L_%d\n",register_name(creg),FUNC_LVAR,lvar_offset_label); } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("\taddu\t%s,$fp,%d\n",register_name(creg),CALLER_ARG); + printf("\taddu\t%s,$fp,%d\n",register_name(creg),CALLER_ARG); } else { /* callee's arguments */ - printf("\taddu\t%s,$fp,%d+L_%d\n",register_name(creg),CALLEE_ARG,r1_offset_label); + printf("\taddu\t%s,$fp,%d+L_%d\n",register_name(creg),CALLEE_ARG,r1_offset_label); } } - void code_lvar(int e2,int creg) { lvar_address(e2,creg); @@ -257,10 +295,16 @@ void gexpr_code_init(void){ regv[creg]=0; - fregv[freg]=0; + regv[freg]=0; } void +code_gexpr(int e){ + if (is_int_reg(creg) && creg!=ireg) error(-1); +} + + +void code_arg_register(NMTBL *fnptr) { int args = fnptr->dsp; @@ -288,20 +332,17 @@ if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) { n->sc = FREGISTER; n->dsp = cadr(reg); - fregv[n->dsp]= 1; - fregs[n->dsp]= INPUT_REG; - if (freg_var<2) freg_var++; - else reg_var++; + regv[n->dsp]= 1; + regs[n->dsp]= INPUT_REG; + freg_var++; cadddr(args)=size(type); /* why we need this? */ } } else if (type==DOUBLE) { if ((reg = get_input_dregister_var(reg_var,n,is_code0,1))) { n->sc = DREGISTER; n->dsp = cadr(reg); - regv[dregister0(n->dsp)]= 1; - regv[dregister1(n->dsp)]= 1; - regs[dregister0(n->dsp)]= INPUT_REG; - regs[dregister1(n->dsp)]= INPUT_REG; + regv[n->dsp]= 1; + regs[n->dsp]= INPUT_REG; reg_var+=2; cadddr(args)=size(type); /* why we need this? */ } @@ -309,7 +350,7 @@ args = cadr(args); } if (is_function(fnptr)) - code_save_input_registers(); + code_save_input_registers(); } int @@ -330,6 +371,16 @@ return reg; } } + /* search dregister stack */ + for(i=0;i=0) { + code_dassign_lvar( + (dreg_stack[i]=new_lvar(size_of_double)),reg,1); + dreg_stack[i]= dreg_stack[i]-REG_LVAR_OFFSET; + free_dregister(reg); + return get_register(); /* 今度は必ずある */ + } + } for(i=0;iMIN_TMP_DREG;i--) { + if (regs[i]) continue; /* 使われている */ + if (regs[dreg_pair0[i-DREG_OFFSET]]) continue; + if (regs[dreg_pair1[i-DREG_OFFSET]]) continue; + regs[dreg_pair0[i-DREG_OFFSET]]=USING_REG; + regs[dreg_pair1[i-DREG_OFFSET]]=USING_REG; + regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ + return i; /* その場所を表す番号を返す */ + } + return -1; +} + +static int +get_dregister0() +{ + int i0,i1,reg,i; + /* とりあえず、空き int register pair を探す */ + if ((i=get_dregister1())!=-1) { + return i; + } + /* search dregister stack */ + for(i=0;i=0) { + code_dassign_lvar( + (dreg_stack[i]=new_lvar(size_of_double)),reg,1); + dreg_stack[i]= dreg_stack[i]-REG_LVAR_OFFSET; + return i; + } + } + /* clear integer register stack */ + for(i=0;i=0) { + code_assign_lvar( + (reg_stack[i]=new_lvar(size_of_int)),reg,0); + reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; + free_register(reg); + } + } + if ((i=get_dregister1())!=-1) { + return i; + } + + error(REG_ERR); return dreg; +} + +static int +get_fregister0() { /* 使われていないレジスタを調べる */ - int i,j,reg; - if (d) { - i = get_register(); - j = get_register(); - return dregister(i,j); - } - for(i=MAX_TMP_FREG;i>MIN_TMP_FREG;i--) { - if (fregs[i]) continue; /* 使われている */ - fregs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ + int i,reg; + for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) { + if (regs[i]) continue; /* 使われている */ + regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ return i; /* その場所を表す番号を返す */ } /* search register stack */ for(i=0;i=0) { code_dassign_lvar( - (freg_stack[i]=new_lvar(size_of_double)),reg,1); + (freg_stack[i]=new_lvar(size_of_float)),reg,1); freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET; return reg; } } for(i=0;imax_freg_var) max_freg_var=i; return reg; } @@ -385,12 +478,29 @@ error(REG_ERR); return freg; } +int +get_dregister(int d) +{ /* 使われていないレジスタを調べる */ + int i,reg; + if (d) { + return get_dregister0(); + } else { + return get_fregister0(); + } +} + int pop_fregister(void) { /* レジスタから値を取り出す */ return freg_stack[--freg_sp]; } +int +pop_dregister(void) +{ /* レジスタから値を取り出す */ + return dreg_stack[--dreg_sp]; +} + void emit_pop_free(int xreg) { @@ -400,56 +510,39 @@ void free_register(int i) { /* いらなくなったレジスタを開放 */ - if (i<0||MAX_REGISTERFDREG) { - j = dregister0(i); - regv[j]=regs[j]=0; - j = dregister1(i); - regv[j]=regs[j]=0; - } - if (i<0||MAX_FREGISTER=MAX_INPUT_DREGISTER_VAR) return 0; + i = i+MIN_TMP_DREG+DREG_OFFSET; } + return list3(DREGISTER,i,(int)n); } else { - if (d) { - if (i==0) { - return list3(DREGISTER,dregister(4,5),(int)n); - } else if (i==1) { - return list3(DREGISTER,dregister(6,7),(int)n); - } + if (is_code) { + if(!(i=MAX_INPUT_FREGISTER_VAR) return 0; + i = i+MIN_TMP_FREG+FREG_OFFSET; } + return list3(FREGISTER,i,(int)n); } - return 0; } int @@ -459,7 +552,22 @@ if(!(i=MAX_INPUT_REGISTER_VAR) return 0; + i = i+MIN_TMP_REG; + } + return list3(REGISTER,i,(int)n); +} + +/* double register case? */ + +int +get_input_register_var_1(int i,NMTBL *n,int is_code) +{ + if (is_code) { + if(!(i=MAX_INPUT_REGISTER_VAR+1) return 0; i = i+MIN_TMP_REG; } return list3(REGISTER,i,(int)n); @@ -474,9 +582,9 @@ if (! regs[i] && ! regv[i]) count++; } for(i=0;i=0;i--) { if(reg_stack[i]>=0) - printf(" %s",register_name(reg_stack[i],0)); + printf(" %s",register_name(reg_stack[i])); } #endif printf("\n"); @@ -537,15 +647,25 @@ while(reg_sp > 0) { free_register(reg_stack[--reg_sp]); } + while(freg_sp > 0) { + free_register(freg_stack[--freg_sp]); + } + while(dreg_sp > 0) { + free_register(dreg_stack[--dreg_sp]); + } if (cond_freg!=-1) { - if(car(cond_freg)==DREGISTER) free_dregister(cadr(cond_freg)); - else if(car(cond_freg)==FREGISTER) free_dregister(cadr(cond_freg)); + if(car(cond_freg)==FREGISTER) free_register(cadr(cond_freg)); cond_freg=-1; } + if (cond_dreg!=-1) { + if(car(cond_dreg)==DREGISTER) free_register(cadr(cond_dreg)); + cond_dreg=-1; + } if (cond_reg!=-1) { if(car(cond_reg)==REGISTER) free_register(cadr(cond_reg)); cond_reg=-1; } + cmpreg = -1; text_mode(); gexpr_code_init(); register_usage("gexpr_init"); @@ -559,6 +679,7 @@ max_reg_var=-1; max_freg_var=-1; reg_sp = 0; freg_sp = 0; + dreg_sp = 0; text_mode(); } @@ -573,13 +694,14 @@ { int i; for(i=0;imax_reg_var) max_reg_var=i; /* その場所を表す番号を返す */ return list3(REGISTER,REG_VAR_BASE-i,(int)n); - } + } } return list2(LVAR,new_lvar(size_of_int)); } @@ -592,17 +714,33 @@ int get_dregister_var(NMTBL *n,int d) { - int i; - for(i=0;imax_freg_var) max_freg_var=i; - /* その場所を表す番号を返す */ - return list3(DREGISTER,FREG_VAR_BASE-i,(int)n); - } + int i,j; + if (d) { + for(i=0;imax_reg_var) max_reg_var=dreg_pair[j]; + /* その場所を表す番号を返す */ + return list3(DREGISTER,DREG_VAR_BASE-i+DREG_OFFSET,(int)n); + } + } + return list2(LVAR,new_lvar(size_of_double)); + } else { + for(i=0;imax_freg_var) max_freg_var=i; + /* その場所を表す番号を返す */ + return list3(FREGISTER,FREG_VAR_BASE-i+FREG_OFFSET,(int)n); + } + } + return list2(LVAR,new_lvar(size_of_float)); } - return list2(LVAR,new_lvar(size_of_double)); } void @@ -612,7 +750,7 @@ if (reg_sp>MAX_MAX) error(-1); new_reg = get_register(); reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ - creg = new_reg; + ireg = creg = new_reg; regv[creg]=1; } @@ -626,7 +764,7 @@ code_rlvar(REG_LVAR_OFFSET+xreg,reg); free_lvar(REG_LVAR_OFFSET+xreg); xreg = reg; - regv[xreg]=1; + regv[creg]=1; } return xreg; } @@ -634,6 +772,7 @@ void code_label(int labelno) { + clear_ptr_cache(); printf("L_%d:\n",labelno); } @@ -659,7 +798,7 @@ void code_register(int e2,int creg) { if (creg!=e2) - printf("\tmove %s,%s\n",register_name(creg),register_name(e2)); + printf("\tmove %s,%s\n",register_name(creg),register_name(e2)); regv[creg]=1; } @@ -684,7 +823,6 @@ code_fname(NMTBL *n,int creg) { printf("\tla %s,%s\n",register_name(creg),n->nm); regv[creg]=1; - return; } @@ -704,19 +842,18 @@ void code_not(int creg) { printf("\tnor %s,%s,%s\n", - register_name(creg), register_name(creg),register_name(creg)); + register_name(creg), register_name(creg),register_name(creg)); } void code_lnot(int creg) { /* if non zero 1 else 0 */ - int dreg = get_register(); printf("\txori %s,%s,0x0\n", - register_name(dreg),register_name(creg)); + register_name(dreg),register_name(creg)); printf("\tsltu %s,%s,1\n", - register_name(creg),register_name(dreg)); + register_name(creg),register_name(dreg)); free_register(dreg); } @@ -725,12 +862,12 @@ char *xrn,*drn; int i,dreg; if (car(e2)==REGISTER) { - printf("\taddu %s,%s,%d\n", - register_name(cadr(e2)),register_name(cadr(e2)), caddr(e1)); - if (cadr(reg)!=e2) - printf("\tmove %s,%s\n",register_name(cadr(reg)),register_name(e2)); - regv[reg]=1; - return; + printf("\taddu %s,%s,%d\n", + register_name(cadr(e2)),register_name(cadr(e2)), caddr(e1)); + if (cadr(reg)!=e2) + printf("\tmove %s,%s\n",register_name(cadr(reg)),register_name(e2)); + regv[reg]=1; + return; } g_expr(e2); xrn = register_name(creg); @@ -750,11 +887,11 @@ char *xrn,*crn,*nrn; int dreg,nreg,i; if (car(e2)==REGISTER) { - printf("\tmove %s,%s\n",register_name(reg),register_name(cadr(e2))); - printf("\taddu %s,%s,%d\n", - register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1)); - regv[reg]=1; - return; + printf("\tmove %s,%s\n",register_name(reg),register_name(cadr(e2))); + printf("\taddu %s,%s,%d\n", + register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1)); + regv[reg]=1; + return; } g_expr(e2); crn = register_name(creg); @@ -777,11 +914,11 @@ char *xrn,*crn,*nrn; int i,nreg,dreg; if (car(e2)==REGISTER) { - printf("\tlb %s,0(%s)\n",register_name(reg),register_name(cadr(e2))); - printf("\taddu %s,%s,%d\n", - register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1)); - regv[reg]=1; - return; + printf("\tlb %s,0(%s)\n",register_name(reg),register_name(cadr(e2))); + printf("\taddu %s,%s,%d\n", + register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1)); + regv[reg]=1; + return; } g_expr(e2); crn = register_name(creg); @@ -805,11 +942,11 @@ char *xrn,*crn,*nrn; int i,nreg,dreg; if (car(e2)==REGISTER) { - printf("\taddu %s,%s,%d\n", - register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1)); - printf("\tlb %s,0(%s)\n",register_name(reg),register_name(cadr(e2))); - regv[reg]=1; - return; + printf("\taddu %s,%s,%d\n", + register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1)); + printf("\tlb %s,0(%s)\n",register_name(reg),register_name(cadr(e2))); + regv[reg]=1; + return; } g_expr(e2); crn = register_name(creg); @@ -833,12 +970,12 @@ char *xrn,*crn,*nrn; int i,nreg,dreg; if (car(e2)==REGISTER) { - crn=register_name(reg); - xrn=register_name(cadr(e2)); - printf("\tlb %s,0(%s)\n",crn,xrn); - printf("\taddu %s,%s,%d\n",xrn,xrn,caddr(e1)); - regv[reg]=1; - return; + crn=register_name(reg); + xrn=register_name(cadr(e2)); + printf("\tlb %s,0(%s)\n",crn,xrn); + printf("\taddu %s,%s,%d\n",xrn,xrn,caddr(e1)); + regv[reg]=1; + return; } g_expr(e2); crn = register_name(creg); @@ -862,12 +999,12 @@ char *xrn,*crn,*nrn; int i,nreg,dreg; if (car(e2)==REGISTER) { - crn=register_name(reg); - xrn=register_name(cadr(e2)); - printf("\taddu %s,%s,%d\n",xrn,xrn,caddr(e1)); - printf("\tlb %s,%d(%s)\n",crn,caddr(e1),xrn); - regv[reg]=1; - return; + crn=register_name(reg); + xrn=register_name(cadr(e2)); + printf("\taddu %s,%s,%d\n",xrn,xrn,caddr(e1)); + printf("\tlb %s,%d(%s)\n",crn,caddr(e1),xrn); + regv[reg]=1; + return; } g_expr(e2); crn = register_name(creg); @@ -919,10 +1056,6 @@ fwddef(e3); } -/* slt $2,$2,$3; beq $2,$0,L1 */ -/* slt $2,$2,$3; xori $2,$2,,0x1,beq $2,$0,L1 */ -/* beq $2,$3,L1 */ - char * code_gt(int cond) { return (cond?"\tslt %s,%s,%s\n\tbeq %s,$0,%s\n": @@ -954,41 +1087,41 @@ void code_cmp_crgvar(int e1) { - if (dreg==-1) dreg = get_register(); - code_crgvar(cadr(e1),dreg); - regv[dreg]=1; + if (cmpreg==-1) cmpreg = get_register(); + code_crgvar(cadr(e1),cmpreg); + regv[cmpreg]=1; } void code_cmp_crlvar(int e2) { - if (dreg==-1) dreg = get_register(); - code_crlvar(e2,dreg); - regv[dreg]=1; + if (cmpreg==-1) cmpreg = get_register(); + code_crlvar(e2,cmpreg); + regv[cmpreg]=1; } void code_cmp_rgvar(int e1) { - if (dreg==-1) dreg = get_register(); - code_rgvar(e1,dreg); - regv[dreg]=1; + if (cmpreg==-1) cmpreg = get_register(); + code_rgvar(e1,cmpreg); + regv[cmpreg]=1; } void code_cmp_rlvar(int e2) { - if (dreg==-1) dreg = get_register(); - code_rlvar(e2,dreg); - regv[dreg]=1; + if (cmpreg==-1) cmpreg = get_register(); + code_rlvar(e1,cmpreg); + regv[cmpreg]=1; } void code_cmp_register(int e2) { - dreg = e2; - /* prevent dreg freeing */ - regv[dreg]=2; + cmpreg = e2; + /* prevent cmpreg freeing */ + regv[cmpreg]=2; } @@ -1009,7 +1142,7 @@ printf("%c",*s); s++; } - printf("\\000%c\n\t.align 2\n",34); + printf("\\0%c\n\t.align 2\n",34); } void @@ -1025,9 +1158,9 @@ printf("L_%d:\n",lb); ascii(s); if (output_mode==TEXT_EMIT_MODE) { - printf(".text\n"); + printf(".text\n"); } else { - text_mode(); + text_mode(); } printf("\tla %s,L_%d\n",crn,lb); } @@ -1047,58 +1180,57 @@ /* length <0 means upward direction copy */ switch (length) { - case 0: break; + case 0: break; case 1: case -1: - printf("\tlb %s,%d(%s)\n",drn,offset,frn); - printf("\tsb %s,%d(%s)\n",drn,offset,trn); - break; + printf("\tlb %s,%d(%s)\n",drn,offset,frn); + printf("\tsb %s,%d(%s)\n",drn,offset,trn); + break; case 2: case -2: - printf("\tlh %s,%d(%s)\n",drn,offset,frn); - printf("\tsh %s,%d(%s)\n",drn,offset,trn); - break; + printf("\tlh %s,%d(%s)\n",drn,offset,frn); + printf("\tsh %s,%d(%s)\n",drn,offset,trn); + break; case 4: case -4: - printf("\tlw %s,%d(%s)\n",drn,offset,frn); - printf("\tsw %s,%d(%s)\n",drn,offset,trn); - break; + printf("\tlw %s,%d(%s)\n",drn,offset,frn); + printf("\tsw %s,%d(%s)\n",drn,offset,trn); + break; default: - if (-MAX_COPY_LEN0) - emit_copy(from,to,length,offset,0,det); - break; - } else if (length <=MAX_COPY_LEN) { - for(;length>=4;length-=4,offset+=4) - emit_copy(from,to,4,offset,0,det); - for(;length>=2;length-=2,offset+=2) - emit_copy(from,to,2,offset,0,det); - if(length>0) - emit_copy(from,to,length,offset,0,det); - break; - } - code_save_stacks(); - printf("\tli $6,%d\n",length); - printf("\tmr $5,%s\n",frn); - printf("\tmr $4,%s\n",trn); + if (-MAX_COPY_LEN0) + emit_copy(from,to,length,offset,0,det); + break; + } else if (length <=MAX_COPY_LEN) { + for(;length>=4;length-=4,offset+=4) + emit_copy(from,to,4,offset,0,det); + for(;length>=2;length-=2,offset+=2) + emit_copy(from,to,2,offset,0,det); + if(length>0) + emit_copy(from,to,length,offset,0,det); + break; + } + code_save_stacks(); + printf("\tli $6,%d\n",length); + printf("\tmr $5,%s\n",frn); + printf("\tmr $4,%s\n",trn); /* overrap must be allowed */ - printf("\tbl L_%s$stub\n",memmove); + printf("\tbl L_%s$stub\n",memmove); fix=0; - set_creg(RET_REGISTER,0); - if (creg!=to) { - free_register(to); to = creg; - } - break; + set_creg(RET_REGISTER,0); + if (creg!=to) { + free_register(to); to = creg; + } + break; } - if (value) { /* creg must point top of the destination data */ /* this code is necessary for the value of assignment or function call */ /* otherwise we don't need this */ - if (fix) printf("\taddi %s,%s,%d\n",trn,trn,fix); - if(creg!=to) { - free_register(creg); creg=to; - } + if (fix) printf("\taddi %s,%s,%d\n",trn,trn,fix); + if(creg!=to) { + free_register(creg); creg=to; + } } free_register(dreg); regv[from]=regv[to]=regv[dreg]=0; @@ -1128,8 +1260,8 @@ free_register(dreg); return count; } else { - printf("\tlw %s,%d(%s)\n",drn,length-size_of_int,crn); - printf("\tsw %s,%d(%s)\n",drn,length-size_of_int,srn); + printf("\tlw %s,%d(%s)\n",drn,length-size_of_int,crn); + printf("\tsw %s,%d(%s)\n",drn,length-size_of_int,srn); } } } @@ -1143,11 +1275,12 @@ void set_creg(int reg,int mode) { + if (!is_int_reg(reg)) error(-1); if (reg!=creg) { - if (mode) - printf("\tmove %s,%s\n",register_name(reg),register_name(creg)); + if (reg!=ireg && mode) + printf("\tmove %s,%s\n",register_name(reg),register_name(creg)); free_register(creg); - creg = reg; + creg = ireg = reg; regs[creg]=1; } } @@ -1155,22 +1288,46 @@ void set_freg(int reg,int mode) { - if (reg!=freg) { - if (mode) - printf("\tfmove %s,%s\n",fregister_name(reg),fregister_name(freg)); - free_dregister(freg); - freg = reg; - fregs[freg]=1; + if (!is_float_reg(reg)) error(-1); + if (reg!=creg) { + if (reg!=freg && mode) { + printf("\tfmove %s,%s\n",fregister_name(reg),fregister_name(freg)); + } + free_register(creg); + creg = freg = reg; + regs[freg]=1; } } void +set_dreg(int reg,int mode) +{ + if (!is_double_reg(reg)) error(-1); + if (reg!=creg) { + if (reg!=dreg && mode) { + printf("\tmove %s,%s\n",register_name(dreg_pair0(reg)), + register_name(dreg_pari0(dreg))); + printf("\tmove %s,%s\n",register_name(dreg_pari1(reg)), + register_name(dreg_pari1(dreg))); + } + free_register(creg); + creg = dreg = reg; + regs[dreg]=1; + regs[dreg_pair0(dreg)]=1; + regs[dreg_pair1(dreg)]=1; + } +} + + +void use_var(int arg) { if (car(arg)==REGISTER) regs[cadr(arg)]=USING_REG; + else if (car(arg)==FREGISTER) + regs[cadr(arg)]=USING_REG; else if (car(arg)==DREGISTER) - fregs[cadr(arg)]=USING_REG; + regs[cadr(arg)]=USING_REG; } void @@ -1197,20 +1354,20 @@ offset+=size_of_int; t = INT; reg += reg_offset; /* for duplicated floating point argument */ - } else if (tag==FREGISTER) { - /* fregs[reg]==INPUT_REG case should be considered */ - n->dsp = offset; - t = n->ty; - if(t==FLOAT) { offset+=size_of_float; reg_offset+=1; } - else if(t==DOUBLE) { offset+=size_of_double; reg_offset+=2; } - else error(-1); - } else if (tag==DREGISTER) { - /* fregs[reg]==INPUT_REG case should be considered */ - n->dsp = offset; - t = n->ty; - if(t==FLOAT) { offset+=size_of_float; reg_offset+=1; } - else if(t==DOUBLE) { offset+=size_of_double; reg_offset+=2; } - else error(-1); + } else if (tag==FREGISTER) { + /* fregs[reg]==INPUT_REG case should be considered */ + n->dsp = offset; + t = n->ty; + if(t==FLOAT) { offset+=size_of_float; reg_offset+=1; } + else if(t==DOUBLE) { offset+=size_of_double; reg_offset+=2; } + else error(-1); + } else if (tag==DREGISTER) { + /* fregs[reg]==INPUT_REG case should be considered */ + n->dsp = offset; + t = n->ty; + if(t==FLOAT) { offset+=size_of_float; reg_offset+=1; } + else if(t==DOUBLE) { offset+=size_of_double; reg_offset+=2; } + else error(-1); } else { offset += size(n->ty); continue; @@ -1218,12 +1375,8 @@ n->sc = LVAR; lvar = list2(LVAR,n->dsp); g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),n->ty,t)); - if (tag==REGISTER) { + if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER) { free_register(reg); - } else if (tag==DREGISTER) { - free_dregister(reg); - } else if (tag==FREGISTER) { - free_dregister(reg); } } my_func_args = offset; @@ -1251,13 +1404,25 @@ { int e2,e3,e4,e5,nargs,t,r0,r1; int arg,reg_arg,freg_arg,arg_assign; + int dots; int reg_arg_list=0,ret_type,special_lvar; NMTBL *fn = 0; int jmp = 0; char *jrn; special_lvar = -1; - ret_type = cadddr(e1); + ret_type = cadr(cadddr(e1)); + if (ret_type==CHAR) ret_type=INT; + + /* check argments type is DOTS? */ + t = caddr(cadddr(e1)); + if (t==0 || t==DOTS) dots = 1; + else { + dots = 0; + for(t = caddr(cadddr(e1));t;t = cadr(t)) { + if (car(t)==DOTS) dots = 1; + } + } e2 = cadr(e1); if (car(e2) == FNAME) { @@ -1275,6 +1440,7 @@ code_save_stacks(); set_creg(CREG_REGISTER,0); set_freg(FREG_FREGISTER,0); + set_dreg(DREG_DREGISTER,0); nargs = reg_arg = freg_arg = arg_assign = 0; for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { @@ -1286,7 +1452,8 @@ } else if (!simple_args(e3) && cadr(e3)) { arg = get_register_var(0); arg_assign = list2( - assign_expr0(get_input_register_var(reg_arg,0,0),arg,t,t), + assign_expr0(get_input_register_var(reg_arg,0,0), + arg,t,t), arg_assign); } else { arg = get_input_register_var(reg_arg,0,0); @@ -1307,13 +1474,13 @@ } else { special_lvar = new_lvar(size_of_double); g_expr(assign_expr0( - (e5=list2(LVAR,special_lvar)),e4,t,t)); + (e5=list2(LVAR,special_lvar)),e4,DOUBLE,t)); reg_arg_list = list2(e5,reg_arg_list); e4 = list2(DREGISTER,freg); /* freg should not change until XXX */ } r0=get_input_register_var(reg_arg,0,0); - r1=get_input_register_var(reg_arg+1,0,0); + r1=get_input_register_var_1(reg_arg+1,0,0); use_var(r0); /* protect from input register free */ use_var(r1); /* protect from input register free */ reg_arg_list = list2(r0,reg_arg_list); @@ -1324,22 +1491,13 @@ INT,INT), arg_assign); reg_arg += 2; } - if (freg_arg>=4 && freg_arg=MAX_INPUT_DREGISTER_VAR) { arg = list2(LVAR,caller_arg_offset_v(nargs)); - } else if (!simple_args(e3)) { + } else if (!simple_args(e3) && cadr(e3)) { arg = get_dregister_var(0,1); arg_assign = list2( - assign_expr0(get_input_dregister_var(freg_arg,0,0,1),arg,t,t), + assign_expr0(get_input_dregister_var(freg_arg,0,0,1), + arg,t,t), arg_assign); } else { arg = get_input_dregister_var(freg_arg,0,0,1); @@ -1363,6 +1521,7 @@ for(;arg_assign;arg_assign=cadr(arg_assign)) { g_expr_u(car(arg_assign)); } + clear_ptr_cache(); if (car(e2) == FNAME) { printf("\tbl\tL_%s$stub\n",fn->nm); } else { @@ -1371,19 +1530,21 @@ } for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) { arg = car(reg_arg_list); - if (car(arg)==DREGISTER) free_dregister(cadr(arg)); - else if (car(arg)==FREGISTER) free_dregister(cadr(arg)); - else if (car(arg)==REGISTER) free_register(cadr(arg)); + if (car(arg)==REGISTER||car(arg)==DREGISTER||car(arg)==FREGISTER) + free_register(cadr(arg)); else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg)); } - if (ret_type==DOUBLE||ret_type==FLOAT) { + if (ret_type==DOUBLE) { + set_dreg(RET_DREGISTER,0); + regv[dreg]=1; regv[creg]=0; + } else if (ret_type==FLOAT) { set_freg(RET_FREGISTER,0); - fregv[freg]=1; regv[creg]=0; + regv[freg]=1; regv[creg]=0; } else if (ret_type==VOID) { - fregv[freg]=0; regv[creg]=0; + regv[freg]=0; regv[creg]=0; } else { set_creg(RET_REGISTER,0); - fregv[freg]=0; regv[creg]=1; + regv[freg]=0; regv[creg]=1; } return ret_type; } @@ -1439,16 +1600,16 @@ crn=register_name(creg); switch (car(e1)) { case FRINDIRECT: case DRINDIRECT: - printf("\t%s %s,%d(%s)\n",fload(car(e1)==DRINDIRECT), - fregister_name(freg),offset,crn); - regv[creg]=0; regv[freg]=1; - return DOUBLE; + printf("\t%s %s,%d(%s)\n",fload(car(e1)==DRINDIRECT), + fregister_name(freg),offset,crn); + regv[creg]=0; regv[freg]=1; + return DOUBLE; case CRINDIRECT: - printf("\tlb %s,%d(%s)\n",crn,offset,crn); - return CHAR; + printf("\tlb %s,%d(%s)\n",crn,offset,crn); + return CHAR; case RINDIRECT: - printf("\tlw %s,%d(%s)\n",crn,offset,crn); - return INT; + printf("\tlw %s,%d(%s)\n",crn,offset,crn); + return INT; } error(-1); return INT; } @@ -1460,9 +1621,9 @@ nm = ((NMTBL*)cadr(e2))->nm; crn=register_name(creg); if (byte) { - printf("\tsb %s,%s\n",crn,nm); + printf("\tsb %s,%s\n",crn,nm); } else { - printf("\tsw %s,%s\n",crn,nm); + printf("\tsw %s,%s\n",crn,nm); } } @@ -1471,16 +1632,16 @@ char *crn; crn=register_name(creg); if (byte) { - printf("\tsb %s,",crn); lvar(e2); + printf("\tsb %s,",crn); lvar(e2); } else { - printf("\tsw %s,",crn); lvar(e2); + printf("\tsw %s,",crn); lvar(e2); } } void code_assign_register(int e2,int byte,int creg) { if (e2!=creg) - printf("\tmove %s,%s\n",register_name(e2),register_name(creg)); + printf("\tmove %s,%s\n",register_name(e2),register_name(creg)); } void @@ -1489,10 +1650,11 @@ char *crn=register_name(creg); if (byte) { - printf("\tsb %s,0(%s)\n",crn,drn); + printf("\tsb %s,0(%s)\n",crn,drn); } else { - printf("\tsw %s,0(%s)\n",crn,drn); + printf("\tsw %s,0(%s)\n",crn,drn); } + regv[creg]=1; } @@ -1504,7 +1666,8 @@ tosop(op,xreg); creg = xreg; if (creg!=reg) - printf("\tmove %s,%s\n",register_name(creg),register_name(reg)); + printf("\tmove %s,%s\n",register_name(creg),register_name(reg)); + regv[creg]=1; } @@ -1522,12 +1685,13 @@ crn = register_name(creg); drn = register_name(edx); if (byte) { - printf("\tsb %s,0(%s)\n",crn,drn); + printf("\tsb %s,0(%s)\n",crn,drn); } else { - printf("\tsw %s,0(%s)\n",crn,drn); + printf("\tsw %s,0(%s)\n",crn,drn); } free_register(edx); emit_pop_free(xreg); + regv[creg]=1; } @@ -1535,7 +1699,7 @@ tosop(int op,int oreg) { int dx; - char *orn,*crn; + char *orn,*crn,*drn; if(oreg==-1) { error(-1); @@ -1550,12 +1714,15 @@ case LSHIFT: case ULSHIFT: shift("sll",oreg); + regv[creg]=1; return; case RSHIFT: shift("srl",oreg); + regv[creg]=1; return; case URSHIFT: shift("sra",oreg); + regv[creg]=1; return; } orn = register_name(oreg); @@ -1585,19 +1752,23 @@ case UMUL: printf("\tmultu %s,%s,%s\n",crn,crn,orn); break; + case DIV: + printf("\tdivw %s,%s,%s\n",crn,crn,orn); + break; case DIV: case UDIV: case MOD: case UMOD: - printf("\t%s $0,%s,%s\n",(op==UDIV||op==UMOD)?"divu":"div",crn,orn); - printf("\t%s %s\n",(op==MOD||op==UMOD)?"mflo":"mfhi",crn); - printf("\t.set noreorder\n"); - printf("\tbeql %s,$0,1f\n",orn); - printf("\tbreak 7\n"); - printf("1:\n"); - printf("\t.set reorder\n"); - break; + printf("\t%s $0,%s,%s\n",(op==UDIV||op==UMOD)?"divu":"div",crn,orn); + printf("\t%s %s\n",(op==MOD||op==UMOD)?"mflo":"mfhi",crn); + printf("\t.set noreorder\n"); + printf("\tbeql %s,$0,1f\n",orn); + printf("\tbreak 7\n"); + printf("1:\n"); + printf("\t.set reorder\n"); + break; default: error(-1); } if(oreg!=creg) free_register(oreg); + regv[creg]=1; } @@ -1614,12 +1785,12 @@ { char *crn = register_name(creg); if (byte) { - printf("\tlb %s,%d(%s)\n",register_name(creg),n, - register_name(xreg)); - printf("\textsb %s,%s\n",crn,crn); + printf("\tlb %s,%d(%s)\n",register_name(creg),n, + register_name(xreg)); + printf("\textsb %s,%s\n",crn,crn); } else - printf("\tlw %s,%d(%s)\n",register_name(creg),n, - register_name(xreg)); + printf("\tlw %s,%d(%s)\n",register_name(creg),n, + register_name(xreg)); } int @@ -1634,8 +1805,8 @@ /* used in dosiwtch() */ if(chk) return; printf("\tli %s,%d\n",register_name(creg),e); - dreg = csreg; - regv[dreg]=2; /* prevent from freeing */ + cmpreg = csreg; + regv[cmpreg]=2; /* prevent from freeing */ } void @@ -1651,13 +1822,13 @@ printf("\t.text\n"); if (asi) { - fclose(asi); - asi = 0; + fclose(asi); + asi = 0; } while ((*cheapp++ = *s++)) { if (*s=='.') { *cheapp++=*s++; *cheapp++='i'; - *cheapp++=0; + *cheapp++=0; break; } } @@ -1670,39 +1841,39 @@ rexpr(int e1, int l1, char *s,int t) { char *crn,*drn; - if (dreg>=0) { free_register(dreg); dreg = -1; } + if (cmpreg>=0) { free_register(cmpreg); cmpreg = -1; } g_expr(cadr(e1)); emit_push(); g_expr(caddr(e1)); - dreg = pop_register(); + cmpreg = pop_register(); crn = register_name(creg); - drn = register_name(dreg); + drn = register_name(cmpreg); if (s[1] == 's') { - if (s[16]=='x') { - /* slt $2,$2,$3; xroi $2,$2,0x1; beq $2,$0,L1 */ - printf(s,crn,drn,drn,crn,crn,crn,l1); - } else { - /* slt $2,$2,$3; beq $2,$0,L1 */ - printf(s,crn,drn,drn,crn,l1); - } + if (s[16]=='x') { + /* slt $2,$2,$3; xroi $2,$2,0x1; beq $2,$0,L1 */ + printf(s,crn,drn,drn,crn,crn,crn,l1); + } else { + /* slt $2,$2,$3; beq $2,$0,L1 */ + printf(s,crn,drn,drn,crn,l1); + } } else { - /* beq $2,$3,L1 */ - printf(s,crn,drn,l1); + /* beq $2,$3,L1 */ + printf(s,crn,drn,l1); } - free_register(dreg) ; dreg = -1; + free_register(cmpreg) ; cmpreg = -1; } void jcond(int l, char cond) { if (chk) return; - if (dreg==-1) error(-1); - printf("\tb%s %s,%s,L_%d\n",register_name(creg),register_name(dreg), - cond?"ne":"eq",l); - if (regv[dreg]==1) { - free_register(dreg); dreg = -1; + if (cmpreg==-1) error(-1); + printf("\tb%s %s,%s,L_%d\n",register_name(creg),register_name(cmpreg), + cond?"ne":"eq",l); + if (regv[cmpreg]==1) { + free_register(cmpreg); cmpreg = -1; } regv[creg]=0; } @@ -1730,7 +1901,7 @@ else printf("\t.align 3\n"); if (stmode!=STATIC) - printf(".globl %s\n",name); + printf(".globl _%s\n",name); printf(".ent %s\n",name); printf("_%s:\n",name); code_disp_label=fwdlabel(); @@ -1740,6 +1911,7 @@ printf("\t.set reorder\n"); printf("\tsubu $sp,$sp,L_%d\n",code_disp_label); printf("\t.cprestore 16\n"); + max_func_args = 0; } @@ -1749,6 +1921,7 @@ { set_creg(CREG_REGISTER,0); set_freg(FREG_FREGISTER,0); + set_dreg(DREG_DREGISTER,0); } void @@ -1759,6 +1932,7 @@ r1_offsetv = -disp+max_func_args*size_of_int+code_disp_offset; fprintf(asi,"L_%d=%d\n",code_disp_label,-r1_offsetv); + local_table(); free_all_register(); } @@ -1771,7 +1945,7 @@ else printf("\t.align 2\n"); if (stmode!=STATIC) - printf(".globl %s\n",name); + printf(".globl _%s\n",name); printf(".ent %s\n",name); printf("_%s:\n",name); @@ -1792,6 +1966,7 @@ printf("\tsubu $sp,$sp,L_%d\n",code_disp_label); printf("\t.cprestore 16\n"); max_func_args = 0; + } void @@ -1799,6 +1974,7 @@ { set_creg(CREG_REGISTER,0); set_freg(FREG_FREGISTER,0); + set_dreg(DREG_DREGISTER,0); } int @@ -1865,9 +2041,17 @@ } disp &= -size_of_int; - - printf("\tj $31\n"); - printf("\t.end %s\n",fnptr->nm); + fwddef(code_setup); + printf("\tstmw r%d,%d(r1)\n", + REG_VAR_BASE-max_reg_var,reg_save); + printf("\tstw r0,8(r1)\n"); + if (max_freg_var>=0) + printf("\tb saveFP+%d ; save f%d-f31\n", + freg_save, + FREG_VAR_BASE-max_freg_var); + else { + printf("\tblr\n"); + } code_offset_set(); local_table(); @@ -1878,8 +2062,11 @@ void code_set_return_register(int mode) { - if (cadr(fnptr->ty)==DOUBLE||cadr(fnptr->ty)==FLOAT) { + if (cadr(fnptr->ty)==DOUBLE) { + set_dreg(RET_DREGISTER,mode); + } else if (cadr(fnptr->ty)==FLOAT) { set_freg(RET_FREGISTER,mode); + } else if (cadr(fnptr->ty)==VOID) { } else { set_creg(RET_REGISTER,mode); } @@ -1887,12 +2074,18 @@ void code_set_fixed_creg(int mode,int type) { - if (type==FLOAT||type==DOUBLE) { + if (type==FLOAT) { if (cond_freg== -1) { - cond_freg = get_dregister_var(0,1); - if(car(cond_freg)!=DREGISTER) error(-1); + cond_freg = get_dregister_var(0,0); + if(car(cond_freg)!=FREGISTER) error(-1); } set_freg(cadr(cond_freg),mode); + } else if (type==DOUBLE) { + if (cond_dreg== -1) { + cond_dreg = get_dregister_var(0,1); + if(car(cond_dreg)!=DREGISTER) error(-1); + } + set_dreg(cadr(cond_dreg),mode); } else { if (cond_reg== -1) { cond_reg = get_register_var(0); @@ -1906,7 +2099,7 @@ gen_gdecl(char *n, int gpc) { if (stmode!=STATIC) - printf(".globl %s\n",n); + printf(".globl _%s\n",n); } void @@ -1951,32 +2144,32 @@ if (data_alignment>0) data_alignment++; gpc += 2; } else { - printf("\t.long %d\n",cadr(e)); + printf("\t.word %d\n",cadr(e)); gpc += size_of_int; } } else if(t==DOUBLE) { - d = dcadr(e); - printf("\t.word\t0x%x\n\t.word\t0x%x\n",code_d2(d),code_d1(d)); + d = dcadr(e); + printf("\t.word\t0x%x\n\t.word\t0x%x\n",code_d2(d),code_d1(d)); } else if(t==FLOAT) { - f = dcadr(e); - printf("\t.word\t0x%x\n",*(int *)&f); + f = dcadr(e); + printf("\t.word\t0x%x\n",*(int *)&f); } else if(t!=CHAR) { gpc += size_of_int; - if(car(e)==ADDRESS&&car(cadr(e))==GVAR) { - printf("\t.word _%s\n",((NMTBL *)cadr(cadr(e)))->nm); - } else if(car(e)==FNAME) { - printf("\t.word _%s\n",((NMTBL *)cadr(e))->nm); - } else if(car(e)==GVAR) { - printf("\t.word _%s\n",((NMTBL *)cadr(e))->nm); - } else if(car(e)==STRING) { - if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) { - l = fwdlabel(); - printf("\t.word L_%d\n",l); - printf(".rdata\n\t.align 2\n"); - printf("L_%d:\n",l); - output_mode = RODATA_EMIT_MODE; - } - ascii((char *)cadr(e)); + if(car(e)==ADDRESS&&car(cadr(e))==GVAR) { + printf("\t.word _%s\n",((NMTBL *)cadr(cadr(e)))->nm); + } else if(car(e)==FNAME) { + printf("\t.word _%s\n",((NMTBL *)cadr(e))->nm); + } else if(car(e)==GVAR) { + printf("\t.word _%s\n",((NMTBL *)cadr(e))->nm); + } else if(car(e)==STRING) { + if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) { + l = fwdlabel(); + printf("\t.word L_%d\n",l); + printf(".rdata\n\t.align 2\n"); + printf("L_%d:\n",l); + output_mode = RODATA_EMIT_MODE; + } + ascii((char *)cadr(e)); } else error(TYERR); } } @@ -1998,28 +2191,27 @@ } } -void global_table(void) { NMTBL *n; int init; init=0; for(n=ntable;n < &ntable[GSYMS];n++) { - if ((n->sc == GVAR) && n->dsp != -1) { - /* n->dsp = -1 means initialized global */ - if (init==0) { - data_mode(0); - init=1; - } - printf(".comm _%s,%d\n",n->nm,size(n->ty)); - } else if ((n->sc==STATIC) && n->dsp != -1) { - /* n->dsp = -1 means initialized global */ - if (init==0) { - data_mode(0); - init=1; - } - printf(".lcomm _%s,%d\n",n->nm,size(n->ty)); - } + if ((n->sc == GVAR) && n->dsp != -1) { + /* n->dsp = -1 means initialized global */ + if (init==0) { + data_mode(0); + init=1; + } + printf(".comm _%s,%d\n",n->nm,size(n->ty)); + } else if ((n->sc==STATIC) && n->dsp != -1) { + /* n->dsp = -1 means initialized global */ + if (init==0) { + data_mode(0); + init=1; + } + printf(".lcomm _%s,%d\n",n->nm,size(n->ty)); + } } } @@ -2062,32 +2254,31 @@ printf("\t.type\t%s,@object\n",name); } -/* floating point */ - char * fstore(int d) { - return (d?"s.d":"s.s"); + return (d?"stfd":"stfs"); } char * fload(int d) { - return d?"l.d":"l.s"; + return d?"lfd":"lfs"; } void code_cmp_dregister(int e2,int d) { - /* not tested.. */ - char *frn,*grn; - int greg; - + char *frn,*rrn,*grn; + int greg,r; grn = register_name(greg = get_dregister(d)); frn = register_name(e2); - printf("\tli.s %s,%g\n",grn,0.0); - printf("\tc.eq.s %s,%s\n",grn,frn); - free_dregister(greg); + float_zero_lib_used=1; + r = get_ptr_cache(&float_zero); + rrn = register_name(r); + printf("\tlfs %s,0(%s)\n",grn,rrn); + printf("\tfcmpu cr0,%s,%s\n",grn,frn); + free_register(greg); return; } @@ -2095,71 +2286,42 @@ code_dregister(int e2,int freg,int d) { if (freg!=e2) { - if (d) { - printf("\tmove %s,%s\n", - fregister_name0(freg), - fregister_name0(e2)); - printf("\tmove %s,%s\n", - fregister_name1(freg), - fregister_name1(e2)); - } else { - printf("\tmov.s %s,%s\n",fregister_name(freg),fregister_name(e2)); - } + if (is_int_reg(e2)) error(-1); + printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2)); } - fregv[freg]=1; + regv[freg]=1; } void code_dassign_gvar(int e2,int freg,int d) { - NMTBL *n = (NMTBL*)cadr(e2); - if (d) { - printf("\tsw %s,0(%s)\n",fregister_name0(freg),n->nm); - printf("\tsw %s,0(%s)\n",fregister_name1(freg),n->nm); - } else { - printf("\t%s.s %s,0(%s)\n",fregister_name(freg),n->nm); - } - fregv[freg]=1; + int r; + r = get_ptr_cache((NMTBL*)cadr(e2)); + if (!is_float_reg(freg)) error(-1); + printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(r)); + regv[freg]=1; } void code_dassign_lvar(int e2,int freg,int d) { - if (d) { - printf("\tsw %s,",fregister_name0(freg)); - lvar(e2); - printf("\tsw %s,",fregister_name1(freg)); - e2 += size_of_double/2; - } else { - printf("\ts.s %s,",fregister_name(freg)); - } + lvar_intro(e2); + if (!is_float_reg(freg)) error(-1); + printf("\t%s %s,",fstore(d),fregister_name(freg)); lvar(e2); - fregv[freg]=1; + regv[freg]=1; } void code_dassign(int e2,int freg,int d) { - if (d) { - printf("\tsw %s,0(%s)\n",fregister_name0(freg),register_name(e2)); - printf("\tsw %s,4(%s)\n",fregister_name1(freg),register_name(e2)); - } else { - printf("\ts.s %s,0(%s)\n",fregister_name(freg),register_name(e2)); - } - fregv[freg]=1; + if (!is_float_reg(freg)) error(-1); + printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(e2)); + regv[freg]=1; } void code_dassign_dregister(int e2,int d,int freg) { - /* これってさ、code_dregister と同じ? */ if (e2!=freg) { - if (d) { - printf("\tmove %s,%s\n", - fregister_name0(freg), - fregister_name0(e2)); - printf("\tmove %s,%s\n", - fregister_name1(freg), - fregister_name1(e2)); - } else { - printf("\tmov.s %s,%s\n",fregister_name(e2),fregister_name(freg)); - } + if (is_int_reg(freg)) error(-1); + printf("\tfmr %s,%s\n",fregister_name(e2),fregister_name(freg)); } } @@ -2187,268 +2349,301 @@ return *j; } -void code_dconst(int e2,int freg,int d) +void +code_dconst(int e2,int freg,int d) { + int lb; double value = dcadr(e2); - char *frn; + int r; + char *rrn,*frn; + frn = fregister_name(freg); + if (value==0.0) { + float_zero_lib_used=1; + r = get_ptr_cache(&float_zero); + rrn = register_name(r); + printf("\tlfs %s,0(%s)\n",frn,rrn); + return; + } + if (value==1.0) { + float_one_lib_used=1; + r = get_ptr_cache(&float_one); + rrn = register_name(r); + printf("\tlfs %s,0(%s)\n",frn,rrn); + return; + } + rrn = register_name((r=get_register())); + printf(" \t.data\n\t.align 3\n"); + lb=fwdlabel(); + printf("L_%d:\n",lb); if (d) { - printf("\tli %s,%g\n",fregister_name0(freg),code_d1(value)); - printf("\tli %s,%g\n",fregister_name1(freg),code_d2(value)); + printf("\t.long\t0x%x,0x%x\n",code_d2(value),code_d1(value)); + } else { + printf("\t.long\t0x%x\n",code_f(value)); + } + if (output_mode==TEXT_EMIT_MODE) { + printf(".text\n"); } else { - frn = fregister_name(freg); - printf("\tli.s %s,%g\n",frn,value); + text_mode(); } - fregv[freg]=1; + printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",rrn,lb,code_base); + printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",rrn,lb,code_base,rrn); + if (d) { + printf("\tlfd %s,0(%s)\n",frn,rrn); + } else { + printf("\tlfs %s,0(%s)\n",frn,rrn); + } + free_register(r); + regv[freg]=1; } void code_dneg(int freg,int d) { - char *frn; - if (d) { - code_save_stacks(); - printf("\tmove $4,%s\n", fregister_name0(freg)); - printf("\tmove $5,%s\n", fregister_name1(freg)); - printf("\tjal dpneg\n"); - set_freg(RET_DREGISTER,0); - } else { - frn = fregister_name(freg); - printf("\tfneg %s,%s\n",frn,frn); - } + char *frn = fregister_name(freg); + if (is_int_reg(freg)) error(-1); + printf("\tfneg %s,%s\n",frn,frn); } -void code_d2i(int freg,int creg) -{ - char *frn = fregister_name(freg); - char *crn = register_name(creg); - int e2 = new_lvar(size_of_double); - free_lvar(e2); - code_save_stacks(); - /* setup arguments */ - printf("\tjal dptoli\n"); - printf("\tstfd %s,",frn); lvar(e2); - printf("\tlwz %s,",crn); lvar(e2+size_of_double-size_of_int); - fregs[freg]=0; - regs[creg]=1; -} - -void code_i2d(int creg,int freg) -{ - code_save_stacks(); - set_creg(RET_REGISTER,1); - printf("\tjal litodp\n"); - set_freg(RET_DREGISTER,0); - fregs[freg]=1; - regs[creg]=0; -} - - -void code_d2u(int freg,int creg) -{ - code_save_stacks(); - set_freg(RET_FREGISTER,1); - printf("\tjal dptoul\n"); - set_creg(RET_REGISTER,0); - fregs[freg]=1; - regs[creg]=0; -} - -void code_u2d(int creg,int freg) +void code_d2i(int freg0) { char *frn; char *crn; - code_save_stacks(); - frn = fregister_name(freg); + int e2 = new_lvar(size_of_double); + + freg0 = use_double(freg0); + frn = fregister_name(freg0); + creg = use_int(creg); crn = register_name(creg); - printf("\tmr r3,%s\n",crn); - printf("\tjal litodp\n"); - printf("\tfmr %s,f1\n",frn); - fregs[freg]=1; - regs[creg]=0; + freg = freg0; + free_lvar(e2); + printf("\tfctiwz %s,%s\n",frn,frn); + lvar_intro(e2); + printf("\tstfd %s,",frn); lvar(e2); + lvar_intro(e2+size_of_double-size_of_int); + printf("\tlwz %s,",crn); lvar(e2+size_of_double-size_of_int); + regv[creg]=1; } -void code_d2f(int freg) { +static int i2d_lib_used=0; +static char *i2d_lib[] = { +".data", +/* ".literal8", */ +" .align 3", +"__i2dLC0:", +" .long 1127219200", +" .long -2147483648", +".text", +" .align 2", +"i2d_:", +" mflr r0", +" bcl 20,31,__i2dL1$pb", +"__i2dL1$pb:", +" mflr r10", +" mtlr r0", +" xoris r3,r3,0x8000", +" stw r3,-28(r30)", +" lis r0,0x4330", +" stw r0,-32(r30)", +" lfd f0,-32(r30)", +" addis r9,r10,ha16(__i2dLC0-__i2dL1$pb)", +" lfd f1,lo16(__i2dLC0-__i2dL1$pb)(r9)", +" fsub f1,f0,f1", +" blr", +0 +}; + +void code_i2d(int creg0) +{ + i2d_lib_used = 1; + clear_ptr_cache(); code_save_stacks(); - /* setup arguments */ - printf("\tmove $4,%s\n", fregister_name0(freg)); - printf("\tmove $5,%s\n", fregister_name1(freg)); - printf("\tjal dptofp\n"); + set_creg(RET_REGISTER,1); + printf("\tbl i2d_\n"); set_freg(RET_FREGISTER,0); + regv[freg]=1; } -void code_f2d(int freg) { +static int d2u_lib_used=0; +static char *d2u_lib[] = { +/* ".literal8", */ +" .align 3", +"__d2uLC0:", +" .long 1105199104", +" .long 0", +".text", +" .align 2", +"d2u_:", +" mflr r0", +" bcl 20,31,__d2uL1$pb", +"__d2uL1$pb:", +" mflr r10", +" mtlr r0", +" addis r9,r10,ha16(__d2uLC0-__d2uL1$pb)", +" lfd f0,lo16(__d2uLC0-__d2uL1$pb)(r9)", +" fcmpu cr0,f1,f0", +" cror 2,1,2", +" beq- cr0,__d2uL2", +" fctiwz f0,f1", +" stfd f0,-32(r30)", +" lwz r3,-28(r30)", +" blr", +"__d2uL2:", +" addis r9,r10,ha16(__d2uLC0-__d2uL1$pb)", +" lfd f0,lo16(__d2uLC0-__d2uL1$pb)(r9)", +" fsub f0,f1,f0", +" fctiwz f0,f0", +" stfd f0,-24(r30)", +" lwz r3,-20(r30)", +" xoris r3,r3,0x8000", +" blr", +0 +}; + +void code_d2u(int freg0) +{ code_save_stacks(); - /* setup arguments */ - printf("\tmov.s f12,%s\n", fregister_name(freg)); - printf("\tjal fptodp\n"); - set_freg(RET_DREGISTER,0); -} - -void code_f2i(int freg,int creg) { - printf("\ttrunc.w.s %s,%s,%s\n",freg,freg,creg); + clear_ptr_cache(); + d2u_lib_used=1; + set_freg(RET_FREGISTER,1); + printf("\tbl d2u_\n"); + set_creg(RET_REGISTER,0); + regv[freg]=1; } -void code_f2u(int freg,int creg) { - printf("\ttrunc.w.s %s,%s,%s\n",freg,freg,creg); +static int u2d_lib_used=0; +static char *u2d_lib[] = { +".data", +/* ".literal8", */ +" .align 3", +"__u2dLC1:", +" .long 1127219200", +" .long 0", +".text", +" .align 2", +"u2d_:", +" mflr r0", +" bcl 20,31,__u2dL2$pb", +"__u2dL2$pb:", +" mflr r10", +" mtlr r0", +" stw r3,-28(r30)", +" lis r0,0x4330", +" stw r0,-32(r30)", +" lfd f0,-32(r30)", +" addis r9,r10,ha16(__u2dLC1-__u2dL2$pb)", +" lfd f1,lo16(__u2dLC1-__u2dL2$pb)(r9)", +" fsub f1,f0,f1", +" blr", +0 +}; + +void code_u2d(int creg0) +{ + code_save_stacks(); + clear_ptr_cache(); + u2d_lib_used = 1; + set_creg(RET_REGISTER,1); + printf("\tbl u2d_\n"); + set_freg(FREG_FREGISTER,0); + regv[freg]=1; } -void code_i2f(int creg,int freg) { - printf("\tcvt.s.w %s,%s\n",freg,freg); -} - -void code_u2f(int creg,int freg) { - printf("\tcvt.s.w %s,%s\n",freg,freg); -} +void code_d2f(int freg) { } +void code_f2d(int freg) { } +void code_f2i(int freg) { code_d2i(freg); } +void code_f2u(int freg) { code_d2u(freg); } +void code_i2f(int creg) { code_i2d(creg); } +void code_u2f(int creg) { code_u2d(creg); } void code_drgvar(int e2,int d,int freg) { - char *nm = ((NMTBL*)cadr(e2))->nm; - if (d) { - printf("\tlw %s,%s\n",fregister_name0(freg),nm); - printf("\tlw %s,%s\n",fregister_name1(freg),nm); - } else { - printf("\tl.s %s,%s\n",fregister_name(freg),nm); - } - fregv[freg]=1; + int r; + r = get_ptr_cache((NMTBL*)cadr(e2)); + printf("\t%s %s,0(%s)\n",fload(d),fregister_name(freg),register_name(r)); + regv[freg]=1; } void code_drlvar(int e2,int d,int freg) { - if (d) { - printf("\tlw %s,\n",fregister_name0(freg)); lvar(e2); - printf("\tlw %s,%s\n",fregister_name1(freg)); lvar(e2+size_of_double/2); - } else { - printf("\tl.s %s,",fregister_name(freg)); lvar(e2); - } - fregv[freg]=1; + lvar_intro(e2); + printf("\t%s %s,",fload(d),fregister_name(freg)); lvar(e2); + regv[freg]=1; } void code_cmp_drgvar(int e2,int d) { + int r; char *frn=fregister_name(freg); - int g,g1; - char *grn; - if (d) { - g=get_input_dregister_var(0,0,0,d); - g1=get_input_dregister_var(1,0,0,d); - code_drgvar(e2,d,g1); - if (freg!=g) { - printf("\tmove $3,%s\n", fregister_name0(freg)); - printf("\tmove $4,%s\n", fregister_name1(freg)); - } - printf("\tjal dcmp\n"); - } else { - g=get_dregister(d); - code_drgvar(e2,d,g); - printf("\tfc.eq.s %s,%s\n",frn,fregister_name(g)); - } - free_dregister(g); - fregv[freg]=0; + int g=get_dregister(d); + char *grn=fregister_name(g); + r = get_ptr_cache((NMTBL*)cadr(e2)); + printf("\t%s %s,0(%s)\n",fload(1),grn,register_name(r)); + printf("\tfcmpu cr0,%s,%s\n",frn,grn); + free_register(g); + regv[freg]=0; } void code_cmp_drlvar(int e2,int d) { char *frn=fregister_name(freg); - int g,g1; - char *grn; - if (d) { - g=get_input_dregister_var(0,0,0,d); - g1=get_input_dregister_var(1,0,0,d); - if (freg!=g) { - printf("\tmove $3,%s\n", fregister_name0(freg)); - printf("\tmove $4,%s\n", fregister_name1(freg)); - } - code_drlvar(e2,d,g1); - printf("\tjal dcmp\n"); - } else { - g=get_dregister(d); - code_drlvar(e2,d,g); - printf("\tc.eq.s %s,%s\n",frn,fregister_name(g)); - } - free_dregister(g); - fregv[freg]=0; -} + int g=get_dregister(d); + char *grn=fregister_name(g); -static void -dtosop0(char *opn,int e1,int d,int cmp) -{ - char *frn; - char *grn; - if (d) { - g=get_input_dregister_var(0,0,0,d); - g1=get_input_dregister_var(1,0,0,d); - if (freg!=g) { - printf("\tmove $3,%s\n", fregister_name0(freg)); - printf("\tmove $4,%s\n", fregister_name1(freg)); - } - if (e1!=g1) { - printf("\tmove $5,%s\n", fregister_name0(e1)); - printf("\tmove $6,%s\n", fregister_name1(e1)); - } - printf("\tjal %s\n",opn); - set_freg(RET_DREGISTER,0); - } else { - frn=fregister_name(freg); - grn=fregister_name(e1); - if (cmp) { - printf("\t%s %s,%s\n",opn,frn,grn); - } else { - printf("\t%s %s,%s,%s\n",opn,frn,frn,grn); - } - } - free_dregister(e1); + lvar_intro(e2); + printf("\t%s %s,",fload(1),grn); lvar(e2); + printf("\tfcmpu cr0,%s,%s\n",frn,grn); + free_register(g); + regv[freg]=0; } void dtosop(int op,int e1) { char *opn=""; - fregv[freg]=1; + char *frn=fregister_name(freg); + char *grn=fregister_name(e1); + regv[freg]=1; switch(op) { - case FADD: dtosop0("fadd",e1,0,0); return; - case DADD: dtosop0("dpadd",e1,1,0); return; - case FSUB: dtosop0("fadd",e1,0,0); return; - case DSUB: dtosop0("dpsub",e1,1,0); return; - case FDIV: dtosop0("fadd",e1,0,0); return; - case DDIV: dtosop0("dpdiv",e1,1,0); return; - case FMUL: dtosop0("fadd",e1,0,0); return; - case DMUL: dtosop0("dpmul",e1,1,0); return; + case FADD: + case DADD: opn="fadd"; break; + case FSUB: + case DSUB: opn="fsub"; break; + case FDIV: + case DDIV: opn="fdiv"; break; + case FMUL: + case DMUL: opn="fmul"; break; + case FCMP: + case DCMP: + printf("\tfcmpu cr0,%s,%s\n",frn,grn); + free_register(e1); + return; + case FCMPGE: case DCMPGE: - case DCMP: dtosop0("dpcmp",e1,1,1); return; - case FCMPGE: dtosop0("c.le.s",e1,0,1); return; - case FCMP: dtosop0("c.eq.s",e1,0,1); return; + printf("\tfcmpu cr7,%s,%s\n",frn,grn); + free_register(e1); + return; default: error(-1); return; } + printf("\t%s %s,%s,%s\n",opn,frn,frn,grn); + regv[freg]=1; + free_register(e1); } void code_dassop(int op,int d) { /* we have lvalue in creg, applied floating value is in freg */ - char *frn; - int xreg; + char *frn=fregister_name(freg); + int xreg=emit_dpop(d); char *crn=register_name(creg); - if (d) { - xreg=emit_dpop(d); - printf("\tlw %s,0(%s)\n",register_name0(freg),crn); - printf("\tlw %s,%d(%s)\n",register_name1(freg),size_of_int,crn); - dtosop(op,xreg); - printf("\tsw %s,0(%s)\n",register_name0(freg),crn); - printf("\tsw %s,%d(%s)\n",register_name1(freg),size_of_int,crn); - emit_dpop_free(xreg,d); - } else { - xreg=emit_dpop(d); - frn=fregister_name(freg); - crn=register_name(creg); - - printf("\tl.s %s,0(%s)\n",frn,crn); - dtosop(op,xreg); - printf("\ts.s %s,0(%s)\n",frn,crn); - emit_dpop_free(xreg,d); - } - fregv[freg]=1; + if (!is_float_reg(freg)) error(-1); + printf("\t%s %s,0(%s)\n",fload(d),frn,crn); + dtosop(op,xreg); + printf("\t%s %s,0(%s)\n",fstore(d),frn,crn); + emit_dpop_free(xreg,d); + regv[freg]=1; } @@ -2458,38 +2653,32 @@ char *crn; int g; char *grn,*drn; + int r; + r = get_ptr_cache(&float_one); + float_one_lib_used=1; + if (car(e2)==DREGISTER||car(e2)==FREGISTER) { + error(-1); /* unspported now */ + } g_expr(e2); - if (d) { - crn=register_name(creg); - frn=fregister_name(freg); + crn=register_name(creg); + frn=fregister_name(freg); + drn=register_name(r); + grn=fregister_name(g=get_dregister(d)); - printf("\tlw $4,0(%s)\n",crn); - printf("\tlw $5,%d(%s)\n",size_of_int,crn); - printf("\tli.d $6,1.0\n"); - if (caddr(e1)>0) - printf("\tjal dpadd\n"); - else - printf("\tjal dpsub\n"); - set_freg(RET_DREGISTER,0); - printf("\tsw $2,0(%s)\n",crn); - printf("\tsw $3,%d(%s)\n",size_of_int,crn); - } else { - crn=register_name(creg); - frn=fregister_name(freg); - grn=fregister_name(g=get_dregister(d)); - - printf("\tl.s %s,0(%s)\n",frn,crn); - printf("\tli.s %s,1.0\n",grn); - if (caddr(e1)>0) - printf("\tfadd %s,%s,%s\n",frn,frn,grn); - else - printf("\tfsub %s,%s,%s\n",frn,frn,grn); - printf("\ts.s %s,0(%s)\n",frn,crn); - free_dregister(g); - } - fregv[freg]=1; + printf("\t%s %s,0(%s)\n",fload(d),frn,crn); + printf("\tlfs %s,0(%s)\n",grn,drn); + if (caddr(e1)>0) + printf("\tfadd %s,%s,%s\n",frn,frn,grn); + else + printf("\tfsub %s,%s,%s\n",frn,frn,grn); + if (!is_float_reg(freg)) error(-1); + printf("\t%s %s,0(%s)\n",fstore(d),frn,crn); + free_register(g); + regv[freg]=1; + regv[ireg]=0; + creg = freg; } void @@ -2498,73 +2687,55 @@ char *crn; int g; char *grn,*drn; + int r; + r = get_ptr_cache(&float_one); + float_one_lib_used=1; + if (car(e2)==DREGISTER||car(e2)==FREGISTER) { + error(-1); /* unspported now */ + } g_expr(e2); - if (d) { - crn=register_name(creg); - frn=fregister_name(freg); - g = get_dregister(d); + crn=register_name(creg); + frn=fregister_name(freg); + drn=register_name(r); + grn=fregister_name(g=get_dregister(d)); - printf("\tlw $4,0(%s)\n",crn); - printf("\tlw $5,%d(%s)\n",size_of_int,crn); - printf("\tmove %s,$4\n",fregister_name0(g)); - printf("\tmove %s,$5\n",fregister_name0(g)); - printf("\tli.d $6,1.0\n"); - if (caddr(e1)>0) - printf("\tjal dpadd\n"); - else - printf("\tjal dpsub\n"); - set_freg(RET_DREGISTER,0); - printf("\tsw $2,0(%s)\n",crn); - printf("\tsw $3,%d(%s)\n",size_of_int,crn); - free_dregister(freg); - set_freg(g,0); - } else { - crn=register_name(creg); - frn=fregister_name(freg); - grn=fregister_name(g=get_dregister(d)); - - printf("\tl.s %s,0(%s)\n",frn,crn); - printf("\tli.s %s,1.0\n",grn); - if (caddr(e1)>0) - printf("\tfadd %s,%s,%s\n",frn,frn,grn); - else - printf("\tfsub %s,%s,%s\n",frn,frn,grn); - printf("\ts.s %s,0(%s)\n",grn,crn); - free_dregister(g); - } - fregv[freg]=1; + printf("\t%s %s,0(%s)\n",fload(d),frn,crn); + printf("\tlfs %s,0(%s)\n",grn,drn); + if (caddr(e1)>0) + printf("\tfadd %s,%s,%s\n",grn,frn,grn); + else + printf("\tfsub %s,%s,%s\n",grn,frn,grn); + if (!is_float_reg(freg)) error(-1); + printf("\t%s %s,0(%s)\n",fstore(d),grn,crn); + free_register(g); + regv[freg]=1; + regv[ireg]=0; + creg = freg; } void drexpr(int e1, int e2,int l1, int op) { - g_expr(list3(((op==FOP+EQ||op==FOP+NEQ)?DCMP:FCMPGE),e1,e2)); + g_expr(list3(((op==DOP+GE)?DCMPGE:DCMP),e1,e2)); switch(op) { case DOP+GE: - printf("\tbgez\tL_%d\n",l1); + case FOP+GE: + printf("\tcror 2,29,30\n"); + printf("\tbne\tcr0,L_%d\n",l1); break; case DOP+GT: - printf("\tbltz\tL_%d\n",l1); + case FOP+GT: + printf("\tble\tcr0,L_%d\n",l1); break; case DOP+EQ: - printf("\tbeq\tL_%d\n",l1); + case FOP+EQ: + printf("\tbne\tcr0,L_%d\n",l1); break; case DOP+NEQ: - printf("\tbne\tL_%d\n",l1); - break; - case FOP+GE: - printf("\tbc1tl\tL_%d\n",l1); - break; - case FOP+GT: - printf("\tbc1tl\tL_%d\n",l1); - break; - case FOP+EQ: - printf("\tbc1f\tL_%d\n",l1); - break; case FOP+NEQ: - printf("\tbc1f\tL_%d\n",l1); + printf("\tbeq\tcr0,L_%d\n",l1); break; } } @@ -2575,26 +2746,26 @@ xreg=pop_fregister(); if (xreg<= -REG_LVAR_OFFSET) { reg = get_dregister(d); - code_drlvar(REG_LVAR_OFFSET+xreg,d,reg); + code_drlvar(REG_LVAR_OFFSET+xreg,1,reg); free_lvar(REG_LVAR_OFFSET+xreg); - fregv[reg]=1; xreg=reg; + regv[reg]=1; xreg=reg; } return xreg; } void emit_dpop_free(int e1,int d) { - free_dregister(e1); + free_register(e1); } void emit_dpush(int d) { int new_reg; if (freg_sp>MAX_MAX) error(-1); - new_reg = get_dregister(d); + new_reg = get_dregister(1); freg_stack[freg_sp++] = freg; /* push するかわりにレジスタを使う */ - freg = new_reg; - fregv[freg]=1; + creg = freg = new_reg; + regv[freg]=1; } void @@ -2628,9 +2799,13 @@ void code_closing() { + 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 (float_zero_lib_used) emit_lib(float_zero_lib); + if (i2d_lib_used) emit_lib(i2d_lib); global_table(); /* printf("\t.ident \"Micro-C compiled\"\n"); */ - fclose(asi); } /* end */ diff -r cb7aa0089681 -r e0eba2993c37 mc-code-powerpc.c --- a/mc-code-powerpc.c Wed Jun 11 12:26:03 2003 +0900 +++ b/mc-code-powerpc.c Sun Jul 13 23:59:26 2003 +0900 @@ -458,8 +458,8 @@ get_input_dregister_var(int i,NMTBL *n,int is_code,int d) { if (is_code) { - if(!(i=MAX_INPUT_DREGISTER_VAR) return 0; i = i+MIN_TMP_FREG+FREG_OFFSET; @@ -566,6 +566,9 @@ while(reg_sp > 0) { free_register(reg_stack[--reg_sp]); } + while(freg_sp > 0) { + free_register(freg_stack[--freg_sp]); + } if (cond_freg!=-1) { if(car(cond_freg)==DREGISTER) free_register(cadr(cond_freg)); else if(car(cond_freg)==FREGISTER) free_register(cadr(cond_freg)); @@ -623,7 +626,7 @@ get_dregister_var(NMTBL *n,int d) { int i; - for(i=0;i