X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fgenarith.c;h=318aa2982ca72644a79262224588046a83d33acb;hb=5c9bc6794175751c36380b2088f0312b79c229b4;hp=8221433fd7b5558891ae2fa8fc788b100f1121dc;hpb=35dd84251b9d153bb48ad98be9c5eae77799cb42;p=fw%2Fsdcc diff --git a/src/pic16/genarith.c b/src/pic16/genarith.c index 8221433f..318aa298 100644 --- a/src/pic16/genarith.c +++ b/src/pic16/genarith.c @@ -602,21 +602,8 @@ static void genAddLit (iCode *ic, int lit) lo = BYTEofLONG(lit,0); if(carry_info) { - switch(lo) { - case 0: - emitSKPNC; - pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset)); - break; - case 0xff: - pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo)); - emitSKPC; - pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset)); - break; - default: - pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo)); - pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset)); - break; - } + pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo)); + pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset)); }else { /* no carry info from previous step */ /* this means this is the first time to add */ @@ -688,7 +675,7 @@ static void genAddLit (iCode *ic, int lit) /* left addend is in a register */ switch(lit & 0xff) { case 0: - mov2w(AOP(left),0); + pic16_mov2w(AOP(left),0); emitMOVWF(result, 0); break; case 1: @@ -717,7 +704,7 @@ static void genAddLit (iCode *ic, int lit) pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff)); pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); } else { - mov2w(AOP(left),0); + pic16_mov2w(AOP(left),0); /* We don't know the state of the carry bit at this point */ clear_carry = 1; } @@ -745,7 +732,7 @@ static void genAddLit (iCode *ic, int lit) } else { pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); - mov2w(AOP(left),offset); + pic16_mov2w(AOP(left),offset); pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset)); } offset++; @@ -780,8 +767,8 @@ void pic16_genPlus (iCode *ic) if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) { operand *t = right; - right = left; - left = t; + right = IC_RIGHT(ic) = left; + left = IC_LEFT(ic) = t; } /* if both left & right are in bit space */ @@ -803,11 +790,15 @@ void pic16_genPlus (iCode *ic) pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0)); } } else { + unsigned long lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit); size = pic16_getDataSize(result); while (size--) { - MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - pic16_emitcode("addc","a,#00 ;%d",__LINE__); - pic16_aopPut(AOP(result),"a",offset++); + pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset)); + pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF)); + pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++)); + //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE)); + //pic16_emitcode("addc","a,#00 ;%d",__LINE__); + //pic16_aopPut(AOP(result),"a",offset++); } } goto release ; @@ -818,12 +809,12 @@ void pic16_genPlus (iCode *ic) if (pic16_genPlusIncr (ic) == TRUE) goto release; - size = pic16_getDataSize(IC_RESULT(ic)); + size = pic16_getDataSize(result); - if(AOP(IC_RIGHT(ic))->type == AOP_LIT) { + if(AOP(right)->type == AOP_LIT) { /* Add a literal to something else */ //bool know_W=0; - unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); + unsigned lit = (unsigned) floatFromVal(AOP(right)->aopu.aop_lit); //unsigned l1=0; //offset = 0; @@ -832,55 +823,55 @@ void pic16_genPlus (iCode *ic) genAddLit (ic, lit); goto release; - } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { + } else if(AOP_TYPE(right) == AOP_CRY) { - pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE)); + pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE)); + pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE)); /* here we are adding a bit to a char or int */ if(size == 1) { - if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { + if (pic16_sameRegs(AOP(left), AOP(result)) ) { - pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0)); - pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0)); + pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0)); pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + AOP(right)->aopu.aop_dir, + AOP(right)->aopu.aop_dir); + pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE)); } else { // not same - if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { - pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0)); + if(AOP_TYPE(left) == AOP_ACC) { + pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0)); pic16_emitpcode(POC_XORLW , pic16_popGetLit(1)); pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); + AOP(right)->aopu.aop_dir, + AOP(right)->aopu.aop_dir); pic16_emitcode(" xorlw","1"); } else { - mov2w(AOP(IC_LEFT(ic)),0); - pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0)); - pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0)); + pic16_mov2w(AOP(left),0); + pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0)); - pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE)); pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + AOP(right)->aopu.aop_dir, + AOP(right)->aopu.aop_dir); + pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE)); } - if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) { + if(AOP_TYPE(result) != AOP_ACC) { - if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) { + if(AOP_TYPE(result) == AOP_CRY) { pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1)); - pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0)); + pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0)); emitSKPZ; - pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0)); + pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0)); } else { - pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0)); - pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0)); + pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE)); } } } @@ -888,39 +879,39 @@ void pic16_genPlus (iCode *ic) } else { int offset = 1; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { + if (pic16_sameRegs(AOP(left), AOP(result)) ) { emitCLRZ; - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0)); - pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0)); + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0)); pic16_emitcode("clrz",""); pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + AOP(right)->aopu.aop_dir, + AOP(right)->aopu.aop_dir); + pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE)); } else { emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then - mov2w(AOP(IC_LEFT(ic)),0); - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0)); - pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0)); - //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitMOVWF(IC_RIGHT(ic),0); + pic16_mov2w(AOP(left),0); + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0)); + //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE)); + emitMOVWF(right,0); - pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE)); pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + AOP(right)->aopu.aop_dir, + AOP(right)->aopu.aop_dir); + pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE)); + pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE)); } while(--size){ emitSKPZ; - pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++)); - //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE)); + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++)); + //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE)); } } @@ -1008,7 +999,7 @@ void pic16_genPlus (iCode *ic) // add first bytes for(i=0; i AOP_SIZE(IC_RIGHT(ic))) { - int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) | - SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) ); + if (AOP_SIZE(result) > AOP_SIZE(right)) { + int sign = !(SPEC_USIGN(getSpec(operandType(left))) | + SPEC_USIGN(getSpec(operandType(right))) ); /* Need to extend result to higher bytes */ - size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1; + size = AOP_SIZE(result) - AOP_SIZE(right) - 1; /* First grab the carry from the lower bytes */ - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset)); if(sign) { /* Now this is really horrid. Gotta check the sign of the addends and propogate * to the result */ - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); + pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); + pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset)); /* if chars or ints or being signed extended to longs: */ if(size) { pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff)); } } @@ -1103,9 +1133,9 @@ void pic16_genPlus (iCode *ic) while(size--) { if(sign) - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); else - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); offset++; } @@ -1115,9 +1145,9 @@ void pic16_genPlus (iCode *ic) //adjustArithmeticResult(ic); release: - pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); + pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -1151,8 +1181,7 @@ bool pic16_genMinusDec (iCode *ic) if(size == 2) { pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB)); - pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB)); - pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16)); + emitSKPC; pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16)); pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); @@ -1160,27 +1189,24 @@ bool pic16_genMinusDec (iCode *ic) pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE)); } else { /* size is 3 or 4 */ - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff)); - pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB)); - emitSKPNC; - pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16)); - emitSKPNC; - pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24)); + pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB)); + pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB16)); + pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB24)); pic16_emitcode("movlw","0xff"); pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); - emitSKPNC; + //emitSKPNC; pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE)); - emitSKPNC; + //emitSKPNC; pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE)); if(size > 3) { - emitSKPNC; - pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32)); + pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB32)); pic16_emitcode("skpnc",""); - emitSKPNC; + //emitSKPNC; pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE)); } @@ -1419,7 +1445,7 @@ void pic16_genMinus (iCode *ic) } } else { - mov2w(AOP(IC_LEFT(ic)),0); + pic16_mov2w(AOP(IC_LEFT(ic)),0); pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0)); pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0)); } @@ -1463,7 +1489,7 @@ void pic16_genMinus (iCode *ic) goto release; } - mov2w(AOP(IC_RIGHT(ic)),0); + pic16_mov2w(AOP(IC_RIGHT(ic)),0); pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff)); pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0)); @@ -1501,7 +1527,7 @@ void pic16_genMinus (iCode *ic) DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) - mov2w(AOP(IC_RIGHT(ic)),0); + pic16_mov2w(AOP(IC_RIGHT(ic)),0); if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0)); @@ -1537,13 +1563,32 @@ void pic16_genMinus (iCode *ic) size--; while(size--){ + if (offset < AOP_SIZE(IC_RIGHT(ic))) + pic16_mov2w(AOP(IC_RIGHT(ic)),offset); + else { + pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg)); + if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) { + // signed -- sign extend the right operand + pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),AOP_SIZE(IC_RIGHT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); + pic16_emitpcode (POC_COMF, pic16_popCopyReg (&pic16_pc_wreg)); + } + } if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) { - mov2w(AOP(IC_RIGHT(ic)),offset); - pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset)); } else { - mov2w(AOP(IC_RIGHT(ic)),offset); - pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); + 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_COMF, 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++; } @@ -1807,7 +1852,7 @@ void pic16_genUMult8X8_8 (operand *left, if(AOP_TYPE(left) != AOP_ACC) { // left is not WREG if(AOP_TYPE(right) != AOP_ACC) { - mov2w(AOP(left), 0); + pic16_mov2w(AOP(left), 0); pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0)); } else { pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0)); @@ -1875,7 +1920,7 @@ void pic16_genUMult16X16_16 (operand *left, pct3 = pic16_popGetTempReg(1); pct4 = pic16_popGetTempReg(1); - mov2w(AOP(left), 0); + pic16_mov2w(AOP(left), 0); pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0)); pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1))); @@ -1887,7 +1932,7 @@ void pic16_genUMult16X16_16 (operand *left, pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3))); - mov2w(AOP(left), 1); + pic16_mov2w(AOP(left), 1); pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0)); pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4))); @@ -1907,7 +1952,7 @@ void pic16_genUMult16X16_16 (operand *left, } else { - mov2w(AOP(left), 0); + pic16_mov2w(AOP(left), 0); pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0)); pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0))); @@ -1919,7 +1964,7 @@ void pic16_genUMult16X16_16 (operand *left, pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl)); pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1)); - mov2w(AOP(left), 1); + pic16_mov2w(AOP(left), 1); pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0)); pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl)); pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1)); @@ -1960,7 +2005,7 @@ void pic16_genSMult8X8_8 (operand *left, #if 0 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi)); - mov2w(AOP(left),0); + pic16_mov2w(AOP(left),0); pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1)); #endif @@ -2152,7 +2197,7 @@ void pic16_genUMult32X32_32 (operand *left, pct3 = pic16_popGetTempReg(1); pct4 = pic16_popGetTempReg(1); - mov2w(AOP(left), 0); + pic16_mov2w(AOP(left), 0); pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0)); pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1))); @@ -2164,7 +2209,7 @@ void pic16_genUMult32X32_32 (operand *left, pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3))); - mov2w(AOP(left), 1); + pic16_mov2w(AOP(left), 1); pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0)); pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4))); @@ -2184,7 +2229,7 @@ void pic16_genUMult32X32_32 (operand *left, } else { - mov2w(AOP(left), 0); + pic16_mov2w(AOP(left), 0); pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0)); pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0))); @@ -2196,7 +2241,7 @@ void pic16_genUMult32X32_32 (operand *left, pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl)); pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1)); - mov2w(AOP(left), 1); + pic16_mov2w(AOP(left), 1); pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0)); pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl)); pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));