{
if (sym->onStack)
{
- char offset = ((sym->stack < 0) ?
- ((char) (sym->stack - _G.nRegsSaved)) :
- ((char) sym->stack)) & 0xff;
+ signed char offset = ((sym->stack < 0) ?
+ ((signed char) (sym->stack - _G.nRegsSaved)) :
+ ((signed char) sym->stack)) & 0xff;
if ((abs(offset) <= 3) ||
(accuse && (abs(offset) <= 7)))
}
/*-----------------------------------------------------------------*/
-/* sameReg - two asmops have the same register at given offsets */
+/* sameByte - two asmops have the same address at given offsets */
/*-----------------------------------------------------------------*/
static bool
-sameReg (asmop * aop1, int off1, asmop * aop2, int off2)
+sameByte (asmop * aop1, int off1, asmop * aop2, int off2)
{
+ if (aop1 == aop2 && off1 == off2)
+ return TRUE;
+
if (aop1->type != AOP_REG && aop1->type != AOP_CRY)
return FALSE;
}
+/*-------------------------------------------------------------------*/
+/* xch_a_aopGet - for exchanging acc with value of the aop */
+/*-------------------------------------------------------------------*/
+static char *
+xch_a_aopGet (operand * oper, int offset, bool bit16, bool dname)
+{
+ char * l;
+
+ if (aopGetUsesAcc (oper, offset))
+ {
+ emitcode("mov", "b,a");
+ MOVA (aopGet (oper, offset, bit16, dname));
+ emitcode("xch", "a,b");
+ aopPut (oper, "a", offset);
+ emitcode("xch", "a,b");
+ l = "b";
+ }
+ else
+ {
+ l = aopGet (oper, offset, bit16, dname);
+ emitcode("xch", "a,%s", l);
+ }
+ return l;
+}
+
+
/*-----------------------------------------------------------------*/
/* genNot - generate code for ! operation */
/*-----------------------------------------------------------------*/
}
}
-
if (fReentrant)
{
if (options.useXstack)
}
else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset))
{
- emitcode ("mov", "b,%s", aopGet (left, offset, FALSE, FALSE));
+ MOVB (aopGet (left, offset, FALSE, FALSE));
MOVA (aopGet (right, offset, FALSE, FALSE));
emitcode ("anl", "a,b");
aopPut (result, "a", offset);
aopPut (result, "a", offset);
}
else
- emitcode ("anl", "%s,a",
- aopGet (left, offset, FALSE, TRUE));
+ emitcode ("anl", "%s,a", aopGet (left, offset, FALSE, TRUE));
}
}
}
{
if (offset)
emitcode("mov", "a,b");
- emitcode ("anl", "a,%s",
- aopGet (right, offset, FALSE, FALSE));
- } else {
- if (AOP_TYPE(left)==AOP_ACC)
+ emitcode ("anl", "a,%s", aopGet (right, offset, FALSE, FALSE));
+ }
+ else if (AOP_TYPE(left)==AOP_ACC)
+ {
+ if (!offset)
{
- if (!offset)
- {
- bool pushedB = pushB ();
- emitcode("mov", "b,a");
- MOVA (aopGet (right, offset, FALSE, FALSE));
- emitcode("anl", "a,b");
- popB (pushedB);
- }
- else
- {
- MOVA (aopGet (right, offset, FALSE, FALSE));
- emitcode("anl", "a,b");
- }
- } else {
+ bool pushedB = pushB ();
+ emitcode("mov", "b,a");
MOVA (aopGet (right, offset, FALSE, FALSE));
- emitcode ("anl", "a,%s",
- aopGet (left, offset, FALSE, FALSE));
+ emitcode("anl", "a,b");
+ popB (pushedB);
+ }
+ else
+ {
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode("anl", "a,b");
}
}
+ else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset))
+ {
+ MOVB (aopGet (left, offset, FALSE, FALSE));
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode ("anl", "a,b");
+ }
+ else if (aopGetUsesAcc (left, offset))
+ {
+ MOVA (aopGet (left, offset, FALSE, FALSE));
+ emitcode ("anl", "a,%s", aopGet (right, offset, FALSE, FALSE));
+ }
+ else
+ {
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode ("anl", "a,%s", aopGet (left, offset, FALSE, FALSE));
+ }
+
emitcode ("jnz", "%05d$", tlbl->key + 100);
offset++;
}
}
// faster than result <- left, anl result,right
// and better if result is SFR
- if (AOP_TYPE (left) == AOP_ACC)
+ if ((AOP_TYPE(right)==AOP_REG || IS_AOP_PREG(right) || AOP_TYPE(right)==AOP_DIR)
+ && AOP_TYPE(left)==AOP_ACC)
{
if (offset)
emitcode("mov", "a,b");
emitcode ("anl", "a,%s", aopGet (right, offset, FALSE, FALSE));
}
+ else if (AOP_TYPE(left)==AOP_ACC)
+ {
+ if (!offset)
+ {
+ bool pushedB = pushB ();
+ emitcode("mov", "b,a");
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode("anl", "a,b");
+ popB (pushedB);
+ }
+ else
+ {
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode("anl", "a,b");
+ }
+ }
else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset))
{
- emitcode ("mov", "b,%s", aopGet (left, offset, FALSE, FALSE));
+ MOVB (aopGet (left, offset, FALSE, FALSE));
MOVA (aopGet (right, offset, FALSE, FALSE));
emitcode ("anl", "a,b");
}
}
else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset))
{
- emitcode ("mov", "b,%s", aopGet (left, offset, FALSE, FALSE));
+ MOVB (aopGet (left, offset, FALSE, FALSE));
MOVA (aopGet (right, offset, FALSE, FALSE));
emitcode ("orl", "a,b");
aopPut (result, "a", offset);
}
else
{
- emitcode ("orl", "%s,a",
- aopGet (left, offset, FALSE, TRUE));
+ emitcode ("orl", "%s,a", aopGet (left, offset, FALSE, TRUE));
}
}
}
emitcode ("setb", "c");
while (sizer--)
{
- if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
- if (offset)
- emitcode("mov", "a,b");
- emitcode ("orl", "a,%s",
- aopGet (right, offset, FALSE, FALSE));
- } else {
- MOVA (aopGet (right, offset, FALSE, FALSE));
- emitcode ("orl", "a,%s",
- aopGet (left, offset, FALSE, FALSE));
+ if ((AOP_TYPE(right)==AOP_REG || IS_AOP_PREG(right) || AOP_TYPE(right)==AOP_DIR)
+ && AOP_TYPE(left)==AOP_ACC)
+ {
+ if (offset)
+ emitcode("mov", "a,b");
+ emitcode ("orl", "a,%s", aopGet (right, offset, FALSE, FALSE));
+ }
+ else if (AOP_TYPE(left)==AOP_ACC)
+ {
+ if (!offset)
+ {
+ bool pushedB = pushB ();
+ emitcode("mov", "b,a");
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode("orl", "a,b");
+ popB (pushedB);
+ }
+ else
+ {
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode("orl", "a,b");
+ }
+ }
+ else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset))
+ {
+ MOVB (aopGet (left, offset, FALSE, FALSE));
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode ("orl", "a,b");
+ }
+ else if (aopGetUsesAcc (left, offset))
+ {
+ MOVA (aopGet (left, offset, FALSE, FALSE));
+ emitcode ("orl", "a,%s", aopGet (right, offset, FALSE, FALSE));
+ }
+ else
+ {
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode ("orl", "a,%s", aopGet (left, offset, FALSE, FALSE));
}
+
emitcode ("jnz", "%05d$", tlbl->key + 100);
offset++;
}
continue;
}
}
- // faster than result <- left, anl result,right
+ // faster than result <- left, orl result,right
// and better if result is SFR
- if (AOP_TYPE (left) == AOP_ACC)
+ if ((AOP_TYPE(right)==AOP_REG || IS_AOP_PREG(right) || AOP_TYPE(right)==AOP_DIR)
+ && AOP_TYPE(left)==AOP_ACC)
{
if (offset)
emitcode("mov", "a,b");
emitcode ("orl", "a,%s", aopGet (right, offset, FALSE, FALSE));
}
+ else if (AOP_TYPE(left)==AOP_ACC)
+ {
+ if (!offset)
+ {
+ bool pushedB = pushB ();
+ emitcode("mov", "b,a");
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode("orl", "a,b");
+ popB (pushedB);
+ }
+ else
+ {
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode("orl", "a,b");
+ }
+ }
else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset))
{
- emitcode ("mov", "b,%s", aopGet (left, offset, FALSE, FALSE));
+ MOVB (aopGet (left, offset, FALSE, FALSE));
MOVA (aopGet (right, offset, FALSE, FALSE));
emitcode ("orl", "a,b");
}
}
}
}
-
}
else
{
}
else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset))
{
- emitcode ("mov", "b,%s", aopGet (left, offset, FALSE, FALSE));
+ MOVB (aopGet (left, offset, FALSE, FALSE));
MOVA (aopGet (right, offset, FALSE, FALSE));
emitcode ("xrl", "a,b");
aopPut (result, "a", offset);
aopPut (result, "a", offset);
}
else
- emitcode ("xrl", "%s,a",
- aopGet (left, offset, FALSE, TRUE));
+ emitcode ("xrl", "%s,a", aopGet (left, offset, FALSE, TRUE));
}
}
}
{
MOVA (aopGet (left, offset, FALSE, FALSE));
}
+ else if ((AOP_TYPE(right)==AOP_REG || IS_AOP_PREG(right) || AOP_TYPE(right)==AOP_DIR)
+ && AOP_TYPE(left)==AOP_ACC)
+ {
+ if (offset)
+ emitcode("mov", "a,b");
+ emitcode ("xrl", "a,%s", aopGet (right, offset, FALSE, FALSE));
+ }
+ else if (AOP_TYPE(left)==AOP_ACC)
+ {
+ if (!offset)
+ {
+ bool pushedB = pushB ();
+ emitcode("mov", "b,a");
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode("xrl", "a,b");
+ popB (pushedB);
+ }
+ else
+ {
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode("xrl", "a,b");
+ }
+ }
+ else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset))
+ {
+ MOVB (aopGet (left, offset, FALSE, FALSE));
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode ("xrl", "a,b");
+ }
+ else if (aopGetUsesAcc (left, offset))
+ {
+ MOVA (aopGet (left, offset, FALSE, FALSE));
+ emitcode ("xrl", "a,%s", aopGet (right, offset, FALSE, FALSE));
+ }
else
{
- if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
- if (offset)
- emitcode("mov", "a,b");
- emitcode ("xrl", "a,%s",
- aopGet (right, offset, FALSE, FALSE));
- } else {
- MOVA (aopGet (right, offset, FALSE, FALSE));
- emitcode ("xrl", "a,%s",
- aopGet (left, offset, FALSE, FALSE));
- }
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode ("xrl", "a,%s", aopGet (left, offset, FALSE, TRUE));
}
+
emitcode ("jnz", "%05d$", tlbl->key + 100);
offset++;
}
continue;
}
}
- // faster than result <- left, anl result,right
+ // faster than result <- left, xrl result,right
// and better if result is SFR
- if (AOP_TYPE (left) == AOP_ACC)
+ if ((AOP_TYPE(right)==AOP_REG || IS_AOP_PREG(right) || AOP_TYPE(right)==AOP_DIR)
+ && AOP_TYPE(left)==AOP_ACC)
{
if (offset)
emitcode("mov", "a,b");
emitcode ("xrl", "a,%s", aopGet (right, offset, FALSE, FALSE));
}
+ else if (AOP_TYPE(left)==AOP_ACC)
+ {
+ if (!offset)
+ {
+ bool pushedB = pushB ();
+ emitcode("mov", "b,a");
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode("xrl", "a,b");
+ popB (pushedB);
+ }
+ else
+ {
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode("xrl", "a,b");
+ }
+ }
else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset))
{
- emitcode ("mov", "b,%s", aopGet (left, offset, FALSE, FALSE));
+ MOVB (aopGet (left, offset, FALSE, FALSE));
MOVA (aopGet (right, offset, FALSE, FALSE));
emitcode ("xrl", "a,b");
}
{
/* don't crash result[offr] */
MOVA (aopGet (left, offl, FALSE, FALSE));
- emitcode ("xch", "a,%s", aopGet (left, offl + MSB16, FALSE, FALSE));
- x = aopGet (result, offr, FALSE, FALSE);
+ x = xch_a_aopGet (left, offl + MSB16, FALSE, FALSE);
+ usedB = !strncmp(x, "b", 1);
}
else if (aopGetUsesAcc (result, offr))
{
{
/* don't crash result[offr] */
MOVA (aopGet (left, offl, FALSE, FALSE));
- emitcode ("xch", "a,%s", aopGet (left, offl + MSB16, FALSE, FALSE));
- x = aopGet (result, offr, FALSE, FALSE);
+ x = xch_a_aopGet (left, offl + MSB16, FALSE, FALSE);
+ usedB = !strncmp(x, "b", 1);
}
else if (aopGetUsesAcc (result, offr))
{
/* shift right accumulator */
AccRsh (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);
}
emitcode ("add", "a,acc");
if (sameRegs (AOP (left), AOP (result)) &&
size >= MSB16 + offr && offr != LSB)
- emitcode ("xch", "a,%s",
- aopGet (left, LSB + offr, FALSE, FALSE));
+ xch_a_aopGet (left, LSB + offr, FALSE, FALSE);
else
aopPut (result, "a", LSB + offr);
}
emitcode ("rlc", "a");
if (sameRegs (AOP (left), AOP (result)) &&
size >= MSB24 + offr && offr != LSB)
- emitcode ("xch", "a,%s",
- aopGet (left, MSB16 + offr, FALSE, FALSE));
+ xch_a_aopGet (left, MSB16 + offr, FALSE, FALSE);
else
aopPut (result, "a", MSB16 + offr);
}
emitcode ("rlc", "a");
if (sameRegs (AOP (left), AOP (result)) &&
size >= MSB32 + offr && offr != LSB)
- emitcode ("xch", "a,%s",
- aopGet (left, MSB24 + offr, FALSE, FALSE));
+ xch_a_aopGet (left, MSB24 + offr, FALSE, FALSE);
else
aopPut (result, "a", MSB24 + offr);
}
shiftRLong (operand * left, int offl,
operand * result, int sign)
{
- bool useSameRegs = regsInCommon (left, result);
+ bool overlapping = regsInCommon (left, result) || operandsEqu(left, result);
- if (useSameRegs && offl>1)
+ if (overlapping && offl>1)
{
// we are in big trouble, but this shouldn't happen
werror(E_INTERNAL_ERROR, __FILE__, __LINE__);
{
emitcode ("rlc", "a");
emitcode ("subb", "a,acc");
- if (useSameRegs && sameReg (AOP (left), MSB32, AOP (result), MSB32))
+ if (overlapping && sameByte (AOP (left), MSB32, AOP (result), MSB32))
{
- emitcode ("xch", "a,%s", aopGet (left, MSB32, FALSE, FALSE));
+ xch_a_aopGet (left, MSB32, FALSE, FALSE);
}
else
{
}
else
{
- aopPut (result, zero, MSB32);
+ if (aopPutUsesAcc (result, zero, MSB32))
+ {
+ emitcode("xch", "a,b");
+ aopPut (result, zero, MSB32);
+ emitcode("xch", "a,b");
+ }
+ else
+ {
+ aopPut (result, zero, MSB32);
+ }
}
}
emitcode ("rrc", "a");
- if (useSameRegs && offl==MSB16 &&
- sameReg (AOP (left), MSB24, AOP (result), MSB32-offl))
+ if (overlapping && offl==MSB16 &&
+ sameByte (AOP (left), MSB24, AOP (result), MSB32-offl))
{
- emitcode ("xch", "a,%s",aopGet (left, MSB24, FALSE, FALSE));
+ xch_a_aopGet (left, MSB24, FALSE, FALSE);
}
else
{
- aopPut (result, "a", MSB32-offl);
+ aopPut (result, "a", MSB32 - offl);
MOVA (aopGet (left, MSB24, FALSE, FALSE));
}
emitcode ("rrc", "a");
- if (useSameRegs && offl==1 &&
- sameReg (AOP (left), MSB16, AOP (result), MSB24-offl))
+ if (overlapping && offl==MSB16 &&
+ sameByte (AOP (left), MSB16, AOP (result), MSB24-offl))
{
- emitcode ("xch", "a,%s",aopGet (left, MSB16, FALSE, FALSE));
+ xch_a_aopGet (left, MSB16, FALSE, FALSE);
}
else
{
- aopPut (result, "a", MSB24-offl);
+ aopPut (result, "a", MSB24 - offl);
MOVA (aopGet (left, MSB16, FALSE, FALSE));
}
+
emitcode ("rrc", "a");
if (offl != LSB)
{
}
else
{
- if (useSameRegs &&
- sameReg (AOP (left), LSB, AOP (result), MSB16-offl))
+ if (overlapping &&
+ sameByte (AOP (left), LSB, AOP (result), MSB16-offl))
{
- emitcode ("xch", "a,%s",aopGet (left, LSB, FALSE, FALSE));
+ xch_a_aopGet (left, LSB, FALSE, FALSE);
}
else
{