}
/* return the value */
- return cexpr->opval.val;
-
+ if (IS_AST_VALUE (cexpr))
+ {
+ return cexpr->opval.val;
+ }
+ return NULL;
}
/*-----------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* decorateType - compute type for this tree, also does type checking.*/
/* This is done bottom up, since type has to flow upwards. */
-/* resultType flows top-down and forces e.g. char-arithmetik, if the */
+/* resultType flows top-down and forces e.g. char-arithmetic, if the */
/* result is a char and the operand(s) are int's. */
/* It also does constant folding, and parameter checking. */
/*--------------------------------------------------------------------*/
into a RRC operation
note : by 7 I mean (number of bits required to hold the
variable -1 ) */
- /* if the root operations is not a | operation the not */
+ /* if the root operation is not a | operation then not */
if (!IS_BITOR (root))
return root;
/* I have to think of a better way to match patterns this sucks */
- /* that aside let start looking for the first case : I use a the
+ /* that aside let's start looking for the first case : I use a
negative check a lot to improve the efficiency */
/* (?expr << 1) | (?expr >> 7) */
if (IS_LEFT_OP (root->left) &&
into a SWAP : operation ..
note : by 4 I mean (number of bits required to hold the
variable /2 ) */
- /* if the root operations is not a | operation the not */
+ /* if the root operation is not a | operation then not */
if (!IS_BITOR (root))
return root;
blen = SPEC_BLEN (etype);
bstr = SPEC_BSTR (etype);
- /* If the bitfield length is less than a byte */
- if (blen < 8)
+ if (ifx && blen <= 8)
{
emitcode ("lda", ",x");
hc08_dirtyReg (hc08_reg_a, FALSE);
- if (!ifx)
- {
- AccRsh (bstr, FALSE);
- emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8 - blen));
- storeRegToAop (hc08_reg_a, AOP (result), offset++);
- }
- else
+ if (blen < 8)
{
emitcode ("and", "#0x%02x",
(((unsigned char) -1) >> (8 - blen)) << bstr);
}
+ genIfxJump (ifx, "a");
+ return;
+ }
+ wassert (!ifx);
+
+ /* If the bitfield length is less than a byte */
+ if (blen < 8)
+ {
+ emitcode ("lda", ",x");
+ hc08_dirtyReg (hc08_reg_a, FALSE);
+ AccRsh (bstr, FALSE);
+ emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8 - blen));
+ if (!SPEC_USIGN (etype))
+ {
+ /* signed bitfield */
+ symbol *tlbl = newiTempLabel (NULL);
+
+ emitcode ("bit", "#0x%02x", 1<<(blen - 1));
+ emitcode ("beq", "%05d$", tlbl->key + 100);
+ emitcode ("ora", "#0x%02x", (unsigned char) (0xff << blen));
+ emitLabel (tlbl);
+ }
+ storeRegToAop (hc08_reg_a, AOP (result), offset++);
goto finish;
}
{
emitcode ("lda", ",x");
hc08_dirtyReg (hc08_reg_a, FALSE);
- if (!ifx)
- storeRegToAop (hc08_reg_a, AOP (result), offset);
+ storeRegToAop (hc08_reg_a, AOP (result), offset);
offset++;
if (rlen>8)
emitcode ("aix", "#1");
{
emitcode ("lda", ",x");
emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8-rlen));
+ if (!SPEC_USIGN (etype))
+ {
+ /* signed bitfield */
+ symbol *tlbl = newiTempLabel (NULL);
+
+ emitcode ("bit", "#0x%02x", 1<<(rlen - 1));
+ emitcode ("beq", "%05d$", tlbl->key + 100);
+ emitcode ("ora", "#0x%02x", (unsigned char) (0xff << rlen));
+ emitLabel (tlbl);
+ }
storeRegToAop (hc08_reg_a, AOP (result), offset++);
}
if (offset < rsize)
{
rsize -= offset;
- while (rsize--)
- storeConstToAop (zero, AOP (result), offset++);
- }
+ if (SPEC_USIGN (etype))
+ {
+ while (rsize--)
+ storeConstToAop (zero, AOP (result), offset++);
+ }
+ else
+ {
+ /* signed bitfield: sign extension with 0x00 or 0xff */
+ emitcode ("rola", "");
+ emitcode ("clra", "");
+ emitcode ("sbc", zero);
- if (ifx && !ifx->generated)
- {
- genIfxJump (ifx, "a");
+ while (rsize--)
+ storeRegToAop (hc08_reg_a, AOP (result), offset++);
+ }
}
}
emitcode ("brclr", "#%d,%s,%05d$",
bstr, aopAdrStr (derefaop, 0, FALSE),
(tlbl->key + 100));
- rmwWithReg ("inc", hc08_reg_a);
+ if (SPEC_USIGN (etype))
+ rmwWithReg ("inc", hc08_reg_a);
+ else
+ rmwWithReg ("dec", hc08_reg_a);
emitLabel (tlbl);
storeRegToAop (hc08_reg_a, AOP (result), offset);
hc08_freeReg (hc08_reg_a);
AccRsh (bstr, FALSE);
emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8 - blen));
hc08_dirtyReg (hc08_reg_a, FALSE);
+ if (!SPEC_USIGN (etype))
+ {
+ /* signed bitfield */
+ symbol *tlbl = newiTempLabel (NULL);
+
+ emitcode ("bit", "#0x%02x", 1<<(blen - 1));
+ emitcode ("beq", "%05d$", tlbl->key + 100);
+ emitcode ("ora", "#0x%02x", (unsigned char) (0xff << blen));
+ emitLabel (tlbl);
+ }
storeRegToAop (hc08_reg_a, AOP (result), offset);
}
else
{
loadRegFromAop (hc08_reg_a, derefaop, size-offset-1);
emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8-rlen));
+ if (!SPEC_USIGN (etype))
+ {
+ /* signed bitfield */
+ symbol *tlbl = newiTempLabel (NULL);
+
+ emitcode ("bit", "#0x%02x", 1<<(rlen - 1));
+ emitcode ("beq", "%05d$", tlbl->key + 100);
+ emitcode ("ora", "#0x%02x", (unsigned char) (0xff << rlen));
+ emitLabel (tlbl);
+ }
storeRegToAop (hc08_reg_a, AOP (result), offset++);
}
if (offset < rsize)
{
rsize -= offset;
- while (rsize--)
- storeConstToAop (zero, AOP (result), offset++);
+ if (SPEC_USIGN (etype))
+ {
+ while (rsize--)
+ storeConstToAop (zero, AOP (result), offset++);
+ }
+ else
+ {
+ /* signed bitfield: sign extension with 0x00 or 0xff */
+ emitcode ("rola", "");
+ emitcode ("clra", "");
+ emitcode ("sbc", zero);
+
+ while (rsize--)
+ storeRegToAop (hc08_reg_a, AOP (result), offset++);
+ }
}
freeAsmop (NULL, derefaop, ic, TRUE);