#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->isInline = _G.lines.isInline;
_G.lines.current->isDebug = _G.lines.isDebug;
_G.lines.current->ic = _G.current_iCode;
+ _G.lines.current->isComment = (*buffer == ';');
+
+ dbuf_destroy(&dbuf);
}
static void
{
va_list ap;
char lb[INITIAL_INLINEASM];
- unsigned char *lbp = lb;
+ char *lbp = lb;
va_start (ap, fmt);
emitLabel (int key)
{
emit2 ("!tlabeldef", key);
+ _G.lines.current->isLabel = 1;
spillCached ();
}
if (aop->aopu.aop_pairId==PAIR_IX)
emit2 ("ld !*ixx,%s", 0, s);
else if (aop->aopu.aop_pairId==PAIR_IY)
- emit2 ("ld !*ixy,%s", 0, s);
+ emit2 ("ld !*iyx,%s", 0, s);
else
emit2 ("ld (%s),%s", _pairs[aop->aopu.aop_pairId].name, s);
break;
}
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);
fetchHL (AOP (IC_LEFT (ic)));
emit2 ("jp !*hl");
emit2 ("!tlabeldef", (rlbl->key + 100));
+ _G.lines.current->isLabel = 1;
_G.stack.pushed -= 2;
}
freeAsmop (IC_LEFT (ic), NULL, ic);
{
sprintf (buffer, "%s_start", sym->rname);
emit2 ("!labeldef", buffer);
+ _G.lines.current->isLabel = 1;
}
emit2 ("!functionlabeldef", sym->rname);
+ _G.lines.current->isLabel = 1;
ftype = operandType (IC_LEFT (ic));
emit2 ("pop af");
//parity odd <==> P/O=0 <==> interrupt enable flag IFF2 was 0 <==>
//don't enable interrupts as they were off before
- emit2 ("jp po,!tlabel", tlbl->key + 100);
+ emit2 ("jp PO,!tlabel", tlbl->key + 100);
emit2 ("!ei");
emit2 ("!tlabeldef", (tlbl->key + 100));
+ _G.lines.current->isLabel = 1;
}
}
}
{
sprintf (buffer, "%s_end", sym->rname);
emit2 ("!labeldef", buffer);
+ _G.lines.current->isLabel = 1;
}
_G.flushStatics = 1;
emit2 ("inc %s", aopGet (AOP (IC_RESULT (ic)), offset++, FALSE));
if (size)
{
- emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+ emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
}
}
emitLabel (tlbl->key + 100);
}
else
{
- emit2 ("!shortjp z,!tlabel", tlbl->key + 100);
+ emit2 ("!shortjp Z,!tlabel", tlbl->key + 100);
emit2 ("ld a,!one");
emitLabel (tlbl->key + 100);
outAcc (result);
wassertl (IS_Z80, "Only implemented for the Z80");
// wassertl (aop->type == AOP_EXSTK, "Only implemented for EXSTK");
+ emitDebug ("; Shift into pair idx %u", idx);
+
switch (idx)
{
case 0:
id = PAIR_HL;
+ setupPair (PAIR_HL, aop, 0);
break;
case 1:
id = PAIR_DE;
_push (PAIR_DE);
- break;
- default:
- wassertl (0, "Internal error - hit default case");
- }
-
- emitDebug ("; Shift into pair idx %u", idx);
-
- if (id == PAIR_HL)
- {
- setupPair (PAIR_HL, aop, 0);
- }
- else
- {
setupPair (PAIR_IY, aop, 0);
emit2 ("push iy");
emit2 ("pop %s", _pairs[id].name);
+ break;
+ case 2:
+ id = PAIR_IY;
+ setupPair (PAIR_IY, aop, 0);
+ break;
+ default:
+ wassertl (0, "Internal error - hit default case");
}
aop->type = AOP_PAIRPTR;
}
static void
-setupToPreserveCarry (asmop *result, asmop *left, asmop *right)
+setupToPreserveCarry (iCode * ic)
{
+ asmop *left = AOP (IC_LEFT (ic));
+ asmop *right = AOP (IC_RIGHT (ic));
+ asmop *result = AOP (IC_RESULT (ic));
+
wassert (left && right);
if (IS_Z80)
shiftIntoPair (0, right);
/* check result again, in case right == result */
if (couldDestroyCarry (result))
- shiftIntoPair (1, result);
+ {
+ if (!isPairInUse (PAIR_DE, ic))
+ shiftIntoPair (1, result);
+ else
+ shiftIntoPair (2, result);
+ }
}
else if (couldDestroyCarry (right))
{
}
/* Special case:
- ld hl,sp+n trashes C so we cant afford to do it during an
- add with stack based varibles. Worst case is:
+ ld hl,sp+n trashes C so we can't afford to do it during an
+ add with stack based variables. Worst case is:
ld hl,sp+left
ld a,(hl)
ld hl,sp+right
adc (hl)
ld hl,sp+result+1
ld (hl),a
- So you cant afford to load up hl if either left, right, or result
+ So you can't afford to load up hl if either left, right, or result
is on the stack (*sigh*) The alt is:
ld hl,sp+left
ld de,(hl)
}
}
- setupToPreserveCarry (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)), AOP (IC_RIGHT (ic)));
+ setupToPreserveCarry (ic);
while (size--)
{
freeAsmop (IC_LEFT (ic), NULL, ic);
freeAsmop (IC_RIGHT (ic), NULL, ic);
freeAsmop (IC_RESULT (ic), NULL, ic);
-
}
/*-----------------------------------------------------------------*/
}
}
- setupToPreserveCarry (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)), AOP (IC_RIGHT (ic)));
+ setupToPreserveCarry (ic);
/* if literal, add a,#-lit, else normal subb */
while (size--)
jlbl = IC_TRUE (ic);
if (!strcmp (jval, "a"))
{
- inst = "nz";
+ inst = "NZ";
}
else if (!strcmp (jval, "c"))
{
- inst = "c";
+ inst = "C";
}
else if (!strcmp (jval, "nc"))
{
- inst = "nc";
+ inst = "NC";
}
else if (!strcmp (jval, "m"))
{
- inst = "m";
+ inst = "M";
}
else if (!strcmp (jval, "p"))
{
- inst = "p";
+ inst = "P";
}
else
{
/* The buffer contains the bit on A that we should test */
- inst = "nz";
+ inst = "NZ";
}
}
else
jlbl = IC_FALSE (ic);
if (!strcmp (jval, "a"))
{
- inst = "z";
+ inst = "Z";
}
else if (!strcmp (jval, "c"))
{
- inst = "nc";
+ inst = "NC";
}
else if (!strcmp (jval, "nc"))
{
- inst = "c";
+ inst = "C";
}
else if (!strcmp (jval, "m"))
{
- inst = "p";
+ inst = "P";
}
else if (!strcmp (jval, "p"))
{
- inst = "m";
+ inst = "M";
}
else
{
/* The buffer contains the bit on A that we should test */
- inst = "z";
+ inst = "Z";
}
}
/* Z80 can do a conditional long jump */
{
emit2 ("or a,a");
}
- emit2 ("jp nz,!tlabel", lbl->key + 100);
+ emit2 ("jp NZ,!tlabel", lbl->key + 100);
}
else
{
while (size--)
{
- emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE));
- if ((AOP_TYPE (right) == AOP_LIT) && lit == 0)
+ _moveA (aopGet (AOP (left), offset, FALSE));
+ if ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0)
emit2 ("or a,a");
else
- emit2 ("cp a,%s", aopGet (AOP (right), offset, FALSE));
- emit2 ("jp nz,!tlabel", lbl->key + 100);
+ emit2 ("sub a,%s", aopGet (AOP (right), offset, FALSE));
+ emit2 ("jp NZ,!tlabel", lbl->key + 100);
offset++;
}
}
while (size--)
{
_moveA (aopGet (AOP (left), offset, FALSE));
- if ((AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) &&
+ if (/*AOP_TYPE (left) == AOP_DIR &&*/ AOP_TYPE (right) == AOP_LIT &&
((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0))
- /* PENDING */
- emit2 ("jp nz,!tlabel", lbl->key + 100);
+ {
+ /* 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);
+ }
else
{
- emit2 ("cp %s", aopGet (AOP (right), offset, FALSE));
- emit2 ("jp nz,!tlabel", lbl->key + 100);
+ emit2 ("sub %s", aopGet (AOP (right), offset, FALSE));
+ emit2 ("jp NZ,!tlabel", lbl->key + 100);
}
offset++;
}
{
_moveA (aopGet (AOP (right), offset, FALSE));
emit2 ("cp %s", aopGet (AOP (left), offset, FALSE));
- emit2 ("!shortjp nz,!tlabel", lbl->key + 100);
+ emit2 ("!shortjp NZ,!tlabel", lbl->key + 100);
offset++;
}
}
{
tlbl = newiTempLabel (NULL);
_toBoolean (left);
- emit2 ("!shortjp z,!tlabel", tlbl->key + 100);
+ emit2 ("!shortjp Z,!tlabel", tlbl->key + 100);
_toBoolean (right);
emitLabel (tlbl->key + 100);
outBitAcc (result);
{
tlbl = newiTempLabel (NULL);
_toBoolean (left);
- emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+ emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
_toBoolean (right);
emitLabel (tlbl->key + 100);
outBitAcc (result);
/* For the flags */
emit2 ("or a,a");
}
- emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+ emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
}
offset++;
}
{
emit2 ("clr c");
emit2 ("!tlabeldef", tlbl->key + 100);
+ _G.lines.current->isLabel = 1;
}
// if(left & literal)
else
_moveA (aopGet (AOP (left), offset, FALSE));
/* OR with any literal is the same as OR with itself. */
emit2 ("or a,a");
- emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+ emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
offset++;
}
{
_moveA (aopGet (AOP (left), offset, FALSE));
emit2 ("xor a,%s", aopGet (AOP (right), offset, FALSE));
- emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+ emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
offset++;
}
if (ifx)
movLeft2Result (left, offl, result, offr, 0);
movLeft2Result (left, offl + 1, result, offr + 1, 0);
+ if (shCount == 0)
+ return;
+
/* if (AOP(result)->type == AOP_REG) { */
tlbl = newiTempLabel (NULL);
emitLabel (tlbl1->key + 100);
emit2 ("dec a");
- emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+ emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
}
}
movLeft2Result (left, offl + 1, result, offr + 1, 0);
}
+ if (shCount == 0)
+ return;
+
if (getPairId (AOP (result)) == PAIR_HL)
{
while (shCount--)
{
emitLabel (tlbl1->key + 100);
emit2 ("dec a");
- emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+ emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
}
}
}
/*-----------------------------------------------------------------*/
-/* genlshTwo - left shift two bytes by known amount != 0 */
+/* genlshTwo - left shift two bytes by known amount */
/*-----------------------------------------------------------------*/
static void
genlshTwo (operand * result, operand * left, int shCount)
if (shCount)
{
movLeft2Result (left, LSB, result, MSB16, 0);
- aopPut (AOP (result), "!zero", 0);
shiftL1Left2Result (left, LSB, result, MSB16, shCount);
+ aopPut (AOP (result), "!zero", LSB);
}
else
{
aopPut (AOP (result), "!zero", LSB);
}
}
- /* 1 <= shCount <= 7 */
+ /* 0 <= shCount <= 7 */
else
{
if (size == 1)
size = getSize (operandType (result));
/* I suppose that the left size >= result size */
- if (shCount == 0)
- {
- wassert (0);
- }
- else if (shCount >= (size * 8))
+ if (shCount >= (size * 8))
{
while (size--)
{
}
emitLabel (tlbl1->key + 100);
emit2 ("dec a");
- emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+ emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
freeAsmop (left, NULL, ic);
freeAsmop (result, NULL, ic);
}
/*-----------------------------------------------------------------*/
-/* genrshTwo - right shift two bytes by known amount != 0 */
+/* genrshTwo - right shift two bytes by known amount */
/*-----------------------------------------------------------------*/
static void
genrshTwo (operand * result, operand * left,
aopPut (AOP (result), "!zero", 1);
}
}
- /* 1 <= shCount <= 7 */
+ /* 0 <= shCount <= 7 */
else
{
shiftR2Left2Result (left, LSB, result, LSB, shCount, sign);
size = getSize (operandType (result));
/* I suppose that the left size >= result size */
- if (shCount == 0)
- {
- wassert (0);
- }
- else if (shCount >= (size * 8)) {
+ if (shCount >= (size * 8)) {
const char *s;
if (!SPEC_USIGN(getSpec(operandType(left)))) {
_moveA(aopGet (AOP (left), 0, FALSE));
}
emitLabel (tlbl1->key + 100);
emit2 ("dec a");
- emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+ emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
freeAsmop (left, NULL, ic);
freeAsmop (result, NULL, ic);
symbol *tlbl = newiTempLabel (NULL);
emit2 ("bit %d,a", blen - 1);
- emit2 ("jp z,!tlabel", tlbl->key + 100);
+ emit2 ("jp Z,!tlabel", tlbl->key + 100);
emit2 ("or a,!immedbyte", (unsigned char) (0xff << blen));
emitLabel (tlbl->key + 100);
}
symbol *tlbl = newiTempLabel (NULL);
emit2 ("bit %d,a", blen - 1);
- emit2 ("jp z,!tlabel", tlbl->key + 100);
+ emit2 ("jp Z,!tlabel", tlbl->key + 100);
emit2 ("or a,!immedbyte", (unsigned char) (0xff << blen));
emitLabel (tlbl->key + 100);
}
symbol *tlbl = newiTempLabel (NULL);
emit2 ("bit %d,a", rlen - 1);
- emit2 ("jp z,!tlabel", tlbl->key + 100);
+ emit2 ("jp Z,!tlabel", tlbl->key + 100);
emit2 ("or a,!immedbyte", (unsigned char) (0xff << rlen));
emitLabel (tlbl->key + 100);
}
//disable interrupt
emit2 ("!di");
//parity odd <==> P/O=0 <==> interrupt enable flag IFF2=0
- emit2 ("jp po,!tlabel", tlbl->key + 100);
+ emit2 ("jp PO,!tlabel", tlbl->key + 100);
aopPut (AOP (IC_RESULT (ic)), "!one", 0);
emit2 ("!tlabeldef", (tlbl->key + 100));
+ _G.lines.current->isLabel = 1;
freeAsmop (IC_RESULT (ic), NULL, ic);
}
else
aopOp (IC_RIGHT (ic), ic, FALSE, TRUE);
_toBoolean (IC_RIGHT (ic));
//don't enable interrupts if they were off before
- emit2 ("!shortjp z,!tlabel", tlbl->key + 100);
+ emit2 ("!shortjp Z,!tlabel", tlbl->key + 100);
emit2 ("!ei");
emitLabel (tlbl->key + 100);
freeAsmop (IC_RIGHT (ic), NULL, ic);
emit2 ("pop af");
//parity odd <==> P/O=0 <==> interrupt enable flag IFF2 was 0 <==>
//don't enable interrupts as they were off before
- emit2 ("jp po,!tlabel", tlbl->key + 100);
+ emit2 ("jp PO,!tlabel", tlbl->key + 100);
emit2 ("!ei");
emit2 ("!tlabeldef", (tlbl->key + 100));
+ _G.lines.current->isLabel = 1;
}
}
emit2 ("ld a,(hl)");
emit2 ("ldi");
emit2 ("or a");
- emit2 ("!shortjp nz,!tlabel ; 1", label->key);
+ emit2 ("!shortjp NZ,!tlabel ; 1", label->key);
freeAsmop (from, NULL, ic->next);
freeAsmop (to, NULL, ic);
}
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);