#define SYM_BP(sym) (SPEC_OCLS (sym->etype)->paged ? "_bpx" : "_bp")
#define R0INB _G.bu.bs.r0InB
-#define R1INB _G.bu.bs.r1InB
-#define OPINB _G.bu.bs.OpInB
-#define BINUSE _G.bu.BInUse
+#define R1INB _G.bu.bs.r1InB
+#define OPINB _G.bu.bs.OpInB
+#define BINUSE _G.bu.BInUse
static struct
{
else
tvsprintf (lb, sizeof(lb), fmt, ap);
- while (isspace (*lbp))
+ while (isspace ((unsigned char)*lbp))
lbp++;
if (lbp && *lbp)
aop->aopu.aop_immd.from_cast_remat = 1;
ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
ptr_type = pointerTypeToGPByte (DCL_TYPE(from_type), NULL, NULL);
- continue ;
+ continue;
} else break;
ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
/* if in bit space then a special case */
if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY)
{
- emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir);
- emitcode ("cpl", "c");
- outBitC (IC_RESULT (ic));
+ /* if left==result then cpl bit */
+ if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
+ {
+ emitcode ("cpl", "%s", IC_LEFT (ic)->aop->aopu.aop_dir);
+ }
+ else
+ {
+ emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir);
+ emitcode ("cpl", "c");
+ outBitC (IC_RESULT (ic));
+ }
goto release;
}
toBoolean (IC_LEFT (ic));
+ /* set C, if a == 0 */
tlbl = newiTempLabel (NULL);
emitcode ("cjne", "a,#0x01,%05d$", tlbl->key + 100);
emitcode ("", "%05d$:", tlbl->key + 100);
bit -> int -> ~int -> bit
uchar -> int -> ~int -> bit
*/
- werror(W_COMPLEMENT);
emitcode ("setb", "%s", IC_RESULT (ic)->aop->aopu.aop_dir);
goto release;
}
else
{
bool bits_pushed = FALSE;
- for (i = 0; i < mcs51_nRegs; i++)
- {
- if (bitVectBitValue (rsave, i))
+ for (i = 0; i < mcs51_nRegs; i++)
+ {
+ if (bitVectBitValue (rsave, i))
{
bits_pushed = pushReg (i, bits_pushed);
}
}
- }
+ }
}
/*-----------------------------------------------------------------*/
else
{
bool bits_popped = FALSE;
- for (i = mcs51_nRegs; i >= 0; i--)
- {
- if (bitVectBitValue (rsave, i))
+ for (i = mcs51_nRegs; i >= 0; i--)
+ {
+ if (bitVectBitValue (rsave, i))
{
bits_popped = popReg (i, bits_popped);
}
}
- }
+ }
}
/*-----------------------------------------------------------------*/
-/* pushSide - */
+/* pushSide - */
/*-----------------------------------------------------------------*/
static void
pushSide (operand * oper, int size)
strcmp (l, "a"))
{
if (strcmp (l, prev) || *l == '@')
- MOVA (l);
+ MOVA (l);
emitcode ("push", "acc");
}
else
/*-----------------------------------------------------------------*/
static void genSend(set *sendSet)
{
- iCode *sic;
+ iCode *sic;
int bit_count = 0;
/* first we do all bit parameters */
- for (sic = setFirstItem (sendSet); sic;
+ for (sic = setFirstItem (sendSet); sic;
sic = setNextItem (sendSet))
{
aopOp (IC_LEFT (sic), sic, FALSE);
emitcode ("mov", "b[%d],c", bit);
}
bit_count++;
+ BitBankUsed = 1;
}
freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
}
for (sic = setFirstItem (sendSet); sic;
sic = setNextItem (sendSet))
{
- int size, offset = 0;
- aopOp (IC_LEFT (sic), sic, FALSE);
- size = AOP_SIZE (IC_LEFT (sic));
+ int size, offset = 0;
+ aopOp (IC_LEFT (sic), sic, FALSE);
+ size = AOP_SIZE (IC_LEFT (sic));
if (sic->argreg == 1)
{
while (size--)
{
char *l = aopGet (IC_LEFT (sic), offset, FALSE, FALSE);
- if (strcmp (l, fReturn[offset]))
- emitcode ("mov", "%s,%s", fReturn[offset], l);
- offset++;
- }
+ if (strcmp (l, fReturn[offset]))
+ emitcode ("mov", "%s,%s", fReturn[offset], l);
+ offset++;
+ }
}
else if (sic->argreg <= 12)
{
emitcode ("mov","%s,%s", rb1regs[sic->argreg+offset-5],
aopGet (IC_LEFT (sic), offset,FALSE, FALSE));
offset++;
- }
- }
- freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+ }
+ }
+ freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* selectRegBank - emit code to select the register bank */
+/*-----------------------------------------------------------------*/
+static void
+selectRegBank (short bank, bool keepFlags)
+{
+ /* if f.e. result is in carry */
+ if (keepFlags)
+ {
+ emitcode ("anl", "psw,#0xE7");
+ if (bank)
+ emitcode ("orl", "psw,#0x%02x", (bank << 3) & 0xff);
+ }
+ else
+ {
+ emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0xff);
}
}
genCall (iCode * ic)
{
sym_link *dtype;
+ sym_link *etype;
// bool restoreBank = FALSE;
bool swapBanks = FALSE;
bool accuse = FALSE;
D(emitcode("; genCall",""));
dtype = operandType (IC_LEFT (ic));
+ etype = getSpec(dtype);
/* if send set is not empty then assign */
if (_G.sendSet)
{
/* if we are calling a not _naked function that is not using
the same register bank then we need to save the
destination registers on the stack */
- dtype = operandType (IC_LEFT (ic));
if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) &&
(FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) &&
!IFFUNC_ISISR (dtype))
- {
+ {
swapBanks = TRUE;
- }
+ }
/* if caller saves & we have not saved then */
if (!ic->regsSaved)
saveRegisters (ic);
if (swapBanks)
- {
+ {
emitcode ("mov", "psw,#0x%02x",
((FUNC_REGBANK(dtype)) << 3) & 0xff);
- }
+ }
/* make the call */
if (IFFUNC_ISBANKEDCALL (dtype) && !SPEC_STAT(getSpec(dtype)))
}
if (swapBanks)
- {
- /* if result is in carry */
- if (IS_BIT (OP_SYM_ETYPE (IC_LEFT (ic))))
- {
- emitcode ("anl", "psw,#0xE7");
- if (FUNC_REGBANK(currFunc->type))
- emitcode ("orl", "psw,#0x%02x",
- ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff);
- }
- else
- {
- emitcode ("mov", "psw,#0x%02x",
- ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff);
- }
+ {
+ selectRegBank (FUNC_REGBANK(currFunc->type), IS_BIT (etype));
}
/* if we need assign a result value */
symbol *rlbl = newiTempLabel (NULL);
// bool restoreBank=FALSE;
bool swapBanks = FALSE;
+ bool resultInF0 = FALSE;
D(emitcode("; genPCall",""));
+ dtype = operandType (IC_LEFT (ic))->next;
+ etype = getSpec(dtype);
/* if caller saves & we have not saved then */
if (!ic->regsSaved)
saveRegisters (ic);
/* if we are calling a not _naked function that is not using
the same register bank then we need to save the
destination registers on the stack */
- dtype = operandType (IC_LEFT (ic))->next;
if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) &&
(FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) &&
!IFFUNC_ISISR (dtype))
- {
+ {
// saveRBank (FUNC_REGBANK (dtype), ic, TRUE);
// restoreBank=TRUE;
swapBanks = TRUE;
// need caution message to user here
- }
+ }
- etype = getSpec(dtype);
if (IS_LITERAL(etype))
{
/* if send set is not empty then assign */
}
}
if (swapBanks)
- {
- emitcode ("mov", "psw,#0x%02x",
- ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff);
- }
+ {
+ selectRegBank (FUNC_REGBANK(currFunc->type), IS_BIT (etype));
+ }
/* if we need assign a result value */
if ((IS_ITEMP (IC_RESULT (ic)) &&
+ !IS_BIT (OP_SYM_ETYPE (IC_RESULT (ic))) &&
(OP_SYMBOL (IC_RESULT (ic))->nRegs ||
OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
IS_TRUE_SYMOP (IC_RESULT (ic)))
freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
- /* adjust the stack for parameters if
- required */
+ /* adjust the stack for parameters if required */
if (ic->parmBytes)
{
int i;
if (ic->parmBytes > 3)
{
+ if (IS_BIT (OP_SYM_ETYPE (IC_LEFT (ic))) &&
+ IS_BIT (OP_SYM_ETYPE (IC_RESULT (ic))))
+ {
+ emitcode ("mov", "F0,c");
+ resultInF0 = TRUE;
+ }
+
emitcode ("mov", "a,%s", spname);
emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
emitcode ("mov", "%s,a", spname);
// if (restoreBank)
// unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE);
- /* if we hade saved some registers then
- unsave them */
+ /* if we had saved some registers then unsave them */
if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
unsaveRegisters (ic);
+
+ if (IS_BIT (OP_SYM_ETYPE (IC_RESULT (ic))))
+ {
+ if (resultInF0)
+ emitcode ("mov", "c,F0");
+
+ aopOp (IC_RESULT (ic), ic, FALSE);
+ assignResultValue (IC_RESULT (ic), IC_LEFT (ic));
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ }
}
/*-----------------------------------------------------------------*/
}
/*-----------------------------------------------------------------*/
-/* genMinusDec :- does subtraction with deccrement if possible */
+/* genMinusDec :- does subtraction with decrement if possible */
/*-----------------------------------------------------------------*/
static bool
genMinusDec (iCode * ic)
while (size--)
{
- if (useCarry || ((lit >> (offset * 8)) & 0x0FFL)) {
+ if (useCarry || ((lit >> (offset * 8)) & 0x0FFL))
+ {
MOVA (aopGet (IC_LEFT (ic), offset, FALSE, FALSE));
- if (!offset && !size && lit== (unsigned long) -1) {
- emitcode ("dec", "a");
- } else if (!useCarry) {
- /* first add without previous c */
- emitcode ("add", "a,#0x%02x",
- (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
- useCarry = TRUE;
- } else {
- emitcode ("addc", "a,#0x%02x",
- (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
- }
- aopPut (IC_RESULT (ic), "a", offset++, isOperandVolatile (IC_RESULT (ic), FALSE));
- } else {
+ if (!offset && !size && lit== (unsigned long) -1)
+ {
+ emitcode ("dec", "a");
+ }
+ else if (!useCarry)
+ {
+ /* first add without previous c */
+ emitcode ("add", "a,#0x%02x",
+ (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
+ useCarry = TRUE;
+ }
+ else
+ {
+ emitcode ("addc", "a,#0x%02x",
+ (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
+ }
+ aopPut (IC_RESULT (ic), "a", offset++, isOperandVolatile (IC_RESULT (ic), FALSE));
+ }
+ else
+ {
/* no need to add zeroes */
+ if (!sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))))
+ {
+ aopPut (IC_RESULT (ic), aopGet (IC_LEFT (ic), offset, FALSE, FALSE),
+ offset, isOperandVolatile (IC_RESULT (ic), FALSE));
+ }
offset++;
}
}
emitcode ("subb", "a,b");
popB (pushedB);
} else {
+ /* reverse subtraction with 2's complement */
+ if (offset == 0)
+ emitcode( "setb", "c");
+ else
+ emitcode( "cpl", "c");
wassertl(!aopGetUsesAcc(leftOp, offset), "accumulator clash");
MOVA (aopGet(rightOp, offset, FALSE, TRUE));
- if (offset == 0) {
- emitcode( "setb", "c");
- }
emitcode("subb", "a,%s", aopGet(leftOp, offset, FALSE, TRUE));
emitcode("cpl", "a");
+ if (size) /* skip if last byte */
+ emitcode( "cpl", "c");
}
} else {
MOVA (aopGet (leftOp, offset, FALSE, FALSE));
aopOp (right, ic, FALSE);
aopOp (result, ic, TRUE);
- genCmp (left, right, result, ifx, sign,ic);
+ genCmp (left, right, result, ifx, sign, ic);
freeAsmop (result, NULL, ic, TRUE);
}
MOVA (aopGet (right, offset, FALSE, FALSE));
emitcode("anl", "a,b");
}
- } else {
+ } else {
MOVA (aopGet (right, offset, FALSE, FALSE));
- emitcode ("anl", "a,%s",
+ emitcode ("anl", "a,%s",
aopGet (left, offset, FALSE, FALSE));
+ }
}
- }
emitcode ("jnz", "%05d$", tlbl->key + 100);
offset++;
}
else
{
/* Add \n for labels, not dirs such as c:\mydir */
- if ( (*bp == ':') && (isspace(bp[1])) )
+ if ( (*bp == ':') && (isspace((unsigned char)bp[1])) )
{
bp++;
*bp = '\0';
freeAsmop (result, NULL, ic, TRUE);
}
+/*-----------------------------------------------------------------*/
+/* genGetAbit - generates code get a single bit */
+/*-----------------------------------------------------------------*/
+static void
+genGetAbit (iCode * ic)
+{
+ operand *left, *right, *result;
+ int shCount;
+
+ D(emitcode ("; genGetAbit",""));
+
+ left = IC_LEFT (ic);
+ right = IC_RIGHT (ic);
+ result = IC_RESULT (ic);
+ aopOp (left, ic, FALSE);
+ aopOp (right, ic, FALSE);
+ aopOp (result, ic, FALSE);
+
+ shCount = (int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+
+ /* get the needed byte into a */
+ MOVA (aopGet (left, shCount / 8, FALSE, FALSE));
+ shCount %= 8;
+ if (AOP_TYPE (result) == AOP_CRY)
+ {
+ if ((shCount) == 7)
+ emitcode ("rlc", "a");
+ else if ((shCount) == 0)
+ emitcode ("rrc", "a");
+ else
+ emitcode ("mov", "c,acc[%d]", shCount);
+ outBitC (result);
+ }
+ else
+ {
+ switch (shCount)
+ {
+ case 2:
+ emitcode ("rr", "a");
+ //fallthrough
+ case 1:
+ emitcode ("rr", "a");
+ //fallthrough
+ case 0:
+ emitcode ("anl", "a,#0x01");
+ break;
+ case 3:
+ case 5:
+ emitcode ("mov", "c,acc[%d]", shCount);
+ emitcode ("clr", "a");
+ emitcode ("rlc", "a");
+ break;
+ case 4:
+ emitcode ("swap", "a");
+ emitcode ("anl", "a,#0x01");
+ break;
+ case 6:
+ emitcode ("rl", "a");
+ //fallthrough
+ case 7:
+ emitcode ("rl", "a");
+ emitcode ("anl", "a,#0x01");
+ break;
+ }
+ outAcc (result);
+ }
+
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genGetByte - generates code get a single byte */
+/*-----------------------------------------------------------------*/
+static void
+genGetByte (iCode * ic)
+{
+ operand *left, *right, *result;
+ int offset;
+
+ D(emitcode ("; genGetByte",""));
+
+ left = IC_LEFT (ic);
+ right = IC_RIGHT (ic);
+ result = IC_RESULT (ic);
+ aopOp (left, ic, FALSE);
+ aopOp (right, ic, FALSE);
+ aopOp (result, ic, FALSE);
+
+ offset = (int)floatFromVal (AOP (right)->aopu.aop_lit) / 8;
+ aopPut (result,
+ aopGet (left, offset, FALSE, FALSE),
+ 0,
+ isOperandVolatile (result, FALSE));
+
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genGetWord - generates code get two bytes */
+/*-----------------------------------------------------------------*/
+static void
+genGetWord (iCode * ic)
+{
+ operand *left, *right, *result;
+ int offset;
+
+ D(emitcode ("; genGetWord",""));
+
+ left = IC_LEFT (ic);
+ right = IC_RIGHT (ic);
+ result = IC_RESULT (ic);
+ aopOp (left, ic, FALSE);
+ aopOp (right, ic, FALSE);
+ aopOp (result, ic, FALSE);
+
+ offset = (int)floatFromVal (AOP (right)->aopu.aop_lit) / 8;
+ aopPut (result,
+ aopGet (left, offset, FALSE, FALSE),
+ 0,
+ isOperandVolatile (result, FALSE));
+ aopPut (result,
+ aopGet (left, offset+1, FALSE, FALSE),
+ 1,
+ isOperandVolatile (result, FALSE));
+
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
+}
+
/*-----------------------------------------------------------------*/
/* genSwap - generates code to swap nibbles or bytes */
/*-----------------------------------------------------------------*/
static void
genReceive (iCode * ic)
{
- int size = getSize (operandType (IC_RESULT (ic)));
- int offset = 0;
+ int size = getSize (operandType (IC_RESULT (ic)));
+ int offset = 0;
D(emitcode ("; genReceive",""));
- if (ic->argreg == 1) { /* first parameter */
+ if (ic->argreg == 1)
+ { /* first parameter */
if (isOperandInFarSpace (IC_RESULT (ic)) &&
(OP_SYMBOL (IC_RESULT (ic))->isspilt ||
- IS_TRUE_SYMOP (IC_RESULT (ic)))) {
-
+ IS_TRUE_SYMOP (IC_RESULT (ic))))
+ {
regs *tempRegs[4];
int receivingA = 0;
int roffset = 0;
}
offset = fReturnSizeMCS51 - size;
- while (size--) {
+ while (size--)
+ {
emitcode ("push", "%s", (strcmp (fReturn[fReturnSizeMCS51 - offset - 1], "a") ?
fReturn[fReturnSizeMCS51 - offset - 1] : "acc"));
offset++;
- }
+ }
aopOp (IC_RESULT (ic), ic, FALSE);
size = AOP_SIZE (IC_RESULT (ic));
offset = 0;
- while (size--) {
+ while (size--)
+ {
emitcode ("pop", "acc");
aopPut (IC_RESULT (ic), "a", offset++, isOperandVolatile (IC_RESULT (ic), FALSE));
- }
-
- } else {
+ }
+ }
+ else
+ {
_G.accInUse++;
aopOp (IC_RESULT (ic), ic, FALSE);
_G.accInUse--;
assignResultValue (IC_RESULT (ic), NULL);
- }
- } else { /* second receive onwards */
+ }
+ }
+ else if (ic->argreg > 12)
+ { /* bit parameters */
+ if (OP_SYMBOL (IC_RESULT (ic))->regs[0]->rIdx != ic->argreg-5)
+ {
+ aopOp (IC_RESULT (ic), ic, FALSE);
+ emitcode ("mov", "c,%s", rb1regs[ic->argreg-5]);
+ outBitC(IC_RESULT (ic));
+ }
+ }
+ else
+ { /* other parameters */
int rb1off ;
aopOp (IC_RESULT (ic), ic, FALSE);
rb1off = ic->argreg;
- while (size--) {
+ while (size--)
+ {
aopPut (IC_RESULT (ic), rb1regs[rb1off++ -5], offset++, isOperandVolatile (IC_RESULT (ic), FALSE));
- }
- }
+ }
+ }
release:
freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
genGetHbit (ic);
break;
+ case GETABIT:
+ genGetAbit (ic);
+ break;
+
+ case GETBYTE:
+ genGetByte (ic);
+ break;
+
+ case GETWORD:
+ genGetWord (ic);
+ break;
+
case LEFT_OP:
genLeftShift (ic);
break;