const char *pic16_AopType(short type)
{
switch(type) {
- case AOP_LIT:
- return "AOP_LIT";
- break;
- case AOP_REG:
- return "AOP_REG";
- break;
- case AOP_DIR:
- return "AOP_DIR";
- break;
- case AOP_DPTR:
- return "AOP_DPTR";
- break;
- case AOP_DPTR2:
- return "AOP_DPTR2";
- break;
- case AOP_R0:
- return "AOP_R0";
- break;
- case AOP_R1:
- return "AOP_R1";
- break;
- case AOP_STK:
- return "AOP_STK";
- break;
- case AOP_IMMD:
- return "AOP_IMMD";
- break;
- case AOP_STR:
- return "AOP_STR";
- break;
- case AOP_CRY:
- return "AOP_CRY";
- break;
- case AOP_ACC:
- return "AOP_ACC";
- break;
- case AOP_PCODE:
- return "AOP_PCODE";
- break;
+ case AOP_LIT: return "AOP_LIT";
+ case AOP_REG: return "AOP_REG";
+ case AOP_DIR: return "AOP_DIR";
+ case AOP_DPTR: return "AOP_DPTR";
+ case AOP_DPTR2: return "AOP_DPTR2";
+ case AOP_FSR0: return "AOP_FSR0";
+ case AOP_FSR2: return "AOP_FSR2";
+ case AOP_R0: return "AOP_R0";
+ case AOP_R1: return "AOP_R1";
+ case AOP_STK: return "AOP_STK";
+ case AOP_IMMD: return "AOP_IMMD";
+ case AOP_STR: return "AOP_STR";
+ case AOP_CRY: return "AOP_CRY";
+ case AOP_ACC: return "AOP_ACC";
+ case AOP_PCODE: return "AOP_PCODE";
+ case AOP_STA: return "AOP_STA";
}
return "BAD TYPE";
switch(pcop->type) {
- case PO_NONE:
- return "PO_NONE";
- case PO_W:
- return "PO_W";
- case PO_WREG:
- return "PO_WREG";
- case PO_STATUS:
- return "PO_STATUS";
- case PO_BSR:
- return "PO_BSR";
- case PO_FSR0:
- return "PO_FSR0";
- case PO_INDF0:
- return "PO_INDF0";
- case PO_INTCON:
- return "PO_INTCON";
- case PO_GPR_REGISTER:
- return "PO_GPR_REGISTER";
- case PO_GPR_BIT:
- return "PO_GPR_BIT";
- case PO_GPR_TEMP:
- return "PO_GPR_TEMP";
- case PO_SFR_REGISTER:
- return "PO_SFR_REGISTER";
- case PO_PCL:
- return "PO_PCL";
- case PO_PCLATH:
- return "PO_PCLATH";
- case PO_PCLATU:
- return "PO_PCLATU";
- case PO_PRODL:
- return "PO_PRODL";
- case PO_PRODH:
- return "PO_PRODH";
- case PO_LITERAL:
- return "PO_LITERAL";
- case PO_REL_ADDR:
- return "PO_REL_ADDR";
- case PO_IMMEDIATE:
- return "PO_IMMEDIATE";
- case PO_DIR:
- return "PO_DIR";
- case PO_CRY:
- return "PO_CRY";
- case PO_BIT:
- return "PO_BIT";
- case PO_STR:
- return "PO_STR";
- case PO_LABEL:
- return "PO_LABEL";
- case PO_WILD:
- return "PO_WILD";
+ case PO_NONE: return "PO_NONE";
+ case PO_W: return "PO_W";
+ case PO_WREG: return "PO_WREG";
+ case PO_STATUS: return "PO_STATUS";
+ case PO_BSR: return "PO_BSR";
+ case PO_FSR0: return "PO_FSR0";
+ case PO_INDF0: return "PO_INDF0";
+ case PO_INTCON: return "PO_INTCON";
+ case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
+ case PO_GPR_BIT: return "PO_GPR_BIT";
+ case PO_GPR_TEMP: return "PO_GPR_TEMP";
+ case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
+ case PO_PCL: return "PO_PCL";
+ case PO_PCLATH: return "PO_PCLATH";
+ case PO_PCLATU: return "PO_PCLATU";
+ case PO_PRODL: return "PO_PRODL";
+ case PO_PRODH: return "PO_PRODH";
+ case PO_LITERAL: return "PO_LITERAL";
+ case PO_REL_ADDR: return "PO_REL_ADDR";
+ case PO_IMMEDIATE: return "PO_IMMEDIATE";
+ case PO_DIR: return "PO_DIR";
+ case PO_CRY: return "PO_CRY";
+ case PO_BIT: return "PO_BIT";
+ case PO_STR: return "PO_STR";
+ case PO_LABEL: return "PO_LABEL";
+ case PO_WILD: return "PO_WILD";
}
}
switch(PCORB(pcop)->subtype) {
- case PO_NONE:
- return "PO_NONE";
- case PO_W:
- return "PO_W";
- case PO_WREG:
- return "PO_WREG";
- case PO_STATUS:
- return "PO_STATUS";
- case PO_BSR:
- return "PO_BSR";
- case PO_FSR0:
- return "PO_FSR0";
- case PO_INDF0:
- return "PO_INDF0";
- case PO_INTCON:
- return "PO_INTCON";
- case PO_GPR_REGISTER:
- return "PO_GPR_REGISTER";
- case PO_GPR_BIT:
- return "PO_GPR_BIT";
- case PO_GPR_TEMP:
- return "PO_GPR_TEMP";
- case PO_SFR_REGISTER:
- return "PO_SFR_REGISTER";
- case PO_PCL:
- return "PO_PCL";
- case PO_PCLATH:
- return "PO_PCLATH";
- case PO_PCLATU:
- return "PO_PCLATU";
- case PO_PRODL:
- return "PO_PRODL";
- case PO_PRODH:
- return "PO_PRODH";
- case PO_LITERAL:
- return "PO_LITERAL";
- case PO_REL_ADDR:
- return "PO_REL_ADDR";
- case PO_IMMEDIATE:
- return "PO_IMMEDIATE";
- case PO_DIR:
- return "PO_DIR";
- case PO_CRY:
- return "PO_CRY";
- case PO_BIT:
- return "PO_BIT";
- case PO_STR:
- return "PO_STR";
- case PO_LABEL:
- return "PO_LABEL";
- case PO_WILD:
- return "PO_WILD";
+ case PO_NONE: return "PO_NONE";
+ case PO_W: return "PO_W";
+ case PO_WREG: return "PO_WREG";
+ case PO_STATUS: return "PO_STATUS";
+ case PO_BSR: return "PO_BSR";
+ case PO_FSR0: return "PO_FSR0";
+ case PO_INDF0: return "PO_INDF0";
+ case PO_INTCON: return "PO_INTCON";
+ case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
+ case PO_GPR_BIT: return "PO_GPR_BIT";
+ case PO_GPR_TEMP: return "PO_GPR_TEMP";
+ case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
+ case PO_PCL: return "PO_PCL";
+ case PO_PCLATH: return "PO_PCLATH";
+ case PO_PCLATU: return "PO_PCLATU";
+ case PO_PRODL: return "PO_PRODL";
+ case PO_PRODH: return "PO_PRODH";
+ case PO_LITERAL: return "PO_LITERAL";
+ case PO_REL_ADDR: return "PO_REL_ADDR";
+ case PO_IMMEDIATE: return "PO_IMMEDIATE";
+ case PO_DIR: return "PO_DIR";
+ case PO_CRY: return "PO_CRY";
+ case PO_BIT: return "PO_BIT";
+ case PO_STR: return "PO_STR";
+ case PO_LABEL: return "PO_LABEL";
+ case PO_WILD: return "PO_WILD";
}
}
/*-----------------------------------------------------------------*/
bool pic16_genPlusIncr (iCode *ic)
{
- unsigned int icount ;
- unsigned int size = pic16_getDataSize(IC_RESULT(ic));
+ unsigned int icount ;
+ unsigned int size = pic16_getDataSize(IC_RESULT(ic));
+
+ FENTRY;
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
//pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
while(--size) {
- emitSKPNZ;
+ emitSKPNC;
pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
//pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
}
/* if the result is a bit */
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ assert(0); // not implemented for PIC16?
+
if (AOP_TYPE(result) == AOP_CRY){
pic16_aopPut(AOP(result),"a",0);
}
/*-----------------------------------------------------------------*/
void pic16_genPlusBits (iCode *ic)
{
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ FENTRY;
DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
/*-----------------------------------------------------------------*/
static void genAddLit2byte (operand *result, int offr, int lit)
{
-
+ FENTRY;
+
switch(lit & 0xff) {
case 0:
break;
operand *result;
operand *left;
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ FENTRY;
left = IC_LEFT(ic);
pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ break;
+ default: /* 0x01LL */
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+ pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
+ emitSKPNC;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
}
break;
genAddLit2byte (result, MSB16, hi);
break;
case 1: /* 0xHH01 */
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1)&0xff));
- pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
- pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
+ pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
break;
/* case 0xff: * 0xHHff *
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
- emitSKPNC;
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1) & 0xff));
- pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
+ pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
break;
}
lo = BYTEofLONG(lit,0);
if(carry_info) {
- switch(lo) {
- case 0:
- switch(carry_info) {
- case 1:
- emitSKPNZ;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
- break;
- case 2:
- pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
- pic16_emitpcode(POC_ANDLW, pic16_popGetLit(1));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
- break;
- default: /* carry_info = 3 */
- emitSKPNC;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
- carry_info = 1;
- break;
- }
- break;
- case 0xff:
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- if(carry_info==1)
- emitSKPZ;
- else
- emitSKPC;
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
- break;
- default:
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- if(carry_info==1)
- emitSKPNZ;
- else
- emitSKPNC;
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo+1));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
- carry_info=2;
- 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 */
/* left addend is in a register */
switch(lit & 0xff) {
case 0:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
+ pic16_mov2w(AOP(left),0);
emitMOVWF(result, 0);
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
break;
case 1:
pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
} else {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
+ pic16_mov2w(AOP(left),0);
/* We don't know the state of the carry bit at this point */
clear_carry = 1;
}
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
clear_carry = 0;
} else {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset,FALSE,FALSE));
- emitMOVWF(result,offset);
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
- emitSKPNC;
- pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
+ pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
}
} else {
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
+ pic16_mov2w(AOP(left),offset);
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
}
offset++;
}
/*-----------------------------------------------------------------*/
void pic16_genPlus (iCode *ic)
{
- int i, size, offset = 0;
- operand *result, *left, *right;
-
- /* special cases :- */
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
+ int i, size, offset = 0;
+ operand *result, *left, *right;
+ FENTRY;
+
+ /* special cases :- */
result = IC_RESULT(ic);
left = IC_LEFT(ic);
right = IC_RIGHT(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 */
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_emitpcode(POC_MOVFW , pic16_popGet(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 {
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(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_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
+ 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(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));
}
}
}
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
}
+
+ DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
// add leftover bytes
if (SPEC_USIGN(getSpec(operandType(right)))) {
// right is signed, oh dear ...
for(i=size; i< AOP_SIZE(result); i++) {
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
// add first bytes
for(i=0; i<size; i++) {
if (AOP_TYPE(right) != AOP_ACC)
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),i));
+ pic16_mov2w(AOP(right),i);
if (pic16_sameRegs(AOP(left), AOP(result)))
{
if(i) { // add with carry
}
}
+ // 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
pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
} else { // not same
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),i));
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
+ pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
}
}
} else {
}
}
goto release;
+#endif
}
}
+ assert( 0 );
// 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);
}
/*-----------------------------------------------------------------*/
unsigned int icount ;
unsigned int size = pic16_getDataSize(IC_RESULT(ic));
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ FENTRY;
/* will try to generate an increment */
/* if the right side is not a literal
we cannot */
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));
}
void pic16_genMinusBits (iCode *ic)
{
symbol *lbl = newiTempLabel(NULL);
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ FENTRY;
if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
int size, offset = 0, same=0;
unsigned long lit = 0L;
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ FENTRY;
pic16_aopOp (IC_LEFT(ic),ic,FALSE);
pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
pic16_aopOp (IC_RESULT(ic),ic,TRUE);
if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
if(lit & 1) {
- pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
+ pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
}
}else{
pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
- pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
+ //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
}
} else {
- pic16_emitpcode(POC_MOVFW , pic16_popGet(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));
}
if( (size == 1) && ((lit & 0xff) == 0) ) {
/* res = 0 - right */
if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
- pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
+ pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
} else {
pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
goto release;
}
- pic16_emitpcode(POC_MOVFW, pic16_popGet(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));
- offset = 1;
+ offset = 0;
while(--size) {
lit >>= 8;
-
- if(size == 1) {
- /* This is the last byte in a multibyte subtraction
- * There are a couple of tricks we can do by not worrying about
- * propogating the carry */
- if(lit == 0xff) {
- /* 0xff - x == ~x */
- if(same) {
- pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
- emitSKPC;
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
- } else {
- pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
- emitSKPC;
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
- }
- } else {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
- emitSKPC;
- pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
- pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
- }
-
- goto release;
- }
-
+ offset++;
if(same) {
-
- if(lit & 0xff) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- emitSKPC;
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
- pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
- } else {
- emitSKPNC;
- pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
-
- }
+ // here we have x = lit - x for sizeof(x)>1
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
} else {
-
- if(lit & 0xff) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
- } else
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
- emitSKPC;
- pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
- pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
}
}
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
+ if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
} else {
- if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
- pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
- if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
- } else {
-
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
- pic16_emitpcode(POC_MOVFW,pic16_popGet(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));
pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
}
}
- }
}
/*
size--;
while(size--){
- if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
+ 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));
+ }
}
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
- emitSKPC;
- pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
- pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
-
+ if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
+ pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
+ } else {
+ 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++;
}
{
unsigned int lit;
int same;
+ int size = AOP_SIZE(result);
+ int i;
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ FENTRY;
+ DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
if (AOP_TYPE(right) != AOP_LIT){
fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
if(same) {
switch(lit) {
case 0:
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+ while (size--) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
+ } // while
return;
case 2:
// its faster to left shift
+ for (i=1; i < size; i++) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
+ } // for
emitCLRC;
pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
+ if (size > 1)
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
return;
default:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+ if(AOP_TYPE(left) != AOP_ACC)
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
pic16_popGet(AOP(result), 0)));
+ if (size > 1) {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
+ pic16_popGet(AOP(result), 1)));
+ for (i=2; i < size; i++) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
+ } // for
+ } // if
return;
}
} else {
// operands different
switch(lit) {
case 0:
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
+ while (size--) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
+ } // while
return;
case 2:
+ for (i=1; i < size; i++) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
+ } // for
emitCLRC;
pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+ if (size > 1)
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
return;
default:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+ if(AOP_TYPE(left) != AOP_ACC)
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
pic16_popGet(AOP(result), 0)));
+
+ if (size > 1) {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
+ pic16_popGet(AOP(result), 1)));
+ for (i=2; i < size; i++) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
+ } // for
+ } // if
return;
}
}
int same;
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
+ FENTRY;
+
if (AOP_TYPE(right) != AOP_LIT){
fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
exit(1);
default: {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pct1 = pic16_popGetTempReg();
- pct2 = pic16_popGetTempReg();
- pct3 = pic16_popGetTempReg();
- pct4 = pic16_popGetTempReg();
+ pct1 = pic16_popGetTempReg(1);
+ pct2 = pic16_popGetTempReg(1);
+ pct3 = pic16_popGetTempReg(1);
+ pct4 = pic16_popGetTempReg(1);
pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
- pic16_popReleaseTempReg( pct4 );
- pic16_popReleaseTempReg( pct3 );
- pic16_popReleaseTempReg( pct2 );
- pic16_popReleaseTempReg( pct1 );
+ pic16_popReleaseTempReg(pct4,1);
+ pic16_popReleaseTempReg(pct3,1);
+ pic16_popReleaseTempReg(pct2,1);
+ pic16_popReleaseTempReg(pct1,1);
}; return;
}
} else {
operand *result)
{
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
+ FENTRY;
+
if (AOP_TYPE(right) == AOP_LIT) {
pic16_genUMult8XLit_8(left,right,result);
if(AOP_TYPE(left) != AOP_ACC) {
// left is not WREG
if(AOP_TYPE(right) != AOP_ACC) {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(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));
{
pCodeOp *pct1, *pct2, *pct3, *pct4;
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ FENTRY;
if (AOP_TYPE(right) == AOP_LIT) {
if(pic16_sameRegs(AOP(result), AOP(left))) {
- pct1 = pic16_popGetTempReg();
- pct2 = pic16_popGetTempReg();
- pct3 = pic16_popGetTempReg();
- pct4 = pic16_popGetTempReg();
+ pct1 = pic16_popGetTempReg(1);
+ pct2 = pic16_popGetTempReg(1);
+ pct3 = pic16_popGetTempReg(1);
+ pct4 = pic16_popGetTempReg(1);
- pic16_emitpcode(POC_MOVFW, pic16_popGet(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)));
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(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)));
pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
- pic16_popReleaseTempReg( pct4 );
- pic16_popReleaseTempReg( pct3 );
- pic16_popReleaseTempReg( pct2 );
- pic16_popReleaseTempReg( pct1 );
+ pic16_popReleaseTempReg( pct4, 1 );
+ pic16_popReleaseTempReg( pct3, 1 );
+ pic16_popReleaseTempReg( pct2, 1 );
+ pic16_popReleaseTempReg( pct1, 1 );
} else {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(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)));
pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(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));
#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));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(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
operand *right,
operand *result)
{
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if(AOP_TYPE(right) == AOP_LIT)
- pic16_genUMult8XLit_8(left,right,result);
- else
- pic16_genUMult8X8_8(left,right,result);
+ FENTRY;
+
+ if(AOP_TYPE(right) == AOP_LIT)
+ pic16_genUMult8XLit_8(left,right,result);
+ else
+ pic16_genUMult8X8_8(left,right,result);
}
operand *right,
operand *result)
{
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if (AOP_TYPE(right) == AOP_LIT)
- pic16_genUMult16XLit_16(left,right,result);
- else
- pic16_genUMult16X16_16(left,right,result);
-
+ FENTRY;
+
+ if (AOP_TYPE(right) == AOP_LIT)
+ pic16_genUMult16XLit_16(left,right,result);
+ else
+ pic16_genUMult16X16_16(left,right,result);
}
int same;
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
+ FENTRY;
+
if (AOP_TYPE(right) != AOP_LIT){
fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
exit(1);
default: {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pct1 = pic16_popGetTempReg();
- pct2 = pic16_popGetTempReg();
- pct3 = pic16_popGetTempReg();
- pct4 = pic16_popGetTempReg();
+ pct1 = pic16_popGetTempReg(1);
+ pct2 = pic16_popGetTempReg(1);
+ pct3 = pic16_popGetTempReg(1);
+ pct4 = pic16_popGetTempReg(1);
pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
- pic16_popReleaseTempReg( pct4 );
- pic16_popReleaseTempReg( pct3 );
- pic16_popReleaseTempReg( pct2 );
- pic16_popReleaseTempReg( pct1 );
+ pic16_popReleaseTempReg( pct4, 1 );
+ pic16_popReleaseTempReg( pct3, 1 );
+ pic16_popReleaseTempReg( pct2, 1 );
+ pic16_popReleaseTempReg( pct1, 1 );
}; return;
}
} else {
{
pCodeOp *pct1, *pct2, *pct3, *pct4;
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
-
+ FENTRY;
+
if (AOP_TYPE(right) == AOP_LIT) {
pic16_genUMult8XLit_8(left,right,result);
return;
if(pic16_sameRegs(AOP(result), AOP(left))) {
- pct1 = pic16_popGetTempReg();
- pct2 = pic16_popGetTempReg();
- pct3 = pic16_popGetTempReg();
- pct4 = pic16_popGetTempReg();
+ pct1 = pic16_popGetTempReg(1);
+ pct2 = pic16_popGetTempReg(1);
+ pct3 = pic16_popGetTempReg(1);
+ pct4 = pic16_popGetTempReg(1);
- pic16_emitpcode(POC_MOVFW, pic16_popGet(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)));
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(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)));
pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
- pic16_popReleaseTempReg( pct4 );
- pic16_popReleaseTempReg( pct3 );
- pic16_popReleaseTempReg( pct2 );
- pic16_popReleaseTempReg( pct1 );
+ pic16_popReleaseTempReg( pct4, 1 );
+ pic16_popReleaseTempReg( pct3, 1 );
+ pic16_popReleaseTempReg( pct2, 1 );
+ pic16_popReleaseTempReg( pct1, 1 );
} else {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(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)));
pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(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));
operand *right,
operand *result)
{
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if (AOP_TYPE(right) == AOP_LIT)
- pic16_genUMult32XLit_32(left,right,result);
- else
- pic16_genUMult32X32_32(left,right,result);
-
+ FENTRY;
+
+ if (AOP_TYPE(right) == AOP_LIT)
+ pic16_genUMult32XLit_32(left,right,result);
+ else
+ pic16_genUMult32X32_32(left,right,result);
}