From: tecodev Date: Wed, 5 Jan 2005 12:20:09 +0000 (+0000) Subject: * src/pic16/gen.c (genGenericShift) added handling of differently X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=cc2423da79ce6f6eedb517fd5a14290e355e3529;p=fw%2Fsdcc * src/pic16/gen.c (genGenericShift) added handling of differently sized left operand and result git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3628 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index eee080e7..3c809247 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-01-05 Raphael Neider + + * src/pic16/gen.c (genGenericShift) added handling of differently + sized left operand and result + 2005-01-04 Raphael Neider * src/pic16/gen.c (genIfxJump) fixed inverted skips on CARRY diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 1a58c9cb..7646de4f 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -10604,9 +10604,7 @@ static void genGenericShift (iCode *ic, int isShiftLeft) { * Note: we perform arithmetic shifts if the left operand is * signed and we do an (effective) right shift, i. e. we * shift in the sign bit from the left. */ - - assert (AOP_SIZE(result) == AOP_SIZE(left)); - + label_complete = newiTempLabel ( NULL ); label_loop_pos = newiTempLabel ( NULL ); label_loop_neg = NULL; @@ -10620,11 +10618,31 @@ static void genGenericShift (iCode *ic, int isShiftLeft) { label_negative = newiTempLabel ( NULL ); } // if - // copy source to result - for (offset=0; offset < AOP_SIZE(result); offset++) { + // copy source to result -- this will effectively truncate the left operand to the size of result! + // (e.g. char c = 0x100 << -3 will become c = 0x00 >> 3 == 0x00 instad of 0x20) + // This is fine, as it only occurs for left shifting with negative count which is not standardized! + for (offset=0; offset < min(AOP_SIZE(left), AOP_SIZE(result)); offset++) { mov2f (AOP(result),AOP(left), offset); } // for + // if result is longer than left, fill with zeros (or sign) + if (AOP_SIZE(left) < AOP_SIZE(result)) { + if (sign && AOP_SIZE(left) > 0) { + // shift signed operand -- fill with sign + pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg)); + pic16_emitpcode (POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), AOP_SIZE(left)-1), 7)); + pic16_emitpcode (POC_MOVLW, pic16_popGetLit (0xFF)); + for (offset=AOP_SIZE(left); offset < AOP_SIZE(result); offset++) { + pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(result), offset)); + } // for + } else { + // shift unsigned operand -- fill result with zeros + for (offset=AOP_SIZE(left); offset < AOP_SIZE(result); offset++) { + pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset)); + } // for + } + } // if (size mismatch) + pic16_mov2w (AOP(right), 0); pic16_emitpcode (POC_BZ, pic16_popGetLabel (label_complete->key)); if (signedCount) pic16_emitpcode (POC_BN, pic16_popGetLabel (label_negative->key));