}
#endif
+#if 0
/*-----------------------------------------------------------------*/
/* genAddlit - generates code for addition */
/*-----------------------------------------------------------------*/
}
}
+#endif
static void emitMOVWF(operand *reg, int offset)
{
static void genAddLit (iCode *ic, int lit)
{
- int size,same;
- int lo;
+ int size,sizeL,same;
+ int i, llit;
operand *result;
operand *left;
+ sym_link *lleft;
FENTRY;
left = IC_LEFT(ic);
+ lleft = operandType (left);
result = IC_RESULT(ic);
same = pic16_sameRegs(AOP(left), AOP(result));
size = pic16_getDataSize(result);
+ sizeL = pic16_getDataSize(left);
+ llit = lit;
+
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+ /* move left to result -- possibly sign extend */
+ for (i=0; i < MIN(size, sizeL); i++) {
+ pic16_mov2f (AOP(result), AOP(left), i);
+ } // for i
+#undef MIN
+
+ /* extend to result size */
+ if (IS_UNSIGNED(lleft)) {
+ /* zero-extend */
+ for (i = sizeL; i < size; i++) {
+ pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
+ } // for i
+ } else {
+ /* sign-extend */
+ if (size == sizeL + 1) {
+ pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), sizeL));
+ pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
+ pic16_emitpcode (POC_SETF, pic16_popGet (AOP(result), sizeL));
+ } else {
+ pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
+ pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
+ pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
+
+ for (i=sizeL; i < size; i++) {
+ pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(result), i));
+ } // for i
+ } // if
+ } // if (SIGNED)
+
+ /* special cases */
+ if (lit == 0) {
+ /* nothing to do */
+ } else if (lit == 1) {
+ switch (size) {
+ case 1:
+ /* handled below */
+ break;
+ case 2:
+ pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(result), 0));
+ break;
+ default:
+ assert (size > 2);
+ pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), 0));
+ for (i=1; i < size-1; i++) {
+ emitSKPNC; /* a jump here saves up to 2(size-2)cycles */
+ pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), i));
+ } // for i
+ emitSKPNC;
+ break;
+ } // switch
+
+ pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1));
+ } else {
+ /* general case */
+
+ /* add literal to result */
+ for (i=0; i < size; i++) {
+ pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit));
+ llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */
+ pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC,
+ pic16_popGet (AOP(result), i));
+ }
+ }
+
+#if 0
if(same) {
}
}
}
+#endif
}
/*-----------------------------------------------------------------*/
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 */
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 ;
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;
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 {
- pic16_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));
}
}
}
} 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
- pic16_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));
}
}
}
}
+ // add leftover bytes
+ // either left or right is too short
+ for (i=size; i < AOP_SIZE(result); i++) {
+ // get right operand into WREG
+ if (i < AOP_SIZE(right)) {
+ pic16_mov2w (AOP(right), i);
+ } else {
+ // right is too short
+ pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
+ if (!SPEC_USIGN(getSpec(operandType(right)))) {
+ // right operand is signed
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_COMF, pic16_popCopyReg (&pic16_pc_wreg));
+ }
+ }
+
+ // get left+WREG+CARRY into result
+ if (i < AOP_SIZE(left)) {
+ if (pic16_sameRegs (AOP(left), AOP(result))) {
+ pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
+ } else {
+ pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
+ }
+ } else {
+ // left is too short
+ pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
+ if (!SPEC_USIGN(getSpec(operandType(left)))) {
+ // left operand is signed
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_COMF, pic16_popGet (AOP(result), i));
+ }
+ pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
+ }
+ } // for i
+ goto release;
+
+#if 0
// add leftover bytes
if (SPEC_USIGN(getSpec(operandType(right)))) {
// right is unsigned
}
}
goto release;
+#endif
}
}
// TODO: anything from here to before "release:" is probably obsolete and should be removed
// when the regression tests are stable
- if (AOP_SIZE(IC_RESULT(ic)) > 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));
}
}
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++;
}
//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);
}
/*-----------------------------------------------------------------*/
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));
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));
}
size--;
while(size--){
- if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
+ if (offset < AOP_SIZE(IC_RIGHT(ic)))
pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
- pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(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)))) {
+ pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
} else {
- pic16_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++;
}