#include "gen.h"
char *aopLiteral (value * val, int offset);
+char *aopLiteralLong (value * val, int offset, int size);
extern int allocInfo;
/* this is the down and dirty file with all kinds of
#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 R0INB _G.bu.bs.r0InB
+#define R1INB _G.bu.bs.r1InB
+#define OPINB _G.bu.bs.OpInB
+#define BINUSE _G.bu.BInUse
static struct
{
_G;
static char *rb1regs[] = {
- "b1_0","b1_1","b1_2","b1_3","b1_4","b1_5","b1_6","b1_7"
+ "b1_0","b1_1","b1_2","b1_3","b1_4","b1_5","b1_6","b1_7",
+ "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7"
};
extern int mcs51_ptrRegReq;
else
tvsprintf (lb, sizeof(lb), fmt, ap);
- while (isspace (*lbp))
+ while (isspace ((unsigned char)*lbp))
lbp++;
if (lbp && *lbp)
emitcode("mov","a,%s", x);
}
+/*-----------------------------------------------------------------*/
+/* movc - moves specified value into the carry */
+/*-----------------------------------------------------------------*/
+static void
+movc (const char *s)
+{
+ if (s == zero)
+ CLRC;
+ else if (s == one)
+ SETC;
+ else if (strcmp (s, "c"))
+ {/* it's not in carry already */
+ MOVA (s);
+ /* set C, if a >= 1 */
+ emitcode ("add", "a,#0xff");
+ }
+}
+
/*-----------------------------------------------------------------*/
/* pushB - saves register B if necessary */
/*-----------------------------------------------------------------*/
}
}
+/*-----------------------------------------------------------------*/
+/* pushReg - saves register */
+/*-----------------------------------------------------------------*/
+static bool
+pushReg (int index, bool bits_pushed)
+{
+ regs * reg = mcs51_regWithIdx (index);
+ if (reg->type == REG_BIT)
+ {
+ if (!bits_pushed)
+ emitcode ("push", "%s", reg->base);
+ return TRUE;
+ }
+ else
+ emitcode ("push", "%s", reg->dname);
+ return bits_pushed;
+}
+
+/*-----------------------------------------------------------------*/
+/* popReg - restores register */
+/*-----------------------------------------------------------------*/
+static bool
+popReg (int index, bool bits_popped)
+{
+ regs * reg = mcs51_regWithIdx (index);
+ if (reg->type == REG_BIT)
+ {
+ if (!bits_popped)
+ emitcode ("pop", "%s", reg->base);
+ return TRUE;
+ }
+ else
+ emitcode ("pop", "%s", reg->dname);
+ return bits_popped;
+}
+
/*-----------------------------------------------------------------*/
/* getFreePtr - returns r0 or r1 whichever is free or can be pushed */
/*-----------------------------------------------------------------*/
sym->aop = aop = newAsmop (AOP_IMMD);
aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (sym->rname) + 1);
strcpy (aop->aopu.aop_immd.aop_immd1, sym->rname);
- aop->size = FPTRSIZE;
+ aop->size = getSize (sym->type);
return aop;
}
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;
return TRUE;
/* if they have the same rname */
- if (sym1->rname[0] && sym2->rname[0]
- && strcmp (sym1->rname, sym2->rname) == 0)
+ if (sym1->rname[0] && sym2->rname[0] &&
+ strcmp (sym1->rname, sym2->rname) == 0 &&
+ !(IS_PARM (op2) && IS_ITEMP (op1)))
return TRUE;
/* if left is a tmp & right is not */
if (aop1 == aop2)
return TRUE;
- if (aop1->type != AOP_REG ||
- aop2->type != AOP_REG)
+ if (aop1->type != AOP_REG && aop1->type != AOP_CRY)
+ return FALSE;
+
+ if (aop1->type != aop2->type)
return FALSE;
if (aop1->size != aop2->size)
return;
}
+ /* if the type is a bit register */
+ if (sym->regType == REG_BIT)
+ {
+ sym->aop = op->aop = aop = newAsmop (AOP_CRY);
+ aop->size = sym->nRegs;//1???
+ aop->aopu.aop_reg[0] = sym->regs[0];
+ aop->aopu.aop_dir = sym->regs[0]->name;
+ return;
+ }
+
/* must be in a register */
sym->aop = op->aop = aop = newAsmop (AOP_REG);
aop->size = sym->nRegs;
emitcode ("setb", "%s", aop->aopu.aop_dir);
else if (!strcmp (s, "c"))
emitcode ("mov", "%s,c", aop->aopu.aop_dir);
- else
+ else if (strcmp (s, aop->aopu.aop_dir))
{
MOVA (s);
/* set C, if a >= 1 */
/* 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);
if (count == 1)
{
- i = bitVectFirstBit (rsave);
- emitcode ("mov", "a,%s", mcs51_regWithIdx (i)->name);
+ regs * reg = mcs51_regWithIdx (bitVectFirstBit (rsave));
+ if (reg->type == REG_BIT)
+ {
+ emitcode ("mov", "a,%s", reg->base);
+ }
+ else
+ {
+ emitcode ("mov", "a,%s", reg->name);
+ }
emitcode ("mov", "r0,%s", spname);
emitcode ("inc", "%s", spname);// allocate before use
emitcode ("movx", "@r0,a");
}
else if (count != 0)
{
+ bitVect *rsavebits = bitVectIntersect (bitVectCopy (mcs51_allBitregs ()), rsave);
+ int nBits = bitVectnBitsOn (rsavebits);
+
+ if (nBits != 0)
+ {
+ count = count - nBits + 1;
+ /* remove all but the first bits as they are pushed all at once */
+ rsave = bitVectCplAnd (rsave, rsavebits);
+ rsave = bitVectSetBit (rsave, bitVectFirstBit (rsavebits));
+ }
+
if (bitVectBitValue (rsave, R0_IDX))
{
emitcode ("push", "%s", mcs51_regWithIdx (R0_IDX)->dname);
{
if (bitVectBitValue (rsave, i))
{
+ regs * reg = mcs51_regWithIdx (i);
if (i == R0_IDX)
{
emitcode ("pop", "acc");
emitcode ("push", "acc");
}
+ else if (reg->type == REG_BIT)
+ {
+ emitcode ("mov", "a,%s", reg->base);
+ }
else
{
- emitcode ("mov", "a,%s", mcs51_regWithIdx (i)->name);
+ emitcode ("mov", "a,%s", reg->name);
}
emitcode ("movx", "@r0,a");
if (--count)
}
}
else
- for (i = 0; i < mcs51_nRegs; i++)
- {
- if (bitVectBitValue (rsave, i))
- emitcode ("push", "%s", mcs51_regWithIdx (i)->dname);
- }
+ {
+ bool bits_pushed = FALSE;
+ for (i = 0; i < mcs51_nRegs; i++)
+ {
+ if (bitVectBitValue (rsave, i))
+ {
+ bits_pushed = pushReg (i, bits_pushed);
+ }
+ }
+ }
}
/*-----------------------------------------------------------------*/
if (count == 1)
{
+ regs * reg = mcs51_regWithIdx (bitVectFirstBit (rsave));
emitcode ("mov", "r0,%s", spname);
emitcode ("dec", "r0");
emitcode ("movx", "a,@r0");
- i = bitVectFirstBit (rsave);
- emitcode ("mov", "%s,a", mcs51_regWithIdx (i)->name);
+ if (reg->type == REG_BIT)
+ {
+ emitcode ("mov", "%s,a", reg->base);
+ }
+ else
+ {
+ emitcode ("mov", "%s,a", reg->name);
+ }
emitcode ("dec", "%s", spname);
}
else if (count != 0)
{
+ bitVect *rsavebits = bitVectIntersect (bitVectCopy (mcs51_allBitregs ()), rsave);
+ int nBits = bitVectnBitsOn (rsavebits);
+
+ if (nBits != 0)
+ {
+ count = count - nBits + 1;
+ /* remove all but the first bits as they are popped all at once */
+ rsave = bitVectCplAnd (rsave, rsavebits);
+ rsave = bitVectSetBit (rsave, bitVectFirstBit (rsavebits));
+ }
+
emitcode ("mov", "r0,%s", spname);
for (i = mcs51_nRegs; i >= 0; i--)
{
if (bitVectBitValue (rsave, i))
{
+ regs * reg = mcs51_regWithIdx (i);
emitcode ("dec", "r0");
emitcode ("movx", "a,@r0");
- if (i != R0_IDX)
- emitcode ("mov", "%s,a", mcs51_regWithIdx (i)->name);
+ if (i == R0_IDX)
+ {
+ emitcode ("push", "acc");
+ }
+ else if (reg->type == REG_BIT)
+ {
+ emitcode ("mov", "%s,a", reg->base);
+ }
else
- emitcode ("push", "acc");
+ {
+ emitcode ("mov", "%s,a", reg->name);
+ }
}
}
emitcode ("mov", "%s,r0", spname);
}
}
else
- for (i = mcs51_nRegs; i >= 0; i--)
- {
- if (bitVectBitValue (rsave, i))
- emitcode ("pop", "%s", mcs51_regWithIdx (i)->dname);
- }
+ {
+ bool bits_popped = FALSE;
+ 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)
emitcode ("push", "acc");
}
else
+ {
emitcode ("push", "%s", l);
}
}
+}
/*-----------------------------------------------------------------*/
/* assignResultValue - also indicates if acc is in use afterwards */
/*-----------------------------------------------------------------*/
static bool
-assignResultValue (operand * oper)
+assignResultValue (operand * oper, operand * func)
{
int offset = 0;
int size = AOP_SIZE (oper);
bool accuse = FALSE;
+ if (func && IS_BIT (OP_SYM_ETYPE (func)))
+ {
+ outBitC (oper);
+ return FALSE;
+ }
+
while (size--)
{
accuse |= aopPut (oper, fReturn[offset], offset, isOperandVolatile (oper, FALSE));
{
int size, offset = 0;
char *l;
+ char *prev = "";
D(emitcode ("; genIpush",""));
return;
}
- /* this is a paramter push: in this case we call
+ /* this is a parameter push: in this case we call
the routine to find the call and save those
registers that need to be saved */
saveRegisters (ic);
AOP_TYPE (IC_LEFT (ic)) != AOP_DIR &&
strcmp (l, "a"))
{
- MOVA (l);
+ if (strcmp (l, prev) || *l == '@')
+ MOVA (l);
emitcode ("push", "acc");
}
else
+ {
emitcode ("push", "%s", l);
+ }
+ prev = l;
}
freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
/*-----------------------------------------------------------------*/
static void genSend(set *sendSet)
{
- iCode *sic;
- int rb1_count = 0 ;
-
- for (sic = setFirstItem (sendSet); sic;
- sic = setNextItem (sendSet)) {
- 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++;
- }
- rb1_count = 0;
- } else {
- while (size--) {
- emitcode ("mov","b1_%d,%s",rb1_count++,
- aopGet (IC_LEFT (sic), offset++,FALSE, FALSE));
- }
- }
- freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+ iCode *sic;
+ int bit_count = 0;
+
+ /* first we do all bit parameters */
+ for (sic = setFirstItem (sendSet); sic;
+ sic = setNextItem (sendSet))
+ {
+ aopOp (IC_LEFT (sic), sic, FALSE);
+
+ if (sic->argreg > 12)
+ {
+ int bit = sic->argreg-13;
+
+ /* if left is a literal then
+ we know what the value is */
+ if (AOP_TYPE (IC_LEFT (sic)) == AOP_LIT)
+ {
+ if (((int) operandLitValue (IC_LEFT (sic))))
+ emitcode ("setb", "b[%d]", bit);
+ else
+ emitcode ("clr", "b[%d]", bit);
+ }
+ else if (AOP_TYPE (IC_LEFT (sic)) == AOP_CRY)
+ {
+ char *l = AOP (IC_LEFT (sic))->aopu.aop_dir;
+ if (strcmp (l, "c"))
+ emitcode ("mov", "c,%s", l);
+ emitcode ("mov", "b[%d],c", bit);
+ }
+ else
+ {
+ /* we need to or */
+ toBoolean (IC_LEFT (sic));
+ /* set C, if a >= 1 */
+ emitcode ("add", "a,#0xff");
+ emitcode ("mov", "b[%d],c", bit);
+ }
+ bit_count++;
+ BitBankUsed = 1;
+ }
+ freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+ }
+
+ if (bit_count)
+ {
+ saveRegisters (setFirstItem (sendSet));
+ emitcode ("mov", "bits,b");
+ }
+
+ /* then we do all other parameters */
+ for (sic = setFirstItem (sendSet); sic;
+ sic = setNextItem (sendSet))
+ {
+ 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++;
+ }
+ }
+ else if (sic->argreg <= 12)
+ {
+ while (size--)
+ {
+ emitcode ("mov","%s,%s", rb1regs[sic->argreg+offset-5],
+ aopGet (IC_LEFT (sic), offset,FALSE, FALSE));
+ offset++;
+ }
+ }
+ 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;
bool accPushed = FALSE;
+ bool resultInF0 = 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 */
- emitcode ("lcall", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
- OP_SYMBOL (IC_LEFT (ic))->rname :
- OP_SYMBOL (IC_LEFT (ic))->name));
+ if (IFFUNC_ISBANKEDCALL (dtype) && !SPEC_STAT(getSpec(dtype)))
+ {
+ if (IFFUNC_CALLEESAVES(dtype))
+ {
+ werror (E_BANKED_WITH_CALLEESAVES);
+ }
+ else
+ {
+ char *l = (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
+ OP_SYMBOL (IC_LEFT (ic))->rname :
+ OP_SYMBOL (IC_LEFT (ic))->name);
+
+ emitcode ("mov", "r0,#%s", l);
+ emitcode ("mov", "r1,#(%s >> 8)", l);
+ emitcode ("mov", "r2,#(%s >> 16)", l);
+ emitcode ("lcall", "__sdcc_banked_call");
+ }
+ }
+ else
+ {
+ emitcode ("lcall", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
+ OP_SYMBOL (IC_LEFT (ic))->rname :
+ OP_SYMBOL (IC_LEFT (ic))->name));
+ }
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))->accuse ||
OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
aopOp (IC_RESULT (ic), ic, FALSE);
_G.accInUse--;
- accuse = assignResultValue (IC_RESULT (ic));
+ accuse = assignResultValue (IC_RESULT (ic), IC_LEFT (ic));
freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
emitcode ("push", "acc");
accPushed = TRUE;
}
+ 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 ("dec", "%s", spname);
}
- /* if we hade saved some registers then unsave them */
+ /* if we had saved some registers then unsave them */
if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
{
if (accuse && !accPushed && options.useXstack)
// if (restoreBank)
// unsaveRBank (FUNC_REGBANK (dtype), ic, FALSE);
+ 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);
+ }
+
if (accPushed)
emitcode ("pop", "acc");
}
genPcall (iCode * ic)
{
sym_link *dtype;
+ sym_link *etype;
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
- }
-
- /* push the return address on to the stack */
- emitcode ("mov", "a,#%05d$", (rlbl->key + 100));
- emitcode ("push", "acc");
- emitcode ("mov", "a,#(%05d$ >> 8)", (rlbl->key + 100));
- emitcode ("push", "acc");
+ }
- /* now push the calling address */
- aopOp (IC_LEFT (ic), ic, FALSE);
+ if (IS_LITERAL(etype))
+ {
+ /* if send set is not empty then assign */
+ if (_G.sendSet)
+ {
+ genSend(reverseSet(_G.sendSet));
+ _G.sendSet = NULL;
+ }
- pushSide (IC_LEFT (ic), FPTRSIZE);
+ if (swapBanks)
+ {
+ emitcode ("mov", "psw,#0x%02x",
+ ((FUNC_REGBANK(dtype)) << 3) & 0xff);
+ }
- freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+ if (IFFUNC_ISBANKEDCALL (dtype) && !SPEC_STAT(getSpec(dtype)))
+ {
+ if (IFFUNC_CALLEESAVES(dtype))
+ {
+ werror (E_BANKED_WITH_CALLEESAVES);
+ }
+ else
+ {
+ char *l = aopLiteralLong (OP_VALUE (IC_LEFT (ic)), 0, 2);
- /* if send set is not empty the assign */
- if (_G.sendSet)
- {
- genSend(reverseSet(_G.sendSet));
- _G.sendSet = NULL;
+ emitcode ("mov", "r0,#%s", l);
+ emitcode ("mov", "r1,#(%s >> 8)", l);
+ emitcode ("mov", "r2,#(%s >> 16)", l);
+ emitcode ("lcall", "__sdcc_banked_call");
+ }
+ }
+ else
+ {
+ emitcode ("lcall", "%s", aopLiteralLong (OP_VALUE (IC_LEFT (ic)), 0, 2));
+ }
}
+ else
+ {
+ if (IFFUNC_ISBANKEDCALL (dtype) && !SPEC_STAT(getSpec(dtype)))
+ {
+ if (IFFUNC_CALLEESAVES(dtype))
+ {
+ werror (E_BANKED_WITH_CALLEESAVES);
+ }
+ else
+ {
+ aopOp (IC_LEFT (ic), ic, FALSE);
- if (swapBanks)
- {
- emitcode ("mov", "psw,#0x%02x",
- ((FUNC_REGBANK(dtype)) << 3) & 0xff);
- }
+ if (!swapBanks)
+ {
+ emitcode ("mov", "ar0,%s", aopGet(IC_LEFT (ic), 0, FALSE, FALSE));
+ emitcode ("mov", "ar1,%s", aopGet(IC_LEFT (ic), 1, FALSE, FALSE));
+ emitcode ("mov", "ar2,%s", aopGet(IC_LEFT (ic), 2, FALSE, FALSE));
+ }
+ else
+ {
+ int reg = ((FUNC_REGBANK(dtype)) << 3) & 0xff;
+ emitcode ("mov", "0x%02x,%s", reg++, aopGet(IC_LEFT (ic), 0, FALSE, FALSE));
+ emitcode ("mov", "0x%02x,%s", reg++, aopGet(IC_LEFT (ic), 1, FALSE, FALSE));
+ emitcode ("mov", "0x%02x,%s", reg, aopGet(IC_LEFT (ic), 2, FALSE, FALSE));
+ }
- /* make the call */
- emitcode ("ret", "");
- emitcode ("", "%05d$:", (rlbl->key + 100));
+ freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+
+ /* if send set is not empty then assign */
+ if (_G.sendSet)
+ {
+ genSend(reverseSet(_G.sendSet));
+ _G.sendSet = NULL;
+ }
+
+ if (swapBanks)
+ {
+ emitcode ("mov", "psw,#0x%02x",
+ ((FUNC_REGBANK(dtype)) << 3) & 0xff);
+ }
+
+ /* make the call */
+ emitcode ("lcall", "__sdcc_banked_call");
+ }
+ }
+ else
+ {
+ /* push the return address on to the stack */
+ emitcode ("mov", "a,#%05d$", (rlbl->key + 100));
+ emitcode ("push", "acc");
+ emitcode ("mov", "a,#(%05d$ >> 8)", (rlbl->key + 100));
+ emitcode ("push", "acc");
+
+ /* now push the calling address */
+ aopOp (IC_LEFT (ic), ic, FALSE);
+ pushSide (IC_LEFT (ic), FPTRSIZE);
+ freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+
+ /* if send set is not empty the assign */
+ if (_G.sendSet)
+ {
+ genSend(reverseSet(_G.sendSet));
+ _G.sendSet = NULL;
+ }
+
+ if (swapBanks)
+ {
+ emitcode ("mov", "psw,#0x%02x",
+ ((FUNC_REGBANK(dtype)) << 3) & 0xff);
+ }
+
+ /* make the call */
+ emitcode ("ret", "");
+ emitcode ("", "%05d$:", (rlbl->key + 100));
+ }
+ }
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)))
aopOp (IC_RESULT (ic), ic, FALSE);
_G.accInUse--;
- assignResultValue (IC_RESULT (ic));
+ assignResultValue (IC_RESULT (ic), IC_LEFT (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);
+ }
}
/*-----------------------------------------------------------------*/
rbank = FUNC_REGBANK (ftype);
for (i = 0; i < mcs51_nRegs; i++)
{
- if (strcmp (regs8051[i].base, "0") == 0)
- emitcode ("", "%s = 0x%02x",
- regs8051[i].dname,
- 8 * rbank + regs8051[i].offset);
- else
- emitcode ("", "%s = %s + 0x%02x",
- regs8051[i].dname,
- regs8051[i].base,
- 8 * rbank + regs8051[i].offset);
+ if (regs8051[i].type != REG_BIT)
+ {
+ if (strcmp (regs8051[i].base, "0") == 0)
+ emitcode ("", "%s = 0x%02x",
+ regs8051[i].dname,
+ 8 * rbank + regs8051[i].offset);
+ else
+ emitcode ("", "%s = %s + 0x%02x",
+ regs8051[i].dname,
+ regs8051[i].base,
+ 8 * rbank + regs8051[i].offset);
+ }
}
}
/* if any registers used */
if (sym->regsUsed)
{
+ bool bits_pushed = FALSE;
/* save the registers used */
for (i = 0; i < sym->regsUsed->size; i++)
{
if (bitVectBitValue (sym->regsUsed, i))
- emitcode ("push", "%s", mcs51_regWithIdx (i)->dname);
+ bits_pushed = pushReg (i, bits_pushed);
}
}
}
/* if any registers used */
if (sym->regsUsed)
{
+ bool bits_pushed = FALSE;
/* save the registers used */
for (i = 0; i < sym->regsUsed->size; i++)
{
/* remember one saved register for later usage */
if (calleesaves_saved_register < 0)
calleesaves_saved_register = i;
- emitcode ("push", "%s", mcs51_regWithIdx (i)->dname);
+ bits_pushed = pushReg (i, bits_pushed);
_G.nRegsSaved++;
}
}
if (IFFUNC_ISCRITICAL (sym->type))
{
- emitcode ("pop", "psw"); /* restore ea via c in psw */
- emitcode ("mov", "ea,c");
+ if (IS_BIT (OP_SYM_ETYPE (IC_LEFT (ic))))
+ {
+ emitcode ("rlc", "a"); /* save c in a */
+ emitcode ("pop", "psw"); /* restore ea via c in psw */
+ emitcode ("mov", "ea,c");
+ emitcode ("rrc", "a"); /* restore c from a */
+ }
+ else
+ {
+ emitcode ("pop", "psw"); /* restore ea via c in psw */
+ emitcode ("mov", "ea,c");
+ }
}
if ((IFFUNC_ISREENT (sym->type) || options.stackAuto))
/* if any registers used */
if (sym->regsUsed)
{
+ bool bits_popped = FALSE;
/* save the registers used */
for (i = sym->regsUsed->size; i >= 0; i--)
{
if (bitVectBitValue (sym->regsUsed, i))
- emitcode ("pop", "%s", mcs51_regWithIdx (i)->dname);
+ bits_popped = popReg (i, bits_popped);
}
}
}
debugFile->writeEndFunction (currFunc, ic, 1);
}
- emitcode ("ret", "");
+ if (IFFUNC_ISBANKEDCALL (sym->type) && !SPEC_STAT(getSpec(sym->type)))
+ {
+ emitcode ("ljmp", "__sdcc_banked_ret");
+ }
+ else
+ {
+ emitcode ("ret", "");
+ }
}
if (!port->peep.getRegsRead || !port->peep.getRegsWritten || options.nopeep)
aopOp (IC_LEFT (ic), ic, FALSE);
size = AOP_SIZE (IC_LEFT (ic));
+
+ if (IS_BIT(_G.currentFunc->etype))
+ {
+ movc (aopGet (IC_LEFT (ic), 0, FALSE, FALSE));
+ size = 0;
+ }
+
while (size--)
{
char *l;
}
}
- if (pushed)
+ while (pushed)
{
- while (pushed)
- {
- pushed--;
- if (strcmp (fReturn[pushed], "a"))
- emitcode ("pop", fReturn[pushed]);
- else
- emitcode ("pop", "acc");
- }
+ pushed--;
+ if (strcmp (fReturn[pushed], "a"))
+ emitcode ("pop", fReturn[pushed]);
+ else
+ emitcode ("pop", "acc");
}
freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
return FALSE;
- /* if the literal value of the right hand side
- is greater than 4 then it is not worth it */
- if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
- return FALSE;
+ icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
D(emitcode ("; genPlusIncr",""));
return TRUE;
}
+ /* if the literal value of the right hand side
+ is greater than 4 then it is not worth it */
+ if (icount > 4)
+ return FALSE;
+
/* if the sizes are greater than 1 then we cannot */
if (AOP_SIZE (IC_RESULT (ic)) > 1 ||
AOP_SIZE (IC_LEFT (ic)) > 1)
if (!offset && !size && lit== (unsigned long) -1) {
emitcode ("dec", "a");
} else if (!useCarry) {
- /* first add without previous c */
+ /* 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));
- }
+ } 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 */
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';
{
operand *cond = IC_COND (ic);
int isbit = 0;
+ char *dup = NULL;
D(emitcode ("; genIfx",""));
if (AOP_TYPE (cond) != AOP_CRY)
toBoolean (cond);
else
- isbit = 1;
- /* the result is now in the accumulator */
+ {
+ isbit = 1;
+ if (AOP(cond)->aopu.aop_dir)
+ dup = Safe_strdup(AOP(cond)->aopu.aop_dir);
+ }
+ /* the result is now in the accumulator or a directly addressable bit */
freeAsmop (cond, NULL, ic, TRUE);
/* if there was something to be popped then do it */
genIpop (popIc);
/* if the condition is a bit variable */
- if (isbit && IS_ITEMP (cond) && SPIL_LOC (cond))
+ if (isbit && dup)
+ genIfxJump(ic, dup, NULL, NULL, NULL);
+ else if (isbit && IS_ITEMP (cond) && SPIL_LOC (cond))
genIfxJump (ic, SPIL_LOC (cond)->rname, NULL, NULL, NULL);
else if (isbit && !IS_ITEMP (cond))
genIfxJump (ic, OP_SYMBOL (cond)->rname, NULL, NULL, NULL);
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));
- }
- } else { /* second receive onwards */
+ assignResultValue (IC_RESULT (ic), NULL);
+ }
+ }
+ 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);