#include "SDCCpeeph.h"
#include "ralloc.h"
#include "gen.h"
+#include "dbuf_string.h"
char *aopLiteral (value * val, int offset);
char *aopLiteralLong (value * val, int offset, int size);
"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,...)
+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++;
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;
}
/*-----------------------------------------------------------------*/
static void
movc (const char *s)
{
- if (s == zero)
+ if (!strcmp (s, zero))
CLRC;
- else if (s == one)
+ else if (!strcmp (s, one))
SETC;
else if (strcmp (s, "c"))
{/* it's not in carry already */
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");
/* 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;
}
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 (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 (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 (";", "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;
}
}
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");
}
/* 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
{
- SNPRINTF (buffer, sizeof(buffer),
- "%s", l + 1);
+ SNPRINTF (buffer, sizeof(buffer), "%s", l);
}
aopPut (result, buffer, offset++);
}
aopOp (right, ic, FALSE);
l = aopGet (result, 0, FALSE, TRUE);
+ l++; //remove #
size = AOP_SIZE (right);
while (size--)
{
if (offset)
- SNPRINTF (buffer, sizeof(buffer), "(%s + %d)", l + 1, offset);
+ SNPRINTF (buffer, sizeof(buffer), "(%s + %d)", l, offset);
else
- SNPRINTF (buffer, sizeof(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
{
/* 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;
}