aboutsummaryrefslogtreecommitdiff
path: root/tccgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'tccgen.c')
-rw-r--r--tccgen.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/tccgen.c b/tccgen.c
index e8f7f82..55b03e6 100644
--- a/tccgen.c
+++ b/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);