#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 R0INB _G.bu.bs.r0InB
#define R1INB _G.bu.bs.r1InB
#define OPINB _G.bu.bs.OpInB
#define BINUSE _G.bu.BInUse
_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;
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;
}
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 (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
+ {
+ bool bits_pushed = FALSE;
for (i = 0; i < mcs51_nRegs; i++)
{
if (bitVectBitValue (rsave, i))
- emitcode ("push", "%s", mcs51_regWithIdx (i)->dname);
+ {
+ 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
+ {
+ bool bits_popped = FALSE;
for (i = mcs51_nRegs; i >= 0; i--)
{
if (bitVectBitValue (rsave, i))
- emitcode ("pop", "%s", mcs51_regWithIdx (i)->dname);
+ {
+ bits_popped = popReg (i, bits_popped);
+ }
+ }
}
}
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"))
{
+ 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 ;
+ int bit_count = 0;
+ /* first we do all bit parameters */
for (sic = setFirstItem (sendSet); sic;
- sic = setNextItem (sendSet)) {
+ 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++;
+ }
+ 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 (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));
+ }
+ 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);
bool swapBanks = FALSE;
bool accuse = FALSE;
bool accPushed = FALSE;
+ bool resultInF0 = FALSE;
D(emitcode("; genCall",""));
}
/* 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);
- }
+ /* 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);
+ }
+ }
/* 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;
// 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);
+ etype = getSpec(dtype);
+ 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",
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);
}
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)
{
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);
{
int size = getSize (operandType (IC_RESULT (ic)));
int offset = 0;
+
D(emitcode ("; genReceive",""));
if (ic->argreg == 1) { /* first parameter */
_G.accInUse++;
aopOp (IC_RESULT (ic), ic, FALSE);
_G.accInUse--;
- assignResultValue (IC_RESULT (ic));
+ assignResultValue (IC_RESULT (ic), NULL);
}
} else { /* second receive onwards */
int rb1off ;