+2009-03-10 Borut Razem <borut.razem AT siol.net>
+
+ * src/mcs51/gen.c, src/z80/gen.c, src/hc08/gen.c, src/ds390/gen.c,
+ support/regression/tests/bug1875933.c:
+ fixed bug #1875933: Evelyn jumps into the void
+ thanks to Robert Larice
+
2009-03-10 Raphael Neider <rneider AT web.de>
* src/pic16/pcode.c (LinkFlow): fix invalid cast from pCodeLabel
case AOP_CRY:
// destination is carry for return-use-only
d = (IS_OP_RUONLY (result)) ? "c" : aop->aopu.aop_dir;
-
+
// source is no literal and not in carry
if ((s != zero) && (s != one) && strcmp (s, "c"))
{
// result = 1
if (size)
emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
- else
+ else if(ifx)
continueIfTrue (ifx);
goto release;
}
emitLabel (tlbl);
}
else
- {
+ { /* FIXME, thats pretty fishy, check for ifx!=0, testcase .. */
genIfxJump (ifx, "a", ic->next);
goto release;
}
if (AOP_TYPE (result) == AOP_CRY)
{
symbol *tlbl = NULL;
- wassertl (ifx, "AOP_CRY result without ifx");
offset = 0;
while (size--)
}
if (tlbl)
emitLabel (tlbl);
- genIfxJump (ifx, "a");
+ if(ifx)
+ genIfxJump (ifx, "a");
goto release;
}
if (AOP_TYPE (result) == AOP_CRY)
{
symbol *tlbl = NULL;
- wassertl (ifx, "AOP_CRY result without ifx");
offset = 0;
while (size--)
}
if (tlbl)
emitLabel (tlbl);
- genIfxJump (ifx, "a");
+ if(ifx)
+ genIfxJump (ifx, "a");
}
if (AOP_TYPE (right) == AOP_LIT)
// result = 1
if (size)
emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
- else
+ else if(ifx)
continueIfTrue (ifx);
goto release;
}
emitLabel (tlbl);
}
else
- {
+ { /* FIXME, thats pretty fishy, check for ifx!=0, testcase .. */
genIfxJump (ifx, "a", left, right, result, ic->next);
goto release;
}
new_high = (v_new >> 8) & 0xff;
old_low = (v_old >> 0) & 0xff;
old_high = (v_old >> 8) & 0xff;
-
+
/* Change lower byte only. */
if(new_high == old_high)
{
emit2 ("ld a, b");
emit2 ("pop bc");
}
-
+
}
emit2 ("adc a,%s", aopGet (AOP (IC_RIGHT (ic)), 1, FALSE));
aopPut (AOP (IC_RESULT (ic)), "a", 1);
if (offset == 0)
{
if(size == 0 && AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT && ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) == 1)
- emit2 ("inc a");
+ emit2 ("inc a");
else
emit2 ("add a,%s", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
}
/* For the flags */
emit2 ("or a,a");
}
+ if (size || ifx) /* emit jmp only, if it is actually used */
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
}
offset++;
bytelit = (lit >> (offset * 8)) & 0x0FFL;
_moveA (aopGet (AOP (left), offset, FALSE));
- /* OR with any literal is the same as OR with itself. */
- emit2 ("or a,a");
- emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
+
+ if (bytelit != 0)
+ { /* FIXME, allways true, shortcut possible */
+ emit2 ("or a,%s", aopGet (AOP (right), offset, FALSE));
+ }
+ else
+ {
+ /* For the flags */
+ emit2 ("or a,a");
+ }
+
+ if (ifx) /* emit jmp only, if it is actually used */
+ emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
offset++;
}
{
fetchPair (dest[i], AOP (pparams[i]));
continue;
- }
+ }
}
}
}
--- /dev/null
+/*
+ * bug1875933.c
+ */
+
+#include <testfwk.h>
+#include <stdint.h>
+
+char identity(char x)
+{
+ return x;
+}
+
+/*
+ * function genAnd() and genOr() in z80/gen.c
+ * were not prepared to handle the special case where ifx == 0
+ */
+
+void void_tand1(char x)
+{
+ char y = (identity(x) & 1) ? 42 : 43;
+}
+
+void void_tand0(char x)
+{
+ char y = (identity(x) & 0) ? 42 : 43;
+}
+
+/*
+ * function genOr() in z80/gen.c
+ * assumed identity of "or a, literal" and "or a,a"
+ * thats definitly not so
+ */
+
+char tor1(char x)
+{
+ char y = (identity(x) | 1) ? 42 : 43;
+ return y;
+}
+
+char tor0(char x)
+{
+ char y = (identity(x) | 0) ? 42 : 43;
+ return y;
+}
+
+char tand1(char x)
+{
+ char y = (identity(x) & 1) ? 42 : 43;
+ return y;
+}
+
+char tand0(char x)
+{
+ char y = (identity(x) & 0) ? 42 : 43;
+ return y;
+}
+
+/*
+ * mcs51 segmentation fault
+ *
+ * function genOr() in mcs51/gen.c
+ * was not prepeared for ifx==0
+ */
+
+void void_tor1(char x)
+{
+ char y = (identity(x) | 1) ? 42 : 43;
+}
+
+void void_tor0(char x)
+{
+ char y = (identity(x) | 0) ? 42 : 43;
+}
+
+void void_tor(char x)
+{
+ char y = (identity(x) | x) ? 42 : 43;
+}
+
+void
+testBug(void)
+{
+ void_tand1(1);
+ void_tand1(0);
+ void_tand0(1);
+ void_tand0(0);
+
+ ASSERT(tor1(1) == 42);
+ ASSERT(tor1(0) == 42);
+ ASSERT(tor0(1) == 42);
+ ASSERT(tor0(0) == 43);
+ ASSERT(tand1(1) == 42);
+ ASSERT(tand1(0) == 43);
+ ASSERT(tand0(1) == 43);
+ ASSERT(tand0(0) == 43);
+
+ void_tor1(1);
+ void_tor1(0);
+ void_tor0(1);
+ void_tor0(0);
+ void_tor(0);
+}