shiftL2Left2Result): fixed bug #879326
(genAnd, genOr, genXor): fixed bug when result was of type AOP_CRY
(genMultOneByte): fixed bug in signed vs unsigned multiplication
* sim/ucsim/hc08.src/inst.cc (inst_clr): added missing effective
address fetch for clr instruction
* device/lib/hc08/_mulint.c: created optimized assembly version
* src/SDCCdflow.c (computeDataFlow): fixed bug #878209
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3141
4a8a32a2-be11-0410-ad9d-
d568d2c75423
+2004-01-20 Erik Petrich <epetrich@ivorytower.norman.ok.us>
+
+ * src/hc08/gen.c (genPlusIncr, genUminus, genMinusDec, genCmp,
+ shiftL2Left2Result): fixed bug #879326
+ (genAnd, genOr, genXor): fixed bug when result was of type AOP_CRY
+ (genMultOneByte): fixed bug in signed vs unsigned multiplication
+ * sim/ucsim/hc08.src/inst.cc (inst_clr): added missing effective
+ address fetch for clr instruction
+ * device/lib/hc08/_mulint.c: created optimized assembly version
+ * src/SDCCdflow.c (computeDataFlow): fixed bug #878209
+
2004-01-19 Bernhard Held <bernhard@bernhardheld.de>
* src/SDCCicode.c (geniCodeArray): applied patch from Stas Sergeev
2004-01-19 Bernhard Held <bernhard@bernhardheld.de>
* src/SDCCicode.c (geniCodeArray): applied patch from Stas Sergeev
has the same precision as the input.
Assembler-functions are provided for:
has the same precision as the input.
Assembler-functions are provided for:
- ds390
- mcs51 small
- mcs51 small stack-auto
- mcs51 large
+#if !defined(_SDCC_NO_ASM_LIB_FUNCS)
+
+#pragma save
+#pragma less_pedantic
+int
+_mulint (int a, int b)
+{
+ a,b; /* reference to make compiler happy */
+
+#if !defined(SDCC_STACK_AUTO)
+ _asm
+ ais #-2
+ psha
+ pshx
+
+ ldx __mulint_PARM_2+1
+ mul
+ sta 4,s
+ stx 3,s
+
+ lda 1,s
+ ldx __mulint_PARM_2+1
+ mul
+ add 3,s
+ sta 3,s
+
+ lda 2,s
+ ldx __mulint_PARM_2
+ mul
+ add 3,s
+ sta 3,s
+
+ ais #2
+ pulx
+ pula
+ _endasm;
+#else
+ _asm
+ ais #-2
+ psha
+ pshx
+
+ ldx 8,s
+ mul
+ sta 4,s
+ stx 3,s
+
+ lda 1,s
+ ldx 8,s
+ mul
+ add 3,s
+ sta 3,s
+
+ lda 2,s
+ ldx 7,s
+ mul
+ add 3,s
+ sta 3,s
+
+ ais #2
+ pulx
+ pula
+#endif
+}
+#pragma restore
+
+#else
+
union uu {
struct { unsigned char hi,lo ;} s;
unsigned int t;
union uu {
struct { unsigned char hi,lo ;} s;
unsigned int t;
else if ((code & 0xf0) == 0x50)
regs.X = operand;
else {
else if ((code & 0xf0) == 0x50)
regs.X = operand;
else {
+ ea = fetchea(code,prefix);
store1(ea, operand);
}
return(resGO);
store1(ea, operand);
}
return(resGO);
/* get blocks that can come to this block */
pred = edgesTo (ebbs[i]);
/* get blocks that can come to this block */
pred = edgesTo (ebbs[i]);
- /* make a copy of the outExpressions or outDefs : to be */
+ /* make a copy of the outExpressions and outDefs : to be */
/* used for iteration */
if (optimize.global_cse)
{
oldOutExprs = setFromSet (ebbs[i]->outExprs);
oldKilledExprs = setFromSet (ebbs[i]->killedExprs);
}
/* used for iteration */
if (optimize.global_cse)
{
oldOutExprs = setFromSet (ebbs[i]->outExprs);
oldKilledExprs = setFromSet (ebbs[i]->killedExprs);
}
- else
- oldOutDefs = bitVectCopy (ebbs[i]->outDefs);
+ oldOutDefs = bitVectCopy (ebbs[i]->outDefs);
setToNull ((void *) &ebbs[i]->inDefs);
/* indefitions are easy just merge them by union */
setToNull ((void *) &ebbs[i]->inDefs);
/* indefitions are easy just merge them by union */
change += !isSetsEqualWith (ebbs[i]->outExprs, oldOutExprs, isCseDefEqual);
change += !isSetsEqualWith (ebbs[i]->killedExprs, oldKilledExprs, isCseDefEqual);
}
change += !isSetsEqualWith (ebbs[i]->outExprs, oldOutExprs, isCseDefEqual);
change += !isSetsEqualWith (ebbs[i]->killedExprs, oldKilledExprs, isCseDefEqual);
}
- else
- change += !bitVectEqual (ebbs[i]->outDefs, oldOutDefs);
+ change += !bitVectEqual (ebbs[i]->outDefs, oldOutDefs);
}
if (!change) /* iterate till no change */
}
if (!change) /* iterate till no change */
sym_link *optype, *rtype;
char *sub;
bool needpula;
sym_link *optype, *rtype;
char *sub;
bool needpula;
D(emitcode ("; genUminus",""));
D(emitcode ("; genUminus",""));
- needpula = pushRegIfUsed (hc08_reg_a);
+ if (!IS_AOP_A (AOP (IC_LEFT (ic))))
+ needpula = pushRegIfUsed (hc08_reg_a);
+ else
+ needpula = FALSE;
loadRegFromAop (hc08_reg_a, AOP( IC_LEFT (ic)), 0);
emitcode ("nega", "");
hc08_freeReg (hc08_reg_a);
loadRegFromAop (hc08_reg_a, AOP( IC_LEFT (ic)), 0);
emitcode ("nega", "");
hc08_freeReg (hc08_reg_a);
+ if (IS_AOP_XA (AOP (IC_RESULT (ic))))
+ result = forceStackedAop (AOP (IC_RESULT (ic)));
+ else
+ result = AOP (IC_RESULT (ic));
+
needpula = pushRegIfUsed (hc08_reg_a);
sub="sub";
while (size--)
{
loadRegFromConst (hc08_reg_a, zero);
accopWithAop (sub, AOP( IC_LEFT (ic)), offset);
needpula = pushRegIfUsed (hc08_reg_a);
sub="sub";
while (size--)
{
loadRegFromConst (hc08_reg_a, zero);
accopWithAop (sub, AOP( IC_LEFT (ic)), offset);
- storeRegToAop (hc08_reg_a, AOP( IC_RESULT (ic)), offset++);
+ storeRegToAop (hc08_reg_a, result, offset++);
- storeRegSignToUpperAop (hc08_reg_a, AOP( IC_RESULT (ic)), offset,
+ storeRegSignToUpperAop (hc08_reg_a, result, offset,
SPEC_USIGN (operandType (IC_LEFT (ic))));
pullOrFreeReg (hc08_reg_a, needpula);
SPEC_USIGN (operandType (IC_LEFT (ic))));
pullOrFreeReg (hc08_reg_a, needpula);
+
+ if (IS_AOP_XA (AOP (IC_RESULT (ic))))
+ freeAsmop (NULL, result, ic, TRUE);
release:
/* release the aops */
freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
release:
/* release the aops */
freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
- freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+ freeAsmop (IC_LEFT (ic), NULL, ic, FALSE);
}
/*-----------------------------------------------------------------*/
}
/*-----------------------------------------------------------------*/
)
&& (icount>=-128) && (icount<=127) && (size==2))
{
)
&& (icount>=-128) && (icount<=127) && (size==2))
{
- needpulx = pushRegIfUsed (hc08_reg_x);
- needpulh = pushRegIfUsed (hc08_reg_h);
+ if (!IS_AOP_HX (AOP (left)))
+ {
+ needpulx = pushRegIfUsed (hc08_reg_x);
+ needpulh = pushRegIfUsed (hc08_reg_h);
+ }
+ else
+ {
+ needpulx = FALSE;
+ needpulh = FALSE;
+ }
loadRegFromAop (hc08_reg_hx, AOP(left), 0);
emitcode ("aix","#%d", icount);
hc08_dirtyReg (hc08_reg_hx, FALSE);
loadRegFromAop (hc08_reg_hx, AOP(left), 0);
emitcode ("aix","#%d", icount);
hc08_dirtyReg (hc08_reg_hx, FALSE);
- needpula = pushRegIfUsed (hc08_reg_a);
+ if (!IS_AOP_A (AOP (result)) && !IS_AOP_XA (AOP (result)))
+ needpula = pushRegIfUsed (hc08_reg_a);
+ else
+ needpula = FALSE;
loadRegFromAop (hc08_reg_a, AOP (result), 0);
accopWithAop ("add", AOP (IC_RIGHT (ic)), 0);
hc08_useReg (hc08_reg_a);
loadRegFromAop (hc08_reg_a, AOP (result), 0);
accopWithAop ("add", AOP (IC_RIGHT (ic)), 0);
hc08_useReg (hc08_reg_a);
if ((AOP_TYPE (left) == AOP_DIR) && (AOP_TYPE (result) == AOP_DIR)
&& (icount>=-127) && (icount<=128) && (size==2))
{
if ((AOP_TYPE (left) == AOP_DIR) && (AOP_TYPE (result) == AOP_DIR)
&& (icount>=-127) && (icount<=128) && (size==2))
{
- needpulx = pushRegIfUsed (hc08_reg_x);
- needpulh = pushRegIfUsed (hc08_reg_h);
+ if (!IS_AOP_HX (AOP (left)))
+ {
+ needpulx = pushRegIfUsed (hc08_reg_x);
+ needpulh = pushRegIfUsed (hc08_reg_h);
+ }
+ else
+ {
+ needpulx = FALSE;
+ needpulh = FALSE;
+ }
loadRegFromAop (hc08_reg_hx, AOP(left), 0);
emitcode ("aix","#%d", -icount);
hc08_dirtyReg (hc08_reg_hx, FALSE);
loadRegFromAop (hc08_reg_hx, AOP(left), 0);
emitcode ("aix","#%d", -icount);
hc08_dirtyReg (hc08_reg_hx, FALSE);
//emitcode (";", "swapped left and right");
}
//emitcode (";", "swapped left and right");
}
- if (SPEC_USIGN(opetype))
+ if (SPEC_USIGN(opetype)
+ || (SPEC_USIGN(operandType(left)) &&
+ SPEC_USIGN(operandType(right))))
{
// just an unsigned 8*8=8/16 multiply
//emitcode (";","unsigned");
{
// just an unsigned 8*8=8/16 multiply
//emitcode (";","unsigned");
- needpula = pushRegIfUsed (hc08_reg_a);
- loadRegFromAop (hc08_reg_a, AOP (left), AOP_SIZE (left) -1);
+ loadRegFromAop (hc08_reg_a, AOP (left), AOP_SIZE (left) -1);
emitcode ("rola", "");
hc08_useReg (hc08_reg_a);
}
emitcode ("rola", "");
hc08_useReg (hc08_reg_a);
}
+
+ if (AOP_TYPE (result) == AOP_CRY)
+ {
+ symbol *tlbl;
+ wassertl (ifx, "AOP_CPY result without ifx");
+
+ tlbl = newiTempLabel (NULL);
+ size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
+ offset = 0;
+ while (size--)
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), offset);
+ if ((AOP_TYPE (right) == AOP_LIT)
+ && (((lit >> (offset*8)) & 0xff) == 0xff))
+ emitcode ("tsta","");
+ else
+ accopWithAop ("and", AOP (right), offset);
+ hc08_freeReg( hc08_reg_a);
+ if (size)
+ emitBranch ("bne", tlbl);
+ else
+ {
+ emitLabel (tlbl);
+ genIfxJump (ifx, "a");
+ }
+ offset++;
+ }
+ }
+
size = AOP_SIZE (result);
if (AOP_TYPE (right) == AOP_LIT)
size = AOP_SIZE (result);
if (AOP_TYPE (right) == AOP_LIT)
offset = 0;
while (size--)
{
offset = 0;
while (size--)
{
- /* if right is bit then exchange them */
- if (AOP_TYPE (right) == AOP_CRY &&
- AOP_TYPE (left) != AOP_CRY)
+ if (AOP_TYPE (result) == AOP_CRY)
- operand *tmp = right;
- right = left;
- left = tmp;
+ symbol *tlbl;
+ wassertl (ifx, "AOP_CPY result without ifx");
+
+ tlbl = newiTempLabel (NULL);
+ size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
+ offset = 0;
+ while (size--)
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), offset);
+ if ((AOP_TYPE (right) == AOP_LIT)
+ && (((lit >> (offset*8)) & 0xff) == 0))
+ emitcode ("tsta","");
+ else
+ accopWithAop ("ora", AOP (right), offset);
+ hc08_freeReg( hc08_reg_a);
+ if (size)
+ emitBranch ("bne", tlbl);
+ else
+ {
+ emitLabel (tlbl);
+ genIfxJump (ifx, "a");
+ }
+ offset++;
+ }
if (AOP_TYPE (right) == AOP_LIT)
lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
if (AOP_TYPE (right) == AOP_LIT)
lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
offset = 0;
while (size--)
{
offset = 0;
while (size--)
{
- /* if right is bit then exchange them */
- if (AOP_TYPE (right) == AOP_CRY &&
- AOP_TYPE (left) != AOP_CRY)
+ if (AOP_TYPE (result) == AOP_CRY)
- operand *tmp = right;
- right = left;
- left = tmp;
+ symbol *tlbl;
+ wassertl (ifx, "AOP_CPY result without ifx");
+
+ tlbl = newiTempLabel (NULL);
+ size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
+ offset = 0;
+ while (size--)
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), offset);
+ if ((AOP_TYPE (right) == AOP_LIT)
+ && (((lit >> (offset*8)) & 0xff) == 0))
+ emitcode ("tsta","");
+ else
+ accopWithAop ("eor", AOP (right), offset);
+ hc08_freeReg( hc08_reg_a);
+ if (size)
+ emitBranch ("bne", tlbl);
+ else
+ {
+ emitLabel (tlbl);
+ genIfxJump (ifx, "a");
+ }
+ offset++;
+ }
if (AOP_TYPE (right) == AOP_LIT)
lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
if (AOP_TYPE (right) == AOP_LIT)
lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
hc08_freeReg( hc08_reg_a);
}
hc08_freeReg( hc08_reg_a);
}
//release:
freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
//release:
freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
bool needpula = FALSE;
bool needpulx = FALSE;
bool needpula = FALSE;
bool needpulx = FALSE;
- needpula = pushRegIfUsed (hc08_reg_a);
- needpulx = pushRegIfUsed (hc08_reg_x);
+ if (!IS_AOP_XA (AOP (left)) && !IS_AOP_A (AOP (left)))
+ needpula = pushRegIfUsed (hc08_reg_a);
+ else
+ needpula = FALSE;
+ if (!IS_AOP_XA (AOP (left)))
+ needpulx = pushRegIfUsed (hc08_reg_x);
+ else
+ needpulx = FALSE;
loadRegFromAop (hc08_reg_xa, AOP (left), offl);
loadRegFromAop (hc08_reg_xa, AOP (left), offl);