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;
}
return aop;
}
+#if 0
if (IS_GB) {
/* if it is in direct space */
if (IN_DIRSPACE(space)) {
return aop;
}
}
+#endif
/* only remaining is far space */
/* in which case DPTR gets the address */
- sym->aop = aop = newAsmop(AOP_IY);
- 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);
+ }
aop->size = getSize(sym->type);
aop->aopu.aop_dir = 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 */
/*-----------------------------------------------------------------*/
case AOP_REG:
return aop->aopu.aop_reg[offset]->name;
+ case AOP_HL:
+ assert(IS_GB);
+ setupHL(aop, offset);
+ sprintf(s, "(hl)");
+ ALLOC_ATOMIC(rs, strlen(s)+1);
+ strcpy(rs,s);
+ return rs;
+
case AOP_IY:
sprintf(s,"%d(iy)", offset);
ALLOC_ATOMIC(rs,strlen(s)+1);
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 {
else
emitcode("ld", "%d(iy),%s", offset, s);
break;
-
+
+ case AOP_HL:
+ assert(IS_GB);
+ if (!strcmp(s, "(hl)")) {
+ emitcode("ld", "a,(hl)");
+ s = "a";
+ }
+ setupHL(aop, offset);
+ emitcode("ld", "(hl),%s", s);
+ break;
+
case AOP_STK:
if (IS_GB) {
if (!strcmp("(hl)", s)) {
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_HL:
case AOP_STK:
return TRUE;
default:
static void fetchHL(asmop *aop)
{
if (IS_GB && requiresHL(aop)) {
- emitcode("ld", "a,%s", aopGet(aop, 0, FALSE));
- emitcode("ld", "h,%s", aopGet(aop, 1, FALSE));
+ aopGet(aop, 0, FALSE);
+ emitcode("ld", "a,(hl+)");
+ emitcode("ld", "h,(hl)");
emitcode("ld", "l,a");
}
else {
*/
static void emitCall (iCode *ic, bool ispcall)
{
- int isPrintf = 0;
-
/* if caller saves & we have not saved then */
if (!ic->regsSaved) {
/* PENDING */
emitcode("ld", "hl,#" LABEL_STR, (rlbl->key+100));
emitcode("push", "hl");
+ _pushed += 2;
aopOp(IC_LEFT(ic),ic,FALSE);
- emitcode("ld", "l,%s", aopGet(AOP(IC_LEFT(ic)), 0,FALSE));
- emitcode("ld", "h,%s", aopGet(AOP(IC_LEFT(ic)), 1,FALSE));
+ fetchHL(AOP(IC_LEFT(ic)));
freeAsmop(IC_LEFT(ic),NULL,ic);
emitcode("jp", "(hl)");
emitcode("","%05d$:",(rlbl->key+100));
+ _pushed -= 2;
}
else {
/* make the call */
OP_SYMBOL(IC_LEFT(ic))->rname :
OP_SYMBOL(IC_LEFT(ic))->name;
emitcode("call", "%s", name);
- if (!strcmp(name, "__printf"))
- isPrintf = 1;
-
}
/* if we need assign a result value */
/* adjust the stack for parameters if required */
if (IC_LEFT(ic)->parmBytes) {
int i = IC_LEFT(ic)->parmBytes;
- emitcode("", ";parmBytes = %u\n", i);
- if (isPrintf)
- i+=2;
_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;
}
size = AOP_SIZE(IC_LEFT(ic));
if ((size == 2) && ((l = aopGetWord(AOP(IC_LEFT(ic)), 0)))) {
+ if (IS_GB) {
+ emitcode("ld", "de,%s", l);
+ }
+ else {
emitcode("ld", "hl,%s", l);
+ }
}
else {
while (size--) {
(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);
+ emitcode("", LABEL_STR ":",tlbl->key+100);
outBitAcc(result);
}
return 0;
}
+/*-----------------------------------------------------------------*/
+/* jmpTrueOrFalse - */
+/*-----------------------------------------------------------------*/
+static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
+{
+ // ugly but optimized by peephole
+ if(IC_TRUE(ic)){
+ symbol *nlbl = newiTempLabel(NULL);
+ emitcode("jp", LABEL_STR, nlbl->key+100);
+ emitcode("", LABEL_STR ":",tlbl->key+100);
+ emitcode("jp",LABEL_STR,IC_TRUE(ic)->key+100);
+ emitcode("", LABEL_STR ":",nlbl->key+100);
+ }
+ else{
+ emitcode("jp", LABEL_STR, IC_FALSE(ic)->key+100);
+ emitcode("", LABEL_STR ":",tlbl->key+100);
+ }
+ ic->generated = 1;
+}
+
/*-----------------------------------------------------------------*/
/* genAnd - code for and */
/*-----------------------------------------------------------------*/
// if(left & literal)
else{
if(ifx)
-#if 0
jmpTrueOrFalse(ifx, tlbl);
-#else
- assert(0);
-#endif
goto release ;
}
}
MOVA(aopGet(AOP(right),offset,FALSE));
emitcode("or","a,%s ; 7",
aopGet(AOP(left),offset,FALSE));
- aopPut(AOP(result),"a ; 8",0);
+ aopPut(AOP(result),"a ; 8", offset);
}
}
}
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);
{
int size, offset ;
link *retype = getSpec(operandType(result));
+ const char *ptr = "hl";
+
+ if (IS_GB)
+ ptr = "de";
aopOp(left,ic,FALSE);
aopOp(result,ic,FALSE);
/* For now we always load into IY */
/* if this is remateriazable */
if (AOP_TYPE(left) == AOP_IMMD)
- emitcode("ld","hl,%s",aopGet(AOP(left),0,TRUE));
+ emitcode("ld","%s,%s", ptr, aopGet(AOP(left),0,TRUE));
else { /* we need to get it byte by byte */
- fetchHL(AOP(left));
+ if (IS_GB) {
+ emitcode("ld", "e,%s", aopGet(AOP(left), 0, FALSE));
+ emitcode("ld", "d,%s", aopGet(AOP(left), 1, FALSE));
+ }
+ else
+ fetchHL(AOP(left));
}
/* so iy now contains the address */
freeAsmop(left,NULL,ic);
while (size--) {
/* PENDING: make this better */
- if (AOP(result)->type == AOP_REG) {
+ if (!IS_GB && AOP(result)->type == AOP_REG) {
aopPut(AOP(result),"(hl)",offset++);
}
else {
- emitcode("ld", "a,(hl)", offset);
+ emitcode("ld", "a,(%s)", ptr, offset);
aopPut(AOP(result),"a",offset++);
}
if (size) {
- emitcode("inc", "hl");
+ emitcode("inc", "%s", ptr);
}
}
}
{
int size, offset ;
link *retype = getSpec(operandType(right));
+ const char *ptr = "hl";
aopOp(result,ic,FALSE);
aopOp(right,ic,FALSE);
+ if (IS_GB)
+ ptr = "de";
+
/* Handle the exceptions first */
if (isPair(AOP(result)) && (AOP_SIZE(right)==1)) {
/* Just do it */
/* if this is remateriazable */
if (AOP_TYPE(result) == AOP_IMMD) {
emitcode("", "; Error 2");
- emitcode("ld", "hl,%s", aopGet(AOP(result), 0, TRUE));
+ emitcode("ld", "%s,%s", ptr, aopGet(AOP(result), 0, TRUE));
}
else { /* we need to get it byte by byte */
- /* PENDING: do this better */
- fetchHL(AOP(result));
+ if (IS_GB) {
+ emitcode("ld", "e,%s", aopGet(AOP(result), 0, TRUE));
+ emitcode("ld", "d,%s", aopGet(AOP(result), 1, TRUE));
+ }
+ else {
+ /* PENDING: do this better */
+ fetchHL(AOP(result));
+ }
}
}
/* so hl know contains the address */
while (size--) {
char *l = aopGet(AOP(right),offset,FALSE);
-
- if (isRegOrLit(AOP(right))) {
- emitcode("ld", "(hl),%s", l);
+ if (isRegOrLit(AOP(right)) && !IS_GB) {
+ emitcode("ld", "(%s),%s", ptr, l);
}
else {
MOVA(l);
- emitcode("ld", "(hl),a", offset);
+ emitcode("ld", "(%s),a", ptr, offset);
}
if (size) {
- emitcode("inc", "hl");
+ emitcode("inc", ptr);
}
offset++;
}
if (sym->onStack) {
/* if it has an offset then we need to compute it */
if (IS_GB) {
- emitcode("lda", "hl,%d+%d(sp)", sym->stack, _spoffset);
+ emitcode("lda", "hl,%d+%d+%d(sp)", sym->stack, _pushed, _spoffset);
emitcode("ld", "d,h");
emitcode("ld", "e,l");
aopPut(AOP(IC_RESULT(ic)), "e", 0);
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;