# The paths below assume that sdcc, sdcc-extra, and gbdk-lib all reside in
# the same directory.
-# Old nores:
+# Old notes:
# Starting at the bottom
# Set of source test suites
# Each source suite is processesd producing multiple device specific test suites.
test-host:
$(MAKE) inter-port-clean clean test-port PORT=host
+test-host2:
+ $(MAKE) test-port PORT=host
+
# Begin per-port rules
# List of all of the known source test suites.
ALL_TESTS = $(shell find $(TESTS_DIR) -name "*.c")
# Rule to generate the iterations of a test suite off the soure suite.
$(PORT_CASES_DIR)/%$(DIREXT): $(TESTS_DIR)/%.c $(GENERATE_CASES)
+ echo Processing $<
rm -rf $(CASES_DIR)/tests
mkdir -p $(CASES_DIR)/tests
mkdir -p $@
# test
# List of all of the generated iteration source files.
-SUB_CASES = $(wildcard $(CASES)/*.c)
+SUB_CASES = $(sort $(wildcard $(CASES)/*.c))
# List of all the sub result logs generated from the iterations.
SUB_RESULTS = $(SUB_CASES:%.c=%.out)
# Overall target. Concatenation of all of the sub results.
#define ASSERT(_a) (__numTests++, (_a) ? (void)0 : __fail("Assertion failed", #_a, __FILE__, __LINE__))
#define LOG(_a) __printf _a
+#define FAIL() FAILM("Failure")
+#define FAILM(_a) __fail(_a, #_a, __FILE__, __LINE__)
typedef void TESTFUN(void);
#define NULL 0
+#define UNUSED(_a) if (_a) { }
+
#endif
# Port specification for compiling on the host machines version of gcc
SDCC = gcc
-SDCCFLAGS = -Wall
+SDCCFLAGS = -Wall -fsigned-char
EXEEXT = .bin
--- /dev/null
+/** Tests argument passing to functions.
+ Assumes that up to the first two arguments can be passed in registers.
+
+ type1: char, int
+ type2: char, int
+ type3: char, int
+ */
+#include <testfwk.h>
+
+static {type1}
+returnFirstArg({type1} arg1, {type2} arg2, {type3} arg3)
+{
+ return arg1;
+}
+
+static {type2}
+returnSecondArg({type1} arg1, {type2} arg2, {type3} arg3)
+{
+ return arg2;
+}
+
+static {type3}
+returnThirdArg({type1} arg1, {type2} arg2, {type3} arg3)
+{
+ return arg3;
+}
+
+static void
+testArgs(void)
+{
+ ASSERT(returnFirstArg(123, 45, 67) == 123);
+ ASSERT(returnFirstArg(-123, 45, 67) == -123);
+
+ ASSERT(returnSecondArg(1, -23, 64) == -23);
+ ASSERT(returnSecondArg(1, 8, 64) == 8);
+
+ ASSERT(returnThirdArg(-33, -34, -35) == -35);
+ ASSERT(returnThirdArg(-33, -34, 35) == 35);
+}
--- /dev/null
+/** Test the bitwise operators.
+
+ type: char, int
+ attr: volatile,
+ storage: static,
+ */
+#include <testfwk.h>
+
+static void
+testTwoOpBitwise(void)
+{
+ {storage} {attr} {type} left, right;
+
+ left = ({type})0x3df7;
+ right = ({type})0xc1ec;
+
+ ASSERT(({type})(left & right) == ({type})0x1E4);
+ ASSERT(({type})(right & left) == ({type})0x1E4);
+ ASSERT(({type})(left & 0xc1ec) == ({type})0x1E4);
+ ASSERT(({type})(0x3df7 & right) == ({type})0x1E4);
+
+ ASSERT(({type})(left | right) == ({type})0xFDFF);
+ ASSERT(({type})(right | left) == ({type})0xFDFF);
+ ASSERT(({type})(left | 0xc1ec) == ({type})0xFDFF);
+ ASSERT(({type})(0x3df7 | right) == ({type})0xFDFF);
+
+ ASSERT(({type})(left ^ right) == ({type})0xFC1B);
+ ASSERT(({type})(right ^ left) == ({type})0xFC1B);
+ ASSERT(({type})(left ^ 0xc1ec) == ({type})0xFC1B);
+ ASSERT(({type})(0x3df7 ^ right) == ({type})0xFC1B);
+}
+
--- /dev/null
+/** Test the comparison operators.
+
+ type: char, int, long
+ storage: static,
+ attr: volatile
+ */
+#include <testfwk.h>
+
+static void
+testCmpAroundZero(void)
+{
+ {attr} {storage} {type} i;
+
+ i = 5;
+
+ ASSERT(0 < i);
+ ASSERT(i > 0);
+ ASSERT(0 <= i);
+ ASSERT(i >= 0);
+
+ i = -33;
+ ASSERT(0 > i);
+ ASSERT(i < 0);
+ ASSERT(0 >= i);
+ ASSERT(i <= 0);
+
+ i = 0;
+ ASSERT(0 == i);
+ ASSERT(0 <= i);
+ ASSERT(0 >= i);
+}
+
+static void
+testCompareConstants(void)
+{
+ {attr} {storage} {type} i;
+
+ i = 12;
+ ASSERT(i < 23);
+ ASSERT(i > 3);
+ ASSERT(i > -14);
+ ASSERT(i <= 23);
+ ASSERT(i >= 3);
+ ASSERT(i >= -14);
+ ASSERT(i <= 12);
+ ASSERT(i >= 12);
+ ASSERT(i == 12);
+
+ i = -34;
+ ASSERT(i > -126);
+ ASSERT(i < -3);
+ ASSERT(i < 47);
+ ASSERT(i >= -126);
+ ASSERT(i <= -3);
+ ASSERT(i <= 47);
+ ASSERT(i <= -34);
+ ASSERT(i >= -34);
+ ASSERT(i == -34);
+}
+
+static void
+testCompareVariables(void)
+{
+ {attr} {storage} {type} left, right;
+
+ left = 12;
+ right = 47;
+ ASSERT(left < right);
+ ASSERT(left <= right);
+ ASSERT(right > left);
+ ASSERT(right >= left);
+
+ right = -8;
+ ASSERT(left > right);
+ ASSERT(left >= right);
+ ASSERT(right < left);
+ ASSERT(right <= left);
+
+ right = 0;
+ ASSERT(left > right);
+ ASSERT(left >= right);
+ ASSERT(right < left);
+ ASSERT(right <= left);
+
+ right = left;
+ ASSERT(left == right);
+ ASSERT(left <= right);
+ ASSERT(left >= right);
+}
+
+/*
+ Common cases:
+ Around zero
+ Constants on either side (reversal)
+ <=
+ >=
+ ==
+ !=
+ <
+ >
+*/
--- /dev/null
+/** Tests the basic logical operations.
+
+ type: char, int, long
+ storage: static,
+ attr: volatile
+ values: 5, 350, 31734
+ */
+#include <testfwk.h>
+
+static {type}
+alwaysTrue(void)
+{
+ return ({type}){values};
+}
+
+static {type}
+alwaysFalse(void)
+{
+ return 0;
+}
+
+static {type}
+neverGetHere(void)
+{
+ FAILM("Shouldn't get here");
+ return 0;
+}
+
+static int hit;
+
+static void
+resetGetHere(void)
+{
+ hit = 0;
+}
+
+static {type}
+alwaysGetHere(void)
+{
+ hit++;
+ return 1;
+}
+
+static void
+testLogicalAnd(void)
+{
+ {type} true = alwaysTrue();
+ {type} false = alwaysFalse();
+
+ ASSERT(true && true && true);
+ ASSERT(true && !false);
+ ASSERT(!false && true);
+
+ /* Test that the evaluation is aborted on the first false. */
+ if (true && false && neverGetHere()) {
+ /* Tested using neverGetHere() */
+ }
+
+ resetGetHere();
+ /* Test that the evaluation is done left to right. */
+ if (alwaysGetHere() && true && false) {
+ ASSERT(hit == 1);
+ }
+}
+
+static void
+testLogicalOr(void)
+{
+ {type} true = alwaysTrue();
+ {type} false = alwaysFalse();
+
+ ASSERT(false || false || true);
+ ASSERT(!true || !false);
+ ASSERT(false || true);
+
+ /* Test that the evaluation is aborted on the first hit. */
+ if (false || true || neverGetHere()) {
+ /* Tested using neverGetHere() */
+ }
+
+ resetGetHere();
+ /* Test that the evaluation is done left to right. */
+ if (alwaysGetHere() || true || false) {
+ ASSERT(hit == 1);
+ }
+}
+
+static void
+testNot(void)
+{
+ {type} true = alwaysTrue();
+ {type} false = alwaysFalse();
+
+ ASSERT(!false);
+ ASSERT(!!true);
+ ASSERT(!!!false);
+}
+
+static void
+testFlagToVariable(void)
+{
+ {type} true = alwaysTrue();
+ {type} false = alwaysFalse();
+ {type} val = !true;
+
+ ASSERT(!val);
+ val = !!false;
+ ASSERT(!false);
+}
{
{attr} {storage} {type} i, result;
- i = 50;
- ASSERT(i>>3 == 6);
- ASSERT(i<<2 == 200);
+ i = 30;
+ ASSERT(i>>3 == 3);
+ ASSERT(i<<2 == 120);
result = i;
result >>= 2;
- ASSERT(result == 12);
+ ASSERT(result == 7);
result = i;
result <<= 2;
- ASSERT(result == 200);
+ ASSERT(result == 120);
}
/** PENDING: Disabled. */
static void
testShiftByteMultiples(void)
{
-#if 0
+#if 1
{attr} {storage} {type} i;
i = ({type}){vals};
ASSERT(i>>24 == (({type}){vals} >> 24));
i = ({type}){vals};
- ASSERT(i<<8 == (({type}){vals} << 8));
+ ASSERT(i<<8 == (({type}){vals} << 8));;
ASSERT(i<<16 == (({type}){vals} << 16));
ASSERT(i<<24 == (({type}){vals} << 24));
#endif
// Test compare against a const
ASSERT(source == 17);
- dest = spoilAssign(134);
- ASSERT(dest == 134);
+ dest = spoilAssign(126);
+ ASSERT(dest == 126);
ASSERT(dest != source);
// Test assignment
--- /dev/null
+/** Tests argument passing to functions via va_args.
+ Assumes that up to the first two arguments can be passed in registers.
+
+ type1: char, int
+ type2: char, int
+ type3: char, int
+ */
+#include <testfwk.h>
+#include <stdarg.h>
+
+static {type1}
+returnFirstArg(int marker, ...)
+{
+ va_list ap;
+ {type1} i;
+
+ va_start(ap, marker);
+ i = va_arg(ap, {type1});
+
+ va_end(ap);
+
+ LOG(("Returning %u\n", i));
+ return i;
+}
+
+static {type2}
+returnSecondArg(int marker, ...)
+{
+ va_list ap;
+ {type2} i;
+
+ va_start(ap, marker);
+ UNUSED(va_arg(ap, {type1}));
+ i = va_arg(ap, {type2});
+
+ va_end(ap);
+
+ LOG(("Returning %u\n", i));
+ return i;
+}
+
+static {type3}
+returnThirdArg(int marker, ...)
+{
+ va_list ap;
+ {type3} i;
+
+ va_start(ap, marker);
+ UNUSED(va_arg(ap, {type1}));
+ UNUSED(va_arg(ap, {type2}));
+ i = va_arg(ap, {type3});
+
+ va_end(ap);
+
+ LOG(("Returning %u\n", i));
+ return i;
+}
+
+void
+disabled_testArgs(void)
+{
+ int marker = 12;
+
+ LOG(("First arg: %u\n", returnFirstArg(marker, ({type1})123, ({type2})45, ({type3})67)));
+ ASSERT(returnFirstArg(marker, ({type1})123, ({type2})45, ({type3})67) == 123);
+ ASSERT(returnFirstArg(marker, ({type1})-123, ({type2})45, ({type3})67) == -123);
+
+ ASSERT(returnSecondArg(marker, ({type1})1, ({type2})-23, ({type3})64) == -23);
+ ASSERT(returnSecondArg(marker, ({type1})1, ({type2})8, ({type3})64) == 8);
+
+ ASSERT(returnThirdArg(marker, -33, -34, -35) == -35);
+ ASSERT(returnThirdArg(marker, -33, -34, 35) == 35);
+}