#include "common.h"
#include "SDCCpeeph.h"
#include "ralloc.h"
+#include "rtrack.h"
#include "gen.h"
+#include "dbuf_string.h"
char *aopLiteral (value * val, int offset);
char *aopLiteralLong (value * val, int offset, int size);
#define AOP_TYPE(op) AOP(op)->type
#define AOP_SIZE(op) AOP(op)->size
#define IS_AOP_PREG(x) (AOP(x) && (AOP_TYPE(x) == AOP_R1 || \
- AOP_TYPE(x) == AOP_R0))
+ AOP_TYPE(x) == AOP_R0))
#define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY || \
- AOP_TYPE(x) == AOP_DPTR || \
- AOP(x)->paged))
+ AOP_TYPE(x) == AOP_DPTR || \
+ AOP(x)->paged))
#define AOP_INPREG(x) (x && (x->type == AOP_REG && \
(x->aopu.aop_reg[0] == REG_WITH_INDEX(R0_IDX) || \
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7"
};
-extern FILE *codeOutFile;
+extern struct dbuf_s *codeOutBuf;
static void saveRBank (int, iCode *, bool);
#define RESULTONSTACK(x) \
/*-----------------------------------------------------------------*/
/* emitcode - writes the code into a file : for now it is simple */
/*-----------------------------------------------------------------*/
-static void
-emitcode (char *inst, const char *fmt,...)
+void
+emitcode (const char *inst, const char *fmt,...)
{
va_list ap;
- char lb[INITIAL_INLINEASM];
- char *lbp = lb;
+ struct dbuf_s dbuf;
+ const char *lbp, *lb;
+
+ dbuf_init (&dbuf, INITIAL_INLINEASM);
va_start (ap, fmt);
if (inst && *inst)
{
+ dbuf_append_str (&dbuf, inst);
+
if (fmt && *fmt)
{
- SNPRINTF (lb, sizeof(lb), "%s\t", inst);
- }
- else
- {
- SNPRINTF (lb, sizeof(lb), "%s", inst);
+ dbuf_append_char (&dbuf, '\t');
+ dbuf_tvprintf (&dbuf, fmt, ap);
}
-
- tvsprintf (lb + strlen(lb), sizeof(lb) - strlen(lb), fmt, ap);
}
else
{
- tvsprintf (lb, sizeof(lb), fmt, ap);
+ dbuf_tvprintf (&dbuf, fmt, ap);
}
+ lbp = lb = dbuf_c_str(&dbuf);
+
while (isspace ((unsigned char)*lbp))
{
lbp++;
if (lbp && *lbp)
{
+ rtrackUpdate (lbp);
+
lineCurr = (lineCurr ?
connectLine (lineCurr, newLineNode (lb)) :
(lineHead = newLineNode (lb)));
lineCurr->ic = _G.current_iCode;
lineCurr->isComment = (*lbp==';');
va_end (ap);
+
+ dbuf_destroy(&dbuf);
}
static void
emitLabel (symbol *tlbl)
{
emitcode ("", "%05d$:", tlbl->key + 100);
+ lineCurr->isLabel = 1;
}
/*-----------------------------------------------------------------*/
if (!strncmp(x, "a", 2) || !strncmp(x, "acc", 4))
return;
+ /* if it is a literal mov try to get it cheaper */
+ if (*x == '#' &&
+ rtrackMoveALit(x))
+ return;
+
emitcode("mov", "a,%s", x);
}
if (!strncmp(x, "b", 2))
return;
- emitcode("mov","b,%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");
+ /* if it is a literal mov try to get it cheaper */
+ if (*x == '#')
+ {
+ emitcode("mov","b,%s", rtrackGetLit(x));
+ return;
}
+
+ emitcode("mov","b,%s", x);
}
/*-----------------------------------------------------------------*/
{
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)))
if (accuse)
emitcode ("push", "acc");
emitcode ("mov", "a,%s", SYM_BP (sym));
- emitcode ("add", "a,#0x%02x", offset);
+ emitcode ("add", "a,#0x%02x", offset & 0xff);
emitcode ("mov", "%s,a", aop->aopu.aop_ptr->name);
if (accuse)
emitcode ("pop", "acc");
/* set immd2 field if required */
if (aop->aopu.aop_immd.from_cast_remat)
{
- sprintf(buffer,"#0x%02x",ptr_type);
+ SNPRINTF (buffer, sizeof(buffer), "#0x%02x", ptr_type);
aop->aopu.aop_immd.aop_immd2 = Safe_strdup(buffer);
}
}
/*-----------------------------------------------------------------*/
-/* 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;
/* rematerialize it NOW */
if (sym->remat)
{
- sym->aop = op->aop = aop =
- aopForRemat (sym);
+ sym->aop = op->aop = aop = aopForRemat (sym);
aop->size = getSize (sym->type);
return;
}
emitcode ("mov", "r1,b");
R1INB--;
}
- if (_G.r1Pushed)
+ else if (_G.r1Pushed)
{
if (pop)
{
emitcode ("pop", "ar1");
_G.r1Pushed--;
}
-
if (_G.r0Pushed)
{
emitcode ("pop", "ar0");
{
SNPRINTF (buffer, sizeof(buffer),
"(%s + %d)",
- aop->aopu.aop_dir,
- offset);
+ aop->aopu.aop_dir,
+ offset);
}
else
{
return aop->aopu.aop_reg[offset]->name;
case AOP_CRY:
- emitcode ("clr", "a");
emitcode ("mov", "c,%s", aop->aopu.aop_dir);
+ emitcode ("clr", "a");
emitcode ("rlc", "a");
return (dname ? "acc" : "a");
case AOP_STK:
if (strcmp (s, "a") == 0)
- emitcode ("push", "acc");
- else
- if (*s=='@') {
+ {
+ emitcode ("push", "acc");
+ }
+ else if (*s=='@')
+ {
MOVA(s);
emitcode ("push", "acc");
- } else {
+ }
+ else if (strcmp (s, "r0") == 0 ||
+ strcmp (s, "r1") == 0 ||
+ strcmp (s, "r2") == 0 ||
+ strcmp (s, "r3") == 0 ||
+ strcmp (s, "r4") == 0 ||
+ strcmp (s, "r5") == 0 ||
+ strcmp (s, "r6") == 0 ||
+ strcmp (s, "r7") == 0)
+ {
+ char buffer[10];
+ SNPRINTF (buffer, sizeof(buffer), "a%s", s);
+ emitcode ("push", buffer);
+ }
+ else
+ {
emitcode ("push", s);
}
break;
case AOP_CRY:
- /* if not bit variable */
+ /* if result no bit variable */
if (!aop->aopu.aop_dir)
{
+ assert (!strcmp (s, "c"));
/* inefficient: move carry into A and use jz/jnz */
emitcode ("clr", "a");
emitcode ("rlc", "a");
accuse = TRUE;
}
- else
+ else if (s == zero)
+ emitcode ("clr", "%s", aop->aopu.aop_dir);
+ else if (s == one)
+ emitcode ("setb", "%s", aop->aopu.aop_dir);
+ else if (!strcmp (s, "c"))
+ emitcode ("mov", "%s,c", aop->aopu.aop_dir);
+ else if (strcmp (s, aop->aopu.aop_dir))
{
- if (s == zero)
- emitcode ("clr", "%s", aop->aopu.aop_dir);
- else if (s == one)
- emitcode ("setb", "%s", aop->aopu.aop_dir);
- else if (!strcmp (s, "c"))
- emitcode ("mov", "%s,c", aop->aopu.aop_dir);
- else if (strcmp (s, aop->aopu.aop_dir))
- {
- MOVA (s);
- /* set C, if a >= 1 */
- emitcode ("add", "a,#0xff");
- emitcode ("mov", "%s,c", aop->aopu.aop_dir);
- }
+ MOVA (s);
+ /* set C, if a >= 1 */
+ emitcode ("add", "a,#0xff");
+ emitcode ("mov", "%s,c", aop->aopu.aop_dir);
}
break;
}
}
+/*-----------------------------------------------------------------*/
+/* toCarry - make boolean and move into carry */
+/*-----------------------------------------------------------------*/
+static void
+toCarry (operand * oper)
+{
+ /* if the operand is a literal then
+ we know what the value is */
+ if (AOP_TYPE (oper) == AOP_LIT)
+ {
+ if ((int) operandLitValue (oper))
+ SETC;
+ else
+ CLRC;
+ }
+ else if (AOP_TYPE (oper) == AOP_CRY)
+ {
+ emitcode ("mov", "c,%s", oper->aop->aopu.aop_dir);
+ }
+ else
+ {
+ /* or the operand into a */
+ toBoolean (oper);
+ /* set C, if a >= 1 */
+ emitcode ("add", "a,#0xff");
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* assignBit - assign operand to bit operand */
+/*-----------------------------------------------------------------*/
+static void
+assignBit (operand * result, operand * right)
+{
+ /* if the right side is a literal then
+ we know what the value is */
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ if ((int) operandLitValue (right))
+ aopPut (result, one, 0);
+ else
+ aopPut (result, zero, 0);
+ }
+ else
+ {
+ toCarry (right);
+ aopPut (result, "c", 0);
+ }
+}
+
+
+/*-------------------------------------------------------------------*/
+/* 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 (ic->regsSaved)
return;
if (IS_SYMOP(IC_LEFT(ic)) &&
- (IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type) ||
- IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT (ic)))))
+ (IFFUNC_CALLEESAVES (OP_SYMBOL (IC_LEFT (ic))->type) ||
+ IFFUNC_ISNAKED (OP_SYM_TYPE (IC_LEFT (ic)))))
return;
/* save the registers in use at this time but skip the
if (options.useXstack)
{
if (!ic)
- {
+ {
/* Assume r0 is available for use. */
r = REG_WITH_INDEX (R0_IDX);;
- }
+ }
else
- {
+ {
aop = newAsmop (0);
r = getFreePtr (ic, &aop, FALSE);
- }
+ }
// allocate space first
emitcode ("mov", "%s,%s", r->name, spname);
MOVA (r->name);
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");
+ toCarry (IC_LEFT (sic));
emitcode ("mov", "b[%d],c", bit);
}
bit_count++;
// need caution message to user here
}
- if (IS_LITERAL(etype))
+ if (IS_LITERAL (etype))
{
/* if send set is not empty then assign */
if (_G.sendSet)
if (!swapBanks)
{
+ /* what if aopGet needs r0 or r1 ??? */
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));
emitcode ("lcall", "__sdcc_banked_call");
}
}
- else
+ else if (_G.sendSet)
{
/* push the return address on to the stack */
emitcode ("mov", "a,#%05d$", (rlbl->key + 100));
emitcode ("ret", "");
emitLabel (rlbl);
}
+ else /* the send set is empty */
+ {
+ char *l;
+ /* now get the calling address into dptr */
+ aopOp (IC_LEFT (ic), ic, FALSE);
+
+ l = aopGet (IC_LEFT (ic), 0, FALSE, FALSE);
+ if (AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR)
+ {
+ emitcode ("mov", "r0,%s", l);
+ l = aopGet (IC_LEFT (ic), 1, FALSE, FALSE);
+ emitcode ("mov", "dph,%s", l);
+ emitcode ("mov", "dpl,r0");
+ }
+ else
+ {
+ emitcode ("mov", "dpl,%s", l);
+ l = aopGet (IC_LEFT (ic), 1, FALSE, FALSE);
+ emitcode ("mov", "dph,%s", l);
+ }
+
+ freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+
+ if (swapBanks)
+ {
+ emitcode ("mov", "psw,#0x%02x",
+ ((FUNC_REGBANK(dtype)) << 3) & 0xff);
+ }
+
+ /* make the call */
+ emitcode ("lcall", "__sdcc_call_dptr");
+ }
}
if (swapBanks)
{
return 0;
}
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define STRCASECMP stricmp
-#else
-#define STRCASECMP strcasecmp
-#endif
-
/*-----------------------------------------------------------------*/
/* inExcludeList - return 1 if the string is in exclude Reg list */
/*-----------------------------------------------------------------*/
emitcode (";", "-----------------------------------------");
emitcode ("", "%s:", sym->rname);
+ lineCurr->isLabel = 1;
ftype = operandType (IC_LEFT (ic));
_G.currentFunc = sym;
}
}
-
if (fReentrant)
{
if (options.useXstack)
if (i > 3 && accIsFree)
{
emitcode ("mov", "a,_spx");
- emitcode ("add", "a,#0x%02x", i);
+ emitcode ("add", "a,#0x%02x", i & 0xff);
emitcode ("mov", "_spx,a");
}
else if (i > 5)
{
emitcode ("push", "acc");
emitcode ("mov", "a,_spx");
- emitcode ("add", "a,#0x%02x", i);
+ emitcode ("add", "a,#0x%02x", i & 0xff);
emitcode ("mov", "_spx,a");
emitcode ("pop", "acc");
}
if (IS_BIT(_G.currentFunc->etype))
{
- movc (aopGet (IC_LEFT (ic), 0, FALSE, FALSE));
- size = 0;
+ toCarry (IC_LEFT (ic));
}
-
- while (size--)
+ else
{
- char *l;
- if (AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR)
+ while (size--)
{
- /* #NOCHANGE */
- l = aopGet (IC_LEFT (ic), offset++,
- FALSE, TRUE);
- emitcode ("push", "%s", l);
- pushed++;
+ char *l;
+ if (AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR)
+ {
+ /* #NOCHANGE */
+ l = aopGet (IC_LEFT (ic), offset++, FALSE, TRUE);
+ emitcode ("push", "%s", l);
+ pushed++;
+ }
+ else
+ {
+ l = aopGet (IC_LEFT (ic), offset, FALSE, FALSE);
+ if (strcmp (fReturn[offset], l))
+ emitcode ("mov", "%s,%s", fReturn[offset++], l);
+ }
}
- else
+
+ while (pushed)
{
- l = aopGet (IC_LEFT (ic), offset,
- FALSE, FALSE);
- if (strcmp (fReturn[offset], l))
- emitcode ("mov", "%s,%s", fReturn[offset++], l);
+ pushed--;
+ if (strcmp (fReturn[pushed], "a"))
+ emitcode ("pop", fReturn[pushed]);
+ else
+ emitcode ("pop", "acc");
}
}
-
- while (pushed)
- {
- pushed--;
- if (strcmp (fReturn[pushed], "a"))
- emitcode ("pop", fReturn[pushed]);
- else
- emitcode ("pop", "acc");
- }
freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
jumpret:
if (IC_LABEL (ic) == entryLabel)
return;
- emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
+ emitLabel (IC_LABEL (ic));
}
/*-----------------------------------------------------------------*/
icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
- D(emitcode ("; genPlusIncr",""));
+ D(emitcode (";","genPlusIncr"));
/* if increment >=16 bits in register or direct space */
- if ((AOP_TYPE(IC_LEFT(ic)) == AOP_REG || AOP_TYPE(IC_LEFT(ic)) == AOP_DIR ) &&
+ if (( AOP_TYPE(IC_LEFT(ic)) == AOP_REG ||
+ AOP_TYPE(IC_LEFT(ic)) == AOP_DIR ||
+ (IS_AOP_PREG (IC_LEFT(ic)) && !AOP_NEEDSACC (IC_LEFT(ic))) ) &&
sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
!isOperandVolatile (IC_RESULT (ic), FALSE) &&
(size > 1) &&
return TRUE;
}
+ if (icount == 1)
+ {
+ MOVA (aopGet (IC_LEFT (ic), 0, FALSE, FALSE));
+ emitcode ("inc", "a");
+ aopPut (IC_RESULT (ic), "a", 0);
+ return TRUE;
+ }
+
return FALSE;
}
{
D (emitcode (";", "genPlusBits"));
+ emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
{
symbol *lbl = newiTempLabel (NULL);
- emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
emitcode ("jnb", "%s,%05d$", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100));
emitcode ("cpl", "c");
emitLabel (lbl);
else
{
emitcode ("clr", "a");
- emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
emitcode ("rlc", "a");
emitcode ("mov", "c,%s", AOP (IC_RIGHT (ic))->aopu.aop_dir);
- emitcode ("addc", "a,#0x00");
+ emitcode ("addc", "a,%s", zero);
outAcc (IC_RESULT (ic));
}
}
!sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
{
char buffer[5];
- sprintf (buffer, "#%d", pointerTypeToGPByte (pointerCode (getSpec (operandType (IC_LEFT (ic)))), NULL, NULL));
+ SNPRINTF (buffer, sizeof(buffer),
+ "#%d", pointerTypeToGPByte (pointerCode (getSpec (operandType (IC_LEFT (ic)))), NULL, NULL));
aopPut (IC_RESULT (ic), buffer, GPTRSIZE - 1);
}
}
while (size--)
{
MOVA (aopGet (IC_RIGHT (ic), offset, FALSE, FALSE));
- emitcode ("addc", "a,#00");
+ emitcode ("addc", "a,%s", zero);
aopPut (IC_RESULT (ic), "a", offset++);
}
}
D (emitcode (";", "genMinusDec"));
/* if decrement >=16 bits in register or direct space */
- if ((AOP_TYPE(IC_LEFT(ic)) == AOP_REG || AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) &&
+ if (( AOP_TYPE(IC_LEFT(ic)) == AOP_REG ||
+ AOP_TYPE(IC_LEFT(ic)) == AOP_DIR ||
+ (IS_AOP_PREG (IC_LEFT(ic)) && !AOP_NEEDSACC (IC_LEFT(ic))) ) &&
sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
(size > 1) &&
(icount == 1))
return TRUE;
}
+ if (icount == 1)
+ {
+ MOVA (aopGet (IC_LEFT (ic), 0, FALSE, FALSE));
+ emitcode ("dec", "a");
+ aopPut (IC_RESULT (ic), "a", 0);
+ return TRUE;
+ }
+
return FALSE;
}
{
if (useCarry || ((lit >> (offset * 8)) & 0x0FFL))
{
- MOVA (aopGet (IC_LEFT (ic), offset, FALSE, FALSE));
+ MOVA (aopGet (IC_LEFT (ic), offset, FALSE, FALSE));
if (!offset && !size && lit== (unsigned long) -1)
{
emitcode ("dec", "a");
/* reverse subtraction with 2's complement */
if (offset == 0)
emitcode( "setb", "c");
- else
+ else
emitcode( "cpl", "c");
wassertl(!aopGetUsesAcc(leftOp, offset), "accumulator clash");
MOVA (aopGet(rightOp, offset, FALSE, TRUE));
{
/* moving to accumulator first helps peepholes */
MOVA (aopGet (left, 0, FALSE, FALSE));
- emitcode ("mov", "b,%s", aopGet (right, 0, FALSE, FALSE));
+ MOVB (aopGet (right, 0, FALSE, FALSE));
}
else
{
if (lUnsigned && rUnsigned)
{
/* unsigned is easy */
- emitcode ("mov", "b,%s", aopGet (right, 0, FALSE, FALSE));
+ MOVB (aopGet (right, 0, FALSE, FALSE));
MOVA (aopGet (left, 0, FALSE, FALSE));
emitcode ("div", "ab");
aopPut (result, "a", 0);
if (lUnsigned && rUnsigned)
{
/* unsigned is easy */
- emitcode ("mov", "b,%s", aopGet (right, 0, FALSE, FALSE));
+ MOVB (aopGet (right, 0, FALSE, FALSE));
MOVA (aopGet (left, 0, FALSE, FALSE));
emitcode ("div", "ab");
aopPut (result, "b", 0);
}
goto release;
}
+ else
+ {//nonzero literal
+ int bytelit = ((lit >> (offset * 8)) & 0x0FFL);
+ while (size && (bytelit == 0))
+ {
+ offset++;
+ bytelit = ((lit >> (offset * 8)) & 0x0FFL);
+ size--;
+ }
+ CLRC;
+ while (size--)
+ {
+ MOVA (aopGet (left, offset, FALSE, FALSE));
+ if (sign && size == 0)
+ {
+ emitcode ("xrl", "a,#0x80");
+ emitcode ("subb", "a,#0x%02x",
+ 0x80 ^ (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
+ }
+ else
+ {
+ emitcode ("subb", "a,%s", aopGet (right, offset, FALSE, FALSE));
+ }
+ offset++;
+ }
+ goto release;
+ }
}
CLRC;
while (size--)
if (sign && size == 0)
{
emitcode ("xrl", "a,#0x80");
- if (AOP_TYPE (right) == AOP_LIT)
- {
- unsigned long lit = (unsigned long)
- floatFromVal (AOP (right)->aopu.aop_lit);
- emitcode ("subb", "a,#0x%02x",
- 0x80 ^ (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
- }
- else
+ if (!rightInB)
{
- if (!rightInB)
- {
- pushedB = pushB ();
- rightInB++;
- MOVB (aopGet (right, offset, FALSE, FALSE));
- }
- emitcode ("xrl", "b,#0x80");
- emitcode ("subb", "a,b");
+ pushedB = pushB ();
+ rightInB++;
+ MOVB (aopGet (right, offset, FALSE, FALSE));
}
+ emitcode ("xrl", "b,#0x80");
+ emitcode ("subb", "a,b");
}
else
{
}
else
{// what is this case? just found it in ds390/gen.c
- emitcode ("anl","a,#!constbyte",1 << (posbit & 0x07));
+ emitcode ("anl","a,#!constbyte",1 << (posbit & 0x07));
}
goto release;
}
}
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)
+ {
+ bool pushedB = pushB ();
+ emitcode("mov", "b,a");
+ MOVA (aopGet (right, offset, FALSE, FALSE));
+ emitcode("anl", "a,b");
+ popB (pushedB);
+ }
+ else
{
- 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 {
MOVA (aopGet (right, offset, FALSE, FALSE));
- emitcode ("anl", "a,%s",
- aopGet (left, 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
{
/* get the string representation of the name */
l = aopGet (left, 0, FALSE, TRUE);
+ l++; // remove #
size = AOP_SIZE (result);
while (size--)
{
if (offset)
{
- SNPRINTF (buffer, sizeof(buffer),
- "(%s + %d)", l + 1, offset);
+ SNPRINTF (buffer, sizeof(buffer), "(%s + %d)", l, offset);
}
else
- sprintf (buffer, "%s", l + 1);
+ {
+ SNPRINTF (buffer, sizeof(buffer), "%s", l);
+ }
aopPut (result, buffer, offset++);
}
}
else
{
- sprintf (buffer, "@%s", rname);
+ SNPRINTF (buffer, sizeof(buffer), "@%s", rname);
aopPut (result, buffer, offset);
}
offset++;
aopOp (right, ic, FALSE);
l = aopGet (result, 0, FALSE, TRUE);
+ l++; //remove #
size = AOP_SIZE (right);
while (size--)
{
if (offset)
- sprintf (buffer, "(%s + %d)", l + 1, offset);
+ SNPRINTF (buffer, sizeof(buffer), "(%s + %d)", l, offset);
else
- sprintf (buffer, "%s", l + 1);
+ SNPRINTF (buffer, sizeof(buffer), "%s", l);
emitcode ("mov", "%s,%s", buffer,
aopGet (right, offset++, FALSE, FALSE));
}
/* if it has an offset then we need to compute it */
if (sym->stack)
{
- emitcode ("mov", "a,%s", SYM_BP (sym));
- emitcode ("add", "a,#0x%02x", ((sym->stack < 0) ?
- ((char) (sym->stack - _G.nRegsSaved)) :
- ((char) sym->stack)) & 0xff);
- aopPut (IC_RESULT (ic), "a", 0);
+ int stack_offset = ((sym->stack < 0) ?
+ ((char) (sym->stack - _G.nRegsSaved)) :
+ ((char) sym->stack)) & 0xff;
+ if ((abs(stack_offset) == 1) &&
+ !AOP_NEEDSACC(IC_RESULT (ic)) &&
+ !isOperandVolatile (IC_RESULT (ic), FALSE))
+ {
+ aopPut (IC_RESULT (ic), SYM_BP (sym), 0);
+ if (stack_offset > 0)
+ emitcode ("inc", "%s", aopGet (IC_RESULT (ic), LSB, FALSE, FALSE));
+ else
+ emitcode ("dec", "%s", aopGet (IC_RESULT (ic), LSB, FALSE, FALSE));
+ }
+ else
+ {
+ emitcode ("mov", "a,%s", SYM_BP (sym));
+ emitcode ("add", "a,#0x%02x", stack_offset & 0xff);
+ aopPut (IC_RESULT (ic), "a", 0);
+ }
}
else
{
sym->rname,
offset * 8);
else
- sprintf (s, "#%s", sym->rname);
+ SNPRINTF (s, sizeof(s), "#%s", sym->rname);
aopPut (IC_RESULT (ic), s, offset++);
}
/* if the result is a bit */
if (AOP_TYPE (result) == AOP_CRY)
{
- /* if the right size is a literal then
- we know what the value is */
- if (AOP_TYPE (right) == AOP_LIT)
- {
- if (((int) operandLitValue (right)))
- aopPut (result, one, 0);
- else
- aopPut (result, zero, 0);
- goto release;
- }
-
- /* the right is also a bit variable */
- if (AOP_TYPE (right) == AOP_CRY)
- {
- emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
- aopPut (result, "c", 0);
- goto release;
- }
-
- /* we need to or */
- toBoolean (right);
- aopPut (result, "a", 0);
+ assignBit (result, right);
goto release;
}
/* if the result is a bit (and not a bitfield) */
if (IS_BIT (OP_SYMBOL (result)->type))
{
- /* if the right size is a literal then
- we know what the value is */
- if (AOP_TYPE (right) == AOP_LIT)
- {
- if (((int) operandLitValue (right)))
- aopPut (result, one, 0);
- else
- aopPut (result, zero, 0);
-
- goto release;
- }
-
- /* the right is also a bit variable */
- if (AOP_TYPE (right) == AOP_CRY)
- {
- emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
- aopPut (result, "c", 0);
- goto release;
- }
-
- /* we need to or */
- toBoolean (right);
- aopPut (result, "a", 0);
+ assignBit (result, right);
goto release;
}
/* print the allocation information */
if (allocInfo && currFunc)
- printAllocInfo (currFunc, codeOutFile);
+ printAllocInfo (currFunc, codeOutBuf);
/* if debug information required */
if (options.debug && currFunc)
{
if (options.iCodeInAsm) {
char regsInUse[80];
int i;
+ char *iLine;
#if 0
for (i=0; i<8; i++) {
}
#endif
}
+ iLine = printILine(ic);
emitcode("", "; [%s] ic:%d: %s", regsInUse, ic->seq, printILine(ic));
+ dbuf_free(iLine);
}
/* if the result is marked as
spilt and rematerializable or code for
peepHole (&lineHead);
/* now do the actual printing */
- printLine (lineHead, codeOutFile);
+ printLine (lineHead, codeOutBuf);
return;
}