From 88459ca0321f463f8185f96c208b22aa47dfa1bc Mon Sep 17 00:00:00 2001 From: tecodev Date: Sat, 17 Nov 2007 18:28:53 +0000 Subject: [PATCH] * src/pic16/genarith.c (pic16_genPlus, pic16_genMinus): take special care when left or right operand resides in result, fixes #1830220 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4967 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 5 ++ src/pic16/genarith.c | 110 ++++++++++++++++++------------------------- 2 files changed, 51 insertions(+), 64 deletions(-) diff --git a/ChangeLog b/ChangeLog index 235ccf38..f3d1fafc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-11-17 Raphael Neider + + * src/pic16/genarith.c (pic16_genPlus, pic16_genMinus): take special + care when left or right operand resides in result, fixes #1830220 + 2007-11-17 Borut Razem * src/SDCCglue.c, src/pic16/glue.c: reverted fix for bug diff --git a/src/pic16/genarith.c b/src/pic16/genarith.c index 904961bc..6f16565b 100644 --- a/src/pic16/genarith.c +++ b/src/pic16/genarith.c @@ -1336,6 +1336,13 @@ void pic16_genPlus (iCode *ic) } else { // add regs + if (pic16_sameRegs(AOP(left), AOP(result)) + && (AOP_SIZE(left) < AOP_SIZE(result))) + { + // extend left operand, sign-bit still intact + pic16_addSign (result, AOP_SIZE(left), !SPEC_USIGN(getSpec(operandType(left)))); + } + // add first bytes for(i=0; i 0) { - - lit >>= 8; - - if(lit & 0xff) { - - if((lit & 0xff) == 0xff) { - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff)); - emitSKPC; - pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset)); - } else { - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff)); - emitSKPNC; - pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff)); - pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset)); - } - - } else { - /* do the rlf known zero trick here */ - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1)); - emitSKPNC; - pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset)); - } - offset++; - } -#endif } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { // bit subtraction @@ -1772,6 +1742,19 @@ void pic16_genMinus (iCode *ic) pic16_AopType(AOP_TYPE(IC_LEFT(ic))), pic16_AopType(AOP_TYPE(IC_RIGHT(ic)))); + if ((AOP_SIZE(IC_LEFT(ic)) < AOP_SIZE(IC_RESULT(ic))) + && pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) { + // extend left in result + pic16_addSign (IC_RESULT(ic), AOP_SIZE(IC_LEFT(ic)), !SPEC_USIGN(getSpec(operandType(IC_LEFT(ic))))); + } + + if ((AOP_SIZE(IC_RIGHT(ic)) < AOP_SIZE(IC_RESULT(ic))) + && pic16_sameRegs (AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) { + // extend right in result---fails if left resides in result as well... + assert ((IC_LEFT(ic) == IC_RIGHT(ic)) || !pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))); + pic16_addSign (IC_RESULT(ic), AOP_SIZE(IC_RIGHT(ic)), !SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic))))); + } + if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0)); @@ -1817,10 +1800,13 @@ void pic16_genMinus (iCode *ic) offset = 1; size--; - while(size--){ - if (offset < AOP_SIZE(IC_RIGHT(ic))) + while (size--) { + if (pic16_sameRegs (AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) { + pic16_mov2w (AOP(IC_RESULT(ic)), offset); + } else if (offset < AOP_SIZE(IC_RIGHT(ic))) pic16_mov2w(AOP(IC_RIGHT(ic)),offset); else { + // right operand is too short, not overwritten with result pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg)); if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) { // signed -- sign extend the right operand @@ -1830,27 +1816,23 @@ void pic16_genMinus (iCode *ic) } if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) { pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + } else if (offset < AOP_SIZE(IC_LEFT(ic))) { + pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); } else { - if (offset < AOP_SIZE(IC_LEFT(ic))) { - pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - } else { - // zero extend the left operand - pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); - if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) { - // signed -- sign extend the left operand - pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),AOP_SIZE(IC_LEFT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact! - } - pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + // left operand is too short, not overwritten with result + pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); + if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) { + // signed -- sign extend the left operand + pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),AOP_SIZE(IC_LEFT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); + pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact! } + pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset)); } offset++; } - } - // adjustArithmeticResult(ic); release: -- 2.30.2