-------------------------------------------------------------------------*/
-#define D(x)
-//#define D(x) x
+//#define D(x)
+#define D(x) x
#include <stdio.h>
#include <stdlib.h>
/* 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])
/* 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;
/*-----------------------------------------------------------------*/
/* shiftLLong - shift left one long from left to result */
-/* offl = LSB or MSB16 */
+/* offr = LSB or MSB16 */
/*-----------------------------------------------------------------*/
static void
shiftLLong (operand * left, operand * result, int offr)
loadRegFromAop (hc08_reg_xa, AOP (left), LSB);
rmwWithReg ("lsl", hc08_reg_a);
rmwWithReg ("rol", hc08_reg_x);
- storeRegToAop (hc08_reg_xa, AOP (result), offr);
if (offr==LSB)
{
+ storeRegToAop (hc08_reg_xa, AOP (result), offr);
loadRegFromAop (hc08_reg_xa, AOP (left), MSB24);
rmwWithReg ("rol", hc08_reg_a);
rmwWithReg ("rol", hc08_reg_x);
}
else if (offr==MSB16)
{
+ storeRegToAop (hc08_reg_a, AOP (result), offr);
loadRegFromAop (hc08_reg_a, AOP (left), MSB24);
+ storeRegToAop (hc08_reg_x, AOP (result), offr+1);
rmwWithReg ("rol", hc08_reg_a);
storeRegToAop (hc08_reg_a, AOP (result), offr+2);
storeConstToAop (zero, AOP (result), 0);
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);
}
/*-----------------------------------------------------------------*/
rmwWithReg ("lsr", hc08_reg_x);
rmwWithReg ("ror", hc08_reg_a);
storeRegToAop (hc08_reg_xa, AOP (result), MSB24);
+ loadRegFromAop (hc08_reg_xa, AOP (left), LSB);
}
else if (offl==MSB16)
{
rmwWithReg ("asr", hc08_reg_a);
else
rmwWithReg ("lsr", hc08_reg_a);
+ loadRegFromAop (hc08_reg_x, AOP (left), MSB24);
storeRegToAop (hc08_reg_a, AOP (result), MSB24);
- storeRegSignToUpperAop (hc08_reg_a, AOP (result), MSB32, sign);
+ loadRegFromAop (hc08_reg_a, AOP (left), MSB16);
}
- loadRegFromAop (hc08_reg_xa, AOP (left), offl);
rmwWithReg ("ror", hc08_reg_x);
rmwWithReg ("ror", hc08_reg_a);
storeRegToAop (hc08_reg_xa, AOP (result), LSB);
+ if (offl==MSB16)
+ {
+ if (sign)
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), MSB24);
+ storeRegSignToUpperAop (hc08_reg_a, AOP (result), MSB32, sign);
+ }
+ else
+ {
+ storeConstToAop (zero, AOP (result), MSB32);
+ }
+ }
pullOrFreeReg (hc08_reg_x, needpulx);
pullOrFreeReg (hc08_reg_a, needpula);
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);
}
variable */
if (sym->onStack)
{
- /* if it has an offset then we need to compute
- it */
+ /* if it has an offset then we need to compute it */
+ offset = _G.stackOfs + _G.stackPushes + sym->stack;
hc08_useReg (hc08_reg_hx);
emitcode ("tsx", "");
- emitcode ("aix", "#%d", _G.stackOfs + _G.stackPushes +sym->stack);
+ while (offset > 127)
+ {
+ emitcode ("aix", "#127");
+ offset -= 127;
+ }
+ while (offset < -128)
+ {
+ emitcode ("aix", "#-128");
+ offset += 128;
+ }
+ emitcode ("aix", "#%d", offset);
storeRegToFullAop (hc08_reg_hx, AOP (IC_RESULT (ic)), FALSE);
hc08_freeReg (hc08_reg_hx);