Mercurial > hg > CbC > old > device
diff mc-code-powerpc.c @ 280:affb054fe920
lrexpr fix. rexpr in MIPS fix.
author | kono |
---|---|
date | Sun, 23 May 2004 15:27:25 +0900 (2004-05-23) |
parents | 87b9cfc86a10 |
children | 230a3b98b843 |
line wrap: on
line diff
--- a/mc-code-powerpc.c Sat May 22 13:00:03 2004 +0900 +++ b/mc-code-powerpc.c Sun May 23 15:27:25 2004 +0900 @@ -1338,6 +1338,14 @@ return (cond?"eq":"ne"); } +static int cmpflag = 0; + +static void +inc_cmpflag() +{ + cmpflag = (cmpflag+1)%7; +} + void code_cmp_crgvar(int e1,int reg,int sz) { int r; @@ -1347,7 +1355,7 @@ r = get_ptr_cache((NMTBL*)cadr(e1)); printf("\t%s %s,0(%s)\n",cload(sz),crn,register_name(r)); cext(0,sz,r); - printf("\tcmpwi cr0,%s,0\n",crn); + printf("\tcmpwi cr%d,%s,0\n",cmpflag,crn); } @@ -1391,7 +1399,7 @@ void code_cmp_register(int e2) { use_int(e2); - printf("\tcmpwi cr0,%s,0\n",register_name(e2)); + printf("\tcmpwi cr%d,%s,0\n",cmpflag,register_name(e2)); } @@ -2301,7 +2309,6 @@ emit_pop_free(xreg); } - void tosop(int op,int creg,int oreg) { @@ -2344,7 +2351,10 @@ printf("\tsub %s,%s,%s\n",crn,crn,orn); break; case CMP: - printf("\tcmpw cr0,%s,%s\n",crn,orn); + printf("\tcmpw cr%d,%s,%s\n",cmpflag,crn,orn); + break; + case UCMP: + printf("\tcmplw cr%d,%s,%s\n",cmpflag,crn,orn); break; case BAND: printf("\tand %s,%s,%s\n",crn,crn,orn); @@ -2423,7 +2433,7 @@ printf("\taddi %s,%s,lo16(-%d)\n",crn,crn,v); break; case CMP: - printf("\tcmpwi cr0,%s,lo16(%d)\n",crn,v); + printf("\tcmpwi cr%d,%s,lo16(%d)\n",cmpflag,crn,v); break; case EOR: printf("\txori %s,%s,lo16(%d)\n",crn,crn,v); @@ -2474,7 +2484,7 @@ { /* used in dosiwtch() */ if(chk) return; - printf("\tcmpwi cr0,%s,%d\n",register_name(csreg),e); + printf("\tcmpwi cr%d,%s,%d\n",cmpflag,register_name(csreg),e); } void @@ -2487,10 +2497,24 @@ } void -rexpr(int e1, int l1, char *s,int t) +rexpr(int e1, int l1, int cond,int t) { - g_expr(list3(CMP,cadr(e1),caddr(e1))); - printf("\tb%s cr0,L_%d\n",s,l1); + char *s; + switch(car(e1)) { + case GT: s=code_gt(cond); break; + case UGT: s=code_ugt(cond); break; + case GE: s=code_ge(cond); break; + case UGE: s=code_uge(cond); break; + case LT: s=code_ge(!cond); break; + case ULT: s=code_uge(!cond);break; + case LE: s=code_gt(!cond); break; + case ULE: s=code_ugt(!cond);break; + case EQ: s=code_eq(cond); break; + case NEQ: s=code_eq(!cond); break; + default: error(-1); + } + g_expr(list3((t==INT?CMP:UCMP),cadr(e1),caddr(e1))); + printf("\tb%s cr%d,L_%d\n",s,cmpflag,l1); } @@ -2498,7 +2522,7 @@ jcond(int l, char cond) { if (chk) return; - printf("\tb%s cr0,L_%d\n",cond?"ne":"eq",l); + printf("\tb%s cr%d,L_%d\n",cond?"ne":"eq",cmpflag,l); } void @@ -2990,7 +3014,7 @@ 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); + printf("\tfcmpu cr%d,%s,%s\n",cmpflag,grn,frn); free_register(greg); return; } @@ -3310,7 +3334,7 @@ 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); + printf("\tfcmpu cr%d,%s,%s\n",cmpflag,frn,grn); free_register(g); } @@ -3326,7 +3350,7 @@ lvar_intro(e2); printf("\t%s %s,",fload(1),grn); lvar(e2); - printf("\tfcmpu cr0,%s,%s\n",frn,grn); + printf("\tfcmpu cr%d,%s,%s\n",cmpflag,frn,grn); free_register(g); } @@ -3584,9 +3608,21 @@ } static void -pcond(char *s,int l1) +pcond(char *s,int cmpflag,int l1) +{ + printf("\tb%s cr%d,L_%d\n",s,cmpflag,l1); +} + +static int +lcmp(int op,int cond) { - printf("\tb%s cr0,L_%d\n",s,l1); + if (op==LOP+UGT||op==LOP+UGE) { + return UCMP; + } else if (op==LOP+LE||op==LOP+GE) { + return CMP; + } else { + return CMP; + } } void @@ -3594,57 +3630,55 @@ { int reg; int e3; + int l2; + int op1,cr0,cr1; + g_expr(e1); emit_lpush(); g_expr(e2); e3 = emit_lpop(); if (!is_longlong_reg(creg)) error(-1); reg = lreg; - - tosop(CMP,regv_h(reg),regv_h(e3)); + op1 = lcmp(op,cond); + tosop(op1,regv_h(e3),regv_h(reg)); + cr0 = cmpflag; + inc_cmpflag(); + cr1 = cmpflag; + tosop(op1,regv_l(e3),regv_l(reg)); + + l2 = fwdlabel(); + // cond==0 jump on false condtion ( if(x) => rexpr(.. cond=0 ...) ) switch(op) { case LOP+GT: - pcond(code_gt(cond),l1); break; case LOP+GE: - pcond(code_ge(cond),l1); break; + pcond(code_gt(1),cr0,cond?l1:l2); + pcond(code_eq(0),cr0,cond?l2:l1); + break; + case LOP+UGT: + case LOP+UGE: + pcond(code_ugt(1),cr0,cond?l1:l2); + pcond(code_eq(0), cr0,cond?l2:l1); + break; case LOP+EQ: - pcond(code_eq(cond),l1); break; + pcond(code_eq(0),cr0,(cond?l2:l1)); + pcond(code_eq(cond),cr1,l1); + break; case LOP+NEQ: - pcond(code_eq(!cond),l1); break; - case LOP+LT: - pcond(code_ge(!cond),l1); break; - case LOP+LE: - pcond(code_gt(!cond),l1); break; - case LOP+UGT: - pcond(code_ugt(cond),l1); break; - case LOP+UGE: - pcond(code_uge(cond),l1); break; + pcond(code_eq(0),cr0,(cond?l1:l2)); + pcond(code_eq(!cond),cr1,l1); + break; default: error(-1); } - tosop(CMP,regv_l(reg),regv_l(e3)); switch(op) { - case LOP+GT: - pcond(code_gt(cond),l1); break; - case LOP+GE: - pcond(code_ge(cond),l1); break; - case LOP+EQ: - pcond(code_eq(cond),l1); break; - case LOP+NEQ: - pcond(code_eq(!cond),l1); break; - case LOP+LT: - pcond(code_ge(!cond),l1); break; - case LOP+LE: - pcond(code_gt(!cond),l1); break; - case LOP+UGT: - pcond(code_ugt(cond),l1); break; - case LOP+UGE: - pcond(code_uge(cond),l1); break; - default: - error(-1); - } - emit_lpop_free(e3); -} + case LOP+GT: pcond(code_gt(cond), cr1,l1); break; + case LOP+GE: pcond(code_ge(cond), cr1,l1); break; + case LOP+UGT: pcond(code_ugt(cond), cr1,l1); break; + case LOP+UGE: pcond(code_uge(cond), cr1,l1); break; + } + fwddef(l2); + emit_lpop_free(e3); +} int emit_lpop() @@ -3677,7 +3711,7 @@ lregister_name_low(reg), lregister_name_low(reg), lregister_name_high(reg)); - printf("\tcmpwi cr0,%s,0\n",lregister_name_low(reg)); + printf("\tcmpwi cr%d,%s,0\n",cmpflag,lregister_name_low(reg)); } void