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.
This commit is contained in:
44
tccgen.c
44
tccgen.c
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user