+/*-----------------------------------------------------------------*
+ * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
+ *
+ *
+ *-----------------------------------------------------------------*/
+void genUMult8XLit_16 (operand *left,
+ operand *right,
+ operand *result,
+ pCodeOpReg *result_hi)
+
+{
+
+ unsigned int lit;
+ unsigned int i,have_first_bit;
+ int same;
+
+ 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(popGet(AOP(result),1));
+ }
+
+ lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
+ lit &= 0xff;
+ pic14_emitcode(";","Unrolled 8 X 8 multiplication");
+
+ same = pic14_sameRegs(AOP(left), AOP(result));
+
+ if(same) {
+ switch(lit) {
+ case 0:
+ emitpcode(POC_CLRF, popGet(AOP(left),0));
+ return;
+ case 2:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ return;
+ case 3:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ return;
+ case 4:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ return;
+ case 16:
+ emitpcode(POC_SWAPFW, popGet(AOP(left),0));
+ emitpcode(POC_ANDLW, popGetLit(0xf0));
+ emitpcode(POC_MOVWF, popGet(AOP(left),0));
+ return;
+ case 17:
+ emitpcode(POC_SWAPFW, popGet(AOP(left),0));
+ emitpcode(POC_ANDLW, popGetLit(0xf0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ return;
+
+ }
+ } else {
+
+ switch(lit) {
+ case 0:
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+ return;
+ case 2:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),0));
+ emitpcode(POC_ADDWF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+ emitpcode(POC_RLF, popCopyReg(result_hi));
+ return;
+ }
+
+ }
+
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+
+ have_first_bit = 0;
+ for(i=0; i<8; i++) {
+
+ if(lit & 1) {
+ emitpcode(POC_ADDWF, popCopyReg(result_hi));
+ have_first_bit = 1;
+ }
+
+ if(have_first_bit) {
+ emitpcode(POC_RRF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popGet(AOP(result),0));
+ }
+
+ lit >>= 1;
+ }
+
+}
+
+/*-----------------------------------------------------------------*
+ * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
+ *
+ *
+ *-----------------------------------------------------------------*/
+void genUMult8X8_16 (operand *left,
+ operand *right,
+ operand *result,
+ pCodeOpReg *result_hi)
+
+{
+
+ int i;
+ int looped = 1;
+
+ if(!result_hi) {
+ result_hi = PCOR(popGet(AOP(result),1));
+ }
+
+ if (AOP_TYPE(right) == AOP_LIT) {
+ genUMult8XLit_16(left,right,result,result_hi);
+ return;
+ }
+
+ if(!looped) {
+ pic14_emitcode(";","Unrolled 8 X 8 multiplication");
+
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+ emitCLRC;
+
+ for(i=0; i<8; i++) {
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
+ emitpcode(POC_ADDWF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, 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.
+ */
+ /*
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+ emitpcode(POC_RRFW, popGet(AOP(left),0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),0));
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+
+ for(i=0; i<8; i++) {
+ emitSKPNC;
+ emitpcode(POC_ADDWF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popGet(AOP(result),0));
+ }
+ */
+
+ } else {
+ symbol *tlbl = newiTempLabel(NULL);
+ pCodeOp *temp;
+
+
+ pic14_emitcode(";","Looped 8 X 8 multiplication");
+
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+
+ emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
+
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+
+ temp = popGetTempReg();
+ emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
+
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+
+ emitpLabel(tlbl->key);
+
+ emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
+ emitSKPNC;
+ emitpcode(POC_ADDWF, popCopyReg(result_hi));
+
+ emitpcode(POC_RRF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popGet(AOP(result),0));
+
+ emitSKPC;
+ emitpcode(POC_GOTO, popGetLabel(tlbl->key));
+
+ popReleaseTempReg(temp);
+
+ }
+}
+
+/*-----------------------------------------------------------------*
+ * 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 genSMult8X8_16 (operand *left,
+ operand *right,
+ operand *result,
+ pCodeOpReg *result_hi)
+{