static char zero[20];
static char *accUse[] = {"a" };
+static char *hlUse[] = { "l", "h" };
short rbank = -1;
short accInUse = 0 ;
short inLine = 0;
if (sym->accuse) {
int i;
- aop = op->aop = sym->aop = newAsmop(AOP_ACC);
- aop->size = getSize(sym->type);
- for ( i = 0 ; i < 2 ; i++ )
- aop->aopu.aop_str[i] = accUse[i];
- return;
+ if (sym->accuse == ACCUSE_A) {
+ aop = op->aop = sym->aop = newAsmop(AOP_ACC);
+ aop->size = getSize(sym->type);
+ for ( i = 0 ; i < 2 ; i++ )
+ aop->aopu.aop_str[i] = accUse[i];
+ }
+ else if (sym->accuse == ACCUSE_HL) {
+ wassert(!IS_GB);
+ aop = op->aop = sym->aop = newAsmop(AOP_HLREG);
+ aop->size = getSize(sym->type);
+ for ( i = 0 ; i < 2 ; i++ )
+ aop->aopu.aop_str[i] = hlUse[i];
+ }
+ else
+ wassert(0);
+ return;
}
if (sym->ruonly ) {
emit2("ld h,!*hl");
emit2("ld l,a");
}
+ else if (IS_Z80 && aop->type == AOP_IY) {
+ /* Instead of fetching relative to IY, just grab directly
+ from the address IY refers to */
+ char *l = aopGetLitWordLong(aop, offset, FALSE);
+ wassert(l);
+ emit2("ld %s,(%s)", _pairs[pairId].name, l);
+ }
else {
emitcode("ld", "%s,%s", _pairs[pairId].l, aopGet(aop, offset, FALSE));
emitcode("ld", "%s,%s", _pairs[pairId].h, aopGet(aop, offset+1, FALSE));
switch (aop->type) {
case AOP_IY:
+ fetchLitPair(pairId, aop, 0);
+ break;
case AOP_HL:
fetchLitPair(pairId, aop, offset);
_G.pairs[pairId].offset = offset;
}
return "!zero";
+ case AOP_HLREG:
+ wassert(offset < 2);
+ return aop->aopu.aop_str[offset];
+
case AOP_LIT:
return aopLiteral (aop->aopu.aop_lit,offset);
break;
case AOP_REG:
- emitcode("ld","%s,%s",
- aop->aopu.aop_reg[offset]->name,s);
+ if (!strcmp(s, "!*hl"))
+ emit2("ld %s,!*hl", aop->aopu.aop_reg[offset]->name);
+ else
+ emit2("ld %s,%s",
+ aop->aopu.aop_reg[offset]->name, s);
break;
case AOP_IY:
}
break;
+ case AOP_HLREG:
+ wassert(offset < 2);
+ emit2("ld %s,%s", aop->aopu.aop_str[offset], s);
+ break;
+
default :
werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
"aopPut got unsupported aop->type");
else {
offset = size;
while (size--) {
- l = aopGet(AOP(IC_LEFT(ic)), --offset, FALSE);
/* Simple for now - load into A and PUSH AF */
- emitcode("ld", "a,%s", l);
- emitcode("push", "af");
- emitcode("inc", "sp");
+ if (AOP(IC_LEFT(ic))->type == AOP_IY) {
+ char *l = aopGetLitWordLong(AOP(IC_LEFT(ic)), --offset, FALSE);
+ wassert(l);
+ emit2("ld a,(%s)", l);
+ }
+ else {
+ l = aopGet(AOP(IC_LEFT(ic)), --offset, FALSE);
+ emit2("ld a,%s", l);
+ }
+ emit2("push af");
+ emit2("inc sp");
_G.stack.pushed++;
}
}
}
offset = size;
while (size--) {
- l = aopGet(AOP(IC_LEFT(ic)), --offset, FALSE);
- emitcode("ld", "a,%s", l);
+ if (AOP(IC_LEFT(ic))->type == AOP_IY) {
+ char *l = aopGetLitWordLong(AOP(IC_LEFT(ic)), --offset, FALSE);
+ wassert(l);
+ emit2("ld a,(%s)", l);
+ }
+ else {
+ l = aopGet(AOP(IC_LEFT(ic)), --offset, FALSE);
+ emit2("ld a,%s", l);
+ }
emitcode("push", "af");
emitcode("inc", "sp");
_G.stack.pushed++;
if(bytelit != 0x0FFL)
emitcode("and","a,%s",
aopGet(AOP(right),offset,FALSE));
+ else
+ /* For the flags */
+ emit2("or a,a");
emit2("!shortjp nz,!tlabel", tlbl->key+100);
}
}
operand *result, int offr,
int shCount, int sign)
{
- if(sameRegs(AOP(result), AOP(left)) &&
- ((offl + MSB16) == offr)){
- wassert(0);
- } else {
- movLeft2Result(left, offl, result, offr, 0);
- movLeft2Result(left, offl+1, result, offr+1, 0);
- }
+ movLeft2Result(left, offl, result, offr, 0);
+ movLeft2Result(left, offl+1, result, offr+1, 0);
if (sign) {
wassert(0);
if (shCount >= 8) {
shCount -= 8 ;
if (shCount) {
- wassert(0);
shiftR1Left2Result(left, MSB16, result, LSB,
shCount, sign);
}
if(AOP_TYPE(right) == AOP_LIT)
lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
- if (isPair(AOP(result)) && isLitWord(AOP(right))) {
- emitcode("ld", "%s,%s", getPairName(AOP(result)), aopGetWord(AOP(right), 0));
+ if (isPair(AOP(result))) {
+ fetchPair(getPairId(AOP(result)), AOP(right));
}
else if((size > 1) &&
(AOP_TYPE(result) != AOP_REG) &&
offset++;
}
}
- else if (size == 2 && requiresHL(AOP(right)) && requiresHL(AOP(result))) {
+ else if (size == 2 && requiresHL(AOP(right)) && requiresHL(AOP(result)) && IS_GB) {
/* 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));
remiCodeFromeBBlock(ebp,ic);
return 1;
-
}
/** Scanning backwards looks for first assig found.
goto accuse ;
return ;
accuse:
- OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
+ OP_SYMBOL(IC_RESULT(ic))->accuse = ACCUSE_A;
+}
+
+static void packRegsForHLUse (iCode *ic)
+{
+ iCode *uic;
+
+ if (IS_GB)
+ return;
+
+ /* has only one definition */
+ if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1)
+ return ;
+
+ /* has only one use */
+ if (bitVectnBitsOn(OP_USES(IC_RESULT(ic))) > 1)
+ return ;
+
+ /* and the usage immediately follows this iCode */
+ if (!(uic = hTabItemWithKey(iCodehTab,
+ bitVectFirstBit(OP_USES(IC_RESULT(ic))))))
+ return ;
+
+ if (ic->next != uic)
+ return ;
+
+ if (ic->op == ADDRESS_OF && uic->op == IPUSH)
+ goto hluse;
+ if (ic->op == CALL && IC_LEFT(ic)->parmBytes == 0 && (uic->op == '-' || uic->op == '+'))
+ goto hluse;
+ return;
+ hluse:
+ printf("Hey, it worked!\n");
+ OP_SYMBOL(IC_RESULT(ic))->accuse = ACCUSE_HL;
}
bool opPreservesA(iCode *ic, iCode *uic)
/** Pack registers for acc use.
When the result of this operation is small and short lived it may
- be able to be stored in the accumelator.
+ be able to be stored in the accumulator.
Note that the 'A preserving' list is currently emperical :)e
*/
only one operand or has two operands but one is literal & the
result of that operation is not on stack then we can leave the
result of this operation in acc:b combination */
+
+ if (IS_ITEMP(IC_RESULT(ic))) {
+ packRegsForHLUse(ic);
+ }
#if 0
if ((IS_ARITHMETIC_OP(ic)
|| IS_BITWISE_OP(ic)