#include "pcode.h"
#include "gen.h"
+//#define D_POS(txt) DEBUGpic16_emitcode ("; TECODEV::: " txt, " (%s:%d (%s))", __FILE__, __LINE__, __FUNCTION__)
+
+#define D_POS(msg) DEBUGpic16_emitcode("; ", msg, "%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__)
+
#if 1
#define pic16_emitcode DEBUGpic16_emitcode
#endif
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";
}
-const char *pic16_pCodeOpType( pCodeOp *pcop)
+const char *pic16_pCodeOpType(pCodeOp *pcop)
{
if(pcop) {
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";
+ }
+ }
+
+ return "BAD PO_TYPE";
+}
+
+const char *pic16_pCodeOpSubType(pCodeOp *pcop)
+{
+
+ if(pcop && (pcop->type == PO_GPR_BIT)) {
+
+ 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";
}
}
//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);
}
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 */
+ D_POS("FIXED: added default case for adding 0x01??");
+ 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));
+ D_POS(">>> IMPROVED");
+ 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));
+ D_POS("<<< IMPROVED");
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));
+ D_POS(">>> IMPROVED");
+ pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
+ D_POS("<<< IMPROVED");
break;
}
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;
- }
+ D_POS(">>> IMPROVED and compacted");
+ emitSKPNC;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
+ D_POS("<<< IMPROVED and compacted");
break;
case 0xff:
pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- if(carry_info==1)
- emitSKPZ;
- else
- emitSKPC;
+ D_POS(">>> Changed from SKPZ/SKPC to always SKPC");
+ emitSKPC;
pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
break;
default:
+ D_POS(">>> IMPROVED and compacted");
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;
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
+ D_POS("<<< IMPROVED and compacted");
break;
}
}else {
case 0:
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
emitMOVWF(result, 0);
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
+ D_POS(">>> REMOVED double assignment");
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),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),offset));
+ D_POS(">>> FIXED from left to result");
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+ D_POS("<<< FIXED from left to result");
clear_carry = 0;
} else {
+ D_POS(">>> FIXED");
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));
+ D_POS("<<< FIXED");
}
} else {
+ D_POS(">>> IMPROVED");
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_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
+ D_POS("<<< IMPROVED");
}
offset++;
}
pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
} else {
-
+ emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
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));
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
size = min( AOP_SIZE(result), AOP_SIZE(right) );
+ size = min( size, AOP_SIZE(left) );
offset = 0;
+ if(pic16_debug_verbose) {
+// fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
+// AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
+// fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
+ }
+
+
+
if ((AOP_TYPE(left) == AOP_PCODE) && (
(AOP(left)->aopu.pcop->type == PO_LITERAL) ||
- (AOP(left)->aopu.pcop->type == PO_DIR) ||
+// (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
(AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
{
// add to literal operand
}
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));
+ D_POS(">>> FIXED sign test from result to right");
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ D_POS("<<< FIXED sign test from result to right");
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));
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));
+ D_POS (">>> FIXED added to uninitialized result");
+ 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));
+ D_POS ("<<< FIXED");
}
}
} else {
// right is signed
for(i=size; i< AOP_SIZE(result); i++) {
- pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0));
- pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
- if (pic16_sameRegs(AOP(left), AOP(result)))
- {
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
- } else { // not same
- pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
+ if(size < AOP_SIZE(left)) {
+ pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
+ if (pic16_sameRegs(AOP(left), AOP(result)))
+ {
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
+ } else { // not same
+ pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
+ }
+ } else {
+ pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
}
}
}
}
+ assert( 0 );
// TODO: anything from here to before "release:" is probably obsolete and should be removed
// when the regression tests are stable
/* 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));
+ 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));
+ 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));
/* 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));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
}
}
if(size == 1) {
pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
- pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
+ pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
} else {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
while(size--)
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
/* if I can do an decrement instead
of subtract then GOOD for ME */
- // if (pic16_genMinusDec (ic) == TRUE)
- // goto release;
+// if (pic16_genMinusDec (ic) == TRUE)
+// goto release;
size = pic16_getDataSize(IC_RESULT(ic));
same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
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));
+ D_POS(">>> FIXED from MOVLW right(=result) to MOVLW left(=literal,left&1==1)");
+ 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));
+ D_POS(">>> IMPROVED removed following assignment W-->result");
+ //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(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));
+ D_POS(">>> IMPROVED changed comf,incf to negf");
+ pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
+ D_POS("<<< IMPROVED changed comf,incf to negf");
} else {
pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
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++;
+ D_POS(">>> FIXED and compacted");
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));
}
+ D_POS("<<< FIXED and compacted");
}
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_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));
+ if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
+ D_POS(">>> IMPROVED by replacing emitSKPC, incfszw by subwfb");
+ pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
+ D_POS("<<< IMPROVED by replacing emitSKPC, incfszw by subwfb");
+ } else {
+ D_POS(">>> FIXED for same regs right and result");
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(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));
- }
- 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));
-
+ }
offset++;
}
pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
}
-/*-----------------------------------------------------------------*
- * pic_genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
- *
- *
- *-----------------------------------------------------------------*/
-void pic16_genUMult8XLit_16 (operand *left,
- operand *right,
- operand *result,
- pCodeOpReg *result_hi)
-
-{
-
- unsigned int lit;
- unsigned int i,have_first_bit;
- int same;
- pCodeOp *temp;
-
- if (AOP_TYPE(right) != AOP_LIT){
- fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
- exit(1);
- }
-
-
- if(!result_hi) {
- result_hi = PCOR(pic16_popGet(AOP(result),1));
- }
-
- lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
- lit &= 0xff;
- pic16_emitcode(";","Unrolled 8 X 8 multiplication");
-
- same = pic16_sameRegs(AOP(left), AOP(result));
-
- if(same) {
- switch(lit) {
- case 0:
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(left),0));
- return;
- case 2:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- return;
- case 3:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- return;
- case 4:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- return;
- case 5:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
- return;
- case 6:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- return;
- case 7:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 7*F
- return;
- case 8:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
- return;
- case 9:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- return;
- case 10:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- return;
- case 11:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 11*F
- return;
- case 12:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- return;
- case 13:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 13*F
- return;
- case 14:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 11*F
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 14*F
- return;
- case 15:
- temp = pic16_popGetTempReg();
- if(!temp) {
- fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
- exit(1);
- }
- pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_MOVWF, temp);
- pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_SWAPFW, temp);
- pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(left),0));
- pic16_popReleaseTempReg(temp);
- return;
- case 16:
- pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
- return;
- case 17:
- pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
- return;
- case 32:
- pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xe0));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
- return;
- case 64:
- pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xc0));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
- return;
- case 128:
- pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),0));
- return;
-
- }
- } else {
-
- switch(lit) {
- case 0:
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
- return;
- case 2:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
- pic16_emitpcode(POC_RLCF, pic16_popCopyReg(result_hi));
- return;
- }
-
- }
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
-
- have_first_bit = 0;
- for(i=0; i<8; i++) {
-
- if(lit & 1) {
- pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
- have_first_bit = 1;
- }
-
- if(have_first_bit) {
- pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
- pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
- }
-
- lit >>= 1;
- }
-
-}
-
/*-----------------------------------------------------------------*
* pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
unsigned int lit;
int same;
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ 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__);
exit(1);
return;
case 2:
// its faster to left shift
- pic16_emitpcode(POC_RLNCF, pic16_popGet(AOP(left),0));
+ emitCLRC;
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
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)));
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
return;
case 2:
- pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left), 0));
+ emitCLRC;
+ pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
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)));
}
}
-/*-----------------------------------------------------------------*
- * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
- *
- *
- *-----------------------------------------------------------------*/
-void pic16_genUMult8X8_16 (operand *left,
- operand *right,
- operand *result,
- pCodeOpReg *result_hi)
-
+/*-----------------------------------------------------------------------*
+ * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
+ *-----------------------------------------------------------------------*/
+void pic16_genUMult16XLit_16 (operand *left,
+ operand *right,
+ operand *result)
{
+ pCodeOp *pct1, *pct2, *pct3, *pct4;
+ unsigned int lit;
+ int same;
- int i;
- int looped = 1;
-
- if(!result_hi) {
- result_hi = PCOR(pic16_popGet(AOP(result),1));
- }
-
- if (AOP_TYPE(right) == AOP_LIT) {
- pic16_genUMult8XLit_16(left,right,result,result_hi);
- return;
- }
-
- if(!looped) {
- pic16_emitcode(";","Unrolled 8 X 8 multiplication");
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
- emitCLRC;
-
- for(i=0; i<8; i++) {
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),i,0));
- pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
- pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
- pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
- }
-
-
- /*
- Here's another version that does the same thing and takes the
- same number of instructions. The one above is slightly better
- because the entry instructions have a higher probability of
- being optimized out.
- */
- /*
- pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
- pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-
- for(i=0; i<8; i++) {
- emitSKPNC;
- pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
- pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
- pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
- }
- */
-
- } else {
- symbol *tlbl = newiTempLabel(NULL);
- pCodeOp *temp;
-
- pic16_emitpcomment("; Looped 8 X 8 multiplication");
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
-
- pic16_emitpcode(POC_BSF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),0,FALSE,FALSE),7,0));
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-
- temp = pic16_popGetTempReg();
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(PCOR(temp)));
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpLabel(tlbl->key);
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pic16_emitpcode(POC_RRCF, pic16_popCopyReg(PCOR(temp)));
- emitSKPNC;
- pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
+ if (AOP_TYPE(right) != AOP_LIT){
+ fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
+ exit(1);
+ }
- pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
- pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
+ lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
+ lit &= 0xffff;
- emitSKPC;
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl->key));
+ same = pic16_sameRegs(AOP(left), AOP(result));
+ if(same) {
+ switch(lit) {
+ case 0:
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
+ return;
+ case 2:
+ // its faster to left shift
+ emitCLRC;
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
+ return;
- pic16_popReleaseTempReg(temp);
- }
+ default: {
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ 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_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+
+ /* WREG still holds the low literal */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+
+ /* load result */
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pct1, pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
+ pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+ pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+ pic16_popReleaseTempReg(pct4,1);
+ pic16_popReleaseTempReg(pct3,1);
+ pic16_popReleaseTempReg(pct2,1);
+ pic16_popReleaseTempReg(pct1,1);
+ }; return;
+ }
+ } else {
+ // operands different
+ switch(lit) {
+ case 0:
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
+ return;
+ case 2:
+ emitCLRC;
+ pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+ pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+ return;
+ default: {
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+
+ /* WREG still holds the low literal */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+
+ }; return;
+ }
+ }
}
+
/*-----------------------------------------------------------------*
* genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
*
operand *result)
{
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+
if (AOP_TYPE(right) == AOP_LIT) {
pic16_genUMult8XLit_8(left,right,result);
return;
}
- pic16_emitpcomment("; Looped 8 X 8 multiplication");
/* cases:
A = A x B B = A x B
A = B x C
if(AOP_TYPE(result) != AOP_ACC) {
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
pic16_popGet(AOP(result), 0)));
+
+
+ if(AOP_SIZE(result)>1) {
+ int i;
+
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
+ pic16_popGet(AOP(result), 1)));
+
+ for(i=2;i<AOP_SIZE(result);i++)
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
+ }
} else {
pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
}
}
+/*------------------------------------------------------------------*
+ * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
+ *------------------------------------------------------------------*/
+void pic16_genUMult16X16_16 (operand *left,
+ operand *right,
+ operand *result)
+
+{
+ pCodeOp *pct1, *pct2, *pct3, *pct4;
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+
+ if (AOP_TYPE(right) == AOP_LIT) {
+ pic16_genUMult8XLit_8(left,right,result);
+ return;
+ }
+
+ /* cases:
+ A = A x B B = A x B
+ A = B x C
+ */
+ /* if result == right then exchange left and right */
+ if(pic16_sameRegs(AOP(result), AOP(right))) {
+ operand *tmp;
+ tmp = left;
+ left = right;
+ right = tmp;
+ }
+
+
+ if(pic16_sameRegs(AOP(result), AOP(left))) {
+
+ 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_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_prodh), pic16_pCodeOpCopy(pct2)));
+
+ /* WREG still holds the lower left */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(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)));
+
+ /* load result */
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
+ pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+ pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+ 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_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_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+
+ /* WREG still holds the lower left */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+ 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_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));
+ }
+}
+
+
+void pic16_genSMult16X16_16(operand *left,
+ operand *right,
+ operand *result)
+{
+
+}
+
+#if 0
/*-----------------------------------------------------------------*
* pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
*
* this routine will call the unsigned multiply routine and then
* post-fix the sign bit.
*-----------------------------------------------------------------*/
-void pic16_genSMult8X8_16 (operand *left,
+void pic16_genSMult8X8_8 (operand *left,
operand *right,
operand *result,
pCodeOpReg *result_hi)
{
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
if(!result_hi) {
result_hi = PCOR(pic16_popGet(AOP(result),1));
}
- pic16_genUMult8X8_16(left,right,result,result_hi);
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0));
+ pic16_genUMult8X8_8(left,right,result);
+
+
+#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_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,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
}
+#endif
/*-----------------------------------------------------------------*
- * pic16_genMult8X8_8 - multiplication of two 8-bit numbers
- *
- * this routine will call the unsigned multiply 8X8=>16 routine and
- * then throw away the high byte of the result.
- *
+ * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
*-----------------------------------------------------------------*/
void pic16_genMult8X8_8 (operand *left,
operand *right,
operand *result)
{
- if (AOP_TYPE(right) == AOP_LIT)
- pic16_genUMult8XLit_8(left,right,result);
- else
- pic16_genUMult8X8_8(left,right,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);
+}
+
+
+/*-----------------------------------------------------------------*
+ * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
+ *-----------------------------------------------------------------*/
+void pic16_genMult16X16_16 (operand *left,
+ 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);
+
+}
+
+
+
+
+/*-----------------------------------------------------------------------*
+ * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
+ *-----------------------------------------------------------------------*/
+void pic16_genUMult32XLit_32 (operand *left,
+ operand *right,
+ operand *result)
+{
+ pCodeOp *pct1, *pct2, *pct3, *pct4;
+ unsigned int lit;
+ int same;
+
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if (AOP_TYPE(right) != AOP_LIT){
+ fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
+ exit(1);
+ }
+
+ lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
+ lit &= 0xffff;
+
+ same = pic16_sameRegs(AOP(left), AOP(result));
+ if(same) {
+ switch(lit) {
+ case 0:
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
+ return;
+ case 2:
+ // its faster to left shift
+ emitCLRC;
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
+ return;
+
+ default: {
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ 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_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+
+ /* WREG still holds the low literal */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+
+ /* load result */
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pct1, pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
+ pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+ pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+ pic16_popReleaseTempReg( pct4, 1 );
+ pic16_popReleaseTempReg( pct3, 1 );
+ pic16_popReleaseTempReg( pct2, 1 );
+ pic16_popReleaseTempReg( pct1, 1 );
+ }; return;
+ }
+ } else {
+ // operands different
+ switch(lit) {
+ case 0:
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
+ return;
+ case 2:
+ emitCLRC;
+ pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+ pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+ return;
+ default: {
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+
+ /* WREG still holds the low literal */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+
+ }; return;
+ }
+ }
+}
+
+
+/*------------------------------------------------------------------*
+ * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
+ *------------------------------------------------------------------*/
+void pic16_genUMult32X32_32 (operand *left,
+ operand *right,
+ operand *result)
+
+{
+ pCodeOp *pct1, *pct2, *pct3, *pct4;
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+
+ if (AOP_TYPE(right) == AOP_LIT) {
+ pic16_genUMult8XLit_8(left,right,result);
+ return;
+ }
+
+ /* cases:
+ A = A x B B = A x B
+ A = B x C
+ */
+ /* if result == right then exchange left and right */
+ if(pic16_sameRegs(AOP(result), AOP(right))) {
+ operand *tmp;
+ tmp = left;
+ left = right;
+ right = tmp;
+ }
+
+
+ if(pic16_sameRegs(AOP(result), AOP(left))) {
+
+ 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_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_prodh), pic16_pCodeOpCopy(pct2)));
+
+ /* WREG still holds the lower left */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(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)));
+
+ /* load result */
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
+ pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+ pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+ 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_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_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+
+ /* WREG still holds the lower left */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+ 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_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));
+ }
+}
+
+
+/*-----------------------------------------------------------------*
+ * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
+ *-----------------------------------------------------------------*/
+void pic16_genMult32X32_32 (operand *left,
+ 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);
+
}
+
+
+
+
+
+
+
#if 0
/*-----------------------------------------------------------------*/
/* constMult - generates code for multiplication by a constant */