{
if (pairId == PAIR_HL || pairId == PAIR_IY)
{
- if (_G.pairs[pairId].last_type == left->type)
+ if ((_G.pairs[pairId].last_type == AOP_IMMD && left->type == AOP_IMMD) ||
+ (_G.pairs[pairId].last_type == AOP_IY && left->type == AOP_IY))
{
if (_G.pairs[pairId].base && !strcmp (_G.pairs[pairId].base, base))
{
if (pairId == PAIR_HL && abs (_G.pairs[pairId].offset - offset) < 3)
{
adjustPair (pair, &_G.pairs[pairId].offset, offset);
- return;
+ goto adjusted;
}
if (pairId == PAIR_IY && (offset >= INT8MIN && offset <= INT8MAX))
{
- return;
+ goto adjusted;
}
}
}
}
+
+ if (pairId == PAIR_HL && left->type == AOP_LIT && _G.pairs[pairId].last_type == AOP_LIT &&
+ !IS_FLOAT (left->aopu.aop_lit->type) && offset == 0 && _G.pairs[pairId].offset == 0)
+ {
+ unsigned new_low, new_high, old_low, old_high;
+ unsigned long v_new = ulFromVal (left->aopu.aop_lit);
+ unsigned long v_old = strtoul (_G.pairs[pairId].base, NULL, 0);
+ new_low = (v_new >> 0) & 0xff;
+ new_high = (v_new >> 8) & 0xff;
+ old_low = (v_old >> 0) & 0xff;
+ old_high = (v_old >> 8) & 0xff;
+
+ /* Change lower byte only. */
+ if(new_high == old_high)
+ {
+ emit2("ld l, %s", aopGet (left, 0, FALSE));
+ goto adjusted;
+ }
+ /* Change upper byte only. */
+ else if(new_low == old_low)
+ {
+ emit2("ld h, %s", aopGet (left, 1, FALSE));
+ goto adjusted;
+ }
+ }
+
+
_G.pairs[pairId].last_type = left->type;
_G.pairs[pairId].base = traceAlloc(&_G.trace.aops, Safe_strdup (base));
_G.pairs[pairId].offset = offset;
}
/* Both a lit on the right and a true symbol on the left */
emit2 ("ld %s,!hashedstr", pair, l);
+ return;
+
+adjusted:
+ _G.pairs[pairId].last_type = left->type;
+ _G.pairs[pairId].base = traceAlloc(&_G.trace.aops, Safe_strdup (base));
+ _G.pairs[pairId].offset = offset;
}
static PAIR_ID
}
else
{
- /* Swapping register contents within register pair */
- if(!strcmp(aopGet (aop, offset, FALSE), _pairs[pairId].h))
+ /* Operand resides (partially) in the pair */
+ if(!strcmp(aopGet (aop, offset + 1, FALSE), _pairs[pairId].l))
{
- emit2 ("ld a,%s",aopGet (aop, offset + 1, FALSE));
+ emit2 ("ld a,%s", aopGet (aop, offset + 1, FALSE));
emit2 ("ld %s,%s", _pairs[pairId].l, aopGet (aop, offset, FALSE));
emit2 ("ld %s,a", _pairs[pairId].h);
}
_G.pairs[pairId].last_type = aop->type;
}
+/* Can be used for local labels where Code generation takes care of spilling */
+static void
+emitLabelNoSpill (int key)
+{
+ emit2 ("!tlabeldef", key);
+ _G.lines.current->isLabel = 1;
+}
+
static void
emitLabel (int key)
{
{
fetchHL (AOP (IC_LEFT (ic)));
emit2 ("push hl");
- spillPair (PAIR_HL);
_G.stack.pushed += 2;
goto release;
}
{
fetchPairLong (PAIR_HL, AOP (IC_LEFT (ic)), ic, 2);
emit2 ("push hl");
- spillPair (PAIR_HL);
_G.stack.pushed += 2;
fetchPairLong (PAIR_HL, AOP (IC_LEFT (ic)), ic, 0);
emit2 ("push hl");
- spillPair (PAIR_HL);
_G.stack.pushed += 2;
goto release;
}
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
}
}
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
return TRUE;
}
{
emit2 ("!shortjp Z,!tlabel", tlbl->key + 100);
emit2 ("ld a,!one");
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
outAcc (result);
}
}
emit2 ("ld a, b");
emit2 ("pop bc");
}
-
+
}
emit2 ("adc a,%s", aopGet (AOP (IC_RIGHT (ic)), 1, FALSE));
aopPut (AOP (IC_RESULT (ic)), "a", 1);
{
_moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE));
if (offset == 0)
- emit2 ("add a,%s", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
+ {
+ if(size == 0 && AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT && ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) == 1)
+ emit2 ("inc a");
+ else
+ emit2 ("add a,%s", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
+ }
else
emit2 ("adc a,%s", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
aopPut (AOP (IC_RESULT (ic)), "a", offset++);
emit2 ("ld l,#0x00");
emit2 ("ld d,l");
emit2 ("ld b,#0x08");
- emitLabel (tlbl1->key + 100);
+ emitLabelNoSpill (tlbl1->key + 100);
emit2 ("add hl,hl");
emit2 ("jp NC,!tlabel", tlbl2->key + 100);
emit2 ("add hl,de");
- emitLabel (tlbl2->key + 100);
+ emitLabelNoSpill (tlbl2->key + 100);
emit2 ("djnz !tlabel", tlbl1->key + 100);
spillPair(PAIR_HL);
}
else
{
- emit2 ("sub %s", aopGet (AOP (right), offset, FALSE));
+ emit2 ("sub a,%s", aopGet (AOP (right), offset, FALSE));
emit2 ("jp NZ,!tlabel", lbl->key + 100);
}
offset++;
emit2 ("; direct compare");
_emitMove (_pairs[pair].l, aopGet (AOP (left), offset, FALSE));
_moveA (aopGet (AOP (right), offset, FALSE));
- emit2 ("sub %s", _pairs[pair].l);
+ emit2 ("sub a,%s", _pairs[pair].l);
emit2 ("!shortjp NZ,!tlabel", lbl->key + 100);
offset++;
}
emit2 ("!shortjp !tlabel", tlbl->key + 100);
emitLabel (lbl->key + 100);
emit2 ("xor a,a");
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
_pop (pop);
}
{
_pop (pop);
emit2 ("jp !tlabel", IC_TRUE (ifx)->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
_pop (pop);
}
else
symbol *lbl = newiTempLabel (NULL);
_pop (pop);
emit2 ("!shortjp !tlabel", lbl->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
_pop (pop);
emit2 ("jp !tlabel", IC_FALSE (ifx)->key + 100);
- emitLabel (lbl->key + 100);
+ emitLabelNoSpill (lbl->key + 100);
}
}
/* mark the icode as generated */
_toBoolean (left);
emit2 ("!shortjp Z,!tlabel", tlbl->key + 100);
_toBoolean (right);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
outBitAcc (result);
}
_toBoolean (left);
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
_toBoolean (right);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
outBitAcc (result);
}
{
symbol *nlbl = newiTempLabel (NULL);
emit2 ("jp !tlabel", nlbl->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
emit2 ("jp !tlabel", IC_TRUE (ic)->key + 100);
- emitLabel (nlbl->key + 100);
+ emitLabelNoSpill (nlbl->key + 100);
}
else
{
emit2 ("jp !tlabel", IC_FALSE (ic)->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
}
ic->generated = 1;
}
/* For the flags */
emit2 ("or a,a");
}
+ if (size || ifx) /* emit jmp only, if it is actually used */
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
}
offset++;
bytelit = (lit >> (offset * 8)) & 0x0FFL;
_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);
+
+ if (bytelit != 0)
+ { /* FIXME, allways true, shortcut possible */
+ emit2 ("or a,%s", aopGet (AOP (right), offset, FALSE));
+ }
+ else
+ {
+ /* For the flags */
+ emit2 ("or a,a");
+ }
+
+ if (ifx) /* emit jmp only, if it is actually used */
+ emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
offset++;
}
{
emit2 ("ld a,!immedbyte", shCount);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
emitRsh2 (AOP (result), size, is_signed);
{
emit2 ("ld a,!immedbyte+1", shCount);
emit2 ("!shortjp !tlabel", tlbl1->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
}
while (size--)
}
if (shCount > 1)
{
- emitLabel (tlbl1->key + 100);
+ emitLabelNoSpill (tlbl1->key + 100);
emit2 ("dec a");
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
}
_pop (PAIR_AF);
emit2 ("!shortjp !tlabel", tlbl1->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
l = aopGet (AOP (result), offset, FALSE);
while (size--)
}
offset++;
}
- emitLabel (tlbl1->key + 100);
+ emitLabelNoSpill (tlbl1->key + 100);
emit2 ("dec a");
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
_pop (PAIR_AF);
emit2 ("!shortjp !tlabel", tlbl1->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
while (size--)
{
l = aopGet (AOP (result), offset--, FALSE);
emit2 ("rr %s", l);
}
}
- emitLabel (tlbl1->key + 100);
+ emitLabelNoSpill (tlbl1->key + 100);
emit2 ("dec a");
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
emit2 ("bit %d,a", blen - 1);
emit2 ("jp Z,!tlabel", tlbl->key + 100);
emit2 ("or a,!immedbyte", (unsigned char) (0xff << blen));
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
}
aopPut (AOP (result), "a", offset++);
goto finish;
{
/* signed bitfield */
symbol *tlbl = newiTempLabel (NULL);
-
- emit2 ("bit %d,a", blen - 1);
+ emit2 ("bit %d,a", blen - 1 - 8);
emit2 ("jp Z,!tlabel", tlbl->key + 100);
- emit2 ("or a,!immedbyte", (unsigned char) (0xff << blen));
- emitLabel (tlbl->key + 100);
+ emit2 ("or a,!immedbyte", (unsigned char) (0xff << (blen - 8)));
+ emitLabelNoSpill (tlbl->key + 100);
}
emit2 ("ld h,a");
spillPair (PAIR_HL);
emit2 ("bit %d,a", rlen - 1);
emit2 ("jp Z,!tlabel", tlbl->key + 100);
emit2 ("or a,!immedbyte", (unsigned char) (0xff << rlen));
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
}
aopPut (AOP (result), "a", offset++);
}
}
static void
-setupForBuiltin3 (iCode *ic, int nparams, operand **pparams)
+setupForMemcpy (iCode *ic, int nparams, operand **pparams)
{
PAIR_ID ids[NUM_PAIRS][NUM_PAIRS];
PAIR_ID dest[3] = {
{
fetchPair (dest[i], AOP (pparams[i]));
continue;
- }
+ }
}
}
}
}
}
-/*static void
-genBuiltInStrcpy (iCode *ic, int nParams, operand **pparams)
-{
- operand *from, *to;
- symbol *label;
- bool deInUse;
-
- wassertl (nParams == 2, "Built-in strcpy must have two parameters");
- to = pparams[0];
- from = pparams[1];
-
- deInUse = bitVectBitValue (ic->rMask, D_IDX) || bitVectBitValue(ic->rMask, E_IDX);
-
- _saveRegsForCall (ic, 0);
-
- setupForBuiltin3 (ic, nParams, pparams);
-
- label = newiTempLabel(NULL);
-
- emitLabel (label->key);
- emit2 ("ld a,(hl)");
- emit2 ("ldi");
- emit2 ("or a");
- emit2 ("!shortjp NZ,!tlabel ; 1", label->key);
-
- freeAsmop (from, NULL, ic->next);
- freeAsmop (to, NULL, ic);
-}*/
-
static void
genBuiltInMemcpy (iCode *ic, int nParams, operand **pparams)
{
operand *from, *to, *count;
- wassertl (nParams == 3, "Built-in memcpy must have three parameters");
+ wassertl (nParams == 3, "Built-in memcpy() must have three parameters");
to = pparams[2];
from = pparams[1];
count = pparams[0];
_saveRegsForCall (ic, 0);
- setupForBuiltin3 (ic, nParams, pparams);
+ setupForMemcpy (ic, nParams, pparams);
emit2 ("ldir");
freeAsmop (count, NULL, ic->next->next);
freeAsmop (from, NULL, ic);
+ spillPair (PAIR_HL);
+
_restoreRegsAfterCall();
/* if we need assign a result value */
/* which function is it */
bif = OP_SYMBOL(IC_LEFT(bi_iCode));
- /*if (strcmp(bif->name,"__builtin_strcpy")==0)
- {
- genBuiltInStrcpy(bi_iCode, nbi_parms, bi_parms);
- }
- else*/ if (strcmp(bif->name,"__builtin_memcpy")==0)
+ if (strcmp(bif->name,"__builtin_memcpy")==0)
{
genBuiltInMemcpy(bi_iCode, nbi_parms, bi_parms);
}