- if (shCount >= 24 ) {
- shCount -= 24;
- if (shCount)
- /* lowest order of left goes to the highest
- order of the destination */
- shiftL1Left2Result(left, LSB, result, MSB32, shCount);
- else
- movLeft2Result(left, LSB, result, MSB32, 0);
- aopPut(AOP(result),zero,LSB);
- aopPut(AOP(result),zero,MSB16);
- aopPut(AOP(result),zero,MSB32);
- return;
- }
-
- /* more than two bytes */
- else if ( shCount >= 16 ) {
- /* lower order two bytes goes to higher order two bytes */
- shCount -= 16;
- /* if some more remaining */
- if (shCount)
- shiftL2Left2Result(left, LSB, result, MSB24, shCount);
- else {
- movLeft2Result(left, MSB16, result, MSB32, 0);
- movLeft2Result(left, LSB, result, MSB24, 0);
- }
- aopPut(AOP(result),zero,MSB16);
- aopPut(AOP(result),zero,LSB);
- return;
- }
-
- /* if more than 1 byte */
- else if ( shCount >= 8 ) {
- /* lower order three bytes goes to higher order three bytes */
- shCount -= 8;
- if(size == 2){
- if(shCount)
- shiftL1Left2Result(left, LSB, result, MSB16, shCount);
- else
- movLeft2Result(left, LSB, result, MSB16, 0);
- }
- else{ /* size = 4 */
- if(shCount == 0){
- movLeft2Result(left, MSB24, result, MSB32, 0);
- movLeft2Result(left, MSB16, result, MSB24, 0);
- movLeft2Result(left, LSB, result, MSB16, 0);
- aopPut(AOP(result),zero,LSB);
- }
- else if(shCount == 1)
- shiftLLong(left, result, MSB16);
- else{
- shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
- shiftL1Left2Result(left, LSB, result, MSB16, shCount);
- shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
- aopPut(AOP(result),zero,LSB);
- }
- }
- }
-
- /* 1 <= shCount <= 7 */
- else if(shCount <= 2){
- shiftLLong(left, result, LSB);
- if(shCount == 2)
- shiftLLong(result, result, LSB);
- }
- /* 3 <= shCount <= 7, optimize */
- else{
- shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
- shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
- shiftL2Left2Result(left, LSB, result, LSB, shCount);
- }
-}
-
-/*-----------------------------------------------------------------*/
-/* genLeftShiftLiteral - left shifting by known count */
-/*-----------------------------------------------------------------*/
-static void genLeftShiftLiteral (operand *left,
- operand *right,
- operand *result,
- iCode *ic)
-{
- int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
- int size;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- freeAsmop(right,NULL,ic,TRUE);
-
- aopOp(left,ic,FALSE);
- aopOp(result,ic,FALSE);
-
- size = getSize(operandType(result));
-
-#if VIEW_SIZE
- pic14_emitcode("; shift left ","result %d, left %d",size,
- AOP_SIZE(left));
-#endif
-
- /* I suppose that the left size >= result size */
- if(shCount == 0){
- while(size--){
- movLeft2Result(left, size, result, size, 0);
- }
- }
-
- else if(shCount >= (size * 8))
- while(size--)
- aopPut(AOP(result),zero,size);
- else{
- switch (size) {
- case 1:
- genlshOne (result,left,shCount);
- break;
-
- case 2:
- case 3:
- genlshTwo (result,left,shCount);
- break;
-
- case 4:
- genlshFour (result,left,shCount);
- break;
- }
- }
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
-}
-
-/*-----------------------------------------------------------------*
- * genMultiAsm - repeat assembly instruction for size of register.
- * if endian == 1, then the high byte (i.e base address + size of
- * register) is used first else the low byte is used first;
- *-----------------------------------------------------------------*/
-static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
-{
-
- int offset = 0;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if(!reg)
- return;
-
- if(!endian) {
- endian = 1;
- } else {
- endian = -1;
- offset = size-1;
- }
-
- while(size--) {
- emitpcode(poc, popGet(AOP(reg),offset));
- offset += endian;
- }
-
-}
-/*-----------------------------------------------------------------*/
-/* genLeftShift - generates code for left shifting */
-/*-----------------------------------------------------------------*/
-static void genLeftShift (iCode *ic)
-{
- operand *left,*right, *result;
- int size, offset;
- char *l;
- symbol *tlbl , *tlbl1;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- right = IC_RIGHT(ic);
- left = IC_LEFT(ic);
- result = IC_RESULT(ic);
-
- aopOp(right,ic,FALSE);
-
- /* if the shift count is known then do it
- as efficiently as possible */
- if (AOP_TYPE(right) == AOP_LIT) {
- genLeftShiftLiteral (left,right,result,ic);
- return ;
- }
-
- /* shift count is unknown then we have to form
- a loop get the loop count in B : Note: we take
- only the lower order byte since shifting
- more that 32 bits make no sense anyway, ( the
- largest size of an object can be only 32 bits ) */
-
-
- aopOp(left,ic,FALSE);
- aopOp(result,ic,FALSE);
-
- /* now move the left to the result if they are not the
- same */
- if (!pic14_sameRegs(AOP(left),AOP(result)) &&
- AOP_SIZE(result) > 1) {
-
- size = AOP_SIZE(result);
- offset=0;
- while (size--) {
- l = aopGet(AOP(left),offset,FALSE,TRUE);
- if (*l == '@' && (IS_AOP_PREG(result))) {
-
- pic14_emitcode("mov","a,%s",l);
- aopPut(AOP(result),"a",offset);
- } else
- aopPut(AOP(result),l,offset);
- offset++;
- }
- }
-
- size = AOP_SIZE(result);
-
- /* if it is only one byte then */
- if (size == 1) {
- if(optimized_for_speed) {
- emitpcode(POC_SWAPFW, popGet(AOP(left),0));
- emitpcode(POC_ANDLW, popGetLit(0xf0));
- emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
- emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
- emitpcode(POC_ADDWF, popGet(AOP(result),0));
- emitpcode(POC_RLFW, popGet(AOP(result),0));
- emitpcode(POC_ANDLW, popGetLit(0xfe));
- emitpcode(POC_ADDFW, popGet(AOP(result),0));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
- emitpcode(POC_ADDWF, popGet(AOP(result),0));
- } else {
-
- tlbl = newiTempLabel(NULL);
- if (!pic14_sameRegs(AOP(left),AOP(result))) {
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
- }
-
- emitpcode(POC_COMFW, popGet(AOP(right),0));
- emitpcode(POC_RRF, popGet(AOP(result),0));
- emitpLabel(tlbl->key);
- emitpcode(POC_RLF, popGet(AOP(result),0));
- emitpcode(POC_ADDLW, popGetLit(1));
- emitSKPC;
- emitpcode(POC_GOTO,popGetLabel(tlbl->key));
- }
- goto release ;
- }
-
- if (pic14_sameRegs(AOP(left),AOP(result))) {
-
- tlbl = newiTempLabel(NULL);
- emitpcode(POC_COMFW, popGet(AOP(right),0));
- genMultiAsm(POC_RRF, result, size,1);
- emitpLabel(tlbl->key);
- genMultiAsm(POC_RLF, result, size,0);
- emitpcode(POC_ADDLW, popGetLit(1));
- emitSKPC;
- emitpcode(POC_GOTO,popGetLabel(tlbl->key));
- goto release;
- }
-
- tlbl = newiTempLabel(NULL);
- offset = 0 ;
- tlbl1 = newiTempLabel(NULL);
-
- reAdjustPreg(AOP(result));
-
- pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- l = aopGet(AOP(result),offset,FALSE,FALSE);
- MOVA(l);
- pic14_emitcode("add","a,acc");
- aopPut(AOP(result),"a",offset++);
- while (--size) {
- l = aopGet(AOP(result),offset,FALSE,FALSE);
- MOVA(l);
- pic14_emitcode("rlc","a");
- aopPut(AOP(result),"a",offset++);
- }
- reAdjustPreg(AOP(result));
-
- pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
- pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
-release:
- freeAsmop (right,NULL,ic,TRUE);
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
-}
-
-/*-----------------------------------------------------------------*/
-/* genrshOne - right shift a one byte quantity by known count */
-/*-----------------------------------------------------------------*/
-static void genrshOne (operand *result, operand *left,
- int shCount, int sign)
-{
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
-}
-
-/*-----------------------------------------------------------------*/
-/* genrshTwo - right shift two bytes by known amount != 0 */
-/*-----------------------------------------------------------------*/
-static void genrshTwo (operand *result,operand *left,
- int shCount, int sign)
-{
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* if shCount >= 8 */
- if (shCount >= 8) {
- shCount -= 8 ;
- if (shCount)
- shiftR1Left2Result(left, MSB16, result, LSB,
- shCount, sign);
- else
- movLeft2Result(left, MSB16, result, LSB, sign);
-
- emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
-
- if(sign) {
- emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
- emitpcode(POC_DECF, popGet(AOP(result),MSB16));
- }
- }
-
- /* 1 <= shCount <= 7 */
- else
- shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
-}
-
-/*-----------------------------------------------------------------*/
-/* shiftRLong - shift right one long from left to result */
-/* offl = LSB or MSB16 */
-/*-----------------------------------------------------------------*/
-static void shiftRLong (operand *left, int offl,
- operand *result, int sign)
-{
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(!sign)
- pic14_emitcode("clr","c");
- MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
- if(sign)
- pic14_emitcode("mov","c,acc.7");
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"a",MSB32-offl);
- if(offl == MSB16)
- /* add sign of "a" */
- addSign(result, MSB32, sign);
-
- MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"a",MSB24-offl);
-
- MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"a",MSB16-offl);
-
- if(offl == LSB){
- MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"a",LSB);
- }
-}
-
-/*-----------------------------------------------------------------*/
-/* genrshFour - shift four byte by a known amount != 0 */
-/*-----------------------------------------------------------------*/
-static void genrshFour (operand *result, operand *left,
- int shCount, int sign)
-{
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* if shifting more that 3 bytes */
- if(shCount >= 24 ) {