From: maartenbrock Date: Sun, 19 Dec 2004 18:44:03 +0000 (+0000) Subject: * src/ds390/gen.c (genCpl): fixed bit=~(char/bit) bugs, added warning X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=0712ffe9a67e08c25e671a333432ff75ea2f7319;p=fw%2Fsdcc * src/ds390/gen.c (genCpl): fixed bit=~(char/bit) bugs, added warning * src/ds390/main.c (_ds390_regparm): don't pass bit params in registers * src/ds390/ralloc.c (serialRegAssign): spill bits * src/mcs51/gen.c (genCpl): fixed bit=~(char) bugs, added warning * support/Util/SDCCerr.c, * support/Util/SDCCerr.h: added warning W_COMPLEMENT for using bit=~(bit) * support/regression/tests/bitvars.c: added tests for bitwise complement(~) * support/regression/tests/bitwise.c: added test for bitwise complement(~) git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3606 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 32d9349d..059d1cb5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2004-12-19 Maarten Brock + + * src/ds390/gen.c (genCpl): fixed bit=~(char/bit) bugs, added warning + * src/ds390/main.c (_ds390_regparm): don't pass bit params in registers + * src/ds390/ralloc.c (serialRegAssign): spill bits + * src/mcs51/gen.c (genCpl): fixed bit=~(char) bugs, added warning + * support/Util/SDCCerr.c, + * support/Util/SDCCerr.h: added warning W_COMPLEMENT for using bit=~(bit) + * support/regression/tests/bitvars.c: added tests for bitwise complement(~) + * support/regression/tests/bitwise.c: added test for bitwise complement(~) + 2004-12-09 Maarten Brock * device/include/sdcc-lib.h: inserted LGPL, added includes diff --git a/src/ds390/gen.c b/src/ds390/gen.c index 518e36cc..94563741 100644 --- a/src/ds390/gen.c +++ b/src/ds390/gen.c @@ -1914,25 +1914,43 @@ genCpl (iCode * ic) int offset = 0; int size; symbol *tlbl; + sym_link *letype = getSpec (operandType (IC_LEFT (ic))); - D (emitcode (";", "genCpl ");); - + D(emitcode (";", "genCpl")); /* assign asmOps to operand & result */ aopOp (IC_LEFT (ic), ic, FALSE, FALSE); aopOp (IC_RESULT (ic), ic, TRUE, AOP_USESDPTR(IC_LEFT (ic))); /* special case if in bit space */ - if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY) { - if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY) { - emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir); - emitcode ("cpl", "c"); - emitcode ("mov", "%s,c", IC_RESULT (ic)->aop->aopu.aop_dir); + if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY) + { + char *l; + + if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY || + (SPEC_USIGN (letype) && IS_CHAR (letype))) + { + /* promotion rules are responsible for this strange result: + bit -> int -> ~int -> bit + uchar -> int -> ~int -> bit + */ + werror(W_COMPLEMENT); + emitcode ("setb", "%s", IC_RESULT (ic)->aop->aopu.aop_dir); goto release; } tlbl=newiTempLabel(NULL); - emitcode ("cjne", "%s,#0x01,%05d$", - aopGet(AOP(IC_LEFT(ic)), 0, FALSE,FALSE,NULL), tlbl->key+100); + l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, FALSE,NULL); + if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC || + AOP_TYPE (IC_LEFT (ic)) == AOP_REG || + IS_AOP_PREG (IC_LEFT (ic))) + { + emitcode ("cjne", "%s,#0xFF,%05d$", l, tlbl->key + 100); + } + else + { + MOVA (l); + emitcode ("cjne", "a,#0xFF,%05d$", tlbl->key + 100); + } emitcode ("", "%05d$:", tlbl->key+100); outBitC (IC_RESULT(ic)); goto release; diff --git a/src/ds390/main.c b/src/ds390/main.c index 27a64e8d..17b52ae0 100644 --- a/src/ds390/main.c +++ b/src/ds390/main.c @@ -78,6 +78,8 @@ _ds390_reset_regparm (void) static int _ds390_regparm (sym_link * l) { + if (IS_SPEC(l) && (SPEC_NOUN(l) == V_BIT)) + return 0; if (options.parms_in_bank1 == 0) { /* simple can pass only the first parameter in a register */ if (regParmFlg) diff --git a/src/ds390/ralloc.c b/src/ds390/ralloc.c index def06af2..fbb65ed8 100644 --- a/src/ds390/ralloc.c +++ b/src/ds390/ralloc.c @@ -1271,7 +1271,7 @@ serialRegAssign (eBBlock ** ebbs, int count) unusedLRs = deassignUnsedLRs(ebbs[i]); - /* of all instructions do */ + /* for all instructions do */ for (ic = ebbs[i]->sch; ic; ic = ic->next) { @@ -1325,6 +1325,16 @@ serialRegAssign (eBBlock ** ebbs, int count) spillThis (sym); continue; } + + /* if this is a bit variable then don't use precious registers + along with expensive bit-to-char conversions but just spill + it */ + if (SPEC_NOUN(sym->etype) == V_BIT) + { + spillThis (sym); + continue; + } + /* if trying to allocate this will cause a spill and there is nothing to spill or this one is rematerializable then diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index c386b760..84c20daf 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -1668,8 +1668,9 @@ genCpl (iCode * ic) int offset = 0; int size; symbol *tlbl; + sym_link *letype = getSpec (operandType (IC_LEFT (ic))); - D(emitcode ("; genCpl","")); + D(emitcode (";", "genCpl")); /* assign asmOps to operand & result */ aopOp (IC_LEFT (ic), ic, FALSE); @@ -1678,27 +1679,32 @@ genCpl (iCode * ic) /* special case if in bit space */ if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY) { - if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY) + char *l; + + if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY || + (SPEC_USIGN (letype) && IS_CHAR (letype))) { - /* promotion rules are responsible for this strange result: */ + /* promotion rules are responsible for this strange result: + bit -> int -> ~int -> bit + uchar -> int -> ~int -> bit + */ + werror(W_COMPLEMENT); emitcode ("setb", "%s", IC_RESULT (ic)->aop->aopu.aop_dir); goto release; } tlbl=newiTempLabel(NULL); + l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, FALSE); if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC || AOP_TYPE (IC_LEFT (ic)) == AOP_REG || IS_AOP_PREG (IC_LEFT (ic))) { - emitcode ("cjne", "%s,#0x01,%05d$", - aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE), - tlbl->key + 100); + emitcode ("cjne", "%s,#0xFF,%05d$", l, tlbl->key + 100); } else { - char *l = aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE); MOVA (l); - emitcode ("cjne", "a,#0x01,%05d$", tlbl->key + 100); + emitcode ("cjne", "a,#0xFF,%05d$", tlbl->key + 100); } emitcode ("", "%05d$:", tlbl->key + 100); outBitC (IC_RESULT(ic)); diff --git a/support/Util/SDCCerr.c b/support/Util/SDCCerr.c index 2bdf092d..e0674aeb 100644 --- a/support/Util/SDCCerr.c +++ b/support/Util/SDCCerr.c @@ -417,6 +417,8 @@ struct { W_POSSBUG2, ERROR_LEVEL_WARNING, "possible code generation error at %s line %d,\n" " please report problem and send source code at SDCC-USER list on SF.Net"}, +{ W_COMPLEMENT, ERROR_LEVEL_WARNING, + "using ~ on bit/bool/unsigned char variables can give unexpected results due to promotion to int" }, }; /* diff --git a/support/Util/SDCCerr.h b/support/Util/SDCCerr.h index 92abb906..728c9753 100644 --- a/support/Util/SDCCerr.h +++ b/support/Util/SDCCerr.h @@ -195,6 +195,7 @@ SDCCERR - SDCC Standard error handler #define E_PREVIOUS_DEF 177 /* previously defined here */ #define W_SIZEOF_VOID 178 /* size of void is zero */ #define W_POSSBUG2 179 /* possible bug, new format */ +#define W_COMPLEMENT 180 /* ~bit can give unexpected results */ #define MAX_ERROR_WARNING 256 /* size of disable warnings array */ diff --git a/support/regression/tests/bitvars.c b/support/regression/tests/bitvars.c index 6bcc1049..fe48a04d 100644 --- a/support/regression/tests/bitvars.c +++ b/support/regression/tests/bitvars.c @@ -1,24 +1,63 @@ /** Bit vars test. + type: bool, char, unsigned char, unsigned short, unsigned long */ + #include +#include + +#ifndef PORT_HOST +#pragma disable_warning 180 //no warning about using complement on bit/unsigned char +#endif -#if defined (SDCC_STACK_AUTO) || defined (SDCC_hc08) || defined (SDCC_z80) || defined (PORT_HOST) +#if defined (SDCC_STACK_AUTO) || defined (SDCC_hc08) || defined (SDCC_z80) #define NO_BITS #endif #ifndef NO_BITS -char foo(bit a, bit b, char c) + +#define TYPE_{type} + +char foo(bool a, bool b, char c) { return a + b + c; } + +char complement(bool a, bool b) +{ + return (a == b); +} + +{type} _0 = 0, _1 = 1, _ff = 0xFF, _ffff = -1; + #endif void testBits(void) { #ifndef NO_BITS - bit x = 2; + bool x = 2; ASSERT (foo(x,3,4) == 6); + + ASSERT (complement (~_0, 1)); + ASSERT (complement (~_1, 1)); + +#if defined TYPE_char + ASSERT (complement (~_ff, 0)); +#else + ASSERT (complement (~_ff, 1)); +#endif + +#if defined TYPE_bool + ASSERT (complement (~_ffff, 1)); +#elif defined TYPE_char + ASSERT (complement (~_ffff, 0)); +#else + if (sizeof({type}) < sizeof(int)) + ASSERT (complement (~_ffff, 1)); + else + ASSERT (complement (~_ffff, 0)); +#endif + #endif } diff --git a/support/regression/tests/bitwise.c b/support/regression/tests/bitwise.c index 1ddc6f7e..3805822f 100644 --- a/support/regression/tests/bitwise.c +++ b/support/regression/tests/bitwise.c @@ -1,6 +1,6 @@ /** Test the bitwise operators. - type: char, int, long + type: char, short, long attr: volatile, storage: static, */ @@ -28,4 +28,6 @@ testTwoOpBitwise(void) ASSERT(({type})(right ^ left) == ({type})0xFC1B); ASSERT(({type})(left ^ 0xc1ec) == ({type})0xFC1B); ASSERT(({type})(0x3df7 ^ right) == ({type})0xFC1B); + + ASSERT(({type})(~left) == ({type})0xFFFFC208); }