static void
emitDebug (const char *szFormat,...)
{
+ if (!options.verboseAsm)
+ return;
if (!DISABLE_DEBUG)
{
va_list ap;
static void
_pop (PAIR_ID pairId)
{
- emit2 ("pop %s", _pairs[pairId].name);
- _G.stack.pushed -= 2;
- spillPair (pairId);
+ if (pairId != PAIR_INVALID)
+ {
+ emit2 ("pop %s", _pairs[pairId].name);
+ _G.stack.pushed -= 2;
+ spillPair (pairId);
+ }
}
void
/* otherwise it is fairly simple */
if (!IS_FLOAT (val->type))
{
- unsigned long v = (unsigned long) floatFromVal (val);
+ unsigned long v = ulFromVal (val);
if (offset == 2)
{
}
else
{
- emit2 ("ld %s,%s", _pairs[pairId].l, aopGet (aop, offset, FALSE));
- emit2 ("ld %s,%s", _pairs[pairId].h, aopGet (aop, offset + 1, FALSE));
+ /* Swapping register contents within register pair */
+ if(!strcmp(aopGet (aop, offset, FALSE), _pairs[pairId].h))
+ {
+ 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);
+ }
+ else
+ {
+ emit2 ("ld %s,%s", _pairs[pairId].l, aopGet (aop, offset, FALSE));
+ emit2 ("ld %s,%s", _pairs[pairId].h, aopGet (aop, offset + 1, FALSE));
+ }
}
/* PENDING: check? */
if (pairId == PAIR_HL)
#define AOP_TYPE(op) AOP(op)->type
#define AOP_SIZE(op) AOP(op)->size
#define AOP_NEEDSACC(x) (AOP(x) && ((AOP_TYPE(x) == AOP_CRY) || (AOP_TYPE(x) == AOP_SFR)))
+#define AOP_IS_PAIRPTR(x, p) (AOP_TYPE (x) == AOP_PAIRPTR && AOP (x)->aopu.aop_pairId == p)
static void
commitPair (asmop * aop, PAIR_ID id)
/** Take the value in carry and put it into a register
*/
void
-outBitCLong (operand * result, bool swap_sense)
+outBitC (operand * result)
{
/* if the result is bit */
if (AOP_TYPE (result) == AOP_CRY)
{
- wassertl (0, "Tried to write carry to a bit");
+ if (!IS_OP_RUONLY (result))
+ aopPut (AOP (result), "c", 0);
}
else
{
emit2 ("ld a,!zero");
emit2 ("rla");
- if (swap_sense)
- emit2 ("xor a,!immedbyte", 1);
outAcc (result);
}
}
-void
-outBitC (operand * result)
-{
- outBitCLong (result, FALSE);
-}
-
/*-----------------------------------------------------------------*/
/* toBoolean - emit code for orl a,operator(sizeop) */
/*-----------------------------------------------------------------*/
aopPut (AOP (oper), _fReturn[size], size-1);
size--;
}
- while (size--)
+ while(size--)
{
aopPut (AOP (oper), _fReturn[size], size);
}
char *l = aopGetLitWordLong (AOP (IC_LEFT (ic)), --offset, FALSE);
wassert (l);
emit2 ("ld a,(%s)", l);
+ emit2 ("push af");
}
else
{
l = aopGet (AOP (IC_LEFT (ic)), --offset, FALSE);
- emit2 ("ld a,%s", l);
+ if (!strcmp(l, "b"))
+ emit2 ("push bc");
+ else if (!strcmp(l, "d"))
+ emit2 ("push de");
+ else if (!strcmp(l, "h"))
+ emit2 ("push hl");
+ else
+ {
+ emit2 ("ld a,%s", l);
+ emit2 ("push af");
+ }
}
- emit2 ("push af");
emit2 ("inc sp");
_G.stack.pushed++;
}
/* Mark the registers as restored. */
_G.saves.saved = FALSE;
- /* if we need assign a result value */
- if ((IS_ITEMP (IC_RESULT (ic)) &&
- (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
- OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
- IS_TRUE_SYMOP (IC_RESULT (ic)))
- {
-
- aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
-
- assignResultValue (IC_RESULT (ic));
-
- freeAsmop (IC_RESULT (ic), NULL, ic);
- }
-
/* adjust the stack for parameters if required */
if (ic->parmBytes)
{
}
}
+ /* if we need assign a result value */
+ if ((IS_ITEMP (IC_RESULT (ic)) &&
+ (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
+ OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
+ IS_TRUE_SYMOP (IC_RESULT (ic)))
+ {
+ aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+
+ assignResultValue (IC_RESULT (ic));
+
+ freeAsmop (IC_RESULT (ic), NULL, ic);
+ }
+
spillCached ();
if (IC_RESULT (ic))
{
else if (sym->stack && IS_GB && sym->stack > -INT8MIN)
emit2 ("!enterxl", sym->stack);
else if (sym->stack)
- emit2 ("!enterx", sym->stack);
+ {
+ if ((optimize.codeSize && sym->stack <= 8) || sym->stack <= 4)
+ {
+ int stack = sym->stack;
+ emit2 ("!enter");
+ while (stack > 1)
+ {
+ emit2 ("push af");
+ stack -= 2;
+ }
+ if(stack > 0)
+ emit2 ("dec sp");
+ }
+ else
+ emit2 ("!enterx", sym->stack);
+ }
else
emit2 ("!enter");
emitDebug ("; genPlusIncr");
- icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
/* If result is a pair */
if (resultId != PAIR_INVALID)
if (genPlusIncr (ic) == TRUE)
goto release;
- emitDebug ("; Can't optimise plus by inc, falling back to the normal way");
-
size = getDataSize (IC_RESULT (ic));
/* Special case when left and right are constant */
{
fetchPair (PAIR_HL, AOP (IC_LEFT (ic)));
emit2 ("add hl,%s", getPairName (AOP (IC_RIGHT (ic))));
- spillCached();
+ spillPair (PAIR_HL);
+ commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
+ goto release;
+ }
+
+ if (isPair (AOP (IC_LEFT (ic))) && AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT && getPairId (AOP (IC_LEFT (ic))) != PAIR_HL)
+ {
+ fetchPair (PAIR_HL, AOP (IC_RIGHT (ic)));
+ emit2 ("add hl,%s", getPairName (AOP (IC_LEFT (ic))));
+ spillPair (PAIR_HL);
commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
goto release;
}
setupToPreserveCarry (ic);
- while (size--)
+ /* This is ugly, but it fixes the worst code generation bug on Z80. */
+ /* Probably something similar has to be done for addition of larger numbers, too. */
+ if(size == 2)
{
- if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC)
+ _moveA (aopGet (AOP (IC_LEFT (ic)), 0, FALSE));
+ emit2 ("add a,%s", aopGet (AOP (IC_RIGHT (ic)), 0, FALSE));
+ if(strcmp (aopGet (AOP (IC_RESULT (ic)), 0, FALSE), aopGet (AOP (IC_LEFT (ic)), 1, FALSE)))
{
- _moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE));
- if (offset == 0)
- 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", 0);
+ _moveA (aopGet (AOP (IC_LEFT (ic)), 1, FALSE));
}
else
{
- _moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE));
- if (offset == 0)
- emit2 ("add a,%s",
- aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
+ emitDebug ("; Addition result is in same register as operand of next addition.");
+ if(strchr (aopGet (AOP (IC_RESULT (ic)), 0, FALSE), 'c') ||
+ strchr (aopGet (AOP (IC_RESULT (ic)), 0, FALSE), 'b') )
+ {
+ emit2 ("push de");
+ emit2 ("ld e, a");
+ emit2 ("ld a, %s", aopGet (AOP (IC_LEFT (ic)), 1, FALSE));
+ emit2 ("ld d, a");
+ emit2 ("ld a, e");
+ emit2 ("ld %s, a", aopGet (AOP (IC_RESULT (ic)), 0, FALSE));
+ emit2 ("ld a, d");
+ emit2 ("pop de");
+ }
else
- emit2 ("adc a,%s",
- aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
+ {
+ emit2 ("push bc");
+ emit2 ("ld c, a");
+ emit2 ("ld a, %s", aopGet (AOP (IC_LEFT (ic)), 1, FALSE));
+ emit2 ("ld b, a");
+ emit2 ("ld a, c");
+ emit2 ("ld %s, a", aopGet (AOP (IC_RESULT (ic)), 0, FALSE));
+ 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);
+ goto release;
+ }
+
+ while (size--)
+ {
+ _moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE));
+ if (offset == 0)
+ 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++);
}
/* if the literal value of the right hand side
is greater than 4 then it is not worth it */
- if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 2)
+ if ((icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 2)
return FALSE;
size = getDataSize (IC_RESULT (ic));
}
else
{
- lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ lit = ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
lit = -(long) lit;
}
{
/* first add without previous c */
if (!offset)
- emit2 ("add a,!immedbyte", (unsigned int) (lit & 0x0FFL));
+ {
+ if (size == 0 && (unsigned int) (lit & 0x0FFL) == 0xFF)
+ emit2 ("dec a");
+ else
+ emit2 ("add a,!immedbyte", (unsigned int) (lit & 0x0FFL));
+ }
else
emit2 ("adc a,!immedbyte", (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
}
wassertl (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT, "Right must be a literal");
- val = (int)floatFromVal ( AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ val = (int) ulFromVal ( AOP (IC_RIGHT (ic))->aopu.aop_lit);
// wassertl (val > 0, "Multiply must be positive");
wassertl (val != 1, "Can't multiply by 1");
_G.stack.pushedDE = TRUE;
}
- if ( AOP_SIZE (IC_LEFT (ic)) == 1 && !SPEC_USIGN (getSpec (operandType ( IC_LEFT (ic)))))
+ if (byteResult)
+ emit2 ("ld a,%s", aopGet (AOP (IC_LEFT (ic)), LSB, FALSE));
+ else if ( AOP_SIZE (IC_LEFT (ic)) == 1 && !SPEC_USIGN (getSpec (operandType ( IC_LEFT (ic)))))
{
emit2 ("ld e,%s", aopGet (AOP (IC_LEFT (ic)), LSB, FALSE));
if (!byteResult)
i = val;
- /* Fully unroled version of mul.s. Not the most efficient.
- */
for (count = 0; count < 16; count++)
{
if (count != 0 && active)
{
- emit2 ("add hl,hl");
+ if (byteResult)
+ emit2 ("add a,a");
+ else
+ emit2 ("add hl,hl");
}
if (i & 0x8000U)
{
if (active == FALSE)
{
- emit2 ("ld l,e");
- if (!byteResult)
- emit2 ("ld h,d");
+ if (byteResult)
+ emit2("ld e,a");
+ else
+ {
+ emit2 ("ld l,e");
+ emit2 ("ld h,d");
+ }
}
else
{
- emit2 ("add hl,de");
+ if (byteResult)
+ emit2 ("add a,e");
+ else
+ emit2 ("add hl,de");
}
active = TRUE;
}
i <<= 1;
}
- spillCached();
+ spillPair(PAIR_HL);
if (IS_Z80 && _G.stack.pushedDE)
{
}
if (byteResult)
- aopPut (AOP (IC_RESULT (ic)), _pairs[PAIR_HL].l, 0);
+ aopPut (AOP (IC_RESULT (ic)), "a", 0);
else
commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
{
if (AOP_TYPE (right) == AOP_LIT)
{
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
/* optimize if(x < 0) or if(x >= 0) */
if (lit == 0L)
{
bool fDidXor = FALSE;
if (AOP_TYPE (left) == AOP_LIT)
{
- unsigned long lit = (unsigned long)
- floatFromVal (AOP (left)->aopu.aop_lit);
+ unsigned long lit = ulFromVal (AOP (left)->aopu.aop_lit);
emit2 ("ld %s,!immedbyte", _fTmp[0],
0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL));
}
}
if (AOP_TYPE (right) == AOP_LIT)
{
- unsigned long lit = (unsigned long)
- floatFromVal (AOP (right)->aopu.aop_lit);
+ unsigned long lit = ulFromVal (AOP (right)->aopu.aop_lit);
emit2 ("ld %s,!immedbyte", _fTmp[1],
0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL));
}
{
int size, offset = 0;
unsigned long lit = 0L;
- bool swap_sense = FALSE;
/* if left & right are bit variables */
if (AOP_TYPE (left) == AOP_CRY &&
if (AOP_TYPE (right) == AOP_LIT)
{
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
/* optimize if(x < 0) or if(x >= 0) */
if (lit == 0)
{
}
if (ifx)
{
- genIfxJump (ifx, swap_sense ? "c" : "nc");
+ genIfxJump (ifx, "nc");
return;
}
}
/* Shift the sign bit up into carry */
emit2 ("rlca");
}
- outBitCLong (result, swap_sense);
+ outBitC (result);
}
else
{
if (IS_GB)
{
emit2 ("rlca");
- genIfxJump (ifx, swap_sense ? "nc" : "c");
+ genIfxJump (ifx, "c");
}
else
{
- genIfxJump (ifx, swap_sense ? "p" : "m");
+ genIfxJump (ifx, "m");
}
}
else
{
- genIfxJump (ifx, swap_sense ? "nc" : "c");
+ genIfxJump (ifx, "c");
}
}
else
/* Shift the sign bit up into carry */
emit2 ("rlca");
}
- outBitCLong (result, swap_sense);
+ outBitC (result);
}
/* leave the result in acc */
}
/*-----------------------------------------------------------------*/
/* gencjneshort - compare and jump if not equal */
+/* returns pair that still needs to be popped */
/*-----------------------------------------------------------------*/
-static void
+static PAIR_ID
gencjneshort (operand * left, operand * right, symbol * lbl)
{
int size = max (AOP_SIZE (left), AOP_SIZE (right));
left = t;
}
- if (AOP_TYPE (right) == AOP_LIT)
- {
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
- }
-
/* if the right side is a literal then anything goes */
- if (AOP_TYPE (right) == AOP_LIT &&
- AOP_TYPE (left) != AOP_DIR)
+ if (AOP_TYPE (right) == AOP_LIT)
{
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
if (lit == 0)
{
- emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE));
+ _moveA (aopGet (AOP (left), offset, FALSE));
if (size > 1)
{
while (--size)
}
}
}
- /* if the right side is in a register or in direct space or
- if the left is a pointer register & right is not */
+ /* if the right side is in a register or
+ pointed to by HL, IX or IY */
else if (AOP_TYPE (right) == AOP_REG ||
- AOP_TYPE (right) == AOP_DIR ||
- (AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT))
+ AOP_TYPE (right) == AOP_HL ||
+ AOP_TYPE (right) == AOP_IY ||
+ AOP_TYPE (right) == AOP_STK ||
+ AOP_IS_PAIRPTR (right, PAIR_HL) ||
+ AOP_IS_PAIRPTR (right, PAIR_IX) ||
+ AOP_IS_PAIRPTR (right, PAIR_IY))
{
while (size--)
{
_moveA (aopGet (AOP (left), offset, FALSE));
- if (/*AOP_TYPE (left) == AOP_DIR &&*/ AOP_TYPE (right) == AOP_LIT &&
+ if (AOP_TYPE (right) == AOP_LIT &&
((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0))
{
- /* 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);
}
offset++;
}
}
+ /* right is in direct space or a pointer reg, need both a & b */
else
{
- /* right is a pointer reg need both a & b */
- /* PENDING: is this required? */
+ PAIR_ID pair;
+ for (pair = PAIR_BC; pair <= PAIR_HL; pair++)
+ {
+ if (((AOP_TYPE (left) != AOP_PAIRPTR) || (AOP (left)->aopu.aop_pairId != pair)) &&
+ ((AOP_TYPE (right) != AOP_PAIRPTR) || (AOP (right)->aopu.aop_pairId != pair)))
+ {
+ break;
+ }
+ }
+ _push (pair);
while (size--)
{
+ emit2 ("; direct compare");
+ _emitMove (_pairs[pair].l, aopGet (AOP (left), offset, FALSE));
_moveA (aopGet (AOP (right), offset, FALSE));
- emit2 ("cp %s", aopGet (AOP (left), offset, FALSE));
+ emit2 ("sub %s", _pairs[pair].l);
emit2 ("!shortjp NZ,!tlabel", lbl->key + 100);
offset++;
}
+ return pair;
}
+ return PAIR_INVALID;
}
/*-----------------------------------------------------------------*/
{
symbol *tlbl = newiTempLabel (NULL);
- gencjneshort (left, right, lbl);
+ PAIR_ID pop = gencjneshort (left, right, lbl);
/* PENDING: ?? */
emit2 ("ld a,!one");
emitLabel (lbl->key + 100);
emit2 ("xor a,a");
emitLabel (tlbl->key + 100);
+ _pop (pop);
}
/*-----------------------------------------------------------------*/
}
else
{
+ PAIR_ID pop;
tlbl = newiTempLabel (NULL);
- gencjneshort (left, right, tlbl);
+ pop = gencjneshort (left, right, tlbl);
if (IC_TRUE (ifx))
{
+ _pop (pop);
emit2 ("jp !tlabel", IC_TRUE (ifx)->key + 100);
emitLabel (tlbl->key + 100);
+ _pop (pop);
}
else
{
/* PENDING: do this better */
symbol *lbl = newiTempLabel (NULL);
+ _pop (pop);
emit2 ("!shortjp !tlabel", lbl->key + 100);
emitLabel (tlbl->key + 100);
+ _pop (pop);
emit2 ("jp !tlabel", IC_FALSE (ifx)->key + 100);
emitLabel (lbl->key + 100);
}
left = tmp;
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
left = tmp;
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
left = tmp;
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
genInline (iCode * ic)
{
char *buffer, *bp, *bp1;
+ bool inComment = FALSE;
_G.lines.isInline += (!options.asmpeep);
- buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
- strcpy (buffer, IC_INLINE (ic));
+ buffer = bp = bp1 = Safe_strdup (IC_INLINE (ic));
/* emit each line as a code */
while (*bp)
{
- if (*bp == '\n')
+ switch (*bp)
{
+ case ';':
+ inComment = TRUE;
+ ++bp;
+ break;
+
+ case '\n':
+ inComment = FALSE;
*bp++ = '\0';
emit2 (bp1);
bp1 = bp;
- }
- else
- {
- if (*bp == ':')
+ break;
+
+ default:
+ /* Add \n for labels, not dirs such as c:\mydir */
+ if (!inComment && (*bp == ':') && (isspace((unsigned char)bp[1])))
{
- bp++;
+ ++bp;
*bp = '\0';
- bp++;
+ ++bp;
emit2 (bp1);
bp1 = bp;
}
else
- bp++;
+ ++bp;
+ break;
}
}
if (bp1 != bp)
emit2 (bp1);
+
+ Safe_free (buffer);
+
_G.lines.isInline -= (!options.asmpeep);
}
int shCount, int is_signed)
{
int size = 2;
- symbol *tlbl, *tlbl1;
+ symbol *tlbl;
movLeft2Result (left, offl, result, offr, 0);
movLeft2Result (left, offl + 1, result, offr + 1, 0);
/* if (AOP(result)->type == AOP_REG) { */
tlbl = newiTempLabel (NULL);
- tlbl1 = newiTempLabel (NULL);
/* Left is already in result - so now do the shift */
- if (shCount <= 4)
+ /* Optimizing for speed by default. */
+ if (!optimize.codeSize || shCount <= 2)
{
while (shCount--)
{
}
else
{
- emit2 ("ld a,!immedbyte+1", shCount);
- emit2 ("!shortjp !tlabel", tlbl1->key + 100);
+ emit2 ("ld a,!immedbyte", shCount);
+
emitLabel (tlbl->key + 100);
emitRsh2 (AOP (result), size, is_signed);
- emitLabel (tlbl1->key + 100);
emit2 ("dec a");
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
}
operand * result, int offr, int shCount)
{
const char *l;
- l = aopGet (AOP (left), offl, FALSE);
- _moveA (l);
- /* shift left accumulator */
- AccLsh (shCount);
- aopPut (AOP (result), "a", offr);
-}
+ /* If operand and result are the same we can shift in place.
+ However shifting in acc using add is cheaper than shifting
+ in place using sla; when shifting by more than 2 shifting in
+ acc is worth the additional effort for loading from/to acc. */
+ if (sameRegs (AOP (left), AOP (result)) && shCount <= 2 && offr == offl)
+ {
+ while (shCount--)
+ emit2 ("sla %s", aopGet (AOP (result), 0, FALSE));
+ }
+ else
+ {
+ l = aopGet (AOP (left), offl, FALSE);
+ _moveA (l);
+ /* shift left accumulator */
+ AccLsh (shCount);
+ aopPut (AOP (result), "a", offr);
+ }
+}
/*-----------------------------------------------------------------*/
/* genlshTwo - left shift two bytes by known amount */
operand * result,
iCode * ic)
{
- int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
int size;
freeAsmop (right, NULL, ic);
iCode * ic,
int sign)
{
- int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
int size;
freeAsmop (right, NULL, ic);
{
/* Case with a bitfield length <8 and literal source
*/
- litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
litval <<= bstr;
litval &= (~mask) & 0xff;
emit2 ("ld a,!*pair", _pairs[pair].name);
{
/* Case with partial byte and literal source
*/
- litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
litval >>= (blen-rlen);
litval &= (~mask) & 0xff;
emit2 ("ld a,!*pair", _pairs[pair].name);
{
if (sym->onStack)
{
- spillCached ();
+ spillPair (PAIR_HL);
if (sym->stack <= 0)
{
setupPairFromSP (PAIR_HL, sym->stack + _G.stack.pushed + _G.stack.offset);
}
else
{
- spillCached ();
+ spillPair (PAIR_HL);
if (sym->onStack)
{
/* if it has an offset then we need to compute it */
if (AOP_TYPE (right) == AOP_LIT)
{
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
}
if (isPair (AOP (result)))
emit2 ("ld e,%s", l);
emit2 ("ld d,!zero");
jtab = newiTempLabel (NULL);
- spillCached ();
+ spillPair (PAIR_HL);
emit2 ("ld hl,!immed!tlabel", jtab->key + 100);
emit2 ("add hl,de");
emit2 ("add hl,de");
}
if (options.iCodeInAsm)
{
- char *iLine = printILine(ic);
+ const char *iLine = printILine(ic);
emit2 (";ic:%d: %s", ic->key, iLine);
dbuf_free(iLine);
}
wassert (aop->type == AOP_LIT);
wassert (!IS_FLOAT (val->type));
- v = (unsigned long) floatFromVal (val);
+ v = ulFromVal (val);
if (xor)
v ^= 0x8000;