+2005-11-18 Bernhard Held <bernhard AT bernhardheld.de>
+
+ * src/SDCCcse.c (ReplaceOpWithCheaperOp): minor fix for debugging only
+ * src/mcs51/gen.c (genUnpackBits): better code and a fix,
+ (genCast) cosmetic change
+ * src/ds390/gen.c (genUnpackBits, ): ported from mcs51
+ * src/ds390/ralloc.c (packRegsForAssign): ported fix for bitfields
+ from mcs51
+ * support/regression/tests/bitfields (testSignedBitfields): added
+
2005-11-18 Borut Razem <borut.razem AT siol.net>
* sdcc/device/lib/Makefile.in: remove all unnecessary files
IS_SYMOP((*op)) ? OP_SYMBOL((*op))->name : "!SYM",
IS_SYMOP(cop) ? OP_SYMBOL(cop)->name : "!SYM");
// if op is a register equivalent
- if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
+ if (IS_ITEMP(cop) && IS_SYMOP((*op)) && OP_SYMBOL((*op))->isreqv) {
operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
if (isOperandEqual(*rop, *op)) {
printf ("true");
if (blen < 8)
{
emitPtrByteGet (rname, ptype, FALSE);
- AccRsh (bstr);
+ AccRol (8 - bstr);
emitcode ("anl", "a,#!constbyte", ((unsigned char) -1) >> (8 - blen));
+ if (!SPEC_USIGN (etype))
+ {
+ /* signed bitfield */
+ symbol *tlbl = newiTempLabel (NULL);
+
+ emitcode ("jnb", "acc.%d,%05d$", blen - 1, tlbl->key + 100);
+ emitcode ("orl", "a,#0x%02x", (unsigned char) (0xff << blen));
+ emitcode ("", "%05d$:", tlbl->key + 100);
+ }
aopPut (AOP (result), "a", offset++);
goto finish;
}
{
emitPtrByteGet (rname, ptype, FALSE);
emitcode ("anl", "a,#!constbyte", ((unsigned char) -1) >> (8-rlen));
+ if (!SPEC_USIGN (etype))
+ {
+ /* signed bitfield */
+ symbol *tlbl = newiTempLabel (NULL);
+
+ emitcode ("jnb", "acc.%d,%05d$", rlen - 1, tlbl->key + 100);
+ emitcode ("orl", "a,#0x%02x", (unsigned char) (0xff << rlen));
+ emitcode ("", "%05d$:", tlbl->key + 100);
+ }
aopPut (AOP (result), "a", offset++);
}
finish:
if (offset < rsize)
{
+ char *source;
+
+ if (SPEC_USIGN (etype))
+ source = zero;
+ else
+ {
+ /* signed bitfield: sign extension with 0x00 or 0xff */
+ emitcode ("rlc", "a");
+ emitcode ("subb", "a,acc");
+
+ source = "a";
+ }
rsize -= offset;
while (rsize--)
- aopPut (AOP (result), zero, offset++);
+ aopPut (AOP (result), source, offset++);
}
}
if (!dic)
return 0; /* did not find */
+ /* if assignment then check that right is not a bit */
+ if (ASSIGNMENT (ic) && !POINTER_SET (ic))
+ {
+ sym_link *etype = operandType (IC_RESULT (dic));
+ if (IS_BITFIELD (etype))
+ {
+ /* if result is a bit too then it's ok */
+ etype = operandType (IC_RESULT (ic));
+ if (!IS_BITFIELD (etype))
+ {
+ return 0;
+ }
+ }
+ }
/* if the result is on stack or iaccess then it must be
the same atleast one of the operands */
if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
if (blen < 8)
{
emitPtrByteGet (rname, ptype, FALSE);
- AccRsh (bstr);
+ AccRol (8 - bstr);
emitcode ("anl", "a,#0x%02x", ((unsigned char) -1) >> (8 - blen));
if (!SPEC_USIGN (etype))
{
/* signed bitfield */
symbol *tlbl = newiTempLabel (NULL);
- emitcode ("jnb", "acc.%d,%05d$", blen - 1, tlbl->key + 100);
+ emitcode ("jnb", "acc.%d,%05d$", rlen - 1, tlbl->key + 100);
emitcode ("orl", "a,#0x%02x", (unsigned char) (0xff << rlen));
emitcode ("", "%05d$:", tlbl->key + 100);
}
/* if the result is a bit (and not a bitfield) */
// if (AOP_TYPE (result) == AOP_CRY)
- if (IS_BITVAR (OP_SYMBOL (result)->type)
- && !IS_BITFIELD (OP_SYMBOL (result)->type) )
+ if (IS_BIT (OP_SYMBOL (result)->type))
+ /* not for bitfields */
{
/* if the right size is a literal then
we know what the value is */
} size3a_bf;
+struct {
+ signed int s0_7 : 7;
+ signed int s7_1 : 1;
+ signed int s8_9 : 9;
+} s_bf;
+
+
void
testBitfieldSizeof(void)
{
ASSERT(size2c_bf.b0==0);
ASSERT(size2c_bf.b1==0x1f);
+ size2c_bf.b0 = 0xff; /* should truncate to 0x0f */
+ size2c_bf.b1 = 0xff; /* should truncate to 0x1f */
+ ASSERT(size2c_bf.b0==0x0f);
+ ASSERT(size2c_bf.b1==0x1f);
+
size2d_bf.b0 = 0xffff; /* should truncate to 0x0fff */
size2d_bf.b1 = 0;
ASSERT(size2d_bf.b0==0x0fff);
ASSERT(size2d_bf.b0==0);
ASSERT(size2d_bf.b1==0x07);
+ size2d_bf.b0 = 0xffff; /* should truncate to 0x0fff */
+ size2d_bf.b1 = 0xffff; /* should truncate to 0x07 */
+ ASSERT(size2d_bf.b0==0x0fff);
+ ASSERT(size2d_bf.b1==0x07);
+
size2d_bf.b0 = 0x0321;
size2d_bf.b1 = 1;
ASSERT(size2d_bf.b0==0x0321);
void
testBitfields(void)
{
-#if 0 // not yet
- c_bitfield.c0_3 = 2;
- c_bitfield.c3_5 = 3;
- ASSERT(*(char *)(&c_bitfield) == (2 + (3<<3)) );
+ c_bf.c0_3 = 2;
+ c_bf.c3_5 = 3;
+ ASSERT(*(char *)(&c_bf) == (2 + (3<<3)) );
- i_bitfield.i0_7 = 23;
- i_bitfield.i7_9 = 234;
- ASSERT(*(int *)(&i_bitfield) == (23 + (234<<7)) );
+#if 0 // not yet
+ i_bf.i0_7 = 23;
+ i_bf.i7_9 = 234;
+ ASSERT(*(int *)(&i_bf) == (23 + (234<<7)) );
l_bitfield.l0_7 = 23;
l_bitfield.l7_10 = 234;
l_bitfield.l17_15 = 2345;
- ASSERT(*(long *)(&l_bitfield) == (23 + (234<<7) + (2345<<17)) );
+ ASSERT(*(long *)(&l_bf) == (23 + (234<<7) + (2345<<17)) );
+#endif
+}
+
+void
+testSignedBitfields(void)
+{
+#if !defined(SDCC_hc08) && !defined(SDCC_z80) && !defined(SDCC_gbz80)
+ s_bf.s0_7 = 0xf0;
+ s_bf.s7_1 = 1;
+ s_bf.s8_9 = 0xfff8;
+ ASSERT(s_bf.s0_7 == -16);
+ ASSERT(s_bf.s7_1 == - 1);
+ ASSERT(s_bf.s8_9 == - 8);
+ ASSERT(s_bf.s0_7 < 0);
+ ASSERT(s_bf.s7_1 < 0);
+ ASSERT(s_bf.s8_9 < 0);
+
+ s_bf.s0_7 = 0x3f;
+ s_bf.s7_1 = 2;
+ s_bf.s8_9 = 0x00ff;
+ ASSERT(s_bf.s0_7 == 0x3f);
+ ASSERT(s_bf.s7_1 == 0);
+ ASSERT(s_bf.s8_9 == 0xff);
+ ASSERT(s_bf.s0_7 > 0);
+ ASSERT(s_bf.s8_9 > 0);
#endif
}