aboutsummaryrefslogtreecommitdiff
path: root/tccgen.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2012-04-16 02:52:15 +0200
committerMichael Matz <matz@suse.de>2012-04-18 20:57:14 +0200
commit9ca9c82ff8a4001299a4b9666d85352f5806d565 (patch)
treecccd695d9db32bcba58c89a614eee9f5564371a5 /tccgen.c
parent718fd591fa93ff254a9ca68a0ad2ff8a55756489 (diff)
downloadtinycc-9ca9c82ff8a4001299a4b9666d85352f5806d565.tar.gz
tinycc-9ca9c82ff8a4001299a4b9666d85352f5806d565.tar.bz2
Fix comparing comparisons
Sometimes the result of a comparison is not directly used in a jump, but in arithmetic or further comparisons. If those further things do a vswap() with the VT_CMP as current top, and then generate instructions for the new top, this most probably destroys the flags (e.g. if it's a bitfield load like in the example). vswap() must do the same like vsetc() and not allow VT_CMP vtops to be moved down.
Diffstat (limited to 'tccgen.c')
-rw-r--r--tccgen.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/tccgen.c b/tccgen.c
index 36a1879..9339b5f 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -452,6 +452,14 @@ ST_FUNC void vswap(void)
{
SValue tmp;
+ /* cannot let cpu flags if other instruction are generated. Also
+ avoid leaving VT_JMP anywhere except on the top of the stack
+ because it would complicate the code generator. */
+ if (vtop >= vstack) {
+ int v = vtop->r & VT_VALMASK;
+ if (v == VT_CMP || (v & ~1) == VT_JMP)
+ gv(RC_INT);
+ }
tmp = vtop[0];
vtop[0] = vtop[-1];
vtop[-1] = tmp;