From: epetrich Date: Tue, 20 Jan 2004 05:48:09 +0000 (+0000) Subject: * src/hc08/gen.c (genPlusIncr, genUminus, genMinusDec, genCmp, X-Git-Url: https://git.gag.com/?p=fw%2Fsdcc;a=commitdiff_plain;h=3ce766b71ad2b6d9f192e0e6c5d3a5f129804812 * 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 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3141 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index dab482aa..24d5cd45 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2004-01-20 Erik Petrich + + * 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 * src/SDCCicode.c (geniCodeArray): applied patch from Stas Sergeev diff --git a/device/lib/hc08/_mulint.c b/device/lib/hc08/_mulint.c index 9ac3a720..57c19b81 100644 --- a/device/lib/hc08/_mulint.c +++ b/device/lib/hc08/_mulint.c @@ -26,13 +26,79 @@ has the same precision as the input. Assembler-functions are provided for: - ds390 - mcs51 small - mcs51 small stack-auto - mcs51 large + hc08 + hc08 stack-auto */ +#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; @@ -60,6 +126,7 @@ _mulint (int a, int b) return t.t; } +#endif #undef _MULINT_ASM diff --git a/sim/ucsim/hc08.src/inst.cc b/sim/ucsim/hc08.src/inst.cc index bdd8312d..839af773 100644 --- a/sim/ucsim/hc08.src/inst.cc +++ b/sim/ucsim/hc08.src/inst.cc @@ -673,6 +673,7 @@ cl_hc08::inst_clr(t_mem code, bool prefix) else if ((code & 0xf0) == 0x50) regs.X = operand; else { + ea = fetchea(code,prefix); store1(ea, operand); } return(resGO); diff --git a/src/SDCCdflow.c b/src/SDCCdflow.c index a4cee93d..8fa4f0c1 100644 --- a/src/SDCCdflow.c +++ b/src/SDCCdflow.c @@ -193,15 +193,14 @@ computeDataFlow (eBBlock ** ebbs, int count) /* 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); } - else - oldOutDefs = bitVectCopy (ebbs[i]->outDefs); + oldOutDefs = bitVectCopy (ebbs[i]->outDefs); setToNull ((void *) &ebbs[i]->inDefs); /* indefitions are easy just merge them by union */ @@ -248,8 +247,7 @@ computeDataFlow (eBBlock ** ebbs, int count) 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 */ diff --git a/src/hc08/gen.c b/src/hc08/gen.c index f64453c4..e9b718cb 100644 --- a/src/hc08/gen.c +++ b/src/hc08/gen.c @@ -2290,6 +2290,7 @@ genUminus (iCode * ic) sym_link *optype, *rtype; char *sub; bool needpula; + asmop *result; D(emitcode ("; genUminus","")); @@ -2313,7 +2314,10 @@ genUminus (iCode * ic) if (size == 1) { - 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); @@ -2323,18 +2327,26 @@ genUminus (iCode * ic) } else { + 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); - storeRegToAop (hc08_reg_a, AOP( IC_RESULT (ic)), offset++); + storeRegToAop (hc08_reg_a, result, offset++); sub = "sbc"; } - 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); + + if (IS_AOP_XA (AOP (IC_RESULT (ic)))) + freeAsmop (NULL, result, ic, TRUE); } @@ -2342,7 +2354,7 @@ genUminus (iCode * ic) 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); } /*-----------------------------------------------------------------*/ @@ -3136,8 +3148,16 @@ genPlusIncr (iCode * ic) ) && (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); @@ -3170,7 +3190,10 @@ genPlusIncr (iCode * ic) } else { - 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); @@ -3287,8 +3310,16 @@ genMinusDec (iCode * ic) 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); @@ -3420,7 +3451,9 @@ genMultOneByte (operand * left, //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"); @@ -3880,8 +3913,7 @@ genCmp (operand * left, operand * right, } else { - 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); } @@ -4504,6 +4536,35 @@ genAnd (iCode * ic, iCode * ifx) left = tmp; } + + 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) @@ -4520,7 +4581,7 @@ genAnd (iCode * ic, iCode * ifx) goto release; } } - + offset = 0; while (size--) { @@ -4579,14 +4640,34 @@ genOr (iCode * ic, iCode * ifx) left = tmp; } - /* 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); @@ -4602,8 +4683,6 @@ genOr (iCode * ic, iCode * ifx) goto release; } - - offset = 0; while (size--) { @@ -4662,14 +4741,34 @@ genXor (iCode * ic, iCode * ifx) left = tmp; } - /* 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); @@ -4683,7 +4782,6 @@ genXor (iCode * ic, iCode * ifx) hc08_freeReg( hc08_reg_a); } - //release: freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -5495,8 +5593,14 @@ shiftL2Left2Result (operand * left, int offl, 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);