if (aop->type == AOP_DUMMY)
return;
-
+
+ if (aop->type == AOP_CRY) /* This can only happen if IFX was optimized */
+ return; /* away, so just toss the result */
+
switch (regidx)
{
case A_IDX:
/* ignore transfers at the same byte, unless its volatile */
if (srcaop->op && !isOperandVolatile (srcaop->op, FALSE)
&& dstaop->op && !isOperandVolatile (dstaop->op, FALSE)
- && operandsEqu(srcaop->op, dstaop->op) && srcofs == dstofs)
+ && operandsEqu(srcaop->op, dstaop->op) && srcofs == dstofs
+ && dstaop->type == srcaop->type)
return;
if (srcaop->stacked && srcaop->stk_aop[srcofs])
if (srcaop->type == AOP_LIT)
{
unsigned long lit;
- unsigned char bytemask;
+ unsigned long bytemask;
lit = (unsigned long) floatFromVal (srcaop->aopu.aop_lit);
bytemask = (lit >> (srcofs*8)) & 0xff;
/* else spill location */
if (sym->usl.spillLoc)
{
+ asmop *oldAsmOp = NULL;
+
if (sym->usl.spillLoc->aop
&& sym->usl.spillLoc->aop->size != getSize (sym->type))
{
/* force a new aop if sizes differ */
+ oldAsmOp = sym->usl.spillLoc->aop;
sym->usl.spillLoc->aop = NULL;
//printf ("forcing new aop\n");
}
sym->aop = op->aop = aop = aopForSym (ic, sym->usl.spillLoc, result);
+ if (sym->usl.spillLoc->aop->size != getSize (sym->type))
+ {
+ /* Don't reuse the new aop, go with the last one */
+ sym->usl.spillLoc->aop = oldAsmOp;
+ }
aop->size = getSize (sym->type);
aop->op = op;
aop->isaddr = op->isaddr;
flagsonly = FALSE;
}
break;
+ case AOP_LIT:
+ /* Higher levels should optimize this case away but let's be safe */
+ if ((unsigned long) floatFromVal (aop->aopu.aop_lit))
+ loadRegFromConst (hc08_reg_a, one);
+ else
+ loadRegFromConst (hc08_reg_a, zero);
+ hc08_freeReg(hc08_reg_a);
+ break;
default:
if (size==1)
{
}
/*-----------------------------------------------------------------*/
-/* genMinusDec :- does subtraction with deccrement if possible */
+/* genMinusDec :- does subtraction with decrement if possible */
/*-----------------------------------------------------------------*/
static bool
genMinusDec (iCode * ic)
/* left unsigned, right signed literal -- literal determines sign handling */
if (AOP_TYPE(right)==AOP_LIT && lUnsigned && !rUnsigned)
{
- signed char val=floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val=(signed char)floatFromVal (AOP (right)->aopu.aop_lit);
loadRegFromAop (hc08_reg_a, AOP (left), 0);
if (val < 0)
if (AOP_TYPE(right)==AOP_LIT && !rUnsigned)
{
- signed char val=floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val=(signed char)floatFromVal (AOP (right)->aopu.aop_lit);
/* AND literal negative */
if (val < 0) {
emitcode ("ldx", "#0x%02x", -val);
operand *left, *right, *result;
int size, offset;
symbol *tlbl, *tlbl1;
-// int i;
char *shift;
- regs *reg;
D(emitcode ("; genLeftShift",""));
more that 32 bits make no sense anyway, ( the
largest size of an object can be only 32 bits ) */
- aopOp (left, ic, FALSE);
aopOp (result, ic, FALSE);
+ aopOp (left, ic, FALSE);
+
+ if (sameRegs(AOP (right), AOP (result)) || IS_AOP_XA (AOP (result)))
+ AOP (result) = forceStackedAop (AOP (result));
/* now move the left to the result if they are not the
same */
if (!sameRegs (AOP (left), AOP (result)))
{
-
size = AOP_SIZE (result);
offset = 0;
while (size--)
offset = 0;
tlbl1 = newiTempLabel (NULL);
- reg = hc08_reg_a;
-
- loadRegFromAop (reg, AOP (right), 0);
- freeAsmop (right, NULL, ic, TRUE);
+ loadRegFromAop (hc08_reg_x, AOP (right), 0);
+ emitcode ("tstx", "");
emitBranch ("beq", tlbl1);
emitLabel (tlbl);
rmwWithAop (shift, AOP (result), offset);
shift="rol";
}
- rmwWithReg ("dec", reg);
+ rmwWithReg ("dec", hc08_reg_x);
emitBranch ("bne", tlbl);
emitLabel (tlbl1);
- hc08_freeReg (reg);
+ hc08_freeReg (hc08_reg_x);
freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
operand *right, *left, *result;
sym_link *retype;
int size, offset;
-// char *l;
symbol *tlbl, *tlbl1;
char *shift;
bool sign;
more that 32 bits make no sense anyway, ( the
largest size of an object can be only 32 bits ) */
- aopOp (left, ic, FALSE);
aopOp (result, ic, FALSE);
+ aopOp (left, ic, FALSE);
if (sameRegs(AOP (right), AOP (result)) || IS_AOP_XA (AOP (result)))
AOP (result) = forceStackedAop (AOP (result));
- size = AOP_SIZE (result);
- offset = size-1;
- while (size--)
+ /* now move the left to the result if they are not the
+ same */
+ if (!sameRegs (AOP (left), AOP (result)))
{
- transferAopAop (AOP (left), offset, AOP (result), offset);
- offset--;
+ size = AOP_SIZE (result);
+ offset = 0;
+ while (size--)
+ {
+ transferAopAop (AOP (left), offset, AOP (result), offset);
+ offset++;
+ }
}
+ freeAsmop (left, NULL, ic, TRUE);
tlbl = newiTempLabel (NULL);
size = AOP_SIZE (result);
loadRegFromAop (hc08_reg_x, AOP (right), 0);
emitcode ("tstx", "");
- emitcode ("beq", "%05d$", tlbl1->key + 100);
- emitcode ("", "%05d$:", tlbl->key + 100);
+ emitBranch ("beq", tlbl1);
+ emitLabel (tlbl);
+
shift= sign ? "asr" : "lsr";
for (offset=size-1;offset>=0;offset--)
{
shift="ror";
}
rmwWithReg ("dec", hc08_reg_x);
- emitcode ("bne","%05d$", tlbl->key + 100);
- emitcode ("", "%05d$:", tlbl1->key + 100);
+ emitBranch ("bne", tlbl);
+ emitLabel (tlbl1);
+ hc08_freeReg (hc08_reg_x);
freeAsmop (result, NULL, ic, TRUE);
- freeAsmop (left, NULL, ic, TRUE);
freeAsmop (right, NULL, ic, TRUE);
}
aopOp (cond, ic, FALSE);
+ /* If the condition is a literal, we can just do an unconditional */
+ /* branch or no branch */
+ if (AOP_TYPE (cond) == AOP_LIT)
+ {
+ unsigned long lit = (unsigned long) floatFromVal (AOP (cond)->aopu.aop_lit);
+ freeAsmop (cond, NULL, ic, TRUE);
+
+ /* if there was something to be popped then do it */
+ if (popIc)
+ genIpop (popIc);
+ if (lit)
+ {
+ if (IC_TRUE (ic))
+ emitBranch ("jmp", IC_TRUE (ic));
+ }
+ else
+ {
+ if (IC_FALSE (ic))
+ emitBranch ("jmp", IC_FALSE (ic));
+ }
+ ic->generated = 1;
+ return;
+ }
+
/* get the value into acc */
if (AOP_TYPE (cond) != AOP_CRY)
asmopToBool (AOP (cond), FALSE);