From: maartenbrock Date: Thu, 9 Dec 2004 18:24:40 +0000 (+0000) Subject: * device/include/sdcc-lib.h: inserted LGPL, added includes X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=3b5dc7119c7a5d3760e4bef555ef4029a1f2712a;p=fw%2Fsdcc * device/include/sdcc-lib.h: inserted LGPL, added includes asm/ds390/features.h and asm/mcs51/features.h * device/include/asm/default/features.h, * device/include/asm/gbz80/features.h, * device/include/asm/z80/features.h: added empty _AUTOMEM and _STATMEM * device/include/asm/ds390/features.h, * device/include/asm/mcs51/features.h: added files with defines for _AUTOMEM and _STATMEM indicating automatic and static storage class * device/lib/printf_large.c (_print_format): optimized & used _AUTOMEM * doc/sdccman.lyx: version 2.4.7, updated xstack documentation * src/SDCCicode.c (geniCodeCast), * src/SDCCsymt.c (compareType): allow cast of data-ptr to idata-ptr * src/SDCCloop.c (loopInduction): removed unused variable lr * src/SDCCopt.c (convilong, convertToFcall): moved "easy special case" to convertToFcall to include char modulo (RFE 1065037), added check if left operand is unsigned and use abs of literal value * src/SDCCpeeph.c (setFromConditionArgs): removed double quotes option as it doesn't work after conversion from peephole.def to peephole.rul * src/mcs51/gen.c (toBoolean): added check for size, (genModOneByte): optimized code for signed char modulo a literal power of 2 (thanks to Hubert Sack), (genRRC): removed unnecessary "clr c", (genRLC): replaced "add a,acc" with cheaper "rlc a" * src/mcs51/peeph.def: renamed 115 to 115.a, added rule 115.b: another jump optimization, swapped rules 256.c and 256.d, extended 256.d by using new multiple checks (thanks Erik), added rules 256.e and 256.f, updated rule 261.a and 261.b to new generated code * support/regression/tests/muldiv.c: added test div/mod by a power of 2 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3605 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 6499d812..32d9349d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,37 @@ +2004-12-09 Maarten Brock + + * device/include/sdcc-lib.h: inserted LGPL, added includes + asm/ds390/features.h and asm/mcs51/features.h + * device/include/asm/default/features.h, + * device/include/asm/gbz80/features.h, + * device/include/asm/z80/features.h: added empty _AUTOMEM + and _STATMEM + * device/include/asm/ds390/features.h, + * device/include/asm/mcs51/features.h: added files with defines for + _AUTOMEM and _STATMEM indicating automatic and static storage class + * device/lib/printf_large.c (_print_format): optimized & used _AUTOMEM + * doc/sdccman.lyx: version 2.4.7, updated xstack documentation + * src/SDCCicode.c (geniCodeCast), + * src/SDCCsymt.c (compareType): allow cast of data-ptr to idata-ptr + * src/SDCCloop.c (loopInduction): removed unused variable lr + * src/SDCCopt.c (convilong, convertToFcall): moved "easy special case" + to convertToFcall to include char modulo (RFE 1065037), added check + if left operand is unsigned and use abs of literal value + * src/SDCCpeeph.c (setFromConditionArgs): removed double quotes option + as it doesn't work after conversion from peephole.def to peephole.rul + * src/mcs51/gen.c (toBoolean): added check for size, + (genModOneByte): optimized code for signed char modulo a literal + power of 2 (thanks to Hubert Sack), + (genRRC): removed unnecessary "clr c", + (genRLC): replaced "add a,acc" with cheaper "rlc a" + * src/mcs51/peeph.def: renamed 115 to 115.a, added rule 115.b: another + jump optimization, + swapped rules 256.c and 256.d, + extended 256.d by using new multiple checks (thanks Erik), + added rules 256.e and 256.f, + updated rule 261.a and 261.b to new generated code + * support/regression/tests/muldiv.c: added test div/mod by a power of 2 + 2004-12-07 Erik Petrich * src/SDCCloop.c (basicInduction, loopInduction): fixed several diff --git a/device/include/asm/default/features.h b/device/include/asm/default/features.h index 7e903b9f..7695c7b4 100644 --- a/device/include/asm/default/features.h +++ b/device/include/asm/default/features.h @@ -5,5 +5,7 @@ #define _REENTRANT reentrant #define _CODE code +#define _AUTOMEM +#define _STATMEM #endif diff --git a/device/include/asm/ds390/features.h b/device/include/asm/ds390/features.h new file mode 100644 index 00000000..cc3e5db4 --- /dev/null +++ b/device/include/asm/ds390/features.h @@ -0,0 +1,46 @@ +/** DS390/DS400 specific features. + */ +#ifndef __SDC51_ASM_DS390_FEATURES_H +#define __SDC51_ASM_DS390_FEATURES_H 1 + +#define _REENTRANT reentrant +#define _CODE code + +/* define _AUTOMEM to indicate the default storage class for + automatic variables. To be used with pointers to automatic variables. + Cannot be used in reentrant declared functions! + + void foo(void) + { + char Ar[10]; + char _AUTOMEM * pAr = Ar; + } +*/ +#if defined(SDCC_STACK_AUTO) + #if defined(SDCC_USE_XSTACK) + #define _AUTOMEM pdata + #else + #define _AUTOMEM idata + #endif +#elif defined(SDCC_MODEL_SMALL) + #define _AUTOMEM data +#else + #define _AUTOMEM xdata +#endif + +/* define _STATMEM to indicate the default storage class for + global/static variables. To be used with pointers to static variables. + + char Ar[10]; + void foo(void) + { + char _STATMEM * pAr = Ar; + } +*/ +#if defined(SDCC_MODEL_SMALL) + #define _STATMEM data +#else + #define _STATMEM xdata +#endif + +#endif diff --git a/device/include/asm/gbz80/features.h b/device/include/asm/gbz80/features.h index fd9dc1ef..dfaecfef 100644 --- a/device/include/asm/gbz80/features.h +++ b/device/include/asm/gbz80/features.h @@ -5,6 +5,8 @@ #define _REENTRANT #define _CODE +#define _AUTOMEM +#define _STATMEM #define _SDCC_MANGLES_SUPPORT_FUNS 1 #define _SDCC_Z80_STYLE_LIB_OPT 1 diff --git a/device/include/asm/mcs51/features.h b/device/include/asm/mcs51/features.h new file mode 100644 index 00000000..04ad0a3a --- /dev/null +++ b/device/include/asm/mcs51/features.h @@ -0,0 +1,46 @@ +/** MCS51 specific features. + */ +#ifndef __SDC51_ASM_MCS51_FEATURES_H +#define __SDC51_ASM_MCS51_FEATURES_H 1 + +#define _REENTRANT reentrant +#define _CODE code + +/* define _AUTOMEM to indicate the default storage class for + automatic variables. To be used with pointers to automatic variables. + Cannot be used in reentrant declared functions! + + void foo(void) + { + char Ar[10]; + char _AUTOMEM * pAr = Ar; + } +*/ +#if defined(SDCC_STACK_AUTO) + #if defined(SDCC_USE_XSTACK) + #define _AUTOMEM pdata + #else + #define _AUTOMEM idata + #endif +#elif defined(SDCC_MODEL_SMALL) + #define _AUTOMEM data +#else + #define _AUTOMEM xdata +#endif + +/* define _STATMEM to indicate the default storage class for + global/static variables. To be used with pointers to static variables. + + char Ar[10]; + void foo(void) + { + char _STATMEM * pAr = Ar; + } +*/ +#if defined(SDCC_MODEL_SMALL) + #define _STATMEM data +#else + #define _STATMEM xdata +#endif + +#endif diff --git a/device/include/asm/z80/features.h b/device/include/asm/z80/features.h index fd9dc1ef..dfaecfef 100644 --- a/device/include/asm/z80/features.h +++ b/device/include/asm/z80/features.h @@ -5,6 +5,8 @@ #define _REENTRANT #define _CODE +#define _AUTOMEM +#define _STATMEM #define _SDCC_MANGLES_SUPPORT_FUNS 1 #define _SDCC_Z80_STYLE_LIB_OPT 1 diff --git a/device/include/sdcc-lib.h b/device/include/sdcc-lib.h index 61fe1afa..00564ecb 100644 --- a/device/include/sdcc-lib.h +++ b/device/include/sdcc-lib.h @@ -1,6 +1,24 @@ -/** Top level header file for the sdcc libraries that enables target +/*------------------------------------------------------------------------- + Top level header file for the sdcc libraries that enables target specific features. -*/ + + Copyright (C) 2004 - Maarten Brock, sourceforge.brock@dse.nl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------*/ + #ifndef __SDC51_SDCC_LIB_H #define __SDC51_SDCC_LIB_H 1 @@ -10,6 +28,12 @@ #elif defined(__gbz80) #include +#elif defined(__mcs51) +#include + +#elif defined(__ds390) +#include + #else /* PENDING */ #include diff --git a/device/lib/printf_large.c b/device/lib/printf_large.c index ef02a052..b5cfb5e7 100644 --- a/device/lib/printf_large.c +++ b/device/lib/printf_large.c @@ -34,23 +34,6 @@ #endif #endif -#if defined(SDCC_mcs51) - #if defined(SDCC_STACK_AUTO) - #if defined(SDCC_USE_XSTACK) - #define NEAR pdata - #else - //strange enough "idata" doesn't work - #define NEAR data - #endif - #elif defined(SDCC_MODEL_LARGE) - #define NEAR xdata - #else - #define NEAR data - #endif -#else - #define NEAR -#endif - #if defined(__ds390) #define USE_FLOATS 1 #endif @@ -60,6 +43,7 @@ #include #include #include +#include #define PTR value.ptr @@ -641,7 +625,7 @@ get_conversion_spec: // with radix "radix" #ifndef ASM_ALLOWED unsigned char store[6]; - unsigned char NEAR *pstore = &store[5]; + unsigned char _AUTOMEM *pstore = &store[5]; #endif // store value in byte[0] (LSB) ... byte[3] (MSB) @@ -711,8 +695,7 @@ _endasm; #endif length++; lsd = !lsd; - } while( (value.byte[0] != 0) || (value.byte[1] != 0) || - (value.byte[2] != 0) || (value.byte[3] != 0) ); + } while( value.ul ); if (width == 0) { diff --git a/doc/sdccman.lyx b/doc/sdccman.lyx index 384f1e9c..a5a057e2 100644 --- a/doc/sdccman.lyx +++ b/doc/sdccman.lyx @@ -83,7 +83,7 @@ SDCC Compiler User Guide \size normal -SDCC 2.4.6 +SDCC 2.4.7 \size footnotesize \newline @@ -13964,15 +13964,6 @@ External Stack \layout Standard - -\series bold -Attention -\series default -: this option wasn't maintained for a long time and is quite buggy. - Small programs might work. - You've been warned! -\layout Standard - The external stack (- \begin_inset ERT status Collapsed @@ -13993,8 +13984,9 @@ status Collapsed \end_inset - memory (usually at the start of the external ram segment) and is 256 bytes - in size. + memory (usually at the start of the external ram segment) and uses all + unused space in pdata (max. + 256 bytes). When - \begin_inset ERT status Collapsed @@ -14030,7 +14022,8 @@ status Collapsed option, all parameters and local variables are allocated on the external stack (note: support libraries will need to be recompiled with the same - options). + options. + There is a predefined target in the library makefile). \layout Standard The compiler outputs the higher order address byte of the external ram segment diff --git a/src/SDCCicode.c b/src/SDCCicode.c index c423c505..8a1d0504 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -323,7 +323,6 @@ printOperand (operand * op, FILE * file) fprintf (file, "]"); } } - #endif break; @@ -700,7 +699,7 @@ newiTempLabel (char *s) if (s) { - itmplbl = newSymbol (s, 1); + itmplbl = newSymbol (s, 1); } else { @@ -2001,7 +2000,12 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) // if not a pointer to a function if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) { if (implicit) { // if not to generic, they have to match - if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) { + if (!IS_GENPTR(type) && + !((DCL_TYPE(optype) == DCL_TYPE(type)) || + ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER)) + ) + ) + { werror(E_INCOMPAT_PTYPES); errors++; } diff --git a/src/SDCCloop.c b/src/SDCCloop.c index 1f751594..476554a6 100644 --- a/src/SDCCloop.c +++ b/src/SDCCloop.c @@ -1018,7 +1018,6 @@ loopInduction (region * loopReg, eBBlock ** ebbs, int count) { operand *aSym; long litVal; - int lr = 0; /* consider only * & / */ if (ic->op != '*' && ic->op != '/') diff --git a/src/SDCCopt.c b/src/SDCCopt.c index 94ee6e18..f7e67ce6 100644 --- a/src/SDCCopt.c +++ b/src/SDCCopt.c @@ -397,34 +397,8 @@ convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op) int su; int bytesPushed=0; - // Easy special case which avoids function call: modulo by a literal power - // of two can be replaced by a bitwise AND. - if (op == '%' && isOperandLiteral(IC_RIGHT(ic))) - { - unsigned litVal = (unsigned)(operandLitValue(IC_RIGHT(ic))); - - // See if literal value is a power of 2. - while (litVal && !(litVal & 1)) - { - litVal >>= 1; - } - if (litVal) - { - // discard first high bit set. - litVal >>= 1; - } - - if (!litVal) - { - ic->op = BITWISEAND; - IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1); - return; - } - } - remiCodeFromeBBlock (ebp, ic); - /* depending on the type */ for (bwd = 0; bwd < 3; bwd++) { @@ -582,6 +556,32 @@ convertToFcall (eBBlock ** ebbs, int count) cnvToFloatCast (ic, ebbs[i]); } + // Easy special case which avoids function call: modulo by a literal power + // of two can be replaced by a bitwise AND. + if (ic->op == '%' && isOperandLiteral(IC_RIGHT(ic)) && + IS_UNSIGNED(operandType(IC_LEFT(ic)))) + { + unsigned litVal = abs(operandLitValue(IC_RIGHT(ic))); + + // See if literal value is a power of 2. + while (litVal && !(litVal & 1)) + { + litVal >>= 1; + } + if (litVal) + { + // discard lowest set bit. + litVal >>= 1; + } + + if (!litVal) + { + ic->op = BITWISEAND; + IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1); + continue; + } + } + /* if long / int mult or divide or mod */ if (ic->op == '*' || ic->op == '/' || ic->op == '%') { diff --git a/src/SDCCpeeph.c b/src/SDCCpeeph.c index 2311c2c3..6b67a1f6 100644 --- a/src/SDCCpeeph.c +++ b/src/SDCCpeeph.c @@ -762,8 +762,8 @@ error: /*------------------------------------------------------------------*/ /* setFromConditionArgs - parse a peephole condition's arguments */ /* to produce a set of strings, one per argument. Variables %x will */ -/* be replaced with their values. String literals (in single or */ -/* double quotes) are accepted an return in unquoted form. */ +/* be replaced with their values. String literals (in single quotes)*/ +/* are accepted and return in unquoted form. */ /*------------------------------------------------------------------*/ static set * setFromConditionArgs (char *cmdLine, hTab * vars) @@ -798,7 +798,7 @@ setFromConditionArgs (char *cmdLine, hTab * vars) else goto error; } - else if (*cmdLine == '"' || *cmdLine == '\'' ) + else if (*cmdLine == '\'' ) { char quote = *cmdLine; @@ -855,7 +855,7 @@ FBYNAME (operandsNotRelated) if (!operands) { fprintf (stderr, - "*** internal error: operandsUnrelated peephole restriction" + "*** internal error: operandsNotRelated peephole restriction" " malformed: %s\n", cmdLine); return FALSE; } diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 668cf777..e6ab1b76 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -1894,7 +1894,10 @@ compareType (sym_link * dest, sym_link * src) if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) { return -1; } - if (IS_PTR (src) && IS_GENPTR (dest)) + if (IS_PTR (src) && + (IS_GENPTR (dest) || + ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER)) + )) return -1; if (IS_PTR (dest) && IS_ARRAY (src)) { value *val=aggregateToPointer (valFromType(src)); diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index c5ffcd85..c386b760 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -1601,7 +1601,7 @@ toBoolean (operand * oper) size = AOP_SIZE (oper) - 1; offset = 1; MOVA (aopGet (AOP (oper), 0, FALSE, FALSE)); - if (AccUsed && (AOP (oper)->type != AOP_ACC)) + if (size && AccUsed && (AOP (oper)->type != AOP_ACC)) { pushedB = pushB (); emitcode("mov", "b,a"); @@ -4698,6 +4698,61 @@ genModOneByte (operand * left, lUnsigned = SPEC_USIGN (getSpec (operandType (left))); rUnsigned = SPEC_USIGN (getSpec (operandType (right))); + /* if right is a literal, check it for 2^n */ + if (AOP_TYPE(right) == AOP_LIT) + { + unsigned char val = abs(operandLitValue(right)); + symbol *lbl2 = NULL; + + switch (val) + { + case 1: /* sometimes it makes sense (on tricky code and hardware)... */ + case 2: + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + if (lUnsigned) + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "modulus of unsigned char by 2^n literal shouldn't be processed here"); + /* because iCode should have been changed to genAnd */ + /* see file "SDCCopt.c", function "convertToFcall()" */ + + MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); + emitcode ("mov", "c,acc.7"); + emitcode ("anl", "a,#0x%02x", val - 1); + lbl = newiTempLabel (NULL); + emitcode ("jz", "%05d$", (lbl->key + 100)); + emitcode ("jnc", "%05d$", (lbl->key + 100)); + emitcode ("orl", "a,#0x%02x", 0xff ^ (val - 1)); + if (size) + { + int size2 = size; + int offs2 = offset; + + aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE)); + while (size2--) + aopPut (AOP (result), "#0xff", offs2++, isOperandVolatile (result, FALSE)); + lbl2 = newiTempLabel (NULL); + emitcode ("sjmp", "%05d$", (lbl2->key + 100)); + } + emitcode ("", "%05d$:", (lbl->key + 100)); + aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE)); + while (size--) + aopPut (AOP (result), zero, offset++, isOperandVolatile (result, FALSE)); + if (lbl2) + { + emitcode ("", "%05d$:", (lbl2->key + 100)); + } + return; + + default: + break; + } + } + pushedB = pushB (); /* signed or unsigned */ @@ -4722,7 +4777,7 @@ genModOneByte (operand * left, /* modulus: sign of the right operand has no influence on the result! */ if (AOP_TYPE(right) == AOP_LIT) { - signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit); + signed char val = (char) operandLitValue(right); if (!rUnsigned && val < 0) emitcode ("mov", "b,#0x%02x", -val); @@ -4833,7 +4888,7 @@ genMod (iCode * ic) D(emitcode ("; genMod","")); - /* assign the amsops */ + /* assign the asmops */ aopOp (left, ic, FALSE); aopOp (right, ic, FALSE); aopOp (result, ic, TRUE); @@ -6565,7 +6620,7 @@ genRRC (iCode * ic) emitcode ("rr", "a"); goto release; } - CLRC; + /* no need to clear carry, bit7 will be written later */ while (size--) { l = aopGet (AOP (left), offset, FALSE, FALSE); @@ -6617,7 +6672,7 @@ genRLC (iCode * ic) emitcode("rl","a"); goto release; } - emitcode ("add", "a,acc"); + emitcode("rlc","a"); /* bit0 will be written later */ if (AOP_SIZE (result) > 1) aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE)); while (size--) diff --git a/src/mcs51/peeph.def b/src/mcs51/peeph.def index ad563da2..a1993c8c 100644 --- a/src/mcs51/peeph.def +++ b/src/mcs51/peeph.def @@ -283,7 +283,6 @@ replace { %1: } if labelInRange - replace { clr a cjne %1,%2,%3 @@ -323,12 +322,24 @@ replace { %3: jnz %4 } by { - ; Peephole 115 jump optimization + ; Peephole 115.a jump optimization cjne %1,%2,%3 sjmp %4 %3: } if labelRefCount %3 1 +replace { + mov %1,a + cjne %1,#0x00,%2 + sjmp %3 +%2: +} by { + ; Peephole 115.b jump optimization + mov %1,a + jz %3 +%2: +} + replace { clr a cjne %1,%2,%3 @@ -3496,29 +3507,63 @@ replace { %2: } if labelRefCount %2 0 -// applies to f.e. malloc.c +// applies to f.e. bug-905492.c replace { jnz %1 %2: mov %3,#0x00 - mov %4,#0x00 } by { - ; Peephole 256.c loading %3,%4 with zero from a + ; Peephole 256.c loading %3 with zero from a jnz %1 +%2: mov %3,a - mov %4,a } if labelRefCount %2 0 -// applies to f.e. bug-905492.c +// applies to f.e. malloc.c replace { jnz %1 %2: + mov %4,%5 mov %3,#0x00 } by { ; Peephole 256.d loading %3 with zero from a jnz %1 +%2: + mov %4,%5 mov %3,a -} if labelRefCount %2 0 +} if labelRefCount(%2 0),operandsNotRelated('a' %4) + +replace { + jnz %1 +%2: + mov %4,%5 + mov %6,%7 + mov %3,#0x00 +} by { + ; Peephole 256.e loading %3 with zero from a + jnz %1 +%2: + mov %4,%5 + mov %6,%7 + mov %3,a +} if labelRefCount(%2 0),operandsNotRelated('a' %4 %6) + +replace { + jnz %1 +%2: + mov %4,%5 + mov %6,%7 + mov %8,%9 + mov %3,#0x00 +} by { + ; Peephole 256.f loading %2 with zero from a + jnz %1 +%2: + mov %4,%5 + mov %6,%7 + mov %8,%9 + mov %3,a +} if labelRefCount(%2 0),operandsNotRelated('a' %4 %6 %8) // unsigned char i=8; do{ } while(--i != 0); @@ -4152,7 +4197,7 @@ replace { // applies to: a = (a << 1) | (a >> 15); replace { mov a,%1 - add a,%1 + rlc a mov %1,a mov a,%2 rlc a @@ -4173,7 +4218,6 @@ replace { // applies to: a = (a << 15) | (a >> 1); replace { - clr c mov a,%1 rrc a mov %1,a diff --git a/support/regression/tests/muldiv.c b/support/regression/tests/muldiv.c index b354d352..b5aa5c18 100644 --- a/support/regression/tests/muldiv.c +++ b/support/regression/tests/muldiv.c @@ -85,6 +85,8 @@ testDiv(void) ASSERT(i/25 == -2); LOG(("i/-12 == 4 = %u\n", (int)i/-12)); ASSERT(i/-12 == 4); + //power of 2 + ASSERT(i/4 == -12); } void @@ -100,10 +102,14 @@ testMod(void) // LOG(("i%%-7 == 2 = %u\n", (int)i%-7)); ASSERT(i%-7 == 2); + //power of 2 + ASSERT(i%-8 == 4); i = -49; // LOG(("i%%3 == -1 = %u\n", (int)i%3)); ASSERT(i%3 == -1); // LOG(("i%%-5 == -4 = %u\n", (int)i%-5)); ASSERT(i%-5 == -4); + //power of 2 + ASSERT(i%4 == -1); }