(genLeftShift, genRightShift): fixed bug
1491627
* src/hc08/peeph.def (rules 7, 8.x): added
* support/regression/tests/shifts.c (ShiftLeftByParam,
ShiftRightByParam, testShiftByParam): added to test variable shifting
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4183
4a8a32a2-be11-0410-ad9d-
d568d2c75423
+2006-05-21 Maarten Brock <sourceforge.brock AT dse.nl>
+
+ * src/hc08/gen.c (transferAopAop): aop forced to stack was not restored,
+ (genLeftShift, genRightShift): fixed bug 1491627
+ * src/hc08/peeph.def (rules 7, 8.x): added
+ * support/regression/tests/shifts.c (ShiftLeftByParam,
+ ShiftRightByParam, testShiftByParam): added to test variable shifting
+
2006-05-20 Raphael Neider <rneider AT web.de>
* src/pic/gen.c (bitpatternFromVal): fixed for 64-bit machines
2006-05-20 Raphael Neider <rneider AT web.de>
* src/pic/gen.c (bitpatternFromVal): fixed for 64-bit machines
/* ignore transfers at the same byte, unless its volatile */
if (srcaop->op && !isOperandVolatile (srcaop->op, FALSE)
&& dstaop->op && !isOperandVolatile (dstaop->op, FALSE)
/* 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])
return;
if (srcaop->stacked && srcaop->stk_aop[srcofs])
operand *left, *right, *result;
int size, offset;
symbol *tlbl, *tlbl1;
operand *left, *right, *result;
int size, offset;
symbol *tlbl, *tlbl1;
D(emitcode ("; genLeftShift",""));
D(emitcode ("; genLeftShift",""));
more that 32 bits make no sense anyway, ( the
largest size of an object can be only 32 bits ) */
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 (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)))
{
/* 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--)
size = AOP_SIZE (result);
offset = 0;
while (size--)
offset = 0;
tlbl1 = newiTempLabel (NULL);
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);
emitBranch ("beq", tlbl1);
emitLabel (tlbl);
rmwWithAop (shift, AOP (result), offset);
shift="rol";
}
rmwWithAop (shift, AOP (result), offset);
shift="rol";
}
- rmwWithReg ("dec", reg);
+ rmwWithReg ("dec", hc08_reg_x);
emitBranch ("bne", tlbl);
emitLabel (tlbl1);
emitBranch ("bne", tlbl);
emitLabel (tlbl1);
+ hc08_freeReg (hc08_reg_x);
freeAsmop (result, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
}
/*-----------------------------------------------------------------*/
operand *right, *left, *result;
sym_link *retype;
int size, offset;
operand *right, *left, *result;
sym_link *retype;
int size, offset;
symbol *tlbl, *tlbl1;
char *shift;
bool sign;
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 ) */
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 (result, ic, FALSE);
+ aopOp (left, ic, FALSE);
if (sameRegs(AOP (right), AOP (result)) || IS_AOP_XA (AOP (result)))
AOP (result) = forceStackedAop (AOP (result));
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);
tlbl = newiTempLabel (NULL);
size = AOP_SIZE (result);
loadRegFromAop (hc08_reg_x, AOP (right), 0);
emitcode ("tstx", "");
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= sign ? "asr" : "lsr";
for (offset=size-1;offset>=0;offset--)
{
shift="ror";
}
rmwWithReg ("dec", hc08_reg_x);
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 (result, NULL, ic, TRUE);
- freeAsmop (left, NULL, ic, TRUE);
freeAsmop (right, NULL, ic, TRUE);
}
freeAsmop (right, NULL, ic, TRUE);
}
; Peephole 6b - replaced jmp to rts with rts
rts
} if labelIsReturnOnly
; Peephole 6b - replaced jmp to rts with rts
rts
} if labelIsReturnOnly
+
+replace restart {
+ psha
+ lda %1
+ sta 1,s
+} by {
+ ; Peephole 7 - optimized stack allocation
+ lda %1
+ psha
+}
+
+replace restart {
+ lda %1
+ sta %1
+} by {
+ ; Peephole 8a - removed redundant sta
+ lda %1
+} if notVolatile %1
+
+replace restart {
+ sta %1
+ lda %1
+} by {
+ ; Peephole 8b - removed redundant lda
+ sta %1
+} if notVolatile %1
result <<= 1;
ASSERT(result == ({type})(({type}){vals} << 1));
}
result <<= 1;
ASSERT(result == ({type})(({type}){vals} << 1));
}
+
+static {type} ShiftLeftByParam ({type} count)
+{
+ {attr} {storage} {type} i;
+ i = ({type}){vals};
+ return (i << count);
+}
+
+static {type} ShiftRightByParam ({type} count)
+{
+ {attr} {storage} {type} i;
+ i = ({type}){vals};
+ return (i >> count);
+}
+
+void
+testShiftByParam(void)
+{
+ ASSERT(ShiftLeftByParam(2) == ({type})({vals} << 2));
+ ASSERT(ShiftRightByParam(2) == ({type})({vals} >> 2));
+}