+/* shiftL2Left2Result - shift left two bytes from left to result */
+/*-----------------------------------------------------------------*/
+static void shiftL2Left2Result (operand *left, int offl,
+ operand *result, int offr, int shCount)
+{
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if(pic14_sameRegs(AOP(result), AOP(left))) {
+ switch(shCount) {
+ case 0:
+ break;
+ case 1:
+ case 2:
+ case 3:
+
+ emitpcode(POC_MOVFW,popGet(AOP(result),offr));
+ emitpcode(POC_ADDWF,popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+
+ while(--shCount) {
+ emitCLRC;
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ }
+
+ break;
+ case 4:
+ case 5:
+ emitpcode(POC_MOVLW, popGetLit(0x0f));
+ emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_SWAPF, popGet(AOP(result),offr));
+ emitpcode(POC_ANDFW, popGet(AOP(result),offr));
+ emitpcode(POC_XORWF, popGet(AOP(result),offr));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
+ if(shCount >=5) {
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ }
+ break;
+ case 6:
+ emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ANDLW,popGetLit(0xc0));
+ emitpcode(POC_XORFW,popGet(AOP(result),offr));
+ emitpcode(POC_XORWF,popGet(AOP(result),offr));
+ emitpcode(POC_XORFW,popGet(AOP(result),offr));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ break;
+ case 7:
+ emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRFW, popGet(AOP(result),offr));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_CLRF, popGet(AOP(result),offr));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ }
+
+ } else {
+ switch(shCount) {
+ case 0:
+ break;
+ case 1:
+ case 2:
+ case 3:
+ /* note, use a mov/add for the shift since the mov has a
+ chance of getting optimized out */
+ emitpcode(POC_MOVFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offr));
+ emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
+
+ while(--shCount) {
+ emitCLRC;
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ }
+ break;
+
+ case 4:
+ case 5:
+ emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_ANDLW, popGetLit(0xF0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ emitpcode(POC_ANDLW, popGetLit(0xF0));
+ emitpcode(POC_XORWF, popGet(AOP(result),offr));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
+
+
+ if(shCount == 5) {
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ }
+ break;
+ case 6:
+ emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRFW, popGet(AOP(result),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+
+ emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ANDLW,popGetLit(0xc0));
+ emitpcode(POC_XORFW,popGet(AOP(result),offr));
+ emitpcode(POC_XORWF,popGet(AOP(result),offr));
+ emitpcode(POC_XORFW,popGet(AOP(result),offr));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ break;
+ case 7:
+ emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_RRFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_CLRF, popGet(AOP(result),offr));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ }
+ }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftR2Left2Result - shift right two bytes from left to result */
+/*-----------------------------------------------------------------*/
+static void shiftR2Left2Result (operand *left, int offl,
+ operand *result, int offr,
+ int shCount, int sign)
+{
+ int same=0;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ same = pic14_sameRegs(AOP(result), AOP(left));
+
+ if(same && ((offl + MSB16) == offr)){
+ same=1;
+ /* don't crash result[offr] */
+ MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+ pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
+ }
+ /* else {
+ movLeft2Result(left,offl, result, offr);
+ MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
+ }
+ */
+ /* a:x >> shCount (x = lsb(result))*/
+ /*
+ if(sign)
+ AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
+ else {
+ AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
+ */
+ switch(shCount) {
+ case 0:
+ break;
+ case 1:
+ case 2:
+ case 3:
+ if(sign)
+ emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
+ else
+ emitCLRC;
+
+ if(same) {
+ emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRF,popGet(AOP(result),offr));
+ } else {
+ emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr));
+ }
+
+ while(--shCount) {
+ if(sign)
+ emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
+ else
+ emitCLRC;
+ emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRF,popGet(AOP(result),offr));
+ }
+ break;
+ case 4:
+ case 5:
+ if(same) {
+
+ emitpcode(POC_MOVLW, popGetLit(0xf0));
+ emitpcode(POC_ANDWF, popGet(AOP(result),offr));
+ emitpcode(POC_SWAPF, popGet(AOP(result),offr));
+
+ emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offr));
+ } else {
+ emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
+ emitpcode(POC_ANDLW, popGetLit(0x0f));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+
+ emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ANDLW, popGetLit(0xf0));
+ emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offr));
+ }
+
+ if(shCount >=5) {
+ emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ }
+
+ if(sign) {
+ emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
+ emitpcode(POC_BTFSC,
+ newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
+ }
+
+ break;
+
+ case 6:
+ if(same) {
+
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RLFW, popGet(AOP(result),offr));
+ emitpcode(POC_ANDLW,popGetLit(0x03));
+ if(sign) {
+ emitpcode(POC_BTFSC,
+ newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
+ emitpcode(POC_IORLW,popGetLit(0xfc));
+ }
+ emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr));
+ } else {
+ emitpcode(POC_RLFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ANDLW,popGetLit(0x03));
+ if(sign) {
+ emitpcode(POC_BTFSC,
+ newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
+ emitpcode(POC_IORLW,popGetLit(0xfc));
+ }
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ //emitpcode(POC_RLF, popGet(AOP(result),offr));
+
+
+ }
+
+ break;
+ case 7:
+ emitpcode(POC_RLFW, popGet(AOP(left),offl));
+ emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr));
+ emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
+ if(sign) {
+ emitSKPNC;
+ emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
+ } else
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftLLeftOrResult - shift left one byte from left, or to result*/
+/*-----------------------------------------------------------------*/
+static void shiftLLeftOrResult (operand *left, int offl,
+ operand *result, int offr, int shCount)
+{
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ /* shift left accumulator */
+ AccLsh(left,offl,shCount);
+ /* or with result */
+ emitpcode (POC_IORWF, popGet (AOP(result), offr));
+ assert ( !"broken (modifies left, fails for left==result))" );
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftRLeftOrResult - shift right one byte from left,or to result*/
+/*-----------------------------------------------------------------*/
+static void shiftRLeftOrResult (operand *left, int offl,
+ operand *result, int offr, int shCount)
+{
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ /* shift right accumulator */
+ AccRsh(left,offl,shCount);
+ /* or with result */
+ emitpcode (POC_IORWF, popGet (AOP(result), offr));
+ assert ( !"broken (modifies left, fails for left==result))" );
+}
+
+/*-----------------------------------------------------------------*/
+/* genlshOne - left shift a one byte quantity by known count */