saveRBank (int bank, iCode * ic, bool pushPsw)
{
int i;
- int count = mcs51_nRegs + (pushPsw ? 1 : 0);
+ int count = 8 + ((mcs51_nRegs > 8) ? 1 : 0) + (pushPsw ? 1 : 0);
asmop *aop = NULL;
regs *r = NULL;
emitcode ("mov", "%s,a", spname);
}
- for (i = 0; i < mcs51_nRegs; i++)
+ for (i = 0; i < 8; i++)
{
if (options.useXstack)
{
regs8051[i].base, 8 * bank + regs8051[i].offset);
}
+ if (mcs51_nRegs > 8)
+ {
+ if (options.useXstack)
+ {
+ emitcode ("mov", "a,bits");
+ emitcode ("movx", "@%s,a", r->name);
+ if (--count)
+ emitcode ("inc", "%s", r->name);
+ }
+ else
+ {
+ emitcode ("push", "bits");
+ }
+ BitBankUsed = 1;
+ }
+
if (pushPsw)
{
if (options.useXstack)
}
}
- for (i = (mcs51_nRegs - 1); i >= 0; i--)
+ if (mcs51_nRegs > 8)
+ {
+ if (options.useXstack)
+ {
+ emitcode ("dec", "%s", r->name);
+ emitcode ("movx", "a,@%s", r->name);
+ emitcode ("mov", "bits,a");
+ }
+ else
+ {
+ emitcode ("pop", "bits");
+ }
+ }
+
+ for (i = 7; i >= 0; i--)
{
if (options.useXstack)
{
same */
if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
{
+ char *l;
+
+ if (aopGetUsesAcc (IC_LEFT (ic), 0))
+ {
+ MOVA (aopGet (IC_RESULT (ic), 0, FALSE, FALSE));
+ l = "a";
+ }
+ else
+ {
+ l = aopGet (IC_RESULT (ic), 0, FALSE, FALSE);
+ }
while (icount--)
- emitcode ("dec", "%s", aopGet (IC_RESULT (ic), 0, FALSE, FALSE));
+ emitcode ("dec", "%s", l);
if (AOP_NEEDSACC (IC_RESULT (ic)))
aopPut (IC_RESULT (ic), "a", 0, isOperandVolatile (IC_RESULT (ic), FALSE));
movLeft2Result (left, offl, result, offr, 0);
pushedB = pushB ();
usedB = TRUE;
- emitcode ("mov", "b,%s", aopGet (left, offl + MSB16, FALSE, FALSE));
- MOVA (aopGet (result, offr, FALSE, FALSE));
- emitcode ("xch", "a,b");
+ emitcode ("mov", "b,%s", aopGet (result, offr, FALSE, FALSE));
+ MOVA (aopGet (left, offl + MSB16, FALSE, FALSE));
x = "b";
}
else
AccAXRsh (x, shCount);
if (usedB)
{
- aopPut (result, "b", offr, isOperandVolatile (result, FALSE));
+ emitcode ("xch", "a,b");
+ aopPut (result, "a", offr, isOperandVolatile (result, FALSE));
+ emitcode ("xch", "a,b");
popB (pushedB);
}
if (getDataSize (result) > 1)
/* shift left accumulator */
AccLsh (shCount);
/* or with result */
- emitcode ("orl", "a,%s", aopGet (result, offr, FALSE, FALSE));
+ if (aopGetUsesAcc (result, offr))
+ {
+ emitcode ("xch", "a,b");
+ MOVA (aopGet (result, offr, FALSE, FALSE));
+ emitcode ("orl", "a,b");
+ }
+ else
+ {
+ emitcode ("orl", "a,%s", aopGet (result, offr, FALSE, FALSE));
+ }
/* back to result */
aopPut (result, "a", offr, isOperandVolatile (result, FALSE));
}
shiftRLong (operand * left, int offl,
operand * result, int sign)
{
- int isSameRegs=sameRegs(AOP(left),AOP(result));
+ int isSameRegs = sameRegs (AOP (left), AOP (result));
if (isSameRegs && offl>1) {
// we are in big trouble, but this shouldn't happen
emitPtrByteGet (rname, ptype, FALSE);
AccRsh (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 ("orl", "a,#0x%02x", (unsigned char) (0xff << blen));
+ emitcode ("", "%05d$:", tlbl->key + 100);
+ }
aopPut (result, "a", offset++, isOperandVolatile (result, FALSE));
goto finish;
}
{
emitPtrByteGet (rname, ptype, FALSE);
emitcode ("anl", "a,#0x%02x", ((unsigned char) -1) >> (8-rlen));
+ 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 << rlen));
+ emitcode ("", "%05d$:", tlbl->key + 100);
+ }
aopPut (result, "a", offset++, isOperandVolatile (result, FALSE));
}
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 (result, zero, offset++, isOperandVolatile (result, FALSE));
+ aopPut (result, source, offset++, isOperandVolatile (result, FALSE));
}
}