Move logic for if (int value) to tccgen.c

Move the logic to do a test of an integer value (ex if (0)) out of
arch-specific code to tccgen.c to avoid code duplication. This also
fixes test of long long value which was only testing the bottom half of
such values on 32 bits architectures.
master
Thomas Preud'homme 2013-12-31 23:51:20 +08:00
parent c634c797c5
commit eda2c756ed
6 changed files with 37 additions and 118 deletions

View File

@ -1390,7 +1390,7 @@ int gtst(int inv, int t)
op|=encbranch(r,t,1);
o(op);
t=r;
} else if (v == VT_JMP || v == VT_JMPI) {
} else { /* VT_JMP || VT_JMPI */
if ((v & 1) == inv) {
if(!vtop->c.i)
vtop->c.i=t;
@ -1412,29 +1412,6 @@ int gtst(int inv, int t)
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;

View File

@ -2103,7 +2103,7 @@ int gtst(int inv, int t)
C67_NOP(5);
t = ind1; //return where we need to patch
} else if (v == VT_JMP || v == VT_JMPI) {
} else { /* VT_JMP || VT_JMPI */
/* && or || optimization */
if ((v & 1) == inv) {
/* insert vtop->c jump list in t */
@ -2129,37 +2129,6 @@ 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;

View File

@ -682,7 +682,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 if (v == VT_JMP || v == VT_JMPI) {
} else { /* VT_JMP || VT_JMPI */
/* && or || optimization */
if ((v & 1) == inv) {
/* insert vtop->c jump list in t */
@ -695,23 +695,6 @@ 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;

View File

@ -515,7 +515,7 @@ int gtst(int inv, int t)
break;
}
t = out_opj(c, t);
} else if (v == VT_JMP || v == VT_JMPI) {
} else { /* VT_JMP || VT_JMPI */
/* && or || optimization */
if ((v & 1) == inv) {
/* insert vtop->c jump list in t */
@ -528,19 +528,6 @@ 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;

View File

@ -1095,6 +1095,26 @@ static void gv_dup(void)
}
}
/* Generate value test
*
* Generate a test for any value (jump, comparison and integers) */
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)
@ -1293,13 +1313,13 @@ static void gen_opl(int op)
b = 0;
gen_op(op1);
if (op1 != TOK_NE) {
a = gtst(1, 0);
a = gvtst(1, 0);
}
if (op != TOK_EQ) {
/* generate non equal test */
/* XXX: NOT PORTABLE yet */
if (a == 0) {
b = gtst(0, 0);
b = gvtst(0, 0);
} else {
#if defined(TCC_TARGET_I386)
b = psym(0x850f, 0);
@ -1324,7 +1344,7 @@ static void gen_opl(int op)
else if (op1 == TOK_GE)
op1 = TOK_UGE;
gen_op(op1);
a = gtst(1, a);
a = gvtst(1, a);
gsym(b);
vseti(VT_JMPI, a);
break;
@ -3665,7 +3685,7 @@ ST_FUNC void unary(void)
vtop->c.i = vtop->c.i ^ 1;
else {
save_regs(1);
vseti(VT_JMP, gtst(1, 0));
vseti(VT_JMP, gvtst(1, 0));
}
break;
case '~':
@ -4182,7 +4202,7 @@ static void expr_land(void)
t = 0;
save_regs(1);
for(;;) {
t = gtst(1, t);
t = gvtst(1, t);
if (tok != TOK_LAND) {
vseti(VT_JMPI, t);
break;
@ -4202,7 +4222,7 @@ static void expr_lor(void)
t = 0;
save_regs(1);
for(;;) {
t = gtst(0, t);
t = gvtst(0, t);
if (tok != TOK_LOR) {
vseti(VT_JMP, t);
break;
@ -4264,9 +4284,9 @@ static void expr_cond(void)
}
if (tok == ':' && gnu_ext) {
gv_dup();
tt = gtst(1, 0);
tt = gvtst(1, 0);
} else {
tt = gtst(1, 0);
tt = gvtst(1, 0);
gexpr();
}
type1 = vtop->type;
@ -4512,7 +4532,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
skip('(');
gexpr();
skip(')');
a = gtst(1, 0);
a = gvtst(1, 0);
block(bsym, csym, case_sym, def_sym, case_reg, 0);
c = tok;
if (c == TOK_ELSE) {
@ -4529,7 +4549,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
skip('(');
gexpr();
skip(')');
a = gtst(1, 0);
a = gvtst(1, 0);
b = 0;
block(&a, &b, case_sym, def_sym, case_reg, 0);
gjmp_addr(d);
@ -4707,7 +4727,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
b = 0;
if (tok != ';') {
gexpr();
a = gtst(1, 0);
a = gvtst(1, 0);
}
skip(';');
if (tok != ')') {
@ -4736,7 +4756,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
skip('(');
gsym(b);
gexpr();
c = gtst(0, 0);
c = gvtst(0, 0);
gsym_addr(c, d);
skip(')');
gsym(a);

View File

@ -1582,7 +1582,7 @@ int gtst(int inv, int t)
}
g(0x0f);
t = psym((vtop->c.i - 16) ^ inv, t);
} else if (v == VT_JMP || v == VT_JMPI) {
} else { /* VT_JMP || VT_JMPI */
/* && or || optimization */
if ((v & 1) == inv) {
/* insert vtop->c jump list in t */
@ -1595,23 +1595,6 @@ 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;