From 9ff288648b23537c205e4dad16002e2b9ca03203 Mon Sep 17 00:00:00 2001 From: jiang <30155751@qq.com> Date: Wed, 30 Apr 2014 14:24:44 +0800 Subject: [PATCH] Restore eda2c756edc4dca004ba217d5bf361235dd9de1f --- arm-gen.c | 83 +++++++++++++++++++++++++++++++++------------------- c67-gen.c | 33 ++++++++++++++++++++- i386-gen.c | 19 +++++++++++- il-gen.c | 15 +++++++++- tccgen.c | 46 ++++++++--------------------- x86_64-gen.c | 19 +++++++++++- 6 files changed, 148 insertions(+), 67 deletions(-) diff --git a/arm-gen.c b/arm-gen.c index 680a490..6da1706 100644 --- a/arm-gen.c +++ b/arm-gen.c @@ -1409,37 +1409,60 @@ void gjmp_addr(int a) /* generate a test. set 'inv' to invert test. Stack entry is popped */ int gtst(int inv, int t) { - int v, r; - uint32_t op; - v = vtop->r & VT_VALMASK; - r=ind; - if (v == VT_CMP) { - op=mapcc(inv?negcc(vtop->c.i):vtop->c.i); - op|=encbranch(r,t,1); - o(op); - t=r; - } else { /* VT_JMP || VT_JMPI */ - if ((v & 1) == inv) { - if(!vtop->c.i) - vtop->c.i=t; - else { - uint32_t *x; - int p,lp; - if(t) { - p = vtop->c.i; - do { - p = decbranch(lp=p); - } while(p); - x = (uint32_t *)(cur_text_section->data + lp); - *x &= 0xff000000; - *x |= encbranch(lp,t,1); - } - t = vtop->c.i; - } - } else { - t = gjmp(t); - gsym(vtop->c.i); + int v, r; + uint32_t op; + v = vtop->r & VT_VALMASK; + r=ind; + if (v == VT_CMP) { + op=mapcc(inv?negcc(vtop->c.i):vtop->c.i); + op|=encbranch(r,t,1); + o(op); + t=r; + } else if (v == VT_JMP || v == VT_JMPI) { + if ((v & 1) == inv) { + if(!vtop->c.i) + vtop->c.i=t; + else { + uint32_t *x; + int p,lp; + if(t) { + p = vtop->c.i; + do { + p = decbranch(lp=p); + } while(p); + x = (uint32_t *)(cur_text_section->data + lp); + *x &= 0xff000000; + *x |= encbranch(lp,t,1); + } + t = vtop->c.i; + } + } else { + t = gjmp(t); + gsym(vtop->c.i); } + } else { + if (is_float(vtop->type.t)) { + r=gv(RC_FLOAT); +#ifdef TCC_ARM_VFP + o(0xEEB50A40|(vfpr(r)<<12)|T2CPR(vtop->type.t)); /* fcmpzX */ + o(0xEEF1FA10); /* fmstat */ +#else + o(0xEE90F118|(fpr(r)<<16)); +#endif + vtop->r = VT_CMP; + vtop->c.i = TOK_NE; + return gtst(inv, t); + } else if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { + /* constant jmp optimization */ + if ((vtop->c.i != 0) != inv) + t = gjmp(t); + } else { + v = gv(RC_INT); + o(0xE3300000|(intr(v)<<16)); + vtop->r = VT_CMP; + vtop->c.i = TOK_NE; + return gtst(inv, t); + } } vtop--; return t; diff --git a/c67-gen.c b/c67-gen.c index a26dfaa..209fa7f 100644 --- a/c67-gen.c +++ b/c67-gen.c @@ -2102,7 +2102,7 @@ int gtst(int inv, int t) C67_NOP(5); t = ind1; //return where we need to patch - } else { /* VT_JMP || VT_JMPI */ + } else if (v == VT_JMP || v == VT_JMPI) { /* && or || optimization */ if ((v & 1) == inv) { /* insert vtop->c jump list in t */ @@ -2128,6 +2128,37 @@ int gtst(int inv, int t) t = gjmp(t); gsym(vtop->c.i); } + } else { + if (is_float(vtop->type.t)) { + vpushi(0); + gen_op(TOK_NE); + } + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { + /* constant jmp optimization */ + if ((vtop->c.i != 0) != inv) + t = gjmp(t); + } else { + // I think we need to get the value on the stack + // into a register, test it, and generate a branch + // return the address of the branch, so it can be + // later patched + + v = gv(RC_INT); // get value into a reg + ind1 = ind; + C67_MVKL(C67_A0, t); //r=reg to load, constant + C67_MVKH(C67_A0, t); //r=reg to load, constant + + if (v != TREG_EAX && // check if not already in a conditional test reg + v != TREG_EDX && v != TREG_ST0 && v != C67_B2) { + C67_MV(v, C67_B2); + v = C67_B2; + } + + C67_IREG_B_REG(inv, v, C67_A0); // [!R] B.S2x A0 + C67_NOP(5); + t = ind1; //return where we need to patch + ind1 = ind; + } } vtop--; return t; diff --git a/i386-gen.c b/i386-gen.c index ece054b..b9811f5 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -677,7 +677,7 @@ ST_FUNC int gtst(int inv, int t) /* fast case : can jump directly since flags are set */ g(0x0f); t = psym((vtop->c.i - 16) ^ inv, t); - } else { /* VT_JMP || VT_JMPI */ + } else if (v == VT_JMP || v == VT_JMPI) { /* && or || optimization */ if ((v & 1) == inv) { /* insert vtop->c jump list in t */ @@ -690,6 +690,23 @@ ST_FUNC int gtst(int inv, int t) t = gjmp(t); gsym(vtop->c.i); } + } else { + if (is_float(vtop->type.t) || + (vtop->type.t & VT_BTYPE) == VT_LLONG) { + vpushi(0); + gen_op(TOK_NE); + } + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { + /* constant jmp optimization */ + if ((vtop->c.i != 0) != inv) + t = gjmp(t); + } else { + v = gv(RC_INT); + o(0x85); + o(0xc0 + v * 9); + g(0x0f); + t = psym(0x85 ^ inv, t); + } } vtop--; return t; diff --git a/il-gen.c b/il-gen.c index 9e1ec64..9dafbbf 100644 --- a/il-gen.c +++ b/il-gen.c @@ -516,7 +516,7 @@ int gtst(int inv, int t) break; } t = out_opj(c, t); - } else { /* VT_JMP || VT_JMPI */ + } else if (v == VT_JMP || v == VT_JMPI) { /* && or || optimization */ if ((v & 1) == inv) { /* insert vtop->c jump list in t */ @@ -529,6 +529,19 @@ int gtst(int inv, int t) t = gjmp(t); gsym(vtop->c.i); } + } else { + if (is_float(vtop->t)) { + vpushi(0); + gen_op(TOK_NE); + } + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) { + /* constant jmp optimization */ + if ((vtop->c.i != 0) != inv) + t = gjmp(t); + } else { + v = gv(RC_INT); + t = out_opj(IL_OP_BRTRUE - inv, t); + } } vtop--; return t; diff --git a/tccgen.c b/tccgen.c index 71a426a..f2e1de0 100644 --- a/tccgen.c +++ b/tccgen.c @@ -92,7 +92,7 @@ static int is_compatible_parameter_types(CType *type1, CType *type2); static void expr_type(CType *type); ST_FUNC void vpush64(int ty, unsigned long long v); ST_FUNC void vpush(CType *type); -ST_FUNC int gvtst(int inv, int t); +ST_FUNC int gtst(int inv, int t); ST_FUNC int is_btype_size(int bt); ST_INLN int is_float(int t) @@ -1128,26 +1128,6 @@ static void gv_dup(void) } } -/* Generate value test - * - * Generate a test for any value (jump, comparison and integers) */ -ST_FUNC int gvtst(int inv, int t) -{ - int v = vtop->r & VT_VALMASK; - if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) { - vpushi(0); - gen_op(TOK_NE); - } - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - /* constant jmp optimization */ - if ((vtop->c.i != 0) != inv) - t = gjmp(t); - vtop--; - return t; - } - return gtst(inv, t); -} - #ifndef TCC_TARGET_X86_64 /* generate CPU independent (unsigned) long long operations */ static void gen_opl(int op) @@ -1346,13 +1326,13 @@ static void gen_opl(int op) b = 0; gen_op(op1); if (op1 != TOK_NE) { - a = gvtst(1, 0); + a = gtst(1, 0); } if (op != TOK_EQ) { /* generate non equal test */ /* XXX: NOT PORTABLE yet */ if (a == 0) { - b = gvtst(0, 0); + b = gtst(0, 0); } else { #if defined(TCC_TARGET_I386) b = psym(0x850f, 0); @@ -1377,7 +1357,7 @@ static void gen_opl(int op) else if (op1 == TOK_GE) op1 = TOK_UGE; gen_op(op1); - a = gvtst(1, a); + a = gtst(1, a); gsym(b); vseti(VT_JMPI, a); break; @@ -3760,7 +3740,7 @@ ST_FUNC void unary(void) vtop->c.i = vtop->c.i ^ 1; else { save_regs(1); - vseti(VT_JMP, gvtst(1, 0)); + vseti(VT_JMP, gtst(1, 0)); } break; case '~': @@ -4288,7 +4268,7 @@ static void expr_land(void) t = 0; save_regs(1); for(;;) { - t = gvtst(1, t); + t = gtst(1, t); if (tok != TOK_LAND) { vseti(VT_JMPI, t); break; @@ -4308,7 +4288,7 @@ static void expr_lor(void) t = 0; save_regs(1); for(;;) { - t = gvtst(0, t); + t = gtst(0, t); if (tok != TOK_LOR) { vseti(VT_JMP, t); break; @@ -4370,9 +4350,9 @@ static void expr_cond(void) } if (tok == ':' && gnu_ext) { gv_dup(); - tt = gvtst(1, 0); + tt = gtst(1, 0); } else { - tt = gvtst(1, 0); + tt = gtst(1, 0); gexpr(); } type1 = vtop->type; @@ -4618,7 +4598,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, skip('('); gexpr(); skip(')'); - a = gvtst(1, 0); + a = gtst(1, 0); block(bsym, csym, case_sym, def_sym, case_reg, 0); c = tok; if (c == TOK_ELSE) { @@ -4635,7 +4615,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, skip('('); gexpr(); skip(')'); - a = gvtst(1, 0); + a = gtst(1, 0); b = 0; block(&a, &b, case_sym, def_sym, case_reg, 0); gjmp_addr(d); @@ -4814,7 +4794,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, b = 0; if (tok != ';') { gexpr(); - a = gvtst(1, 0); + a = gtst(1, 0); } skip(';'); if (tok != ')') { @@ -4843,7 +4823,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, skip('('); gsym(b); gexpr(); - c = gvtst(0, 0); + c = gtst(0, 0); gsym_addr(c, d); skip(')'); gsym(a); diff --git a/x86_64-gen.c b/x86_64-gen.c index a8a7e87..72709be 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -1593,7 +1593,7 @@ int gtst(int inv, int t) } g(0x0f); t = psym((vtop->c.i - 16) ^ inv, t); - } else { /* VT_JMP || VT_JMPI */ + } else if (v == VT_JMP || v == VT_JMPI) { /* && or || optimization */ if ((v & 1) == inv) { /* insert vtop->c jump list in t */ @@ -1606,6 +1606,23 @@ int gtst(int inv, int t) t = gjmp(t); gsym(vtop->c.i); } + } else { + if (is_float(vtop->type.t) || + (vtop->type.t & VT_BTYPE) == VT_LLONG) { + vpushi(0); + gen_op(TOK_NE); + } + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { + /* constant jmp optimization */ + if ((vtop->c.i != 0) != inv) + t = gjmp(t); + } else { + v = gv(RC_INT); + orex(0,v,v,0x85); + o(0xc0 + REG_VALUE(v) * 9); + g(0x0f); + t = psym(0x85 ^ inv, t); + } } vtop--; return t;