Mercurial > hg > CbC > old > device
changeset 131:09379ec2a74b
*** empty log message ***
author | kono |
---|---|
date | Mon, 07 Apr 2003 22:40:24 +0900 |
parents | fea1b499d47b |
children | 07eb1249f07a |
files | Changes mc-code-mips.c mc-code-powerpc.c |
diffstat | 3 files changed, 253 insertions(+), 466 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Fri Apr 04 14:01:33 2003 +0900 +++ b/Changes Mon Apr 07 22:40:24 2003 +0900 @@ -2746,3 +2746,28 @@ おいぉい、-O3 にすると、mc-codegen.c の arg_register は r14 まで使うよ。それは、まずいんでないかい? 困ったなぁ。 + +Mon Apr 7 14:29:51 JST 2003 + +そういえば、unsigned char は処理してんの? crgvar はあるけど、 +curgvar とかはないみたいだけど。 + +あと、-1.0 とかが d2i とかを生成するのを直してないんでないかい? + +MIPS の比較命令は、 + + beq $2,$3,$L18 + + slt $2,$2,$3 + bne $2,$0,$L17 + +という感じなわけね。(signed less than か?) + +だとすると今の方法ではうまくないかも。 + +PS2Linuxのアセンブラが低能すぎて、forward reference を全然 +解決してくれない。どうすりゃいいんだ? + +.include を使うと良いらしい。(そんなんでいいのか?!) + +csvalue() で取って来たregiserを誰がfreeするの?
--- a/mc-code-mips.c Fri Apr 04 14:01:33 2003 +0900 +++ b/mc-code-mips.c Mon Apr 07 22:40:24 2003 +0900 @@ -1,4 +1,4 @@ -/* Micro-C Code Generatation Part for Power PC (Mac OS X) */ +/* Micro-C Code Generatation Part for MIPS (PS2Linux) */ /* $Id$ */ #define EXTERN extern @@ -11,7 +11,6 @@ #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); @@ -38,33 +37,35 @@ #define REG_fp 1 #define REG_sp 30 #define REG_VAR_BASE 29 -#define REG_VAR_MIN 22 -#define MIN_TMP_REG 3 -#define MAX_TMP_REG 15 +#define REG_VAR_MIN 18 +#define MIN_TMP_REG 4 +#define MAX_TMP_REG 11 #define PTRC_REG 3 #define FREG_VAR_BASE 31 -#define FREG_VAR_MIN 24 +#define FREG_VAR_MIN 20 #define MIN_TMP_FREG 1 -#define MAX_TMP_FREG 15 +#define MAX_TMP_FREG 14 #define RET_REGISTER 3 #define RET_FREGISTER 1 -int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ +int MAX_REGISTER=30; /* MIPSのレジスタを10個まで使う*/ int MAX_FREGISTER=31; -#define REAL_MAX_REGISTER 32 /* PowerPCのレジスタが32ということ*/ -#define REAL_MAX_FREGISTER 32 /* PowerPCのレジスタが32ということ*/ +#define REAL_MAX_REGISTER 32 /* MIPSのレジスタが32ということ*/ +#define REAL_MAX_FREGISTER 32 /* MIPSのレジスタが32ということ*/ -int MAX_INPUT_REGISTER_VAR = 11-MIN_TMP_REG; -int MAX_CODE_INPUT_REGISTER_VAR = 11-MIN_TMP_REG; +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_CODE_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; #define CREG_REGISTER MAX_TMP_REG #define FREG_FREGISTER MAX_TMP_FREG +static int dreg; /* general temporal register */ + int powerpc_regs[REAL_MAX_REGISTER]; int powerpc_regv[REAL_MAX_REGISTER]; @@ -81,17 +82,17 @@ static int cond_reg=-1,cond_freg=-1; static char *reg_name[] = { - "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9", - "r10","r11","r12","r13","r14","r15","r16","r17","r18","r19", - "r20","r21","r22","r23","r24","r25","r26","r27","r28","r29", - "r30","r31" + "$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[] = { - "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" + "$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] @@ -108,14 +109,16 @@ static int code_d2(double d); static void code_save_stacks(); static void code_save_input_registers(); -static void clear_ptr_cache_reg(int r); static void set_creg(int,int); static void set_freg(int,int); +static FILE *asi; int max_func_args; int my_func_args; #define ARG_LVAR_OFFSET 0x10000000 +#define DOT_SIZE 1 + /* r0 return value etc. @@ -190,85 +193,50 @@ static void -lvar8(int l) +lvar(int l) { if (fnptr->sc==CODE) { if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("lo16(%d)(r1)\n",CODE_CALLER_ARG); + printf("%d($fp)\n",CODE_CALLER_ARG); } else - printf("lo16(%d)(r30)\n",CODE_LVAR); + printf("%d($fp)\n",CODE_LVAR); } else if (l<0) { /* local variable */ - printf("lo16(%d+L_%d)(r30)\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("lo16(%d)(r30)\n",CALLER_ARG); + printf("%d($fp)\n",CALLER_ARG); } else { /* callee's arguments */ - printf("lo16(%d+L_%d)(r30)\n",CALLEE_ARG,r1_offset_label); - } -} - -/* if size of local variables / input variables is more then 64k, - lo16 does not work. We have to use ha16 also. But we can't know - the exact size in one path compile. We may safely use lvar16ha - if disp or max_func_args > 32k. Of course this is reduantant for - smaller offset. But who cares who use very large local variables? - */ - -#define LARGE_LVAR (disp<-32765||max_func_args>32765) - -static void -lvar16ha(int l) -{ - if (fnptr->sc==CODE) { - if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("la r0,ha16(%d)(r1)\n",CODE_CALLER_ARG); - } else - printf("la r0,ha16(%d)(r30)\n",CODE_LVAR); - } else if (l<0) { /* local variable */ - printf("la r0,ha16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); - } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - if (CALLER_ARG>32765) - printf("la r0,ha16(%d)(r30)\n",CALLER_ARG); - } else { /* callee's arguments */ - printf("la r0,ha16(%d+L_%d)(r30)\n",CALLEE_ARG,r1_offset_label); + printf("%d+L_%d($fp)\n",CALLEE_ARG,r1_offset_label); } } static void -lvar16lo(int l) +lvar_address(int l,int creg) { if (fnptr->sc==CODE) { if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("lo16(%d)(r0)\n",CODE_CALLER_ARG); + printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_CALLER_ARG); } else - printf("lo16(%d)(r0)\n",CODE_LVAR); + printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_LVAR); } else if (l<0) { /* local variable */ - printf("lo16(%d+L_%d)(r0)\n",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 */ - if (CALLER_ARG>32765) - printf("lo16(%d)(r0)\n",CALLER_ARG); - else - printf("lo16(%d)(r30)\n",CALLER_ARG); + printf("\taddu\t%s,$fp,%d\n",register_name(creg),CALLER_ARG); } else { /* callee's arguments */ - printf("lo16(%d+L_%d)(r0)\n",CALLEE_ARG,r1_offset_label); + printf("\taddu\t%s,$fp,%d+L_%d\n",register_name(creg),CALLEE_ARG,r1_offset_label); } } -#define lvar_intro(i) if (LARGE_LVAR) lvar16ha(i) - -#define lvar(i) if (LARGE_LVAR) lvar16lo(i); else lvar8(i) void code_lvar(int e2,int creg) { - lvar_intro(e2); - printf("\tla %s,",register_name(creg)); - lvar(e2); + lvar_address(e2,creg); regv[creg]=1; } void code_init(void) { - init_ptr_cache(); + /* this is called once program call */ } void @@ -294,15 +262,6 @@ regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ return i; /* その場所を表す番号を返す */ } - /* INPUT_REG か PTR_CACHE をつぶす */ - for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { - if (regs[i]==PTRC_REG) { - clear_ptr_cache_reg(i); - } else - continue; - regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ - return i; /* その場所を表す番号を返す */ - } /* search register stack */ for(i=0;i<reg_sp;i++) { if ((reg=reg_stack[i])>=0) { @@ -312,6 +271,15 @@ return reg; } } + for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { + reg =REG_VAR_BASE-i; + if (! regs[reg]) { /* 使われていないなら */ + regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ + regv[reg]=0; + if (i>max_reg_var) max_reg_var=i; + return reg; + } + } /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ error(-1); return creg; } @@ -340,6 +308,15 @@ return reg; } } + for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) { + reg =FREG_VAR_BASE-i; + if (! fregs[reg]) { /* 使われていないなら */ + fregs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ + fregv[reg]=0; + if (i>max_freg_var) max_freg_var=i; + return reg; + } + } /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ error(REG_ERR); return freg; } @@ -376,19 +353,16 @@ if (is_code) { if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; i = REG_VAR_BASE-i; - } else { - if (i<0||MAX_FREGISTER<i+MIN_TMP_FREG) return 0; - return list3(DREGISTER,i+MIN_TMP_FREG,(int)n); - i = i+MIN_TMP_FREG; - } - return list3(DREGISTER,i,(int)n); + return list3(DREGISTER,i,(int)n); + } else + return 0; } int get_input_register_var(int i,NMTBL *n,int is_code) { if (is_code) { - if(!(i<FREG_VAR_BASE-FREG_VAR_MIN)) return 0; + if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; i = REG_VAR_BASE-i; } else { if (i<0||MAX_REGISTER<i+MIN_TMP_REG) return 0; @@ -564,122 +538,27 @@ static int code_base; -#define MAX_PTR_CACHE 10 - -int ptr_cache=0; - -void -init_ptr_cache() -{ - int i; - for(i=0;i<MAX_PTR_CACHE;i++) { - ptr_cache=glist3(0,ptr_cache,0); - } -} - -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(r); - return; - } - ptcptr=cadr(ptcptr); - } -} - -void -clear_ptr_cache() -{ - int ptcptr=ptr_cache; - while(ptcptr) { - if(car(ptcptr)) - free_register(caddr(ptcptr)); - car(ptcptr)=0; - caddr(ptcptr)=0; - ptcptr=cadr(ptcptr); - } -} - - -int -get_ptr_cache(NMTBL *nptr) -{ - int r; - int ptcptr=ptr_cache; - int g = (int)nptr; - int p,p1; - char *rrn; - - p1 = ptcptr; p = cadr(p1); /* unnecesary, if ptcptr is initialized */ - while(ptcptr) { - if(car(ptcptr)==g) return caddr(ptcptr); - p1=p; p=ptcptr; - ptcptr=cadr(ptcptr); - } - cadr(p1)=0; /* remove the last one */ - 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; regs[r]=PTRC_REG; - } else { - error(-1); - r=creg; /* this can't happen */ - } - car(p)=g; - } else { - r = caddr(p); - } - rrn = register_name(r); - if (nptr->sc==STATIC) { - printf("\taddis %s,r31,ha16(_%s-L_%d)\n", - rrn,nptr->nm,code_base); - printf("\tla %s,lo16(_%s-L_%d)(%s)\n", - rrn,nptr->nm,code_base,rrn); - } else { - printf("\taddis %s,r31,ha16(L_%s$non_lazy_ptr-L_%d)\n", - rrn,nptr->nm,code_base); - printf("\tlwz %s,lo16(L_%s$non_lazy_ptr-L_%d)(%s)\n", - rrn,nptr->nm,code_base,rrn); - } - return r; -} - void code_label(int labelno) { - clear_ptr_cache(); printf("L_%d:\n",labelno); } void code_gvar(int e1,int creg) { - int r; - r = get_ptr_cache((NMTBL*)cadr(e1)); - if(r!=creg) - printf("\tmr %s,%s\n",register_name(creg),register_name(r)); + printf("\tla %s,%s\n",register_name(creg),(NMTBL*)cadr(e1)); regv[creg]=1; - return; } void code_rgvar(int e1,int creg) { - printf("\tlwz %s,0(%s)\n",register_name(creg), - register_name(get_ptr_cache((NMTBL*)cadr(e1)))); + printf("\tlw %s,%s\n",register_name(creg),(NMTBL*)cadr(e1)); regv[creg]=1; } void code_crgvar(int e1,int creg){ - char *crn = register_name(creg); - printf("\tlbz %s,0(%s)\n",crn, - register_name(get_ptr_cache((NMTBL*)cadr(e1)))); - printf("\textsb %s,%s\n",crn,crn); + printf("\tlb %s,%s\n",register_name(creg),(NMTBL*)cadr(e1)); regv[creg]=1; } @@ -687,15 +566,14 @@ void code_register(int e2,int creg) { if (creg!=e2) - printf("\tmr %s,%s\n",register_name(creg),register_name(e2)); + printf("\tmove %s,%s\n",register_name(creg),register_name(e2)); regv[creg]=1; } void code_rlvar(int e2,int reg) { - lvar_intro(e2); - printf("\tlwz %s,",register_name(reg)); + printf("\tlw %s,",register_name(reg)); lvar(e2); regv[creg]=1; } @@ -703,20 +581,16 @@ void code_crlvar(int e2,int reg) { - lvar_intro(e2); - printf("\tlbz %s,",register_name(reg)); + printf("\tlb %s,",register_name(reg)); lvar(e2); - printf("\textsb %s,%s\n",register_name(reg),register_name(reg)); regv[reg]=1; } void code_fname(NMTBL *n,int creg) { - int r; - r = get_ptr_cache(n); if(r!=creg) - printf("\tmr %s,%s\n",register_name(creg),register_name(r)); + printf("\tla %s,%s\n",register_name(creg),n->nm); regv[creg]=1; return; } @@ -724,20 +598,14 @@ void code_const(int e2,int creg) { - char *crn = register_name(creg); - if (-32768<e2&&e2<32768) - printf("\tli %s,%d\n",crn,e2); - else { - printf("\tlis %s,ha16(%d)\n",crn,e2); - printf("\taddi %s,%s,lo16(%d)\n",crn,crn,e2); - } + printf("\tli %s,%d\n",register_name(creg),e2); regv[creg]=1; } void code_neg(int creg) { - printf("\tneg %s,%s\n", register_name(creg), register_name(creg)); + printf("\tsubu %s,$0,%s\n", register_name(creg), register_name(creg)); } @@ -750,8 +618,14 @@ void code_lnot(int creg) { - printf("\tsubfic r0,%s,0\n", register_name(creg)); - printf("\tadde %s,r0,%s\n", register_name(creg),register_name(creg)); + /* if non zero 1 else 0 */ + + int dreg = get_register(); + printf("\txori %s,%s,0x0\n", + register_name(dreg),register_name(creg)); + printf("\tsltu %s,%s,1\n", + register_name(creg),register_name(dreg)); + free_register(dreg); } void @@ -759,10 +633,10 @@ char *xrn,*drn; int i,dreg; if (car(e2)==REGISTER) { - printf("\taddi %s,%s,%d\n", + printf("\taddu %s,%s,%d\n", register_name(cadr(e2)),register_name(cadr(e2)), caddr(e1)); if (cadr(reg)!=e2) - printf("\tmr %s,%s\n",register_name(cadr(reg)),register_name(e2)); + printf("\tmove %s,%s\n",register_name(cadr(reg)),register_name(e2)); regv[reg]=1; return; } @@ -770,9 +644,9 @@ xrn = register_name(creg); dreg=get_register(); if (!dreg) error(-1); drn = register_name(dreg); - printf("\tlwz %s,0(%s)\n",drn,xrn); - printf("\taddi %s,%s,%d\n",drn,drn,caddr(e1)); - printf("\tstw %s,0(%s)\n",drn,xrn); + printf("\tlw %s,0(%s)\n",drn,xrn); + printf("\taddu %s,%s,%d\n",drn,drn,caddr(e1)); + printf("\tsw %s,0(%s)\n",drn,xrn); i=creg;creg=dreg;dreg=i; regv[creg]=1; free_register(dreg); @@ -784,8 +658,8 @@ char *xrn,*crn,*nrn; int dreg,nreg,i; if (car(e2)==REGISTER) { - printf("\tmr %s,%s\n",register_name(reg),register_name(cadr(e2))); - printf("\taddi %s,%s,%d\n", + 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; @@ -796,9 +670,9 @@ xrn = register_name(dreg); nreg=get_register(); if (!nreg) error(-1); nrn = register_name(nreg); - printf("\tlwz %s,0(%s)\n",xrn,crn); - printf("\taddi %s,%s,%d\n",nrn,xrn,caddr(e1)); - printf("\tstw %s,0(%s)\n",nrn,crn); + printf("\tlw %s,0(%s)\n",xrn,crn); + printf("\taddu %s,%s,%d\n",nrn,xrn,caddr(e1)); + printf("\tsw %s,0(%s)\n",nrn,crn); i=creg;creg=dreg;dreg=i; free_register(nreg); free_register(dreg); @@ -811,9 +685,8 @@ char *xrn,*crn,*nrn; int i,nreg,dreg; if (car(e2)==REGISTER) { - printf("\tlbz %s,0(%s)\n",register_name(reg),register_name(cadr(e2))); - printf("\textsb %s,%s\n",register_name(reg),register_name(reg)); - printf("\taddi %s,%s,%d\n", + 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; @@ -824,11 +697,10 @@ xrn = register_name(dreg); nreg=get_register(); if (!nreg) error(-1); nrn = register_name(nreg); - printf("\tlwz %s,0(%s)\n",xrn,crn); - printf("\tlbz %s,0(%s)\n",nrn,xrn); - printf("\textsb %s,%s\n",nrn,nrn); - printf("\taddi %s,%s,%d\n", xrn,xrn,caddr(e1)); - printf("\tstw %s,0(%s)\n",xrn,crn); + printf("\tlw %s,0(%s)\n",xrn,crn); + printf("\tlb %s,0(%s)\n",nrn,xrn); + printf("\taddu %s,%s,%d\n", xrn,xrn,caddr(e1)); + printf("\tsw %s,0(%s)\n",xrn,crn); i=creg;creg=nreg;nreg=i; free_register(nreg); free_register(dreg); @@ -841,8 +713,9 @@ char *xrn,*crn,*nrn; int i,nreg,dreg; if (car(e2)==REGISTER) { - printf("\tlbzu %s,%d(%s)\n",register_name(reg),caddr(e1),register_name(cadr(e2))); - printf("\textsb %s,%s\n",register_name(reg),register_name(reg)); + 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; } @@ -852,10 +725,10 @@ xrn = register_name(dreg); nreg=get_register(); if (!nreg) error(-1); nrn = register_name(nreg); - printf("\tlwz %s,0(%s)\n",xrn,crn); - printf("\tlbzu %s,%d(%s)\n",nrn,caddr(e1),xrn); - printf("\tstw %s,0(%s)\n",xrn,crn); - printf("\textsb %s,%s\n",nrn,nrn); + printf("\tlw %s,0(%s)\n",xrn,crn); + printf("\taddu %s,%s,%d\n", nrn,xrn,caddr(e1)); + printf("\tlb %s,0(%s)\n",nrn,xrn); + printf("\tsw %s,0(%s)\n",xrn,crn); i=creg;creg=nreg;nreg=i; free_register(nreg); free_register(dreg); @@ -870,9 +743,8 @@ if (car(e2)==REGISTER) { crn=register_name(reg); xrn=register_name(cadr(e2)); - printf("\tlbz %s,0(%s)\n",crn,xrn); - printf("\taddi %s,%s,%d\n",xrn,xrn,caddr(e1)); - printf("\textsb %s,%s\n",crn,crn); + printf("\tlb %s,0(%s)\n",crn,xrn); + printf("\taddu %s,%s,%d\n",xrn,xrn,caddr(e1)); regv[reg]=1; return; } @@ -882,11 +754,10 @@ xrn = register_name(dreg); nreg=get_register(); if (!nreg) error(-1); nrn = register_name(nreg); - printf("\tlwz %s,0(%s)\n",xrn,crn); - printf("\tlbz %s,0(%s)\n",nrn,xrn); - printf("\taddi %s,%s,%d\n",xrn,xrn,caddr(e1)); - printf("\tstw %s,0(%s)\n",xrn,crn); - printf("\textsb %s,%s\n",nrn,nrn); + printf("\tlw %s,0(%s)\n",xrn,crn); + printf("\tlb %s,0(%s)\n",nrn,xrn); + printf("\taddu %s,%s,%d\n",xrn,xrn,caddr(e1)); + printf("\tsw %s,0(%s)\n",xrn,crn); i=creg;creg=nreg;nreg=i; free_register(nreg); free_register(dreg); @@ -901,8 +772,8 @@ if (car(e2)==REGISTER) { crn=register_name(reg); xrn=register_name(cadr(e2)); - printf("\tlbzu %s,%d(%s)\n",crn,caddr(e1),xrn); - printf("\textsb %s,%s\n",crn,crn); + printf("\taddu %s,%s,%d\n",xrn,xrn,caddr(e1)); + printf("\tlb %s,%d(%s)\n",crn,caddr(e1),xrn); regv[reg]=1; return; } @@ -912,10 +783,10 @@ xrn = register_name(dreg); nreg=get_register(); if (!nreg) error(-1); nrn = register_name(nreg); - printf("\tlwz %s,0(%s)\n",xrn,crn); - printf("\tlbzu %s,%d(%s)\n",nrn,caddr(e1),xrn); - printf("\tstw %s,0(%s)\n",xrn,crn); - printf("\textsb %s,%s\n",nrn,nrn); + printf("\tlw %s,0(%s)\n",xrn,crn); + printf("\taddu %s,%s,%d\n",xrn,xrn,caddr(e1)); + printf("\tlb %s,%d(%s)\n",nrn,caddr(e1),xrn); + printf("\tsw %s,0(%s)\n",xrn,crn); i=creg;creg=nreg;nreg=i; free_register(nreg); free_register(dreg); @@ -926,8 +797,7 @@ void code_return(int creg) { char *crn = register_name(creg); - printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",crn,retcont,code_base); - printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",crn,retcont,code_base,crn); + printf("\tla %s,L_%d\n",crn,retcont); } #define R1SAVE 1 @@ -936,11 +806,11 @@ code_environment(int creg) { /* save frame pointer */ #if R1SAVE - printf("\tlwz %s,0(r1)\n",register_name(creg)); + printf("\tlw %s,0($fp)\n",register_name(creg)); #else int l = 0; - printf("\tla %s,",register_name(creg)); - printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); + printf("\taddu %s,",register_name(creg)); + printf("$fp,%d+L_%d\n",FUNC_LVAR,lvar_offset_label); #endif } @@ -984,51 +854,41 @@ void code_cmp_crgvar(int e1) { - int r; - char *crn = register_name(creg); - r = get_ptr_cache((NMTBL*)cadr(e1)); - printf("\tlbz %s,0(%s)\n",crn,register_name(r)); - printf("\tcmpwi cr0,%s,0\n",crn); - regv[creg]=0; + if (dreg==-1) dreg = get_register(); + code_crgvar(cadr(e1),dreg); + regv[dreg]=1; } void code_cmp_crlvar(int e2) { - char *crn = register_name(creg); - lvar_intro(e2); - printf("\tlbz %s,",crn); - lvar(e2); - code_cmp_register(creg); - regv[creg]=0; + if (dreg==-1) dreg = get_register(); + code_crlvar(e2,dreg); + regv[dreg]=1; } void code_cmp_rgvar(int e1) { - int r; - char *crn = register_name(creg); - r = get_ptr_cache((NMTBL*)cadr(e1)); - printf("\tlwz %s,0(%s)\n",crn,register_name(r)); - code_cmp_register(creg); - regv[creg]=0; + if (dreg==-1) dreg = get_register(); + code_rgvar(e1,dreg); + regv[dreg]=1; } void code_cmp_rlvar(int e2) { - char *crn = register_name(creg); - lvar_intro(e2); - printf("\tlwz %s,",crn); - lvar(e2); - code_cmp_register(creg); - regv[creg]=0; + if (dreg==-1) dreg = get_register(); + code_rlvar(e1,dreg); + regv[dreg]=1; } void code_cmp_register(int e2) { - printf("\tcmpwi cr0,%s,0\n",register_name(e2)); + dreg = e2; + /* prevent dreg freeing */ + regv[dreg]=2; } @@ -1049,7 +909,7 @@ printf("%c",*s); s++; } - printf("\\0%c\n\t.align 2\n",34); + printf("\\000%c\n\t.align 2\n",34); } void @@ -1060,7 +920,7 @@ crn=register_name(creg); s=(char *)cadr(e1); - printf(".data\t\n.cstring\n\t.align 2\n"); + printf("\t.rdata\n\t.align 2\n"); lb=fwdlabel(); printf("L_%d:\n",lb); ascii(s); @@ -1069,8 +929,7 @@ } else { text_mode(); } - printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",crn,lb,code_base); - printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",crn,lb,code_base,crn); + printf("\tla %s,L_%d\n",crn,lb); } #define MAX_COPY_LEN 20 @@ -1090,16 +949,16 @@ switch (length) { case 0: break; case 1: case -1: - printf("\tlbz %s,%d(%s)\n",drn,offset,frn); - printf("\tstb %s,%d(%s)\n",drn,offset,trn); + printf("\tlb %s,%d(%s)\n",drn,offset,frn); + printf("\tsb %s,%d(%s)\n",drn,offset,trn); break; case 2: case -2: - printf("\tlhz %s,%d(%s)\n",drn,offset,frn); - printf("\tsth %s,%d(%s)\n",drn,offset,trn); + printf("\tlh %s,%d(%s)\n",drn,offset,frn); + printf("\tsh %s,%d(%s)\n",drn,offset,trn); break; case 4: case -4: - printf("\tlwz %s,%d(%s)\n",drn,offset,frn); - printf("\tstw %s,%d(%s)\n",drn,offset,trn); + printf("\tlw %s,%d(%s)\n",drn,offset,frn); + printf("\tsw %s,%d(%s)\n",drn,offset,trn); break; default: if (-MAX_COPY_LEN<length && length <0) { @@ -1119,14 +978,12 @@ emit_copy(from,to,length,offset,0,det); break; } - clear_ptr_cache(); code_save_stacks(); - printf("\tli r5,%d\n",length); - printf("\tmr r4,%s\n",frn); - printf("\tmr r3,%s\n",trn); + 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); - extern_define(memmove,0,FUNCTION,1); fix=0; set_creg(RET_REGISTER,0); if (creg!=to) { @@ -1171,8 +1028,8 @@ free_register(dreg); return count; } else { - printf("\tlwz %s,%d(%s)\n",drn,length-size_of_int,crn); - printf("\tstwu %s,%d(%s)\n",drn,-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); } } } @@ -1187,9 +1044,8 @@ set_creg(int reg,int mode) { if (reg!=creg) { - clear_ptr_cache_reg(reg); if (mode) - printf("\tmr %s,%s\n",register_name(reg),register_name(creg)); + printf("\tmove %s,%s\n",register_name(reg),register_name(creg)); free_register(creg); creg = reg; regs[creg]=1; @@ -1201,7 +1057,7 @@ { if (reg!=freg) { if (mode) - printf("\tfmr %s,%s\n",fregister_name(reg),fregister_name(freg)); + printf("\tfmove %s,%s\n",fregister_name(reg),fregister_name(freg)); free_fregister(freg); freg = reg; fregs[freg]=1; @@ -1220,44 +1076,6 @@ void code_save_input_registers() { -#if 0 - int args; - NMTBL *n; - int reg; - int tag; - int lvar; - int t; - /* fnptr->dsp=list4(type,fnptr->dsp,(int)n,0); */ - int reg_offset = 0; - - for(args = fnptr->dsp;args;args = cadr(args)) { - n = (NMTBL *)caddr(args); - tag = n->sc; - reg = n->dsp; - if (!n||n==&null_nptr) error(REG_ERR); - if (tag==REGISTER) { - /* regs[reg]==INPUT_REG case should be considered */ - n->dsp = new_lvar(size_of_int); - t = INT; - reg += reg_offset; /* for duplicated floating point argument */ - } else if (tag==DREGISTER) { - /* fregs[reg]==INPUT_REG case should be considered */ - n->dsp = new_lvar(size_of_double); - t = DOUBLE; - reg_offset+=2; - } else - continue; - 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) { - free_register(reg); - } else if (tag==DREGISTER) { - free_fregister(reg); - } - } - my_func_args = 0; -#else int args; NMTBL *n; int reg; @@ -1300,7 +1118,6 @@ } } my_func_args = offset; -#endif } int @@ -1437,13 +1254,11 @@ 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 { jrn = register_name(cadr(jmp)); - printf("\tmtctr %s\n",jrn); - printf("\tbctrl\n"); + printf("\tj %s\n",jrn); } for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) { arg = car(reg_arg_list); @@ -1466,9 +1281,9 @@ void code_frame_pointer(int e3) { #if R1SAVE - printf("\tmr r1,%s\n",register_name(e3)); + printf("\tmove $fp,%s\n",register_name(e3)); #else - printf("\tmr r30,%s\n",register_name(e3)); + printf("\tmove $fp,%s\n",register_name(e3)); #endif } @@ -1476,15 +1291,15 @@ void code_fix_frame_pointer(int disp_offset) { int l = 0; - printf("\tla r30,"); - printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); + printf("\tla $fp,"); + printf("%d+L_%d($sp)\n",FUNC_LVAR,lvar_offset_label); } void code_jmp(char *s) { max_reg_var = REG_VAR_BASE-REG_VAR_MIN; max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; - printf("\tb L_%s$stub\n",s); + printf("\tj L_%s\n",s); } @@ -1492,8 +1307,7 @@ code_indirect_jmp(int e2) { max_reg_var = REG_VAR_BASE-REG_VAR_MIN; max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; - printf("\tmtctr %s\n",register_name(e2)); - printf("\tbctr\n"); + printf("\tj %s\n",register_name(e2)); } int @@ -1520,11 +1334,10 @@ regv[creg]=0; regv[freg]=1; return DOUBLE; case CRINDIRECT: - printf("\tlbz %s,%d(%s)\n",crn,offset,crn); - printf("\textsb %s,%s\n",crn,crn); + printf("\tlb %s,%d(%s)\n",crn,offset,crn); return CHAR; case RINDIRECT: - printf("\tlwz %s,%d(%s)\n",crn,offset,crn); + printf("\tlw %s,%d(%s)\n",crn,offset,crn); return INT; } error(-1); return INT; @@ -1538,9 +1351,9 @@ rrn=register_name(r); crn=register_name(creg); if (byte) { - printf("\tstb %s,0(%s)\n",crn,rrn); + printf("\tsb %s,0(%s)\n",crn,rrn); } else { - printf("\tstw %s,0(%s)\n",crn,rrn); + printf("\tsw %s,0(%s)\n",crn,rrn); } } @@ -1548,18 +1361,17 @@ code_assign_lvar(int e2,int creg,int byte) { char *crn; crn=register_name(creg); - lvar_intro(e2); if (byte) { - printf("\tstb %s,",crn); lvar(e2); + printf("\tsb %s,",crn); lvar(e2); } else { - printf("\tstw %s,",crn); lvar(e2); + printf("\tsw %s,",crn); lvar(e2); } } void code_assign_register(int e2,int byte,int creg) { if (e2!=creg) - printf("\tmr %s,%s\n",register_name(e2),register_name(creg)); + printf("\tmove %s,%s\n",register_name(e2),register_name(creg)); } void @@ -1568,9 +1380,9 @@ char *crn=register_name(creg); if (byte) { - printf("\tstb %s,0(%s)\n",crn,drn); + printf("\tsb %s,0(%s)\n",crn,drn); } else { - printf("\tstw %s,0(%s)\n",crn,drn); + printf("\tsw %s,0(%s)\n",crn,drn); } } @@ -1583,7 +1395,7 @@ tosop(op,xreg); creg = xreg; if (creg!=reg) - printf("\tmr %s,%s\n",register_name(creg),register_name(reg)); + printf("\tmove %s,%s\n",register_name(creg),register_name(reg)); } @@ -1601,9 +1413,9 @@ crn = register_name(creg); drn = register_name(edx); if (byte) { - printf("\tstb %s,0(%s)\n",crn,drn); + printf("\tsb %s,0(%s)\n",crn,drn); } else { - printf("\tstw %s,0(%s)\n",crn,drn); + printf("\tsw %s,0(%s)\n",crn,drn); } free_register(edx); emit_pop_free(xreg); @@ -1628,26 +1440,26 @@ switch(op) { case LSHIFT: case ULSHIFT: - shift("slw",oreg); + shift("sll",oreg); return; case RSHIFT: - shift("srw",oreg); + shift("srl",oreg); return; case URSHIFT: - shift("sraw",oreg); + shift("sra",oreg); return; } orn = register_name(oreg); crn = register_name(creg); switch(op) { case ADD: - printf("\tadd %s,%s,%s\n",crn,crn,orn); + printf("\taddu %s,%s,%s\n",crn,crn,orn); break; case SUB: - printf("\tsub %s,%s,%s\n",crn,crn,orn); + printf("\tsubu %s,%s,%s\n",crn,crn,orn); break; case CMP: - printf("\tcmpw cr0,%s,%s\n",crn,orn); + printf("\tslt %s,%s\n",crn,orn); break; case BAND: printf("\tand %s,%s,%s\n",crn,crn,orn); @@ -1659,32 +1471,19 @@ printf("\tor %s,%s,%s\n",crn,crn,orn); break; case MUL: - printf("\tmullw %s,%s,%s\n",crn,crn,orn); + printf("\tmult %s,%s,%s\n",crn,crn,orn); break; case UMUL: - printf("\tmullw %s,%s,%s\n",crn,crn,orn); - break; - case DIV: - printf("\tdivw %s,%s,%s\n",crn,crn,orn); - break; - case UDIV: - printf("\tdivwu %s,%s,%s\n",crn,crn,orn); + printf("\tmultu %s,%s,%s\n",crn,crn,orn); break; - case MOD: - dx=get_register(); - drn = register_name(dx); - printf("\tdivw %s,%s,%s\n",drn,crn,orn); - printf("\tmullw %s,%s,%s\n",drn,drn,orn); - printf("\tsubf %s,%s,%s\n",crn,drn,crn); - free_register(dx); - break; - case UMOD: - dx=get_register(); - drn = register_name(dx); - printf("\tdivwu %s,%s,%s\n",drn,crn,orn); - printf("\tmullw %s,%s,%s\n",drn,drn,orn); - printf("\tsubf %s,%s,%s\n",crn,drn,crn); - free_register(dx); + 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; default: error(-1); @@ -1706,11 +1505,11 @@ { char *crn = register_name(creg); if (byte) { - printf("\tlbz %s,%d(%s)\n",register_name(creg),n, + printf("\tlb %s,%d(%s)\n",register_name(creg),n, register_name(xreg)); printf("\textsb %s,%s\n",crn,crn); } else - printf("\tlwz %s,%d(%s)\n",register_name(creg),n, + printf("\tlw %s,%d(%s)\n",register_name(creg),n, register_name(xreg)); } @@ -1725,16 +1524,36 @@ { /* used in dosiwtch() */ if(chk) return; - printf("\tcmpwi cr0,%s,%d\n",register_name(csreg),e); + printf("\tli %s,%d\n",register_name(creg),e); + dreg = csreg; + regv[dreg]=2; /* prevent from freeing */ } void code_opening(char *filename) { + /* this is called once per month */ + char *p=cheapp; + printf("\t.file \"%s\"\n",filename); /* printf("\t.version\t\"01.01\"\n"); */ /* printf("gcc2_compiled.:\n"); */ - printf(".text\n"); + printf("\t.abicalls\n"); + printf("\t.text\n"); + + if (asi) { + fclose(asi); + asi = 0; + } + while ((*cheapp++ = *s++)) { + if (*s=='.') { + *cheapp++=*s++; *cheapp++='i'; + *cheapp++=0; + break; + } + } + asi = fopen(p,"w"); + if (!asi) error(-1); } void @@ -1744,12 +1563,17 @@ printf("\tb%s cr0,L_%d\n",s,l1); } - void jcond(int l, char cond) -{ +{ if (chk) return; - printf("\tb%s cr0,L_%d\n",cond?"ne":"eq",l); + if (dreg==-1) error(-1); + printf("\tb%s %s,%s,L_%d\n",register_name(creg),regiser_name(dreg), + cond?"ne":"eq",l); + if (regv[dreg]==1) { + free_register(dreg); dreg = -1; + } + regv[creg]=0; } void @@ -1757,7 +1581,7 @@ { control=0; if (chk) return; - printf("\tb\tL_%d\n",l); + printf("\tj\tL_%d\n",l); } void @@ -1775,7 +1599,7 @@ else printf("\t.align 2\n"); if (stmode!=STATIC) - printf(".globl _%s\n",name); + printf(".globl %s\n",name); #ifdef DOT_SIZE printf("\t.type\t%s,@function\n",name); #endif @@ -1816,7 +1640,7 @@ else printf("\t.align 2\n"); if (stmode!=STATIC) - printf(".globl _%s\n",name); + printf(".globl %s\n",name); /* printf("\t.type\t%s,@function\n",name); */ @@ -1853,7 +1677,7 @@ void leave(int control, char *name) { - int retcont1,sz; + int retcont1=0,sz; if (max_freg_var>=0 && max_freg_var<=3) max_freg_var=3; reg_save = reg_save_offset(); @@ -1953,10 +1777,8 @@ void gen_gdecl(char *n, int gpc) { - /* if (stmode!=STATIC) - printf(".globl _%s\n",n); - */ + printf(".globl %s\n",n); } void @@ -2006,23 +1828,23 @@ } } else if(t==DOUBLE) { d = dcadr(e); - printf("\t.long\t0x%x,0x%x\n",code_d2(d),code_d1(d)); + 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.long\t0x%x\n",*(int *)&f); + 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.long _%s\n",((NMTBL *)cadr(cadr(e)))->nm); + printf("\t.word _%s\n",((NMTBL *)cadr(cadr(e)))->nm); } else if(car(e)==FNAME) { - printf("\t.long _%s\n",((NMTBL *)cadr(e))->nm); + printf("\t.word _%s\n",((NMTBL *)cadr(e))->nm); } else if(car(e)==GVAR) { - printf("\t.long _%s\n",((NMTBL *)cadr(e))->nm); + 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.long L_%d\n",l); - printf(".cstring\n\t.align 2\n"); + printf("\t.word L_%d\n",l); + printf(".rdata\n\t.align 2\n"); printf("L_%d:\n",l); output_mode = RODATA_EMIT_MODE; } @@ -2052,7 +1874,7 @@ global_table(void) { NMTBL *n; - int init; char *extrn; + int init; init=0; for(n=ntable;n < &ntable[GSYMS];n++) { if ((n->sc == GVAR) && n->dsp != -1) { @@ -2071,61 +1893,6 @@ printf(".lcomm _%s,%d\n",n->nm,size(n->ty)); } } - for(n=ntable;n < &ntable[GSYMS];n++) { - if (is_code(n)||is_function(n)) { - extrn = n->nm; - if (n->sc==EXTRN1) { - data_mode(0); -printf(".picsymbol_stub\n"); -printf("L_%s$stub:\n",extrn); -printf("\t.indirect_symbol _%s\n",extrn); -printf("\tmflr r0\n"); -printf("\tbcl 20,31,L0$_%s\n",extrn); -printf("L0$_%s:\n",extrn); -printf("\tmflr r11\n"); -printf("\taddis r11,r11,ha16(L_%s$lazy_ptr-L0$_%s)\n",extrn,extrn); -printf("\tmtlr r0\n"); -printf("\tlwz r12,lo16(L_%s$lazy_ptr-L0$_%s)(r11)\n",extrn,extrn); -printf("\tmtctr r12\n"); -printf("\taddi r11,r11,lo16(L_%s$lazy_ptr-L0$_%s)\n",extrn,extrn); -printf("\tbctr\n"); -printf(".data\n"); -printf(".lazy_symbol_pointer\n"); -printf("L_%s$lazy_ptr:\n",extrn); -printf("\t.indirect_symbol _%s\n",extrn); -printf("\t.long dyld_stub_binding_helper\n"); - } else if (n->sc==FUNCTION||n->sc==CODE) { - text_mode(); -printf("\t.set L_%s$stub,_%s\n",extrn,extrn); - data_mode(0); -printf("L_%s$non_lazy_ptr:\n\t.long\t_%s\n",extrn,extrn); - } - } - } - init=0; - for(n=ntable;n < &ntable[GSYMS];n++) { - if (n->sc == GVAR) { - if (init==0) { - printf(".data\n"); - init=1; - } -printf("L_%s$non_lazy_ptr:\n\t.long\t_%s\n",n->nm,n->nm); - } - } - init = 0; - for(n=ntable;n < &ntable[GSYMS];n++) { - if (is_code(n)||is_function(n)) continue; - if (n->sc==EXTRN1) { - if(init==0) { - printf(".data\n"); -printf(".non_lazy_symbol_pointer\n"); - init=1; - } -printf("L_%s$non_lazy_ptr:\n",n->nm); -printf("\t.indirect_symbol _%s\n",n->nm); -printf("\t.long\t0\n"); - } - } } void @@ -2243,7 +2010,6 @@ void code_dassign_lvar(int e2,int freg,int d) { - lvar_intro(e2); printf("\t%s %s,",fstore(d),fregister_name(freg)); lvar(e2); fregv[freg]=1; @@ -2328,9 +2094,7 @@ int e2 = new_lvar(size_of_double); 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); fregs[freg]=0; regs[creg]=1; @@ -2479,7 +2243,6 @@ void code_drlvar(int e2,int d,int freg) { - lvar_intro(e2); printf("\t%s %s,",fload(d),fregister_name(freg)); lvar(e2); fregv[freg]=1; } @@ -2503,7 +2266,6 @@ int g=get_fregister(); char *grn=fregister_name(g); - lvar_intro(e2); printf("\t%s %s,",fload(1),grn); lvar(e2); printf("\tfcmpu cr0,%s,%s\n",frn,grn); free_fregister(g);
--- a/mc-code-powerpc.c Fri Apr 04 14:01:33 2003 +0900 +++ b/mc-code-powerpc.c Mon Apr 07 22:40:24 2003 +0900 @@ -406,7 +406,7 @@ get_input_register_var(int i,NMTBL *n,int is_code) { if (is_code) { - if(!(i<FREG_VAR_BASE-FREG_VAR_MIN)) return 0; + if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; i = REG_VAR_BASE-i; } else { if (i<0||MAX_REGISTER<i+MIN_TMP_REG) return 0;