+2004-12-19 Maarten Brock <sourceforge.brock AT dse.nl>
+
+ * 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 <sourceforge.brock AT dse.nl>
* device/include/sdcc-lib.h: inserted LGPL, added includes
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;
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)
unusedLRs = deassignUnsedLRs(ebbs[i]);
- /* of all instructions do */
+ /* for all instructions do */
for (ic = ebbs[i]->sch; ic; ic = ic->next)
{
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
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);
/* 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));
{ 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" },
};
/*
#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 */
/** Bit vars test.
+ type: bool, char, unsigned char, unsigned short, unsigned long
*/
+
#include <testfwk.h>
+#include <stdbool.h>
+
+#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
}
/** Test the bitwise operators.
- type: char, int, long
+ type: char, short, long
attr: volatile,
storage: static,
*/
ASSERT(({type})(right ^ left) == ({type})0xFC1B);
ASSERT(({type})(left ^ 0xc1ec) == ({type})0xFC1B);
ASSERT(({type})(0x3df7 ^ right) == ({type})0xFC1B);
+
+ ASSERT(({type})(~left) == ({type})0xFFFFC208);
}