+/*-----------------------------------------------------------------*/
+/* shiftLeft_Left2ResultLit - shift left by known count */
+/*-----------------------------------------------------------------*/
+
+static void shiftLeft_Left2ResultLit (operand *left, operand *result, int shCount)
+{
+ int size, same, offr, i;
+
+ size = AOP_SIZE(left);
+ if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
+
+ same = pic14_sameRegs (AOP(left), AOP(result));
+
+ offr = shCount / 8;
+ shCount = shCount & 0x07;
+
+ size -= offr;
+
+ switch (shCount)
+ {
+ case 0: /* takes 0 or 2N cycles (for offr==0) */
+ if (!same || offr) {
+ for (i=size-1; i >= 0; i--)
+ movLeft2Result (left, i, result, offr + i);
+ } // if
+ break;
+
+ case 1: /* takes 1N+1 or 2N+1 cycles (or offr==0) */
+ if (same && offr) {
+ shiftLeft_Left2ResultLit (left, result, 8 * offr);
+ shiftLeft_Left2ResultLit (result, result, shCount);
+ return; /* prevent clearing result again */
+ } else {
+ emitCLRC;
+ for (i=0; i < size; i++) {
+ if (same && !offr) {
+ emitpcode (POC_RLF, popGet (AOP(left), i));
+ } else {
+ emitpcode (POC_RLFW, popGet (AOP(left), i));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
+ } // if
+ } // for
+ } // if (offr)
+ break;
+
+ case 4: /* takes 3+5(N-1) = 5N-2 cycles (for offr==0) */
+ /* works in-place/with offr as well */
+ emitpcode (POC_SWAPFW, popGet (AOP(left), size-1));
+ emitpcode (POC_ANDLW, popGetLit (0xF0));
+ emitpcode (POC_MOVWF, popGet(AOP(result), size-1+offr));
+
+ for (i = size - 2; i >= 0; i--)
+ {
+ emitpcode (POC_SWAPFW, popGet (AOP(left), i));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
+ emitpcode (POC_ANDLW, popGetLit (0x0F));
+ emitpcode (POC_IORWF, popGet (AOP(result), i + offr + 1));
+ emitpcode (POC_XORWF, popGet (AOP(result), i + offr));
+ } // for i
+ break;
+
+ case 7: /* takes 2(N-1)+3 = 2N+1 cycles */
+ /* works in-place/with offr as well */
+ emitpcode (POC_RRFW, popGet (AOP(left), size-1));
+ for (i = size-2; i >= 0; i--) {
+ emitpcode (POC_RRFW, popGet (AOP(left), i));
+ emitpcode (POC_MOVWF, popGet (AOP(result), offr + i + 1));
+ } // for i
+ emitpcode (POC_CLRF, popGet (AOP(result), offr));
+ emitpcode (POC_RRF, popGet (AOP(result), offr));
+ break;
+
+ default:
+ shiftLeft_Left2ResultLit (left, result, offr * 8 + shCount-1);
+ shiftLeft_Left2ResultLit (result, result, 1);
+ return; /* prevent clearing result again */
+ break;
+ } // switch
+
+ while (0 < offr--)
+ {
+ emitpcode (POC_CLRF, popGet (AOP(result), offr));
+ } // while
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftRight_Left2ResultLit - shift right by known count */
+/*-----------------------------------------------------------------*/
+
+static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign)
+{
+ int size, same, offr, i;
+
+ size = AOP_SIZE(left);
+ if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
+
+ same = pic14_sameRegs (AOP(left), AOP(result));
+
+ offr = shCount / 8;
+ shCount = shCount & 0x07;
+
+ size -= offr;
+
+ if (size)
+ {
+ switch (shCount)
+ {
+ case 0: /* takes 0 or 2N cycles (for offr==0) */
+ if (!same || offr) {
+ for (i=0; i < size; i++)
+ movLeft2Result (left, i + offr, result, i);
+ } // if
+ break;
+
+ case 1: /* takes 1N+1(3) or 2N+1(3) cycles (or offr==0) */
+ emitpComment ("%s:%d: shCount=%d, size=%d, sign=%d, same=%d, offr=%d", __FUNCTION__, __LINE__, shCount, size, sign, same, offr);
+ if (same && offr) {
+ shiftRight_Left2ResultLit (left, result, 8 * offr, sign);
+ shiftRight_Left2ResultLit (result, result, shCount, sign);
+ return; /* prevent sign-extending result again */
+ } else {
+ emitCLRC;
+ if (sign) {
+ emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(left), AOP_SIZE(left)-1, FALSE, FALSE), 7, 0));
+ emitSETC;
+ }
+ for (i = size-1; i >= 0; i--) {
+ if (same && !offr) {
+ emitpcode (POC_RRF, popGet (AOP(left), i));
+ } else {
+ emitpcode (POC_RRFW, popGet (AOP(left), i + offr));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i));
+ }
+ } // for i
+ } // if (offr)
+ break;
+
+ case 4: /* takes 3(6)+5(N-1) = 5N-2(+1) cycles (for offr==0) */
+ /* works in-place/with offr as well */
+ emitpcode (POC_SWAPFW, popGet (AOP(left), offr));
+ emitpcode (POC_ANDLW, popGetLit (0x0F));
+ emitpcode (POC_MOVWF, popGet(AOP(result), 0));
+
+ for (i = 1; i < size; i++)
+ {
+ emitpcode (POC_SWAPFW, popGet (AOP(left), i + offr));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i));
+ emitpcode (POC_ANDLW, popGetLit (0xF0));
+ emitpcode (POC_IORWF, popGet (AOP(result), i - 1));
+ emitpcode (POC_XORWF, popGet (AOP(result), i));
+ } // for i
+
+ if (sign)
+ {
+ emitpcode (POC_MOVLW, popGetLit (0xF0));
+ emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(result), size-1, FALSE, FALSE), 3, 0));
+ emitpcode (POC_IORWF, popGet (AOP(result), size-1));
+ } // if
+ break;
+
+ case 7: /* takes 2(N-1)+3(4) = 2N+1(2) cycles */
+ /* works in-place/with offr as well */
+ emitpcode (POC_RLFW, popGet (AOP(left), offr));
+ for (i = 0; i < size-1; i++) {
+ emitpcode (POC_RLFW, popGet (AOP(left), offr + i + 1));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i));
+ } // for i
+ emitpcode (POC_CLRF, popGet (AOP(result), size-1));
+ if (!sign) {
+ emitpcode (POC_RLF, popGet (AOP(result), size-1));
+ } else {
+ emitSKPNC;
+ emitpcode (POC_DECF, popGet (AOP(result), size-1));
+ }
+ break;
+
+ default:
+ shiftRight_Left2ResultLit (left, result, offr * 8 + shCount-1, sign);
+ shiftRight_Left2ResultLit (result, result, 1, sign);
+ return; /* prevent sign extending result again */
+ break;
+ } // switch
+ } // if
+
+ addSign (result, size, sign);
+}
+
+#if 0