diff --git a/test/val/bug2461.c b/test/val/bug2461.c index e8340b224..77a8dff57 100644 --- a/test/val/bug2461.c +++ b/test/val/bug2461.c @@ -2,13 +2,22 @@ /* Note: The values for MASK1, MASK2, the return values of GarbleAX and the * arguments for CALC() are carefully chosen to elicit the bug. + * CALCLX() errors appear with cc65 -Osi optimizations. */ #include #define MASK1 0x000FU #define MASK2 0x00FFU -#define CALC(num, op) (((num) & (~MASK1)) op ((num) & MASK2)) +#define CALCLA(num, op) (((num) & (~MASK1)) op ((num) & MASK2)) +/* + 0x100 here invokes g_inc(), case CF_INT: if (val <= 0x300), when +** CodeSizeFactor >= 200; then g_inc() produces a single "inx" +*/ +#define CALCLX(num, op) (((num) + 0x100) op ((num) & MASK2)) +#define CALCRX(num, op) (((num) & MASK2) op ((num) << 8)) + +#define CALCX(num, op) (((num) + 0x100) op ((num) & (~MASK1))) + static unsigned Failures = 0; static unsigned TestCount = 0; @@ -16,33 +25,157 @@ static unsigned TestCount = 0; unsigned GarbleAX(void) { static const unsigned Garbage[] = { - 0x1234, 0x0000, 0x1234, 0x1234 + 0x1234, 0x1234, 0x0000, 0x1234, 0x1234, /* Lhs A: Add, Sub, And, Or, Xor */ + 0x0057, 0x0057, 0x0037, 0x0057, /* Lhs A: Eq, Neq, Gte, Lte */ + + 0x1234, 0x1234, 0x2003, 0x1002, 0x5678, /* Lhs X: Add, Sub, And, Or, Xor */ + 0x0101, 0xFF00, 0xFF00, 0xFF00, /* Lhs X: Eq, Neq, Gte, Lte */ + + 0x1234, 0x1234, 0xFFFF, 0xFFFF, 0xFFFF, /* Rhs X: Add, Sub, And, Or, Xor */ }; return Garbage[TestCount - 1]; } -unsigned WrongAdd(unsigned num) +unsigned LhsAAdd(unsigned num) { unsigned ret=GarbleAX(); - return CALC(num, +); + return CALCLA(num, +); } -unsigned WrongAnd(unsigned num) +unsigned LhsASub(unsigned num) { unsigned ret=GarbleAX(); - return CALC(num, &); + return CALCLA(num, -); } -unsigned WrongOr(unsigned num) +unsigned LhsAAnd(unsigned num) { unsigned ret=GarbleAX(); - return CALC(num, |); + return CALCLA(num, &); } -unsigned WrongXor(unsigned num) +unsigned LhsAOr(unsigned num) { unsigned ret=GarbleAX(); - return CALC(num, ^); + return CALCLA(num, |); +} + +unsigned LhsAXor(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCLA(num, ^); +} + + +unsigned LhsAEq(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCLA(num, ==); +} + +unsigned LhsANeq(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCLA(num, !=); +} + +unsigned LhsAGte(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCLA(num, >=); +} + +unsigned LhsALte(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCLA(num, <=); +} + + +unsigned LhsXAdd(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCX(num, +); +} + +unsigned LhsXSub(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCX(num, -); +} + +unsigned LhsXAnd(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCX(num, &); +} + +unsigned LhsXOr(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCLX(num, |); +} + +unsigned LhsXXor(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCLX(num, ^); +} + + +unsigned LhsXEq(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCLX(num, ==); +} + +unsigned LhsXNeq(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCX(num, !=); +} + +unsigned LhsXGte(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCLX(num, >=); +} + +unsigned LhsXLte(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCLX(num, <=); +} + + +unsigned RhsXAdd(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCRX(num, +); +} + +unsigned RhsXSub(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCRX(num, -); +} + +unsigned RhsXAnd(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCRX(num, &); +} + +unsigned RhsXOr(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCRX(num, |); +} + +unsigned RhsXXor(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALCRX(num, ^); } void Test(unsigned (*F)(unsigned), unsigned Num, unsigned Ref) @@ -58,10 +191,39 @@ void Test(unsigned (*F)(unsigned), unsigned Num, unsigned Ref) int main(void) { - Test(WrongAdd, 0x4715, CALC(0x4715, +)); - Test(WrongAnd, 0x4715, CALC(0x4715, &)); - Test(WrongOr, 0x4715, CALC(0x4715, |)); - Test(WrongXor, 0x4715, CALC(0x4715, ^)); + /* Test 1+ */ + Test(LhsAAdd, 0x4715, CALCLA(0x4715, +)); + Test(LhsASub, 0x4715, CALCLA(0x4715, -)); + Test(LhsAAnd, 0x4715, CALCLA(0x4715, &)); + Test(LhsAOr, 0x4715, CALCLA(0x4715, |)); + Test(LhsAXor, 0x4715, CALCLA(0x4715, ^)); + + /* Test 6+ */ + Test(LhsAEq, 0x4750, CALCLA(0x4750, ==)); + Test(LhsANeq, 0x4750, CALCLA(0x4750, !=)); + Test(LhsAGte, 0x4750, CALCLA(0x4750, >=)); + Test(LhsALte, 0x4750, CALCLA(0x4750, <=)); + + /* Test 10+ */ + Test(LhsXAdd, 0x3F15, CALCX(0x3F15, +)); + Test(LhsXSub, 0x3F15, CALCX(0x3F15, -)); + Test(LhsXAnd, 0x3F15, CALCX(0x3F15, &)); + Test(LhsXOr, 0x3F15, CALCLX(0x3F15, |)); + Test(LhsXXor, 0x3F15, CALCLX(0x3F15, ^)); + + /* Test 15+ */ + Test(LhsXEq, 0xFF50, CALCLX(0xFF50, ==)); + Test(LhsXNeq, 0xFF50, CALCX(0xFF50, !=)); + Test(LhsXGte, 0xFF50, CALCLX(0xFF50, >=)); + Test(LhsXLte, 0xFF50, CALCLX(0xFF50, <=)); + + /* Test 19+ */ + Test(RhsXAdd, 0x3F15, CALCRX(0x3F15, +)); + Test(RhsXSub, 0x3F15, CALCRX(0x3F15, -)); + Test(RhsXAnd, 0x3F15, CALCRX(0x3F15, &)); + Test(RhsXOr, 0x3F15, CALCRX(0x3F15, |)); + Test(RhsXXor, 0x3F15, CALCRX(0x3F15, ^)); + printf("Failures: %u\n", Failures); return Failures; }