-/*-----------------------------------------------------------------*
-* 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;
- pCodeOp *temp;
-
- FENTRY;
- if (AOP_TYPE(right) != AOP_LIT){
- fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
- exit(EXIT_FAILURE);
- }
-
-
- if(!result_hi) {
- result_hi = PCOR(popGet(AOP(result),1));
- }
-
- lit = (unsigned int) ulFromVal (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));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- return;
- case 5:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
- return;
- case 6:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- return;
- case 7:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F
- return;
- case 8:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
- return;
- case 9:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- return;
- case 10:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- return;
- case 11:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F
- return;
- case 12:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- return;
- case 13:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*F
- return;
- case 14:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F
- return;
- case 15:
- temp = popGetTempReg();
- if(!temp) {
- fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
- exit(EXIT_FAILURE);
- }
- emitpcode(POC_SWAPFW, popGet(AOP(left),0));
- emitpcode(POC_MOVWF, temp);
- emitpcode(POC_ANDLW, popGetLit(0xf0));
- emitpcode(POC_MOVWF, popGet(AOP(left),0));
- emitpcode(POC_SWAPFW, temp);
- emitpcode(POC_SUBWF, popGet(AOP(left),0));
- popReleaseTempReg(temp);
- 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;
- case 32:
- emitpcode(POC_SWAPF, popGet(AOP(left),0));
- emitpcode(POC_RLFW, popGet(AOP(left),0));
- emitpcode(POC_ANDLW, popGetLit(0xe0));
- emitpcode(POC_MOVWF, popGet(AOP(left),0));
- return;
- case 64:
- emitpcode(POC_SWAPF, popGet(AOP(left),0));
- emitpcode(POC_RLF, popGet(AOP(left),0));
- emitpcode(POC_RLFW, popGet(AOP(left),0));
- emitpcode(POC_ANDLW, popGetLit(0xc0));
- emitpcode(POC_MOVWF, popGet(AOP(left),0));
- return;
- case 128:
- emitpcode(POC_RRFW, popGet(AOP(left),0));
- emitpcode(POC_CLRF, popGet(AOP(left),0));
- emitpcode(POC_RRF, 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;
- case 4:
- case 8:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
- emitpcode(POC_CLRF, popCopyReg(result_hi));
- emitpcode(POC_BCF, popCopyReg(&pc_status));
- emitpcode(POC_RLF, popGet(AOP(result),0));
- emitpcode(POC_RLF, popCopyReg(result_hi));
- emitpcode(POC_RLF, popGet(AOP(result),0));
- emitpcode(POC_RLF, popCopyReg(result_hi));
- if (lit >= 8) {
- emitpcode(POC_RLF, popGet(AOP(result),0));
- 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;
- }
-}