Mercurial > hg > CbC > old > device
changeset 379:c7abd48191b3
ARM continue...
author | kono |
---|---|
date | Sun, 18 Jul 2004 12:26:30 +0900 |
parents | b3c6c479c522 |
children | c9ae2ea267c2 |
files | Changes mc-code-arm.c mc-code-mips.c mc-codegen.c mc-parse.c stdio.h test/float.c |
diffstat | 7 files changed, 257 insertions(+), 142 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Wed Jul 14 14:37:37 2004 +0900 +++ b/Changes Sun Jul 18 12:26:30 2004 +0900 @@ -5857,3 +5857,22 @@ ってなんだ? せっかく作ったのに? +ちょっとバグってました。でも、なんでだろう? logic miss がある? + +drexpr_bool for MIPS は作ってないみたいね。long long はさすがに +大変そうだし。 + +double/long long の定数だけどさ、 + local const table に連続して入れる + 大域領域に初期化して、そこへのポインタをlocal const table に入れる +でいいんだけど... 前者だと、searchがめんどい。後者だと、double load +になるので、なんか嫌。たまたま一致した0を使えないのもなんかね。 + +adr なんて言うのがあるのか。adr して ldmia ってなんか変。mvfs #0 +なんてのがあるのか。0,1,10 があるのがわかるけど... + +float の switch ってあるの? + +(はぁ、めんどくさい... 一週間かかってるし...) + +
--- a/mc-code-arm.c Wed Jul 14 14:37:37 2004 +0900 +++ b/mc-code-arm.c Sun Jul 18 12:26:30 2004 +0900 @@ -8,10 +8,9 @@ #include "mc-code.h" #include "mc-codegen.h" -#define Linux_Zaurus 1 -#define GameBoyAdvance 2 - -int arch_mode = Linux_Zaurus; +#define UseFPP 1 + +int arch_mode = UseFPP; char **l_include_path[]; @@ -61,7 +60,6 @@ static int freg,ireg,lreg; -static int cmpreg; int code_lassop_p = 1; @@ -177,9 +175,9 @@ char *lh(i) { return lregister_name_high(i); } #define is_int_reg(i) (0<i&&i<REAL_MAX_REGISTER) -#define is_float_reg(i) (arch_mode==Linux_Zaurus?(REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER):is_int_reg(i)) +#define is_float_reg(i) (arch_mode&UseFPP?(REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER):is_int_reg(i)) #define is_longlong_reg(i) (LREG_OFFSET<=i&&i<LREG_OFFSET+REAL_MAX_LREGISTER+LREG_V) -#define is_double_reg(i) (arch_mode==GameBoyAdvance?is_longlong_reg(i):is_float_reg(i)) +#define is_double_reg(i) (arch_mode&UseFPP?is_float_reg(i):is_longlong_reg(i)) #define use_int(reg) if (reg==USE_CREG) reg=use_int0() static @@ -222,7 +220,7 @@ #if FLOAT_CODE -#define use_float(d,reg) if (reg==USE_CREG) arch_mode==GameBoyAdvance?(reg=d?use_double0():use_float0()):use_float0() +#define use_float(d,reg) if (reg==USE_CREG) arch_mode&UseFPP?use_float0():(reg=d?use_double0():use_float0()) static int use_float0() { int i = creg; @@ -501,7 +499,6 @@ void gexpr_code_init(void){ - cmpreg = CMP_C1T ; } void @@ -645,7 +642,7 @@ get_dregister(int d) { /* 使われていないレジスタを調べる */ int i,reg; - if (arch_mode==GameBoyAdvance) { + if (!(arch_mode&UseFPP)) { i = get_lregister(); if (i!=-1) regs[i]=USING_DREG; return i; @@ -1149,12 +1146,10 @@ nth element has offset n * SIZE_OF_INT */ -#define new_const(e,v) (const_list = glist3(e,const_list,v)) - static int search_const(int tag,int value,int *label) { - int p,i,j,list; + int p,i,j,list,prev; for(j=0;j<2;j++) { i = 0; @@ -1174,14 +1169,44 @@ case CONST: case LABEL: if (caddr(p)!=value) continue; return i; - default: error(-1); } + prev = p; } } - new_const(tag,cadr(e)); + cadr(p) = glist3(tag,0,value); return i+SIZE_OF_INT; } +static int +search_double_const(int tag,int value1,int value2,int *label) +{ + int p,i,j,list,prev; + + for(j=0;j<2;j++) { + i = 0; + if(j==1) { + if (!const_list_label) const_list_label = fwdlabel(); + list = const_list; *label = const_list_label; + } else { + list = prev_const_list; *label = prev_const_list_label; + } + for(p = list; p ;p=cadr(p),i+=SIZE_OF_INT) { + if (car(p)!=tag) continue; + switch(tag) { + case DCONST: case LCONST: + if (caddr(p)!=value1) continue; + p = cadr(p); + if (!p||car(p)!=tag) error(-1); + if (caddr(p)!=value2) continue; + return i; + } + prev = p; + } + } + cadr(p) = glist3(tag,glist3(tag,0,value2),value1); + return i+SIZE_OF_INT*2; +} + static void const_list() { @@ -1191,7 +1216,6 @@ jmp(lb); printf("\t.align\t2\n"); } - const_list = reverse0(const_list); fwddef(const_list_label); for(p = const_list; p ; p = cadr(p)) { switch(car(p)) { @@ -1639,7 +1663,7 @@ code_ld(cload(sz,0),reg,cadr(e1),xreg,get_ptr_cache((NMTBL*)caddr(e1)), sz==1?" @ zero_extendqisi2":""); cext(0,sz,r); - cmpreg = reg; + printf("\tcmp\t%s, #0\n",register_name(reg)); jcond(label,cond); } @@ -1680,6 +1704,7 @@ void code_cmp_register(int e2,int label,int cond) { use_int(e2); + printf("\tcmp\t%s, #0\n",register_name(e2)); jcond(label,cond); } @@ -1843,7 +1868,7 @@ free_register(freg); if (mode) { printf("\t%s %s,%s\n", - arch_mode==Linux_Zaurus?"mvfd":mov", + arch_mode&UseFPP?"mvfd":mov", fregister_name(reg),fregister_name(freg)); } } @@ -2469,7 +2494,7 @@ max_reg_var = REG_VAR_BASE-REG_VAR_MIN; max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; use_int(e2); - printf("\tmov\tpc, %s\n",s); // ?! + printf("\tmov\tpc, %s @ indirect jump\n",s); // ?! control=0; } @@ -2490,7 +2515,7 @@ code_drindirect(int e1, int reg,int offset, int d) { int xreg; - if(arch_mode==GameBoyAdvance) { + if(!(arch_mode&UseFPP)) { if (d) { code_lrindirect(e1,reg,offset,1); return DOUBLE; @@ -2874,70 +2899,42 @@ #define COND_BRANCH 1 #define COND_VALUE 2 + /* + if (r1 cmp r2) goto l1 COND_BRANCH + r0 = (r1 cmp r2) COND_VALUE + */ static void pcond(int op, int r2,int r1,int r0,int cond,int l1,int mode) { - char *slt = "slt"; - char *sltu = "sltu"; - char *eq = "eq"; - char *ne = "ne"; int t; char *rn2; char *rn1; char *rn0; -// printf("# pcond %d cond %d\n",op,cond); + rn1 = register_name(r1); + rn2 = register_name(r2); + printf("\tcmp\t%s, %s\n",rn1,rn2); + switch(op+(!cond)*BNOT) { - case GT: case LE+BNOT: - t=r1;r1=r0;r0=t; - case LT: case GE+BNOT: - eq = ne; - break; - case UGT: case ULE+BNOT: - t=r1;r1=r0;r0=t; - case ULT: case UGE+BNOT: - eq = ne; slt = sltu; - break; - case ULE: case UGT+BNOT: - t=r1;r1=r0;r0=t; - case UGE: case ULT+BNOT: - slt = sltu; - break; - case LE: case GT+BNOT: - t=r1;r1=r0;r0=t; - case GE: case LT+BNOT: - case EQ: case NEQ+BNOT: - break; - case NEQ: case EQ+BNOT: - eq = ne; - break; + case GT: case LE+BNOT: cc="gt"; ncc="le"; break; + case LE: case GT+BNOT: cc="le"; ncc="gt"; break; + case GE: case LT+BNOT: cc="ge"; ncc="lt"; break; + case LT: case GE+BNOT: cc="lt"; ncc="ge"; break; + case UGT: case ULE+BNOT: cc="hi"; ncc="ls"; break; + case ULE: case UGT+BNOT: cc="ls"; ncc="hi"; break; + case UGE: case ULT+BNOT: cc="hs"; ncc="lo"; break; + case ULT: case UGE+BNOT: cc="lo"; ncc="hs"; break; + case EQ: case NEQ+BNOT: cc="eq"; ncc="ne"; break; + case NEQ: case EQ+BNOT: cc="ne"; ncc="eq"; break; default: error(-1); } - rn2 = register_name(r2); - rn1 = register_name(r1); - rn0 = register_name(r0); - if (mode==COND_BRANCH) { - if (op==EQ||op==NEQ) { - printf("\tb%s\t%s,%s,$L_%d\n",eq,rn0,rn1, l1); - } else { - printf("\t%s\t%s,%s,%s\n",slt,rn2,rn1,rn0); - printf("\tb%s %s,$0,$L_%d\n",eq,rn2,l1); - } + printf("\tb%s\t.L%d\n",cc,l1); } else if (mode==COND_VALUE) { - if (op==EQ) { - printf("\txor\t%s,%s,%s\n",rn2,rn1,rn0); - printf("\tsltu\t%s,%s,1\n",rn2,rn2); - } else if (op==NEQ) { - printf("\txor\t%s,%s,%s\n",rn2,rn1,rn0); - printf("\tsltu\t%s,$0,%s\n",rn2,rn2); - } else { - printf("\t%s\t%s,%s,%s\n",slt,rn2,rn1,rn0); - if (eq==ne) { - printf("\txor\t%s,%s,1\n",rn2,rn2); - } - } + rn0 = register_name(r0); + printf("\tmov%s\t%s, #0\n",rn2,ncc); + printf("\tmov%s\t%s, #1\n",rn2,cc); } else error(-1); } @@ -2946,7 +2943,6 @@ { int e2,reg0; int op = car(e1); -return 0; if (!( op== GT || op== LT || op== UGT || op== ULT || op== ULE || op== UGE || op== LE || op== GE || @@ -2980,13 +2976,10 @@ #define CMP_C1T (-1) static void -jcond(int l, char cond) +jcond(int l, int reg,char cond,int reg) { if (chk) return; - if (cmpreg==CMP_C1T) { - printf("\tbc1%s $L_%d\n",cond?"f":"t",l); - } else - printf("\tb%s %s,$0,$L_%d\n",cond?"ne":"eq",register_name(cmpreg),l); + printf("\tb%s\t%\t.L%d\n",cond?"ne":"eq",l); } void @@ -2994,7 +2987,7 @@ { control=0; if (chk) return; - printf("\tj\t$L_%d\n",l); + printf("\tb\t.L%d\n",l); } void @@ -3009,7 +3002,7 @@ { int i; for (i=reg_var_num(0);i>reg_var_num(reg_save);i--) { - printf("\tsw %s,$L_%d-%d($sp)\n",register_name(i), + printf("\tstr\t%s, [sp, #%d]\n",register_name(i), r1_offset_label,-disp); disp -= SIZE_OF_INT; } @@ -3402,7 +3395,7 @@ static void comm(NMTBL *n) { - printf(".comm %s,%d,%d\n",n->nm,size(n->ty), + printf(".comm %s,%d @ %d\n",n->nm,size(n->ty), (n->ty==DOUBLE||n->ty==LONGLONG||n->ty==ULONGLONG)?8:4 ); } @@ -3427,7 +3420,7 @@ data_mode(0); init=1; } - printf(".local %s\n",n->nm); + // printf(".local %s\n",n->nm); comm(n); } } @@ -3502,83 +3495,132 @@ code_cmp_dregister(int e2,int d,int label,int cond) { char *grn,*frn; - int greg; + int greg,cmpreg; use_float(d,e2); - if (d) { + if (!(arch_mode&UseFPP)) { code_save_stacks(); clear_ptr_cache(); - set_dreg(DREGISTER_OPERAND,0); - dconst(DREGISTER_OPERAND_1_L,DREGISTER_OPERAND_1_H,0.0); - extern_conv("dpcmp"); - set_dreg(RET_DREGISTER,0); - cmpreg = 2; + if (d) { + set_dreg(DREGISTER_OPERAND,0); + dconst(DREGISTER_OPERAND_1_L,DREGISTER_OPERAND_1_H,0.0); + extern_conv("__nedf2"); + printf("\tcmp\tr0, #0\n"); + } else { + set_freg(FREGISTER_OPERAND,0); + fconst(REGISTER_OPERAND,0.0); + extern_conv("__nesf2"); + printf("\tcmp\tr0, #0\n"); + } } else { grn = register_name(greg = get_dregister(d)); frn = register_name(e2); - printf("\tmtc1 $0,%s\n",grn); - printf("\tc.eq.s %s,%s\n",grn,frn); + printf("\tcmf\t%s, #0\n",grn); free_register(greg); - cmpreg = CMP_C1T; } jcond(label,cond); return; } +static char * +movef(int d) +{ + return d?"mvfd":mvfs"; +} + +static char * +storef(int d) +{ + return d?"stfd":stfs"; +} + +static char * +loadf(int d) +{ + return d?"ldfd":ldfs"; +} + + void code_dregister(int e2,int freg,int d) { use_float(d,freg); - if (d) { - code_lregister(e2,freg); set_double(freg); return; - } - if (freg!=e2) { - if (is_int_reg(e2)) error(-1); - printf("\tmov.s %s,%s\n",fregister_name(freg),fregister_name(e2)); + if (!(arch_mode&UseFPP)) { + if (d) { + code_lregister(e2,freg); set_double(freg); return; + } else { + code_register(e2,freg); set_float(freg); return; + } + } else { + if (freg!=e2) { + if (is_int_reg(e2)) error(-1); + printf("\t%s\t%s,%s\n",movef(d), + fregister_name(freg),fregister_name(e2)); + } } } void code_dassign_gvar(int e2,int freg,int d) { - if (d) { - code_lassign_gvar(e2,freg); set_double(freg); return; + if (!(arch_mode&UseFPP)) { + if (d) { + code_lassign_gvar(e2,freg); set_double(freg); return; + } else { + code_assign_gvar(e2,freg); set_float(freg); return; + } + } else { + use_float(d,freg); + code_ldf(storef(d),fregister_name(freg),cadr(e2), + get_ptr_cache((NMTBL*)caddr(e2))," @ float"); } - use_float(d,freg); - code_ldf("s.s",fregister_name(freg),cadr(e2), - get_ptr_cache((NMTBL*)caddr(e2))); } void code_dassign_lvar(int e2,int freg,int d) { - if (d) { - code_lassign_lvar(e2,freg); set_double(freg); return; + if (!(arch_mode&UseFPP)) { + if (d) { + code_lassign_lvar(e2,freg); set_double(freg); return; + } else { + code_assign_lvar(e2,freg); set_float(freg); return; + } + } else { + use_float(d,freg); + lvar_intro(e2); + printf("\t%s\t%s,",fstore(d),fregister_name(freg)); + lvar(e2,"@ float"); } - use_float(d,freg); - lvar_intro(e2); - printf("\ts.s %s,",fregister_name(freg)); - lvar(e2,""); } void code_dassign(int e2,int freg,int d) { - if (d) { - code_lassign(e2,freg); set_double(freg); return; + if (!(arch_mode&UseFPP)) { + if (d) { + code_lassign(e2,freg); set_double(freg); return; + } else { + code_assign(e2,freg); set_float(freg); return; + } } use_float(d,freg); - printf("\ts.s %s,0(%s)\n",fregister_name(freg),register_name(e2)); + printf("\t%s\t%s,0(%s) @ float\n",fstore(d), + fregister_name(freg),register_name(e2)); } void code_dassign_dregister(int e2,int d,int freg) { - if (d) { - code_lassign_lregister(e2,freg); set_double(freg); return; + if (!(arch_mode&UseFPP)) { + if (d) { + code_lassign_lregister(e2,freg); set_double(freg); return; + } else { + code_assign_register(e2,freg); set_float(freg); return; + } } use_float(d,freg); if (e2!=freg) { - printf("\tmov.s %s,%s\n",fregister_name(e2),fregister_name(freg)); + printf("\t%s\t%s,%s\n",movef(d), + fregister_name(e2),fregister_name(freg)); } } @@ -3610,26 +3652,54 @@ dconst(int l,int h,double value) { #if ENDIAN==0 - printf("\tli %s,0x%x\n",register_name(l),code_d1(value)); - printf("\tli %s,0x%x\n",register_name(h),code_d2(value)); + code_const(code_d1(value),l); + code_const(code_d2(value),h); #else - printf("\tli %s,0x%x\n",register_name(h),code_d1(value)); - printf("\tli %s,0x%x\n",register_name(l),code_d2(value)); + code_const(code_d1(value),h); + code_const(code_d2(value),l); #endif } +static void +fconst(int reg,double value) +{ + float f = value; + code_const(*((int*)f),reg); +} + void code_dconst(int e2,int freg,int d) { double value = dcadr(e2); char *frn; + int label,disp; use_float(d,freg); - if (d) { - dconst(regv_l(freg),regv_h(freg),value); + if (!(arch_mode&UseFPP)) { + if (d) { + dconst(regv_l(freg),regv_h(freg),value); + } else { + code_const0(*((int*)f),freg,"\t@ float"); + } } else { - frn = fregister_name(freg); - printf("\tli.s %s,%10.10g\n",frn,value); + frn = register_name(freg); + if (value==0 || value==1 || value==10) { + printf("\t%s\t%s, #%d\n",movef(d),(int)value); + } else if (value==-1 || value==-10) { + printf("\t%s\t%s, #%d\n",d?"mnfd":"mnfs",(int)-value); + } else if (d) { +#if ENDIAN==0 + disp = search_double_const(DCONST, + code_d1(value),code_d2(value),&label); +#else + disp = search_double_const(DCONST, + code_d2(value),code_d1(value),&label); +#endif + disp = printf("\tldfd\t%s, .L%d+%d\n",frn,label,disp); + } else { + disp = search_const(CONST,*((int*)f),freg,&label); + printf("\tldfs\t%s, .L%d+%d\n",frn,label,disp); + } } } @@ -3639,19 +3709,26 @@ { char *frn; use_float(d,freg); - if (d) { - code_save_stacks(); - clear_ptr_cache(); - set_dreg(DREGISTER_OPERAND_1,1); - printf("\tmove $4,$0\n"); - printf("\tmove $5,$0\n"); - /// set_dreg_operand(oreg,1); - extern_conv("dpsub"); - set_dreg(RET_DREGISTER,0); - return; + if (!(arch_mode&UseFPP)) { + if (d) { + code_save_stacks(); + clear_ptr_cache(); + set_dreg(DREGISTER_OPERAND_1,1); + extern_conv("__negdf2"); + set_dreg(RET_DREGISTER,0); + return; + } else { + code_save_stacks(); + clear_ptr_cache(); + set_dreg(FREGISTER_OPERAND,1); + extern_conv("__negsf2"); + set_dreg(RET_FREGISTER,0); + return; + } + } else { + frn = fregister_name(freg); + printf("\t%s\t%s, %s\n",d?"mnfd":"mnfs",frn,frn); } - frn = fregister_name(freg); - printf("\tneg.s %s,%s\n",frn,frn); } void @@ -3862,7 +3939,7 @@ code_cmp_drgvar(int e2,int reg,int d,int label,int cond) { char *frn,*fr1; - int g; + int g,cmpreg; use_float(d,reg); if (d) { @@ -3890,7 +3967,7 @@ code_cmp_drlvar(int e2,int reg,int d,int label,int cond) { char *frn,*fr1; - int g; + int g,cmpreg; use_float(d,reg); if (d) {
--- a/mc-code-mips.c Wed Jul 14 14:37:37 2004 +0900 +++ b/mc-code-mips.c Sun Jul 18 12:26:30 2004 +0900 @@ -2818,7 +2818,6 @@ { int e2,reg0; int op = car(e1); -return 0; if (!( op== GT || op== LT || op== UGT || op== ULT || op== ULE || op== UGE || op== LE || op== GE || @@ -2830,7 +2829,7 @@ e2 = emit_pop(1); reg0 = ireg; use_int(reg); - pcond(op, reg,e2,reg0,1,0,COND_VALUE); + pcond(op, reg,e2,reg0,0,0,COND_VALUE); emit_pop_free(e2); return 1; }
--- a/mc-codegen.c Wed Jul 14 14:37:37 2004 +0900 +++ b/mc-codegen.c Sun Jul 18 12:26:30 2004 +0900 @@ -554,7 +554,8 @@ case FOP+GT: case FOP+GE: case FOP+LT: case FOP+LE: case FOP+EQ: case FOP+NEQ: case EQ: case NEQ: case DOP+EQ: case DOP+NEQ: - if ((car(caddr(e1))==CONST||(car(caddr(e1))==DCONST))) { + if (car(caddr(e1))==CONST||(car(caddr(e1))==DCONST)|| + car(caddr(e1))==FCONST) { b_expr(list3(rop_dual(op),caddr(e1),cadr(e1)),cond,l1,0); return; }
--- a/mc-parse.c Wed Jul 14 14:37:37 2004 +0900 +++ b/mc-parse.c Sun Jul 18 12:26:30 2004 +0900 @@ -2434,7 +2434,7 @@ e=rvalue(expr13()); #if FLOAT_CODE if(type==FLOAT) { - return(car(e)==DCONST?dlist2(DCONST,-dcadr(e)):list2(FMINUS,e)); + return(car(e)==FCONST?dlist2(FCONST,-dcadr(e)):list2(FMINUS,e)); } else if(type==DOUBLE) { return(car(e)==DCONST?dlist2(DCONST,-dcadr(e)):list2(DMINUS,e)); } @@ -2462,7 +2462,7 @@ e=rvalue(expr13()); type=INT; #if FLOAT_CODE - if (car(e)==DCONST) return list2(CONST,!dcadr(e)); + if (car(e)==DCONST||car(e)==FCONST) return list2(CONST,!dcadr(e)); #endif #if LONGLONG_CODE if (car(e)==LCONST) return list2(CONST,!lcadr(e)); @@ -2675,6 +2675,12 @@ getsym(0); break; #if FLOAT_CODE + case FCONST: + conv-> const_(symval); + type= FLOAT; + e1=dlist2(FCONST,dsymval); + getsym(0); + break; case DCONST: conv-> const_(symval); type= DOUBLE;
--- a/stdio.h Wed Jul 14 14:37:37 2004 +0900 +++ b/stdio.h Sun Jul 18 12:26:30 2004 +0900 @@ -1,5 +1,4 @@ -#define __micro_c__ 1 -#ifndef __micro_c__ +#ifndef __micro_c__aaa #include "/usr/include/stdio.h" long long strtoll(const char *, char **, int); char *malloc(int);
--- a/test/float.c Wed Jul 14 14:37:37 2004 +0900 +++ b/test/float.c Sun Jul 18 12:26:30 2004 +0900 @@ -35,6 +35,20 @@ return (double)u; } +double +f2d(float u) { + double u1; + u1 = f1; + return (double)u; +} + +float +d2f(double u) { + float u1; + u1 = d1; + return (float)u; +} + int main(int ac,char *av[]) { double g;