From 508062e44ac0d6b44e3e299d032ddc382065ce19 Mon Sep 17 00:00:00 2001 From: michaelh Date: Mon, 20 Aug 2001 04:32:44 +0000 Subject: [PATCH] Added tests for switch statement and the z80 loop induction problem git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1154 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- support/regression/Makefile | 6 +- support/regression/fwk/include/testfwk.h | 2 +- support/regression/fwk/lib/testfwk.c | 7 +- support/regression/ports/z80/spec.mk | 5 +- support/regression/ports/z80/support.asm | 4 + support/regression/tests/bug-453196.c | 72 +++++++++++ support/regression/tests/switch.c | 146 +++++++++++++++++++++++ 7 files changed, 236 insertions(+), 6 deletions(-) create mode 100644 support/regression/tests/bug-453196.c create mode 100644 support/regression/tests/switch.c diff --git a/support/regression/Makefile b/support/regression/Makefile index 98ef6d7d..daa42ef7 100644 --- a/support/regression/Makefile +++ b/support/regression/Makefile @@ -72,6 +72,10 @@ test-ports: test-z80: $(MAKE) inter-port-clean test-port PORT=z80 +# Helper rule for testing the mcs51 small model port only +test-mcs51: + $(MAKE) inter-port-clean test-port PORT=mcs51 + # Helper rule for testing the host cc only test-host: $(MAKE) inter-port-clean clean test-port PORT=host @@ -109,7 +113,7 @@ ifdef PORT include $(PORTS_DIR)/$(PORT)/spec.mk endif -SDCCFLAGS += -Ifwk/include +SDCCFLAGS += -Ifwk/include -Itests # List of intermediate files to keep. Pretty much keep everything as # disk space is free. diff --git a/support/regression/fwk/include/testfwk.h b/support/regression/fwk/include/testfwk.h index 91f15039..4a178514 100644 --- a/support/regression/fwk/include/testfwk.h +++ b/support/regression/fwk/include/testfwk.h @@ -4,7 +4,7 @@ extern int __numTests; void __fail(const char *szMsg, const char *szCond, const char *szFile, int line); -void __printf(const char *szFormat, ...); +void __printf(const char *szFormat, ...) REENTRANT; #define ASSERT(_a) (__numTests++, (_a) ? (void)0 : __fail("Assertion failed", #_a, __FILE__, __LINE__)) #define LOG(_a) __printf _a diff --git a/support/regression/fwk/lib/testfwk.c b/support/regression/fwk/lib/testfwk.c index 0bfcbc0b..55e2085b 100644 --- a/support/regression/fwk/lib/testfwk.c +++ b/support/regression/fwk/lib/testfwk.c @@ -9,6 +9,7 @@ #define BROKEN_DIV_MOD 1 void _putchar(char c); +void _exitEmu(void); #if BROKEN_DIV_MOD int __div(int num, int denom) @@ -56,7 +57,7 @@ static void _printn(int n) _putchar('0' + rem); } -void __printf(const char *szFormat, ...) +void __printf(const char *szFormat, ...) REENTRANT { va_list ap; va_start(ap, szFormat); @@ -65,7 +66,7 @@ void __printf(const char *szFormat, ...) if (*szFormat == '%') { switch (*++szFormat) { case 's': { - const char *sz = va_arg(ap, const char *); + char GENERIC *sz = va_arg(ap, char GENERIC *); while (*sz) { _putchar(*sz++); } @@ -123,5 +124,5 @@ main(void) __numFailures, __numTests, numCases ); - return __numFailures; + _exitEmu(); } diff --git a/support/regression/ports/z80/spec.mk b/support/regression/ports/z80/spec.mk index 13339495..48db49e8 100644 --- a/support/regression/ports/z80/spec.mk +++ b/support/regression/ports/z80/spec.mk @@ -3,7 +3,7 @@ RRZ80 = $(SDCC_EXTRA_DIR)/emu/rrz80/rrz80 -SDCCFLAGS += --lesspedantic --profile +SDCCFLAGS += --lesspedantic --profile -DREENTRANT= -DGENERIC= --dumpall EXEEXT = .bin @@ -24,6 +24,9 @@ EXTRAS = fwk/lib/testfwk$(OBJEXT) ports/$(PORT)/support$(OBJEXT) %$(OBJEXT): %.s ../../bin/as-z80 -plosgff $@ $< +%$(OBJEXT): %.c + $(SDCC) $(SDCCFLAGS) -c $< + # PENDING: Path to sdcc-extra %.out: %$(EXEEXT) mkdir -p `dirname $@` diff --git a/support/regression/ports/z80/support.asm b/support/regression/ports/z80/support.asm index 4c4c35ad..01e0ef8b 100644 --- a/support/regression/ports/z80/support.asm +++ b/support/regression/ports/z80/support.asm @@ -1,5 +1,9 @@ .area _CODE .globl _putchar + .globl _exit __putchar:: jp _putchar + +__exitEmu:: + jp _exit diff --git a/support/regression/tests/bug-453196.c b/support/regression/tests/bug-453196.c new file mode 100644 index 00000000..47a84902 --- /dev/null +++ b/support/regression/tests/bug-453196.c @@ -0,0 +1,72 @@ +/* Demonstrates the aliasing problem with the z80 port when loop + induction is turned on. Run_Index and Int_2_Loc get joined into + the same spill location. + + Stripped down version of dhry.c + */ + +#include + +#define NOENUM 1 +#define NOSTRUCTASSIGN 1 +#define REG + +#define Ident_2 1 + +typedef int Enumeration; + +typedef int One_Fifty; +typedef char Capital_Letter; + +char Ch_2_Glob; + +Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val); + +void +testDhry(void) +{ + One_Fifty Int_1_Loc; + REG One_Fifty Int_2_Loc; + One_Fifty Int_3_Loc; + REG Capital_Letter Ch_Index; + Enumeration Enum_Loc; + REG int Run_Index; + REG int Number_Of_Runs; + + /* Must be more than 13... */ + Number_Of_Runs = 50; + + /* Main test loop */ + for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) { + Int_1_Loc = 2; + Int_2_Loc = 3; + Enum_Loc = Ident_2; + + /* Removing this section removes the problem. */ + while (Int_1_Loc < Int_2_Loc) + { + Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc; + Int_1_Loc += 1; + } + + /* Removing this section removes the problem. */ + for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index) + { + if (Enum_Loc == Func_1 (Ch_Index, 'C')) + { + Int_2_Loc = Run_Index; + } + } + + /* Removing any one of the following lines removes the problem. */ + Int_2_Loc = Int_2_Loc * Int_1_Loc; + Int_1_Loc = Int_2_Loc / Int_3_Loc; + Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc; + } +} + +Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val) +{ + UNUSED(Ch_1_Par_Val); + UNUSED(Ch_2_Par_Val); +} diff --git a/support/regression/tests/switch.c b/support/regression/tests/switch.c new file mode 100644 index 00000000..bb29967a --- /dev/null +++ b/support/regression/tests/switch.c @@ -0,0 +1,146 @@ +/* Test the types of switch statement. + + type: char, int, long + sign: signed, unsigned + storage: static, + attr: volatile + */ +#include + +{sign} {type} +sparseSwitch({sign} {type} val) +{ + {sign} {type} ret; + {storage} {attr} {sign} {type} local; + + local = val; + + switch (local) { + case 1: + ret = 7; + break; + case 4: + ret = 12; + break; + case 6: + ret = 13; + /* Fall through */ + case 12: + ret = 14; + break; + case 13: + case 14: + case 15: + ret = 19; + break; + default: + ret = 30; + } + + return ret; +} + +void +testSparseSwitch(void) +{ + ASSERT(sparseSwitch(1) == 7); + ASSERT(sparseSwitch(4) == 12); + ASSERT(sparseSwitch(6) == 14); + ASSERT(sparseSwitch(12) == 14); + ASSERT(sparseSwitch(13) == 19); + ASSERT(sparseSwitch(14) == 19); + ASSERT(sparseSwitch(15) == 19); + ASSERT(sparseSwitch(19) == 30); + ASSERT(sparseSwitch(0) == 30); +} + +{sign} {type} +denseSwitch({sign} {type} val) +{ + {sign} {type} ret; + {storage} {attr} {sign} {type} local; + + local = val; + ret = 12; + + switch (local) { + case 0: + ret = 1; + break; + case 1: + ret = 14; + break; + case 2: + ret = 15; + break; + case 3: + ret = 34; + break; + case 4: + ret = 17; + break; + /* No default */ + } + + return ret; +} + +void +testDenseSwitch(void) +{ + ASSERT(denseSwitch(0) == 1); + ASSERT(denseSwitch(1) == 14); + ASSERT(denseSwitch(2) == 15); + ASSERT(denseSwitch(3) == 34); + ASSERT(denseSwitch(4) == 17); + ASSERT(denseSwitch(5) == 12); + ASSERT(denseSwitch(100) == 12); +} + +void +testDenseIntSwitch(void) +{ + volatile int val = 1000; + volatile int ret = 0; + + switch (val) { + case 999: + ret = 5; + break; + case 1000: + ret = 6; + break; + case 1001: + ret = 7; + break; + case 1002: + ret = 12; + break; + case 1003: + ret = 14; + break; + } + + ASSERT(ret == 6); + + val = 129; + + switch (val) { + case 126: + ret = 5; + break; + case 127: + ret = 6; + break; + case 128: + ret = 7; + break; + case 129: + ret = 8; + break; + default: + ret = 9; + } + + ASSERT(ret == 8); +} -- 2.30.2