#include <string.h>
#include <ctype.h>
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define STRCASECMP stricmp
-#else
-#define STRCASECMP strcasecmp
-#endif
-
#include "z80.h"
#include "SDCCglobl.h"
#include "SDCCpeeph.h"
static char **_fReturn;
static char **_fTmp;
-extern FILE *codeOutFile;
+extern struct dbuf_s *codeOutBuf;
enum
{
}
static lineNode *
-_newLineNode (char *line)
+_newLineNode (const char *line)
{
lineNode *pl;
static void
_vemit2 (const char *szFormat, va_list ap)
{
- char buffer[INITIAL_INLINEASM];
+ struct dbuf_s dbuf;
+ const char *buffer;
- tvsprintf (buffer, sizeof(buffer), szFormat, ap);
+ dbuf_init(&dbuf, INITIAL_INLINEASM);
- _tidyUp (buffer);
+ dbuf_tvprintf (&dbuf, szFormat, ap);
+
+ buffer = dbuf_c_str(&dbuf);
+
+ _tidyUp ((char *)buffer);
_G.lines.current = (_G.lines.current ?
connectLine (_G.lines.current, _newLineNode (buffer)) :
(_G.lines.head = _newLineNode (buffer)));
_G.lines.current->isDebug = _G.lines.isDebug;
_G.lines.current->ic = _G.current_iCode;
_G.lines.current->isComment = (*buffer == ';');
+
+ dbuf_destroy(&dbuf);
}
static void
static void
_pop (PAIR_ID pairId)
{
- emit2 ("pop %s", _pairs[pairId].name);
- _G.stack.pushed -= 2;
- spillPair (pairId);
+ if (pairId != PAIR_INVALID)
+ {
+ emit2 ("pop %s", _pairs[pairId].name);
+ _G.stack.pushed -= 2;
+ spillPair (pairId);
+ }
}
void
#define AOP_TYPE(op) AOP(op)->type
#define AOP_SIZE(op) AOP(op)->size
#define AOP_NEEDSACC(x) (AOP(x) && ((AOP_TYPE(x) == AOP_CRY) || (AOP_TYPE(x) == AOP_SFR)))
+#define AOP_IS_PAIRPTR(x, p) (AOP_TYPE (x) == AOP_PAIRPTR && AOP (x)->aopu.aop_pairId == p)
static void
commitPair (asmop * aop, PAIR_ID id)
/** Take the value in carry and put it into a register
*/
void
-outBitCLong (operand * result, bool swap_sense)
+outBitC (operand * result)
{
/* if the result is bit */
if (AOP_TYPE (result) == AOP_CRY)
{
- wassertl (0, "Tried to write carry to a bit");
+ if (!IS_OP_RUONLY (result))
+ aopPut (AOP (result), "c", 0);
}
else
{
emit2 ("ld a,!zero");
emit2 ("rla");
- if (swap_sense)
- emit2 ("xor a,!immedbyte", 1);
outAcc (result);
}
}
-void
-outBitC (operand * result)
-{
- outBitCLong (result, FALSE);
-}
-
/*-----------------------------------------------------------------*/
/* toBoolean - emit code for orl a,operator(sizeop) */
/*-----------------------------------------------------------------*/
char *l = aopGetLitWordLong (AOP (IC_LEFT (ic)), --offset, FALSE);
wassert (l);
emit2 ("ld a,(%s)", l);
+ emit2 ("push af");
}
else
{
l = aopGet (AOP (IC_LEFT (ic)), --offset, FALSE);
- emit2 ("ld a,%s", l);
+ if (!strcmp(l, "b"))
+ emit2 ("push bc");
+ else if (!strcmp(l, "d"))
+ emit2 ("push de");
+ else if (!strcmp(l, "h"))
+ emit2 ("push hl");
+ else
+ {
+ emit2 ("ld a,%s", l);
+ emit2 ("push af");
+ }
}
- emit2 ("push af");
emit2 ("inc sp");
_G.stack.pushed++;
}
OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
IS_TRUE_SYMOP (IC_RESULT (ic)))
{
-
aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
assignResultValue (IC_RESULT (ic));
if (genPlusIncr (ic) == TRUE)
goto release;
- emitDebug ("; Can't optimise plus by inc, falling back to the normal way");
-
size = getDataSize (IC_RESULT (ic));
/* Special case when left and right are constant */
{
int size, offset = 0;
unsigned long lit = 0L;
- bool swap_sense = FALSE;
/* if left & right are bit variables */
if (AOP_TYPE (left) == AOP_CRY &&
}
if (ifx)
{
- genIfxJump (ifx, swap_sense ? "c" : "nc");
+ genIfxJump (ifx, "nc");
return;
}
}
/* Shift the sign bit up into carry */
emit2 ("rlca");
}
- outBitCLong (result, swap_sense);
+ outBitC (result);
}
else
{
if (IS_GB)
{
emit2 ("rlca");
- genIfxJump (ifx, swap_sense ? "nc" : "c");
+ genIfxJump (ifx, "c");
}
else
{
- genIfxJump (ifx, swap_sense ? "p" : "m");
+ genIfxJump (ifx, "m");
}
}
else
{
- genIfxJump (ifx, swap_sense ? "nc" : "c");
+ genIfxJump (ifx, "c");
}
}
else
/* Shift the sign bit up into carry */
emit2 ("rlca");
}
- outBitCLong (result, swap_sense);
+ outBitC (result);
}
/* leave the result in acc */
}
/*-----------------------------------------------------------------*/
/* gencjneshort - compare and jump if not equal */
+/* returns pair that still needs to be popped */
/*-----------------------------------------------------------------*/
-static void
+static PAIR_ID
gencjneshort (operand * left, operand * right, symbol * lbl)
{
int size = max (AOP_SIZE (left), AOP_SIZE (right));
left = t;
}
+ /* if the right side is a literal then anything goes */
if (AOP_TYPE (right) == AOP_LIT)
{
lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
- }
-
- /* if the right side is a literal then anything goes */
- if (AOP_TYPE (right) == AOP_LIT &&
- AOP_TYPE (left) != AOP_DIR)
- {
if (lit == 0)
{
- emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE));
+ _moveA (aopGet (AOP (left), offset, FALSE));
if (size > 1)
{
while (--size)
}
}
}
- /* if the right side is in a register or in direct space or
- if the left is a pointer register & right is not */
+ /* if the right side is in a register or
+ pointed to by HL, IX or IY */
else if (AOP_TYPE (right) == AOP_REG ||
- AOP_TYPE (right) == AOP_DIR ||
- (AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT))
+ AOP_TYPE (right) == AOP_HL ||
+ AOP_TYPE (right) == AOP_IY ||
+ AOP_TYPE (right) == AOP_STK ||
+ AOP_IS_PAIRPTR (right, PAIR_HL) ||
+ AOP_IS_PAIRPTR (right, PAIR_IX) ||
+ AOP_IS_PAIRPTR (right, PAIR_IY))
{
while (size--)
{
_moveA (aopGet (AOP (left), offset, FALSE));
- if (/*AOP_TYPE (left) == AOP_DIR &&*/ AOP_TYPE (right) == AOP_LIT &&
+ if (AOP_TYPE (right) == AOP_LIT &&
((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0))
{
- /* PENDING */
- /* MB: pending what? doesn't this need "or a,a"? */
- /* and I don't think AOP_TYPE(left) has anything to do with this */
emit2 ("or a,a");
emit2 ("jp NZ,!tlabel", lbl->key + 100);
}
offset++;
}
}
+ /* right is in direct space or a pointer reg, need both a & b */
else
{
- /* right is a pointer reg need both a & b */
- /* PENDING: is this required? */
+ PAIR_ID pair;
+ for (pair = PAIR_BC; pair <= PAIR_HL; pair++)
+ {
+ if (((AOP_TYPE (left) != AOP_PAIRPTR) || (AOP (left)->aopu.aop_pairId != pair)) &&
+ ((AOP_TYPE (right) != AOP_PAIRPTR) || (AOP (right)->aopu.aop_pairId != pair)))
+ {
+ break;
+ }
+ }
+ _push (pair);
while (size--)
{
+ emit2 ("; direct compare");
+ _emitMove (_pairs[pair].l, aopGet (AOP (left), offset, FALSE));
_moveA (aopGet (AOP (right), offset, FALSE));
- emit2 ("cp %s", aopGet (AOP (left), offset, FALSE));
+ emit2 ("sub %s", _pairs[pair].l);
emit2 ("!shortjp NZ,!tlabel", lbl->key + 100);
offset++;
}
+ return pair;
}
+ return PAIR_INVALID;
}
/*-----------------------------------------------------------------*/
{
symbol *tlbl = newiTempLabel (NULL);
- gencjneshort (left, right, lbl);
+ PAIR_ID pop = gencjneshort (left, right, lbl);
/* PENDING: ?? */
emit2 ("ld a,!one");
emitLabel (lbl->key + 100);
emit2 ("xor a,a");
emitLabel (tlbl->key + 100);
+ _pop (pop);
}
/*-----------------------------------------------------------------*/
}
else
{
+ PAIR_ID pop;
tlbl = newiTempLabel (NULL);
- gencjneshort (left, right, tlbl);
+ pop = gencjneshort (left, right, tlbl);
if (IC_TRUE (ifx))
{
+ _pop (pop);
emit2 ("jp !tlabel", IC_TRUE (ifx)->key + 100);
emitLabel (tlbl->key + 100);
+ _pop (pop);
}
else
{
/* PENDING: do this better */
symbol *lbl = newiTempLabel (NULL);
+ _pop (pop);
emit2 ("!shortjp !tlabel", lbl->key + 100);
emitLabel (tlbl->key + 100);
+ _pop (pop);
emit2 ("jp !tlabel", IC_FALSE (ifx)->key + 100);
emitLabel (lbl->key + 100);
}
int shCount, int is_signed)
{
int size = 2;
- symbol *tlbl, *tlbl1;
+ symbol *tlbl;
movLeft2Result (left, offl, result, offr, 0);
movLeft2Result (left, offl + 1, result, offr + 1, 0);
/* if (AOP(result)->type == AOP_REG) { */
tlbl = newiTempLabel (NULL);
- tlbl1 = newiTempLabel (NULL);
/* Left is already in result - so now do the shift */
- if (shCount <= 4)
+ /* Optimizing for speed by default. */
+ if (!optimize.codeSize || shCount <= 2)
{
while (shCount--)
{
}
else
{
- emit2 ("ld a,!immedbyte+1", shCount);
- emit2 ("!shortjp !tlabel", tlbl1->key + 100);
+ emit2 ("ld a,!immedbyte", shCount);
+
emitLabel (tlbl->key + 100);
emitRsh2 (AOP (result), size, is_signed);
- emitLabel (tlbl1->key + 100);
emit2 ("dec a");
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
}
}
if (options.iCodeInAsm)
{
- emit2 (";ic:%d: %s", ic->key, printILine(ic));
+ char *iLine = printILine(ic);
+ emit2 (";ic:%d: %s", ic->key, iLine);
+ dbuf_free(iLine);
}
/* if the result is marked as
spilt and rematerializable or code for
/* This is unfortunate */
/* now do the actual printing */
{
- FILE *fp = codeOutFile;
- if (isInHome () && codeOutFile == code->oFile)
- codeOutFile = home->oFile;
- printLine (_G.lines.head, codeOutFile);
+ struct dbuf_s *buf = codeOutBuf;
+ if (isInHome () && codeOutBuf == &code->oBuf)
+ codeOutBuf = &home->oBuf;
+ printLine (_G.lines.head, codeOutBuf);
if (_G.flushStatics)
{
flushStatics ();
_G.flushStatics = 0;
}
- codeOutFile = fp;
+ codeOutBuf = buf;
}
freeTrace(&_G.lines.trace);