Hi there,
while trying to fix the test of long long value on 32 bits architectures, I was
wondering whether this code should be done in tccgen.c instead of in each
architecture. There is already the comparison logic required to test if a
value is different than 0 in each architecture. Why not detect when an integer
is tested and convert to a comparison? So I did just this and the git stat is:
arm-gen.c | 25 +------------------------
c67-gen.c | 33 +--------------------------------
i386-gen.c | 19 +------------------
il-gen.c | 15 +--------------
tccgen.c | 44 ++++++++++++++++++++++++++++++++------------
x86_64-gen.c | 19 +------------------
6 files changed, 37 insertions(+), 118 deletions(-)
I tried the patch with make test and it seems to work. is there a fundamental
problem with this approache or a bug in the current patch? For those reading
the patch, basically the test is made in a new function gvtst (gen value test)
and tccgen.c is updated to use this function in place of gtst for all tests
that works on value (?: not being the case with gnu extension for instance)
and removing all the corresponding code in each architecture.
Best regards,
Thomas
diff --git a/arm-gen.c b/arm-gen.c
index 0aa07b1..eecb7d2 100644
--- a/arm-gen.c
+++ b/arm-gen.c
@@ -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;
diff --git a/c67-gen.c b/c67-gen.c
index 1189dbb..df4b5d3 100644
--- a/c67-gen.c
+++ b/c67-gen.c
@@ -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;
diff --git a/i386-gen.c b/i386-gen.c
index ebc0d14..2cb31ff 100644
--- a/i386-gen.c
+++ b/i386-gen.c
@@ -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;
diff --git a/il-gen.c b/il-gen.c
index 170f436..33f9f36 100644
--- a/il-gen.c
+++ b/il-gen.c
@@ -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;
diff --git a/tccgen.c b/tccgen.c
index bf208af..e498d68 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 '~':
@@ -4169,7 +4189,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;
@@ -4189,7 +4209,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;
@@ -4251,9 +4271,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;
@@ -4499,7 +4519,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) {
@@ -4516,7 +4536,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);
@@ -4694,7 +4714,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 != ')') {
@@ -4723,7 +4743,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);
diff --git a/x86_64-gen.c b/x86_64-gen.c
index 1550c07..fe028d9 100644
--- a/x86_64-gen.c
+++ b/x86_64-gen.c
@@ -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;
_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel