#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 *_z80_return[] =
-{"l", "h", "e", "d"};
+ {"l", "h", "e", "d"};
static char *_gbz80_return[] =
-{"e", "d", "l", "h"};
+ {"e", "d", "l", "h"};
static char *_fReceive[] =
{ "c", "b", "e", "d" };
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;
+
+ dbuf_init(&dbuf, INITIAL_INLINEASM);
- tvsprintf (buffer, sizeof(buffer), szFormat, ap);
+ dbuf_tvprintf (&dbuf, szFormat, ap);
- _tidyUp (buffer);
+ 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)
}
else
{
+ if ((AOP_TYPE (oper) == AOP_REG) && (AOP_SIZE (oper) == 4) &&
+ !strcmp (AOP (oper)->aopu.aop_reg[size-1]->name, _fReturn[size-2]))
+ {
+ size--;
+ _emitMove ("a", _fReturn[size-1]);
+ _emitMove (_fReturn[size-1], _fReturn[size]);
+ _emitMove (_fReturn[size], "a");
+ aopPut (AOP (oper), _fReturn[size], size-1);
+ size--;
+ }
while (size--)
{
aopPut (AOP (oper), _fReturn[size], size);
OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
IS_TRUE_SYMOP (IC_RESULT (ic)))
{
-
aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
assignResultValue (IC_RESULT (ic));
/*-----------------------------------------------------------------*/
/* 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);
}
}
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
spilt live range, if there is an ifx statement
following this pop then the if statement might
be using some of the registers being popped which
- would destory the contents of the register so
+ would destroy the contents of the register so
we need to check for this condition and handle it */
if (ic->next &&
ic->next->op == IFX &&
/* 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);