aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjiang <30155751@qq.com>2014-04-30 14:24:44 +0800
committerjiang <30155751@qq.com>2014-04-30 14:24:44 +0800
commit9ff288648b23537c205e4dad16002e2b9ca03203 (patch)
tree04168042a0103b0dfde4491e8c664086db990711
parent515169f21bf6c75a3179822e1dd9e006f5ef4412 (diff)
downloadtinycc-9ff288648b23537c205e4dad16002e2b9ca03203.tar.gz
tinycc-9ff288648b23537c205e4dad16002e2b9ca03203.tar.bz2
Restore eda2c756edc4dca004ba217d5bf361235dd9de1f
-rw-r--r--arm-gen.c83
-rw-r--r--c67-gen.c33
-rw-r--r--i386-gen.c19
-rw-r--r--il-gen.c15
-rw-r--r--tccgen.c46
-rw-r--r--x86_64-gen.c19
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;