/* Test operandOperation() in SDCCicode.c type: char, short, LONG */ #include /* 64 bit hosts */ #if defined(__alpha__) || defined(__x86_64__) || defined(__sparc64__) || defined(__PPC64__) || defined(__aarch64__) # define LONG int #else # define LONG long #endif typedef signed {type} stype; typedef unsigned {type} utype; volatile char is8 = 8; #if !defined(__SDCC_pdk14) // Lack of memory signed char sc; signed short ss; signed LONG sl; unsigned char uc; unsigned short us; unsigned LONG ul; volatile signed char vsc; volatile signed short vss; volatile signed LONG vsl; volatile unsigned char vuc; volatile unsigned short vus; volatile unsigned LONG vul; stype s; volatile stype vs; utype u; volatile utype vu; unsigned LONG t1, t2; #endif int mulWrapper (int a, int b) { return a * b; } void testOpOp (void) { #if !defined( __SDCC_pdk14) && !defined( __SDCC_pdk15) // Lack of memory /* mul signedness: usualBinaryConversions() */ vsc = 0x7f; vuc = 0xfe; sc = vsc * vsc; ASSERT (sc == 1); sc = vuc * vsc; ASSERT (sc == 2); sc = vuc * vuc; ASSERT (sc == 4); ss = vsc * vsc; ASSERT (ss == 0x3f01); ss = vuc * vsc; ASSERT (ss == 0x7e02); ss = vuc * vuc; ASSERT (ss == (short) 0xfc04); #ifdef __SDCC /* after promotion the result of the multiplication is 'signed int', which overflows! */ ASSERT(vuc * vuc < 1); #endif /* mul ast: valMult() */ ASSERT ((stype) -3 * (stype) -1 == (stype) 3); ASSERT ((stype) -3 * (stype) 1 == (stype) -3); ASSERT ((stype) 3 * (stype) -1 == (stype) -3); ASSERT ((stype) 1 * (utype) 0xfffffff7 == (utype) 0xfffffff7); ASSERT ((unsigned char ) 0xfffffff8 * (unsigned char ) 0xfffffff7 == 0xef48); ASSERT (mulWrapper ((unsigned short) 0xfffffff8, (unsigned short) 0xfffffff7) == (sizeof(int) == 2 ? 0x0048 : (unsigned int)0xffef0048)); ASSERT ((unsigned LONG ) 0xfffffff8 * (unsigned LONG ) 0xfffffff7 == 0x0048); ASSERT ((stype ) 0xfffffff8 * (stype ) 0xfffffff7 == 72); ASSERT ((signed char ) -1 * (unsigned char ) 0xfffffff7 == (sizeof(int) == 2 ? (int)0xff09 : (int)0xffffff09)); ASSERT ((signed short) -1 * (unsigned short) 0xfffffff7 == (sizeof(int) == 2 ? 9u : 0xffff0009)); ASSERT ((signed LONG ) -1 * (unsigned LONG ) 0xfffffff7 == 9u); ASSERT ((signed char ) -2 * (unsigned char ) 0x8004 == (sizeof(int) == 2 ? (int)0xfff8 : (int)0xfffffff8)); ASSERT ((signed short) -2 * (unsigned short) 0x8004 == (sizeof(int) == 2 ? (int)0xfff8 : (int)0xfffefff8)); ASSERT ((signed LONG ) -2 * (unsigned LONG ) 0x8004 == 0xfffefff8); ASSERT (-1 * 0xfff7 == (sizeof(int) == 2 ? 9 : 0xffff0009)); // 0xfff7 is stored in 'unsigned int' // but: ASSERT (-1 * 65527 == -65527); // 65527 (== 0xfff7) is stored in 'signed LONG' ASSERT (-1 * 33000 == -33000); ASSERT (1 * 10000 * is8 == (sizeof(int) == 2 ? 14464 : 80000)); /* int */ ASSERT (1 * 10000l * is8 == 80000); /* LONG */ ASSERT (1 * 40000u * is8 == (sizeof(int) == 2 ? 57856u : 320000)); /* unsigned */ ASSERT (1 * 40000 * is8 == 320000); /* LONG */ ASSERT (1 * 0x4000 * is8 == (sizeof(int) == 2 ? 0 : 0x20000)); /* unsigned */ ASSERT (-2 * 1 < 1); /* comparison with 0 is optimized, so let's use 1 instead */ ASSERT (-2 * 1u > 1); ASSERT (0x7fffu * 2 > 1); ASSERT (0x7fffffffu * 2 > 1); if (sizeof (int) == 2) ASSERT (0x7fff * (unsigned char) 2 < 1); else ASSERT (mulWrapper (0x7fffffff, (unsigned char) 2) < 1); ASSERT (mulWrapper (0x7fffffff, (unsigned short) 2) < 1); /* mul icode: operandOperation() */ s = -3; ASSERT (s * (stype) -1 == (stype) 3); ASSERT (s * (stype) 1 == (stype) -3); s = 3; ASSERT (s * (stype) -1 == (stype) -3); s = 1; ASSERT (s * (utype) 0xfffffff7 == (utype) 0xfffffff7); uc = (unsigned char ) 0xfffffff8; ASSERT (uc * (unsigned char ) 0xfffffff7 == 0xef48); us = (unsigned short) 0xfffffff8; #if !(defined(PORT_HOST) && defined(__NetBSD__) && defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ == 1)) /* this test fails on i386 and sparc64 NetBSD gcc 4.1 when compiled with -O2: * the result of us * (unsigned short) 0xfffffff7 is 0x7fffffff */ #if !(defined(PORT_HOST) && defined(__APPLE__)) /* this test also fails on MacOS x86-64 with -O2 flag, but succeeds when switches to -O0 */ ASSERT (us * (unsigned short) 0xfffffff7 == (sizeof(int) == 2 ? 0x0048 : 0xffef0048)); #endif #endif ul = (unsigned LONG ) 0xfffffff8; ASSERT (ul * (unsigned LONG ) 0xfffffff7 == 0x0048); ul = (unsigned LONG ) 0xfffffff8; ASSERT ((stype ) 0xfffffff8 * (stype ) 0xfffffff7 == 72); ASSERT ((signed char ) -1 * (unsigned char ) 0xfffffff7 == (sizeof(int) == 2 ? (int)0xff09 : (int)0xffffff09)); ASSERT ((signed short) -1 * (unsigned short) 0xfffffff7 == (sizeof(int) == 2 ? 9u : 0xffff0009)); ASSERT ((signed LONG ) -1 * (unsigned LONG ) 0xfffffff7 == 9u); ASSERT ((signed char ) -2 * (unsigned char ) 0x8004 == (sizeof(int) == 2 ? (int)0xfff8 : (int)0xfffffff8)); ASSERT ((signed short) -2 * (unsigned short) 0x8004 == (sizeof(int) == 2 ? (int)0xfff8 : (int)0xfffefff8)); ASSERT ((signed LONG ) -2 * (unsigned LONG ) 0x8004 == 0xfffefff8); /* div ast: valDiv() */ ASSERT ((stype) -12 / (stype) -3 == (stype) 4); ASSERT ((stype) -12 / (stype) 3 == (stype) -4); ASSERT ((stype) 12 / (stype) -3 == (stype) -4); ASSERT ((unsigned char ) -12 / (signed char ) -3 == (sizeof(int) == 2 ? (int)0xffaf : (int)0xffffffaf)); ASSERT ((unsigned short) -12 / (signed short) -3 == (sizeof(int) == 2 ? 0 : 0xffffaaaf)); ASSERT ((unsigned LONG ) -12 / (signed LONG ) -3 == 0); ASSERT ((utype) -12 / (stype) 3 == (stype) 0x55555551); ASSERT ((unsigned char ) 12 / (signed char ) -3 == -4); ASSERT ((unsigned short) 12 / (signed short) -3 == (sizeof(int) == 2 ? 0 : 0xfffffffc)); ASSERT ((unsigned LONG ) 12 / (signed LONG ) -3 == 0); ASSERT ((stype) -12 / (utype) -3 == 0); ASSERT ((signed char ) -12 / (unsigned char ) 3 == -4); ASSERT ((signed short) -12 / (unsigned short) 3 == (sizeof(int) == 2 ? 0x5551 : -4)); ASSERT ((signed LONG ) -12 / (unsigned LONG ) 3 == 0x55555551); ASSERT ((stype) 12 / (utype) -3 == 0); ASSERT (12u / 3 * 10000 == 40000); ASSERT (-1 / 1 < 0); /* div icode: operandOperation() */ s = -12; ASSERT (s / (stype) -3 == (stype) 4); s = -12; ASSERT (s / (stype) 3 == (stype) -4); s = 12; ASSERT (s / (stype) -3 == (stype) -4); uc = -12; ASSERT (uc / (signed char ) -3 == (sizeof(int) == 2 ? (int)0xffaf : (int)0xffffffaf)); us = -12; ASSERT (us / (signed short) -3 == (sizeof(int) == 2 ? 0 : 0xffffaaaf)); ul = -12; ASSERT (ul / (signed LONG ) -3 == 0); u = -12; ASSERT (u / (stype) 3 == (stype) 0x55555551); uc = 12; ASSERT (uc / (signed char ) -3 == -4); us = 12; ASSERT (us / (signed short) -3 == (sizeof(int) == 2 ? 0 : 0xfffffffc)); ul = 12; ASSERT (ul / (signed LONG ) -3 == 0); s = -12; ASSERT (s / (utype) -3 == 0); sc = -12; ASSERT (sc / (unsigned char ) 3 == -4); ss = -12; ASSERT (ss / (unsigned short) 3 == (sizeof(int) == 2 ? 0x5551 : -4)); sl = -12; ASSERT (sl / (unsigned LONG ) 3 == 0x55555551); s = 12; ASSERT (s / (utype) -3 == 0); /* mod ast: valMod() */ /* -11 : 0xfff5 */ /* -17 : 0xffef */ ASSERT ((stype) -17 % (stype) -11 == (stype) -6); ASSERT ((stype) -17 % (stype) 11 == (stype) -6); ASSERT ((stype) 17 % (stype) -11 == (stype) 6); ASSERT ((unsigned char ) -17 % (signed char ) -11 == 8); ASSERT ((unsigned short) -17 % (signed short) -11 == (sizeof(int) == 2 ? -17 : 3)); ASSERT ((unsigned LONG ) -17 % (signed LONG ) -11 == -17); ASSERT ((unsigned char ) -17 % (signed char ) 11 == 8); ASSERT ((unsigned short) -17 % (signed short) 11 == 3); ASSERT ((unsigned LONG ) -17 % (signed LONG ) 11 == 9); ASSERT ((unsigned char ) 17 % (signed char ) -11 == 6); ASSERT ((unsigned short) 17 % (signed short) -11 == (sizeof(int) == 2 ? 17 : 6)); ASSERT ((unsigned LONG ) 17 % (signed LONG ) -11 == 17); ASSERT (-3 % 2 < 0); /* add */ ASSERT ( 80 + 80 == 160); ASSERT (150 + 150 == 300); ASSERT (160u + 160u == 320); #endif }