+2003-08-18 Erik Petrich <epetrich@ivorytower.norman.ok.us>
+
+ Made bitfield a distinct type from bit so that bitfields
+ convert as per ANSI C and bits retain their traditional
+ boolean style behaviour. Implemented bitfield support in
+ the z80 port.
+
+ * src/SDCCsymt.h,
+ * src/SDCCsymt.c,
+ * src/SDCCast.c,
+ * src/cdbFile.c,
+ * src/mcs51/gen.c,
+ * src/ds390/gen.c: bit v bitfield split
+ * src/z80/gen.c: New support for bitfields
+ * support/regression/tests/bitfields.c: reenabled z80,
+ added more tests
+
2003-08-17 Frieder Ferlemann <Frieder.Ferlemann@web.de>
Rules 246.x, 247.x relate to bitfields, the others speed up
case V_STRUCT:
typeofv = TYPEOF_STRUCT;
break;
+ case V_BITFIELD:
+ typeofv = TYPEOF_BITFIELD;
+ break;
case V_BIT:
typeofv = TYPEOF_BIT;
break;
case V_VOID: return "void";
case V_STRUCT: return "struct";
case V_LABEL: return "label";
+ case V_BITFIELD: return "bitfield";
case V_BIT: return "bit";
case V_SBIT: return "sbit";
case V_DOUBLE: return "double";
case V_LABEL:
return 0;
case V_SBIT:
- return BITSIZE;
case V_BIT:
+ return BITSIZE;
+ case V_BITFIELD:
return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
default:
return 0;
case V_LABEL:
return 0;
case V_SBIT:
- return 1;
case V_BIT:
+ return 1;
+ case V_BITFIELD:
return SPEC_BLEN (p);
default:
return 0;
if (loop->bitVar) {
/* change it to a unsigned bit */
- SPEC_NOUN (loop->etype) = V_BIT;
+ SPEC_NOUN (loop->etype) = V_BITFIELD;
SPEC_USIGN (loop->etype) = 1;
SPEC_BLEN (loop->etype) = loop->bitVar;
if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
(SPEC_NOUN (sym->etype) == V_BIT ||
SPEC_NOUN (sym->etype) == V_SBIT ||
+ SPEC_NOUN (sym->etype) == V_BITFIELD ||
SPEC_SCLS (sym->etype) == S_SFR))
werror (E_BIT_ARRAY, sym->name);
printTypeChain (sym_link * start, FILE * of)
{
int nlr = 0;
+ value *args;
sym_link * type, * search;
STORAGE_CLASS scls;
fprintf (of, "function %s %s",
(IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
(IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
+ fprintf (of, "( ");
+ for (args = FUNC_ARGS(type);
+ args;
+ args=args->next) {
+ printTypeChain(args->type, of);
+ if (args->next)
+ fprintf(of, ", ");
+ }
+ fprintf (of, ") ");
break;
case GPOINTER:
fprintf (of, "generic* ");
break;
case V_BIT:
- fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
+ fprintf (of, "bit");
+ break;
+
+ case V_BITFIELD:
+ fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
break;
case V_DOUBLE:
TYPEOF_LONG,
TYPEOF_FLOAT,
TYPEOF_BIT,
+ TYPEOF_BITFIELD,
TYPEOF_SBIT,
TYPEOF_SFR,
TYPEOF_VOID,
V_STRUCT,
V_LABEL,
V_BIT,
+ V_BITFIELD,
V_SBIT,
V_DOUBLE
}
x->select.d.ptr_volatile)
#define IS_INTEGRAL(x) (IS_SPEC(x) && (x->select.s.noun == V_INT || \
x->select.s.noun == V_CHAR || \
+ x->select.s.noun == V_BITFIELD || \
x->select.s.noun == V_BIT || \
x->select.s.noun == V_SBIT ))
-#define IS_BITFIELD(x) (IS_SPEC(x) && (x->select.s.noun == V_BIT))
-#define IS_BITVAR(x) (IS_SPEC(x) && (x->select.s.noun == V_BIT || \
+#define IS_BITFIELD(x) (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD))
+#define IS_BITVAR(x) (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD || \
+ x->select.s.noun == V_BIT || \
x->select.s.noun == V_SBIT ))
#define IS_FLOAT(x) (IS_SPEC(x) && x->select.s.noun == V_FLOAT)
#define IS_ARITHMETIC(x) (IS_INTEGRAL(x) || IS_FLOAT(x))
case V_SBIT: fprintf (cdbFilePtr, "SX"); break;
case V_BIT:
+ case V_BITFIELD:
fprintf (cdbFilePtr, "SB%d$%d", SPEC_BSTR (type),
SPEC_BLEN (type));
break;
aopPut (AOP (result), zero, offset++);
}
}
-#if 0
-/*-----------------------------------------------------------------*/
-/* genUnpackBits - generates code for unpacking bits */
-/*-----------------------------------------------------------------*/
-static void
-genUnpackBits (operand * result, char *rname, int ptype)
-{
- int shCnt;
- int rlen = 0;
- sym_link *etype;
- int offset = 0;
- int rsize;
-
- D (emitcode (";", "genUnpackBits "););
-
- etype = getSpec (operandType (result));
- rsize = getSize (operandType (result));
-
- /* read the first byte */
- switch (ptype)
- {
-
- case POINTER:
- case IPOINTER:
- emitcode ("mov", "a,@%s", rname);
- break;
-
- case PPOINTER:
- emitcode ("movx", "a,@%s", rname);
- break;
-
- case FPOINTER:
- emitcode ("movx", "a,@dptr");
- break;
-
- case CPOINTER:
- emitcode ("clr", "a");
- emitcode ("movc", "a,@a+dptr");
- break;
-
- case GPOINTER:
- emitcode ("lcall", "__gptrget");
- break;
- }
-
- /* if we have bitdisplacement then it fits */
- /* into this byte completely or if length is */
- /* less than a byte */
- if (((shCnt = SPEC_BSTR (etype)) != 0) || (SPEC_BLEN (etype) <= 8))
- {
-
- /* shift right acc */
- AccRsh (shCnt);
-
- emitcode ("anl", "a,#!constbyte",
- ((unsigned char) -1) >> (8 - SPEC_BLEN (etype)));
- aopPut (AOP (result), "a", offset++);
- goto finish;
- }
-
- /* bit field did not fit in a byte */
- rlen = SPEC_BLEN (etype);
- aopPut (AOP (result), "a", offset++);
-
- while (1)
- {
-
- switch (ptype)
- {
- case POINTER:
- case IPOINTER:
- emitcode ("inc", "%s", rname);
- emitcode ("mov", "a,@%s", rname);
- break;
-
- case PPOINTER:
- emitcode ("inc", "%s", rname);
- emitcode ("movx", "a,@%s", rname);
- break;
-
- case FPOINTER:
- emitcode ("inc", "dptr");
- emitcode ("movx", "a,@dptr");
- break;
-
- case CPOINTER:
- emitcode ("clr", "a");
- emitcode ("inc", "dptr");
- emitcode ("movc", "a,@a+dptr");
- break;
-
- case GPOINTER:
- emitcode ("inc", "dptr");
- emitcode ("lcall", "__gptrget");
- break;
- }
-
- rlen -= 8;
- /* if we are done */
- if (rlen < 8)
- break;
-
- aopPut (AOP (result), "a", offset++);
-
- }
-
- if (rlen)
- {
- emitcode ("anl", "a,#!constbyte", ((unsigned char) -1) >> (8-rlen));
- aopPut (AOP (result), "a", offset++);
- }
-
-finish:
- if (offset < rsize)
- {
- rsize -=offset;
- while (rsize--)
- aopPut (AOP (result), zero, offset++);
- }
-}
-#endif
/*-----------------------------------------------------------------*/
}
-#if 0
-/*-----------------------------------------------------------------*/
-/* genPackBits - generates code for packed bit storage */
-/*-----------------------------------------------------------------*/
-static void
-genPackBits (sym_link * etype,
- operand * right,
- char *rname, int p_type)
-{
- int shCount = 0;
- int offset = 0;
- int rLen;
- int blen, bstr;
- char *l;
-
- blen = SPEC_BLEN (etype);
- bstr = SPEC_BSTR (etype);
-
- MOVA (aopGet (AOP (right), offset++, FALSE, FALSE, NULL));
-
- /* if the bit lenth is less than or */
- /* it exactly fits a byte then */
- if (SPEC_BLEN (etype) <= 8)
- {
- unsigned char mask = ((unsigned char) (0xFF << (blen + bstr)) |
- (unsigned char) (0xFF >> (8 - bstr)));
- shCount = SPEC_BSTR (etype);
-
- /* shift left acc */
- AccLsh (shCount);
-
- if (SPEC_BLEN (etype) < 8)
- { /* if smaller than a byte */
-
- emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
-
- switch (p_type)
- {
- case POINTER:
- emitcode ("mov", "b,a");
- emitcode ("mov", "a,@%s", rname);
- break;
-
- case FPOINTER:
- emitcode ("mov", "b,a");
- emitcode ("movx", "a,@dptr");
- break;
-
- case GPOINTER:
- emitcode ("push", "b");
- emitcode ("push", "acc");
- emitcode ("lcall", "__gptrget");
- emitcode ("pop", "b");
- break;
- }
-
- emitcode ("anl", "a,#!constbyte", mask);
- emitcode ("orl", "a,b");
- if (p_type == GPOINTER)
- emitcode ("pop", "b");
- }
- }
-
- switch (p_type)
- {
- case POINTER:
- emitcode ("mov", "@%s,a", rname);
- break;
-
- case FPOINTER:
- emitcode ("movx", "@dptr,a");
- break;
-
- case GPOINTER:
- emitcode ("lcall", "__gptrput");
- break;
- }
-
- /* if we r done */
- if (SPEC_BLEN (etype) <= 8)
- return;
-
- emitcode ("inc", "%s", rname);
- rLen = SPEC_BLEN (etype);
-
- /* now generate for lengths greater than one byte */
- while (1)
- {
-
- l = aopGet (AOP (right), offset++, FALSE, TRUE, NULL);
-
- rLen -= 8;
- if (rLen < 8)
- break;
-
- switch (p_type)
- {
- case POINTER:
- if (*l == '@')
- {
- MOVA (l);
- emitcode ("mov", "@%s,a", rname);
- }
- else
- emitcode ("mov", "@%s,%s", rname, l);
- break;
-
- case FPOINTER:
- MOVA (l);
- emitcode ("movx", "@dptr,a");
- break;
-
- case GPOINTER:
- MOVA (l);
- emitcode ("lcall", "__gptrput");
- break;
- }
- emitcode ("inc", "%s", rname);
- }
-
- MOVA (l);
-
- /* last last was not complete */
- if (rLen)
- {
- emitcode ("anl", "a,#!constbyte",
- (~(((unsigned char) -1 << rLen) & 0xff)) & 0xff);
-
- /* save the byte & read byte */
- switch (p_type)
- {
- case POINTER:
- emitcode ("mov", "b,a");
- emitcode ("mov", "a,@%s", rname);
- break;
-
- case FPOINTER:
- emitcode ("mov", "b,a");
- emitcode ("movx", "a,@dptr");
- break;
-
- case GPOINTER:
- emitcode ("push", "b");
- emitcode ("push", "acc");
- emitcode ("lcall", "__gptrget");
- emitcode ("pop", "b");
- break;
- }
-
- emitcode ("anl", "a,#!constbyte", (((unsigned char) -1 << rLen) & 0xff));
- emitcode ("orl", "a,b");
- }
-
- if (p_type == GPOINTER)
- emitcode ("pop", "b");
-
- switch (p_type)
- {
-
- case POINTER:
- emitcode ("mov", "@%s,a", rname);
- break;
-
- case FPOINTER:
- emitcode ("movx", "@dptr,a");
- break;
-
- case GPOINTER:
- emitcode ("lcall", "__gptrput");
- break;
- }
-}
-#endif
/*-----------------------------------------------------------------*/
/* genDataPointerSet - remat pointer to data space */
aopOp (result, ic, FALSE, AOP_USESDPTR(right));
/* if the result is a bit */
- // if (AOP_TYPE (result) == AOP_CRY) /* works only for true symbols */
- if (IS_BITVAR(OP_SYMBOL(result)->type))
+ if (IS_BITVAR (OP_SYMBOL (result)->type)
+ && !IS_BITFIELD (OP_SYMBOL (result)->type) )
{
/* if the right size is a literal then
we know what the value is */
aopOp (result, ic, FALSE);
/* if the result is a bit (and not a bitfield) */
- if (AOP_TYPE (result) == AOP_CRY)
+ // if (AOP_TYPE (result) == AOP_CRY)
+ if (IS_BITVAR (OP_SYMBOL (result)->type)
+ && !IS_BITFIELD (OP_SYMBOL (result)->type) )
{
/* if the right size is a literal then
we know what the value is */
{
shCount &= 0x0007; // shCount : 0..7
+#if 0
switch (shCount)
{
case 0:
emit2 ("srl a");
break;
}
+#else
+ switch (shCount)
+ {
+ case 0:
+ break;
+ case 1:
+ emit2 ("rlca");
+ break;
+ case 2:
+ emit2 ("rlca");
+ emit2 ("rlca");
+ break;
+ case 3:
+ emit2 ("rlca");
+ emit2 ("rlca");
+ emit2 ("rlca");
+ break;
+ case 4:
+ emit2 ("rlca");
+ emit2 ("rlca");
+ emit2 ("rlca");
+ emit2 ("rlca");
+ break;
+ case 5:
+ emit2 ("rrca");
+ emit2 ("rrca");
+ emit2 ("rrca");
+ break;
+ case 6:
+ emit2 ("rrca");
+ emit2 ("rrca");
+ break;
+ case 7:
+ emit2 ("rrca");
+ break;
+ }
+#endif
}
/*-----------------------------------------------------------------*/
freeAsmop (result, NULL, ic);
}
+
+/*-----------------------------------------------------------------*/
+/* genUnpackBits - generates code for unpacking bits */
+/*-----------------------------------------------------------------*/
+static void
+genUnpackBits (operand * result, int pair)
+{
+ int offset = 0; /* result byte offset */
+ int rsize; /* result size */
+ int rlen = 0; /* remaining bitfield length */
+ sym_link *etype; /* bitfield type information */
+ int blen; /* bitfield length */
+ int bstr; /* bitfield starting bit within byte */
+
+ emitDebug ("; genUnpackBits");
+
+ etype = getSpec (operandType (result));
+ rsize = getSize (operandType (result));
+ blen = SPEC_BLEN (etype);
+ bstr = SPEC_BSTR (etype);
+
+ /* If the bitfield length is less than a byte */
+ if (blen < 8)
+ {
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+ AccRsh (bstr);
+ emit2 ("and a,!immedbyte", ((unsigned char) -1) >> (8 - blen));
+ aopPut (AOP (result), "a", offset++);
+ goto finish;
+ }
+
+ /* TODO: what if pair == PAIR_DE ? */
+ if (getPairId (AOP (result)) == PAIR_HL)
+ {
+ wassertl (rsize == 2, "HL must be of size 2");
+ emit2 ("ld a,!*hl");
+ emit2 ("inc hl");
+ emit2 ("ld h,!*hl");
+ emit2 ("ld l,a");
+ emit2 ("ld a,h");
+ emit2 ("and a,!immedbyte", ((unsigned char) -1) >> (16 - blen));
+ emit2 ("ld h,a");
+ spillPair (PAIR_HL);
+ return;
+ }
+
+ /* Bit field did not fit in a byte. Copy all
+ but the partial byte at the end. */
+ for (rlen=blen;rlen>=8;rlen-=8)
+ {
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+ aopPut (AOP (result), "a", offset++);
+ if (rlen>8)
+ {
+ emit2 ("inc %s", _pairs[pair].name);
+ _G.pairs[pair].offset++;
+ }
+ }
+
+ /* Handle the partial byte at the end */
+ if (rlen)
+ {
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+ emit2 ("and a,!immedbyte", ((unsigned char) -1) >> (8 - rlen));
+ aopPut (AOP (result), "a", offset++);
+ }
+
+finish:
+ if (offset < rsize)
+ {
+ rsize -= offset;
+ while (rsize--)
+ aopPut (AOP (result), "!zero", offset++);
+ }
+}
+
/*-----------------------------------------------------------------*/
/* genGenPointerGet - get value from generic pointer space */
/*-----------------------------------------------------------------*/
size = AOP_SIZE (result);
- if (isPair (AOP (left)) && size == 1)
+ if (isPair (AOP (left)) && size == 1 && !IS_BITVAR (retype))
{
/* Just do it */
if (isPtrPair (AOP (left)))
goto release;
}
- if (getPairId (AOP (left)) == PAIR_IY)
+ if (getPairId (AOP (left)) == PAIR_IY && !IS_BITVAR (retype))
{
/* Just do it */
offset = 0;
/* if bit then unpack */
if (IS_BITVAR (retype))
{
- wassert (0);
+ genUnpackBits (result, pair);
+ freeAsmop (left, NULL, ic);
+ goto release;
+ //wassert (0);
}
else if (getPairId (AOP (result)) == PAIR_HL)
{
return FALSE;
}
+
+/*-----------------------------------------------------------------*/
+/* genPackBits - generates code for packed bit storage */
+/*-----------------------------------------------------------------*/
+static void
+genPackBits (sym_link * etype,
+ operand * right,
+ int pair,
+ iCode *ic)
+{
+ int offset = 0; /* source byte offset */
+ int rlen = 0; /* remaining bitfield length */
+ int blen; /* bitfield length */
+ int bstr; /* bitfield starting bit within byte */
+ int litval; /* source literal value (if AOP_LIT) */
+ unsigned char mask; /* bitmask within current byte */
+ int extraPair; /* a tempory register */
+ bool needPopExtra=0; /* need to restore original value of temp reg */
+
+ emitDebug ("; genPackBits","");
+
+ blen = SPEC_BLEN (etype);
+ bstr = SPEC_BSTR (etype);
+
+ /* If the bitfield length is less than a byte */
+ if (blen < 8)
+ {
+ mask = ((unsigned char) (0xFF << (blen + bstr)) |
+ (unsigned char) (0xFF >> (8 - bstr)));
+
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ /* Case with a bitfield length <8 and literal source
+ */
+ litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval <<= bstr;
+ litval &= (~mask) & 0xff;
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+ if ((mask|litval)!=0xff)
+ emit2 ("and a,!immedbyte", mask);
+ if (litval)
+ emit2 ("or a,!immedbyte", litval);
+ emit2 ("ld !*pair,a", _pairs[pair].name);
+ return;
+ }
+ else
+ {
+ /* Case with a bitfield length <8 and arbitrary source
+ */
+ _moveA (aopGet (AOP (right), 0, FALSE));
+ /* shift and mask source value */
+ AccLsh (bstr);
+ emit2 ("and a,!immedbyte", (~mask) & 0xff);
+
+ extraPair = getFreePairId(ic);
+ if (extraPair == PAIR_INVALID)
+ {
+ extraPair = PAIR_BC;
+ if (getPairId (AOP (right)) != PAIR_BC
+ || !isLastUse (ic, right))
+ {
+ _push (extraPair);
+ needPopExtra = 1;
+ }
+ }
+ emit2 ("ld %s,a", _pairs[extraPair].l);
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+
+ emit2 ("and a,!immedbyte", mask);
+ emit2 ("or a,%s", _pairs[extraPair].l);
+ emit2 ("ld !*pair,a", _pairs[pair].name);
+ if (needPopExtra)
+ _pop (extraPair);
+ return;
+ }
+ }
+
+ /* Bit length is greater than 7 bits. In this case, copy */
+ /* all except the partial byte at the end */
+ for (rlen=blen;rlen>=8;rlen-=8)
+ {
+ emit2 ("ld a,%s", aopGet (AOP (right), offset++, FALSE) );
+ emit2 ("ld !*pair,a", _pairs[pair].name);
+ if (rlen>8)
+ {
+ emit2 ("inc %s", _pairs[pair].name);
+ _G.pairs[pair].offset++;
+ }
+ }
+
+ /* If there was a partial byte at the end */
+ if (rlen)
+ {
+ mask = (((unsigned char) -1 << rlen) & 0xff);
+
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ /* Case with partial byte and literal source
+ */
+ litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval >>= (blen-rlen);
+ litval &= (~mask) & 0xff;
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+ if ((mask|litval)!=0xff)
+ emit2 ("and a,!immedbyte", mask);
+ if (litval)
+ emit2 ("or a,!immedbyte", litval);
+ }
+ else
+ {
+ /* Case with partial byte and arbitrary source
+ */
+ _moveA (aopGet (AOP (right), offset++, FALSE));
+ emit2 ("and a,!immedbyte", (~mask) & 0xff);
+
+ extraPair = getFreePairId(ic);
+ if (extraPair == PAIR_INVALID)
+ {
+ extraPair = getPairId (AOP (right));
+ if (!isLastUse (ic, right) || (extraPair == PAIR_INVALID))
+ extraPair = PAIR_BC;
+
+ if (getPairId (AOP (right)) != PAIR_BC
+ || !isLastUse (ic, right))
+ {
+ _push (extraPair);
+ needPopExtra = 1;
+ }
+ }
+ emit2 ("ld %s,a", _pairs[extraPair].l);
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+
+ emit2 ("and a,!immedbyte", mask);
+ emit2 ("or a,%s", _pairs[extraPair].l);
+ if (needPopExtra)
+ _pop (extraPair);
+
+ }
+ emit2 ("ld !*pair,a", _pairs[pair].name);
+ }
+}
+
+
/*-----------------------------------------------------------------*/
/* genGenPointerSet - stores the value into a pointer location */
/*-----------------------------------------------------------------*/
{
int size, offset;
sym_link *retype = getSpec (operandType (right));
+ sym_link *letype = getSpec (operandType (result));
PAIR_ID pairId = PAIR_HL;
+ bool isBitvar;
aopOp (result, ic, FALSE, FALSE);
aopOp (right, ic, FALSE, FALSE);
size = AOP_SIZE (right);
+ isBitvar = IS_BITVAR(retype) || IS_BITVAR(letype);
+ emitDebug("; isBitvar = %d", isBitvar);
+
/* Handle the exceptions first */
- if (isPair (AOP (result)) && size == 1)
+ if (isPair (AOP (result)) && size == 1 && !isBitvar)
{
/* Just do it */
const char *l = aopGet (AOP (right), 0, FALSE);
goto release;
}
- if ( getPairId( AOP (result)) == PAIR_IY)
+ if ( getPairId( AOP (result)) == PAIR_IY && !isBitvar)
{
/* Just do it */
const char *l = aopGet (AOP (right), 0, FALSE);
}
goto release;
}
- else if (getPairId (AOP (result)) == PAIR_HL && !isLastUse (ic, result))
+ else if (getPairId (AOP (result)) == PAIR_HL && !isLastUse (ic, result)
+ && !isBitvar)
{
offset = 0;
freeAsmop (result, NULL, ic);
/* if bit then unpack */
- if (IS_BITVAR (retype))
+ if (isBitvar)
{
- wassert (0);
+ genPackBits ((IS_BITVAR (retype) ? retype : letype), right, pairId, ic);
+ goto release;
+ //wassert (0);
}
else
{
void
testBitfieldsSingleBitLiteral(void)
{
-#if !defined(SDCC_z80) && !defined(SDCC_gbz80)
size2b_bf.b0 = 0;
size2b_bf.b1 = 0;
size2b_bf.b2 = 0;
ASSERT(size2b_bf.b7==0);
ASSERT(size2b_bf.b8==0);
ASSERT(size2b_bf.b9==1);
-#endif
}
void
testBitfieldsSingleBit(void)
{
-#if !defined(SDCC_z80) && !defined(SDCC_gbz80)
volatile unsigned char c;
c = 0;
ASSERT(size2b_bf.b7==0);
ASSERT(size2b_bf.b8==0);
ASSERT(size2b_bf.b9==1);
-#endif
}
void
-testBitfieldsMultibit(void)
+testBitfieldsMultibitLiteral(void)
{
-#if !defined(SDCC_z80) && !defined(SDCC_gbz80)
size2c_bf.b0 = 0xff; /* should truncate to 0x0f */
size2c_bf.b1 = 0;
ASSERT(size2c_bf.b0==0x0f);
size2d_bf.b1 = 5;
ASSERT(size2d_bf.b0==0x0a46);
ASSERT(size2d_bf.b1==5);
-#endif
+}
+
+void
+testBitfieldsMultibit(void)
+{
+ volatile int allones = 0xffff;
+ volatile int zero = 0;
+ volatile int x;
+
+ size2c_bf.b0 = allones; /* should truncate to 0x0f */
+ size2c_bf.b1 = zero;
+ ASSERT(size2c_bf.b0==0x0f);
+ ASSERT(size2c_bf.b1==0);
+
+ size2c_bf.b1 = allones; /* should truncate to 0x1f */
+ size2c_bf.b0 = zero;
+ ASSERT(size2c_bf.b0==0);
+ ASSERT(size2c_bf.b1==0x1f);
+
+ size2d_bf.b0 = allones; /* should truncate to 0x0fff */
+ size2d_bf.b1 = zero;
+ ASSERT(size2d_bf.b0==0x0fff);
+ ASSERT(size2d_bf.b1==0);
+
+ size2d_bf.b1 = allones; /* should truncate to 0x07 */
+ size2d_bf.b0 = zero;
+ ASSERT(size2d_bf.b0==0);
+ ASSERT(size2d_bf.b1==0x07);
+
+ x = 0x0321;
+ size2d_bf.b0 = x;
+ x = 1;
+ size2d_bf.b1 = x;
+ ASSERT(size2d_bf.b0==0x0321);
+ ASSERT(size2d_bf.b1==1);
+
+ x = 0x0a46;
+ size2d_bf.b0 = x;
+ x = 5;
+ size2d_bf.b1 = x;
+ ASSERT(size2d_bf.b0==0x0a46);
+ ASSERT(size2d_bf.b1==5);
}
void