extern int nRegs;
extern FILE *codeOutFile;
set *sendSet = NULL;
+const char *_shortJP = "jp";
+
#define RESULTONSTACK(x) \
(IC_RESULT(x) && IC_RESULT(x)->aop && \
IC_RESULT(x)->aop->type == AOP_STK )
static int _lastStack = 0;
static int _pushed = 0;
static int _spoffset;
+static int _lastHLOff = 0;
+static asmop *_lastHL;
#define LSB 0
#define MSB16 1
if (sym->onStack || sym->iaccess) {
sym->aop = aop = newAsmop(AOP_STK);
aop->size = getSize(sym->type);
-
+ _lastHL = NULL;
aop->aopu.aop_stk = sym->stack;
return aop;
}
/* only remaining is far space */
/* in which case DPTR gets the address */
- if (IS_GB)
+ if (IS_GB) {
sym->aop = aop = newAsmop(AOP_HL);
+ _lastHL = NULL;
+ }
else {
sym->aop = aop = newAsmop(AOP_IY);
emitcode ("ld","iy,#%s ; a", sym->rname);
return aopGetWordLong(aop, offset, TRUE);
}
+static void setupHL(asmop *aop, int offset)
+{
+ if (_lastHL != aop) {
+ switch (aop->type) {
+ case AOP_HL:
+ emitcode("ld", "hl,#%s+%d", aop->aopu.aop_dir, offset);
+ break;
+ case AOP_STK:
+ /* In some cases we can still inc or dec hl */
+ emitcode("lda", "hl,%d+%d+%d(sp)", aop->aopu.aop_stk+offset, _pushed, _spoffset);
+ break;
+ default:
+ assert(0);
+ }
+ _lastHL = aop;
+ _lastHLOff = offset;
+ }
+ else {
+ while (offset < _lastHLOff) {
+ emitcode("dec", "hl");
+ _lastHLOff--;
+ }
+ while (offset > _lastHLOff) {
+ emitcode("inc", "hl");
+ _lastHLOff++;
+ }
+ }
+}
+
/*-----------------------------------------------------------------*/
/* aopGet - for fetching value of the aop */
/*-----------------------------------------------------------------*/
return aop->aopu.aop_reg[offset]->name;
case AOP_HL:
- emitcode("ld", "hl,#%s+%d", aop->aopu.aop_dir, offset);
+ assert(IS_GB);
+ setupHL(aop, offset);
sprintf(s, "(hl)");
ALLOC_ATOMIC(rs, strlen(s)+1);
strcpy(rs,s);
case AOP_STK:
if (IS_GB) {
- /* We cant really optimise this as we cant afford to
- change the flags.
- */
- emitcode("lda", "hl,%d+%d+%d(sp)", aop->aopu.aop_stk+offset, _pushed, _spoffset);
+ setupHL(aop, offset);
sprintf(s, "(hl)");
}
else {
emitcode("ld", "a,(hl)");
s = "a";
}
- emitcode("ld", "hl,#%s+%d", aop->aopu.aop_dir, offset);
+ setupHL(aop, offset);
emitcode("ld", "(hl),%s", s);
break;
emitcode("ld", "a,(hl)");
s = "a";
}
- emitcode("lda", "hl,%d+%d+%d(sp)", aop->aopu.aop_stk+offset, _pushed, _spoffset);
+ setupHL(aop, offset);
if (!canAssignToPtr(s)) {
emitcode("ld", "a,%s", s);
emitcode("ld", "(hl),a");
static bool requiresHL(asmop *aop)
{
switch (aop->type) {
- case AOP_DIR:
case AOP_HL:
case AOP_STK:
return TRUE;
if (IC_LEFT(ic)->parmBytes) {
int i = IC_LEFT(ic)->parmBytes;
_pushed -= i;
- if (i>6) {
- emitcode("ld", "hl,#%d", i);
- emitcode("add", "hl,sp");
- emitcode("ld", "sp,hl");
+ if (IS_GB) {
+ emitcode("lda", "sp,%d(sp)", i);
}
else {
- while (i>1) {
- emitcode("pop", "hl");
- i-=2;
+ if (i>6) {
+ emitcode("ld", "hl,#%d", i);
+ emitcode("add", "hl,sp");
+ emitcode("ld", "sp,hl");
+ }
+ else {
+ while (i>1) {
+ emitcode("pop", "hl");
+ i-=2;
+ }
+ if (i)
+ emitcode("inc", "sp");
}
- if (i)
- emitcode("inc", "sp");
}
}
_lastStack = sym->stack;
if (sym->stack) {
- emitcode("ld", "hl,#-%d", sym->stack);
- emitcode("add", "hl,sp");
- emitcode("ld", "sp,hl");
+ if (IS_GB) {
+ emitcode("lda", "sp,-%d(sp)", sym->stack);
+ }
+ else {
+ emitcode("ld", "hl,#-%d", sym->stack);
+ emitcode("add", "hl,sp");
+ emitcode("ld", "sp,hl");
+ }
}
_spoffset = sym->stack;
}
(icount == 1)) {
symbol *tlbl = newiTempLabel(NULL);
emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE));
- emitcode("jp", "nz," LABEL_STR ,tlbl->key+100);
+ emitcode(_shortJP, "nz," LABEL_STR ,tlbl->key+100);
emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE));
if(size == 4) {
assert(0);
}
else {
- emitcode("jp","z," LABEL_STR ,tlbl->key+100);
+ emitcode(_shortJP,"z," LABEL_STR ,tlbl->key+100);
emitcode("ld","a,%s",one);
emitcode("", LABEL_STR ":",tlbl->key+100);
outAcc(result);
/* PENDING: ?? */
emitcode("ld","a,%s",one);
- emitcode("jp", LABEL_STR ,tlbl->key+100);
+ emitcode(_shortJP, LABEL_STR ,tlbl->key+100);
emitcode("", LABEL_STR ":",lbl->key+100);
emitcode("xor","a,a");
emitcode("", LABEL_STR ":",tlbl->key+100);
} else {
/* PENDING: do this better */
symbol *lbl = newiTempLabel(NULL);
- emitcode("jp", LABEL_STR ,lbl->key+100);
+ emitcode(_shortJP, LABEL_STR ,lbl->key+100);
emitcode("", LABEL_STR ":",tlbl->key+100);
emitcode("jp", LABEL_STR ,IC_FALSE(ifx)->key+100);
emitcode("", LABEL_STR ":",lbl->key+100);
} else {
tlbl = newiTempLabel(NULL);
toBoolean(left);
- emitcode("jp","z," LABEL_STR ,tlbl->key+100);
+ emitcode(_shortJP, "z," LABEL_STR ,tlbl->key+100);
toBoolean(right);
emitcode("", LABEL_STR ":",tlbl->key+100);
outBitAcc(result);
} else {
tlbl = newiTempLabel(NULL);
toBoolean(left);
- emitcode("jp","nz," LABEL_STR,tlbl->key+100);
+ emitcode(_shortJP, "nz," LABEL_STR,tlbl->key+100);
toBoolean(right);
emitcode("", LABEL_STR,tlbl->key+100);
outBitAcc(result);
emitcode("ld","a,#%u+1", shCount);
tlbl = newiTempLabel(NULL);
tlbl1 = newiTempLabel(NULL);
- emitcode("jp", LABEL_STR ,tlbl1->key+100);
+ emitcode(_shortJP, LABEL_STR ,tlbl1->key+100);
emitcode("", LABEL_STR ":",tlbl->key+100);
}
if (shCount>1) {
emitcode("", LABEL_STR ":",tlbl1->key+100);
emitcode("dec", "a");
- emitcode("jp","nz," LABEL_STR ,tlbl->key+100);
+ emitcode(_shortJP,"nz," LABEL_STR ,tlbl->key+100);
}
}
}
emitcode("ld","a,#%u+1", shCount);
tlbl = newiTempLabel(NULL);
tlbl1 = newiTempLabel(NULL);
- emitcode("jp", LABEL_STR ,tlbl1->key+100);
+ emitcode(_shortJP, LABEL_STR ,tlbl1->key+100);
emitcode("", LABEL_STR ":",tlbl->key+100);
}
if (shCount>1) {
emitcode("", LABEL_STR ":",tlbl1->key+100);
emitcode("dec", "a");
- emitcode("jp","nz," LABEL_STR ,tlbl->key+100);
+ emitcode(_shortJP,"nz," LABEL_STR ,tlbl->key+100);
}
}
}
offset = 0 ;
tlbl1 = newiTempLabel(NULL);
- emitcode("jp", LABEL_STR ,tlbl1->key+100);
+ emitcode(_shortJP, LABEL_STR ,tlbl1->key+100);
emitcode("", LABEL_STR ":",tlbl->key+100);
l = aopGet(AOP(result),offset,FALSE);
emitcode("or", "a,a");
}
emitcode("", LABEL_STR ":",tlbl1->key+100);
emitcode("dec", "a");
- emitcode("jp","nz," LABEL_STR ,tlbl->key+100);
+ emitcode(_shortJP,"nz," LABEL_STR ,tlbl->key+100);
freeAsmop(left,NULL,ic);
freeAsmop(result,NULL,ic);
offset);
offset++;
}
+ }
+ else if (size == 2 && requiresHL(AOP(right)) && requiresHL(AOP(result))) {
+ /* Special case. Load into a and d, then load out. */
+ MOVA(aopGet(AOP(right), 0, FALSE));
+ emitcode("ld", "e,%s", aopGet(AOP(right), 1, FALSE));
+ aopPut(AOP(result), "a", 0);
+ aopPut(AOP(result), "e", 1);
} else {
while (size--) {
aopPut(AOP(result),
emitcode("ld", "hl,#" LABEL_STR, jtab->key+100);
emitcode("add", "hl,de");
emitcode("add", "hl,de");
+ emitcode("add", "hl,de");
freeAsmop(IC_JTCOND(ic),NULL,ic);
if (!IS_GB)
emitcode("pop", "de");
if (IS_GB) {
_fReturn = _gbz80_return;
_fTmp = _gbz80_return;
+ _shortJP = "jr";
}
else {
_fReturn = _z80_return;
_fTmp = _z80_return;
+ _shortJP = "jp";
}
lineHead = lineCurr = NULL;