X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fgenarith.c;h=fe7788522b861e40d097deacf5af8aee7d2a68da;hb=de6743d71bc9d1e681e14c9bb874b7b21f2f12c0;hp=0bf43881e1cd43a8b35ab1459fb71eb0368f2eda;hpb=fab1b2b01944a97bc9a7275a2df59fe22f42d81f;p=fw%2Fsdcc diff --git a/src/pic16/genarith.c b/src/pic16/genarith.c index 0bf43881..fe778852 100644 --- a/src/pic16/genarith.c +++ b/src/pic16/genarith.c @@ -1,5 +1,6 @@ /*------------------------------------------------------------------------- - genarith.c - source file for code generation - arithmetic + + genarith.c - source file for code generation - arithmetic Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) and - Jean-Louis VERN.jlvern@writeme.com (1999) @@ -47,110 +48,110 @@ #include "pcode.h" #include "gen.h" +#if 1 +#define pic16_emitcode DEBUGpic16_emitcode +#endif #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff) void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result); - +void pic16_emitpcomment(char *, ...); +pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst); 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_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"; } } @@ -162,10 +163,11 @@ const char *pic16_pCodeOpType( pCodeOp *pcop) /*-----------------------------------------------------------------*/ 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))), @@ -179,8 +181,8 @@ bool pic16_genPlusIncr (iCode *ic) DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__); /* if the literal value of the right hand side - is greater than 1 then it is faster to add */ - if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 1) // this was > 2 why? VR + is greater than 2 then it is faster to add */ + if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2) return FALSE ; /* if increment 16 bits in register */ @@ -193,7 +195,7 @@ bool pic16_genPlusIncr (iCode *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)); } @@ -203,7 +205,7 @@ bool pic16_genPlusIncr (iCode *ic) DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__); /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?! - if( strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") && + if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) && (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) { pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0)); @@ -227,7 +229,6 @@ bool pic16_genPlusIncr (iCode *ic) } - /* if the sizes are greater than 1 then we cannot */ if (AOP_SIZE(IC_RESULT(ic)) > 1 || AOP_SIZE(IC_LEFT(ic)) > 1 ) @@ -258,6 +259,8 @@ void pic16_outBitAcc(operand *result) /* 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); } @@ -274,8 +277,7 @@ void pic16_outBitAcc(operand *result) /*-----------------------------------------------------------------*/ 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))), @@ -414,12 +416,14 @@ static void adjustArithmeticResult(iCode *ic) } #endif +#if 0 /*-----------------------------------------------------------------*/ /* genAddlit - generates code for addition */ /*-----------------------------------------------------------------*/ static void genAddLit2byte (operand *result, int offr, int lit) { - + FENTRY; + switch(lit & 0xff) { case 0: break; @@ -435,6 +439,7 @@ static void genAddLit2byte (operand *result, int offr, int lit) } } +#endif static void emitMOVWF(operand *reg, int offset) { @@ -453,19 +458,90 @@ static void emitMOVWF(operand *reg, int offset) static void genAddLit (iCode *ic, int lit) { - int size,same; - int lo; + int size,sizeL,same; + int i, llit; operand *result; operand *left; + sym_link *lleft; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + FENTRY; left = IC_LEFT(ic); + lleft = operandType (left); result = IC_RESULT(ic); same = pic16_sameRegs(AOP(left), AOP(result)); size = pic16_getDataSize(result); + sizeL = pic16_getDataSize(left); + llit = lit; + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + /* move left to result -- possibly sign extend */ + for (i=0; i < MIN(size, sizeL); i++) { + pic16_mov2f (AOP(result), AOP(left), i); + } // for i +#undef MIN + + /* extend to result size */ + if (IS_UNSIGNED(lleft)) { + /* zero-extend */ + for (i = sizeL; i < size; i++) { + pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i)); + } // for i + } else { + /* sign-extend */ + if (size == sizeL + 1) { + pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), sizeL)); + pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7)); + pic16_emitpcode (POC_SETF, pic16_popGet (AOP(result), sizeL)); + } else { + pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg)); + pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7)); + pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg)); + + for (i=sizeL; i < size; i++) { + pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(result), i)); + } // for i + } // if + } // if (SIGNED) + + /* special cases */ + if (lit == 0) { + /* nothing to do */ + } else if (lit == 1) { + switch (size) { + case 1: + /* handled below */ + break; + case 2: + pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(result), 0)); + break; + default: + assert (size > 2); + pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), 0)); + for (i=1; i < size-1; i++) { + emitSKPNC; /* a jump here saves up to 2(size-2)cycles */ + pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), i)); + } // for i + emitSKPNC; + break; + } // switch + + pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1)); + } else { + /* general case */ + + /* add literal to result */ + for (i=0; i < size; i++) { + pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit)); + llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */ + pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC, + pic16_popGet (AOP(result), i)); + } + } + +#if 0 if(same) { @@ -524,6 +600,13 @@ static void genAddLit (iCode *ic, int lit) 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; @@ -563,10 +646,9 @@ static void genAddLit (iCode *ic, int lit) 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)); @@ -578,9 +660,7 @@ static void genAddLit (iCode *ic, int lit) 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; } @@ -595,44 +675,8 @@ static void genAddLit (iCode *ic, int lit) 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 */ @@ -704,10 +748,8 @@ static void genAddLit (iCode *ic, int lit) /* 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)); @@ -735,7 +777,7 @@ static void genAddLit (iCode *ic, int lit) 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; } @@ -751,30 +793,26 @@ static void genAddLit (iCode *ic, int lit) 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++; } } } +#endif } /*-----------------------------------------------------------------*/ @@ -782,294 +820,323 @@ static void genAddLit (iCode *ic, int lit) /*-----------------------------------------------------------------*/ void pic16_genPlus (iCode *ic) { - int size, offset = 0; + int i, size, offset = 0; operand *result, *left, *right; - - /* special cases :- */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - -#if 1 + FENTRY; + + /* special cases :- */ result = IC_RESULT(ic); left = IC_LEFT(ic); right = IC_RIGHT(ic); - pic16_aopOp (left,ic,FALSE); - pic16_aopOp (right,ic,FALSE); - pic16_aopOp (result,ic,TRUE); - DEBUGpic16_pic16_AopType(__LINE__,left, right, result); - -#else - pic16_aopOp (IC_LEFT(ic),ic,FALSE); - pic16_aopOp (IC_RIGHT(ic),ic,FALSE); - pic16_aopOp (IC_RESULT(ic),ic,TRUE); - DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic)); -#endif - - - /* if literal, literal on the right or - if left requires ACC or right is already - in ACC */ - - if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) { - operand *t = IC_RIGHT(ic); - IC_RIGHT(ic) = IC_LEFT(ic); - IC_LEFT(ic) = t; - } - - /* if both left & right are in bit space */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && - AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { - pic16_genPlusBits (ic); - goto release ; - } - - /* if left in bit space & right literal */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && - AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) { - /* if result in bit space */ - if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){ - if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) { - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0)); - if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0)); - pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0)); - } - } else { - size = pic16_getDataSize(IC_RESULT(ic)); - while (size--) { - MOVA(pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - pic16_emitcode("addc","a,#00 ;%d",__LINE__); - pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++); - } - } - goto release ; - } - - /* if I can do an increment instead - of add then GOOD for ME */ - if (pic16_genPlusIncr (ic) == TRUE) - goto release; - - size = pic16_getDataSize(IC_RESULT(ic)); - - if(AOP(IC_RIGHT(ic))->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 l1=0; - - // offset = 0; - DEBUGpic16_emitcode(";","adding lit to something. size %d",size); - - genAddLit (ic, lit); - goto release; - - } else if(AOP_TYPE(IC_RIGHT(ic)) == 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)); - - /* 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))) ) { - - pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0)); - pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),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)); - } else { - - if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { - pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),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); - 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_aopOp (left,ic,FALSE); + pic16_aopOp (right,ic,FALSE); + pic16_aopOp (result,ic,TRUE); + DEBUGpic16_pic16_AopType(__LINE__,left, right, result); + // pic16_DumpOp("(left)",left); + + /* if literal, literal on the right or + if left requires ACC or right is already + in ACC */ + + if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) { + operand *t = right; + right = IC_RIGHT(ic) = left; + left = IC_LEFT(ic) = t; + } - pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),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)); + /* if both left & right are in bit space */ + if (AOP_TYPE(left) == AOP_CRY && + AOP_TYPE(right) == AOP_CRY) { + pic16_genPlusBits (ic); + goto release ; } + + /* if left in bit space & right literal */ + if (AOP_TYPE(left) == AOP_CRY && + AOP_TYPE(right) == AOP_LIT) { + /* if result in bit space */ + if(AOP_TYPE(result) == AOP_CRY){ + if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0)); + if (!pic16_sameRegs(AOP(left), AOP(result)) ) + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0)); + 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--) { + 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 ; + } // left == CRY + + /* if I can do an increment instead + of add then GOOD for ME */ + if (pic16_genPlusIncr (ic) == TRUE) + goto release; + + size = pic16_getDataSize(result); + + if(AOP(right)->type == AOP_LIT) { + /* Add a literal to something else */ + //bool know_W=0; + unsigned lit = (unsigned) floatFromVal(AOP(right)->aopu.aop_lit); + //unsigned l1=0; + + //offset = 0; + DEBUGpic16_emitcode(";","adding lit to something. size %d",size); + + genAddLit (ic, lit); + goto release; + + } else if(AOP_TYPE(right) == AOP_CRY) { + + 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(left), AOP(result)) ) { + + 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(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(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(right)->aopu.aop_dir, + AOP(right)->aopu.aop_dir); + pic16_emitcode(" xorlw","1"); + } else { + 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(left),0,FALSE,FALSE)); + pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", + 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) { - pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1)); - pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0)); - emitSKPZ; - pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),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)); - } - } - } - - } else { - int offset = 1; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - emitCLRZ; - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0)); - pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),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)); - - } 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)); - 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)); - - } - - 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)); - } - - } + if(AOP_TYPE(result) == AOP_CRY) { + pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1)); + pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0)); + emitSKPZ; + pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0)); + } else { + 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(left), AOP(result)) ) { + emitCLRZ; + 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(right)->aopu.aop_dir, + AOP(right)->aopu.aop_dir); + pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE)); + + } else { + emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then + pic16_mov2w(AOP(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(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(result),offset++)); + //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE)); + } + + } - } else { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - /* Add the first bytes */ - - if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) { - pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0)); - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0)); - } else { - - if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { - pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0)); - if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0)); - } else { - - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0)); + } else { + // add bytes + + // Note: the following is an example of WISC code, eg. + // it's supposed to run on a Weird Instruction Set Computer :o) + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if ( AOP_TYPE(left) == AOP_ACC) { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0)); + if ( AOP_TYPE(result) != AOP_ACC) + pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0)); + goto release; // we're done, since WREG is 1 byte + } + + + 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) || // patch 9 + (AOP(left)->aopu.pcop->type == PO_IMMEDIATE))) + { + // add to literal operand + + // add first bytes + for(i=0; iaopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) - poc = POC_ADDLW; - pic16_emitpcode(poc, pic16_popGet(AOP(IC_LEFT(ic)),0)); - if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0)); } - } - } - - size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1; - offset = 1; - - - 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)); - - pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); - } - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset)); - emitSKPNC; - pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RIGHT(ic)),offset)); - pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - - /* - pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitSKPNC; - pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); - */ - - offset++; - } - - } - - 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)))) ); - - - /* Need to extend result to higher bytes */ - size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 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)); - - - 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)); - 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_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_MOVLW, pic16_popGetLit(0xff)); - } - } - - offset++; - while(size--) { - - if(sign) - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - else - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),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); + assert( 0 ); + +release: + pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -1080,7 +1147,7 @@ bool pic16_genMinusDec (iCode *ic) 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 */ @@ -1103,8 +1170,7 @@ bool pic16_genMinusDec (iCode *ic) 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)); @@ -1112,27 +1178,24 @@ bool pic16_genMinusDec (iCode *ic) 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)); } @@ -1190,15 +1253,15 @@ void pic16_addSign(operand *result, int offset, int sign) 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_DECF, pic16_popGet(AOP(result),offset)); + pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); + pic16_emitpcode(POC_SETF, 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),size)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size)); } } else @@ -1213,7 +1276,8 @@ void pic16_addSign(operand *result, int offset, int sign) 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)); @@ -1240,7 +1304,7 @@ void pic16_genMinus (iCode *ic) 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); @@ -1267,8 +1331,8 @@ void pic16_genMinus (iCode *ic) /* 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))); @@ -1349,7 +1413,7 @@ void pic16_genMinus (iCode *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)); + pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1)); pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0)); } }else{ @@ -1365,12 +1429,12 @@ void pic16_genMinus (iCode *ic) 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)); } @@ -1405,8 +1469,7 @@ void pic16_genMinus (iCode *ic) 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)); @@ -1415,66 +1478,23 @@ void pic16_genMinus (iCode *ic) 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)); } } @@ -1486,23 +1506,17 @@ void pic16_genMinus (iCode *ic) pic16_AopType(AOP_TYPE(IC_LEFT(ic))), pic16_AopType(AOP_TYPE(IC_RIGHT(ic)))); - if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) { + if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { 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)); @@ -1522,7 +1536,6 @@ void pic16_genMinus (iCode *ic) pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0)); } } - } } /* @@ -1539,15 +1552,33 @@ void pic16_genMinus (iCode *ic) 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_SETF, 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_SETF, 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++; } @@ -1561,362 +1592,673 @@ void pic16_genMinus (iCode *ic) pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } + + /*-----------------------------------------------------------------* - * pic_genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers. + * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers. * * *-----------------------------------------------------------------*/ -void pic16_genUMult8XLit_16 (operand *left, +void pic16_genUMult8XLit_8 (operand *left, operand *right, - operand *result, - pCodeOpReg *result_hi) - + operand *result) { - 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; - } + int size = AOP_SIZE(result); + int i; - } + FENTRY; + DEBUGpic16_pic16_AopType(__LINE__,left,right,result); - 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)); + if (AOP_TYPE(right) != AOP_LIT){ + fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__); + exit(1); + } - have_first_bit = 0; - for(i=0; i<8; i++) { + lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit); + lit &= 0xff; + pic16_emitpcomment("Unrolled 8 X 8 multiplication"); + pic16_emitpcomment("FIXME: the function does not support result==WREG"); + + same = pic16_sameRegs(AOP(left), AOP(result)); + if(same) { + switch(lit) { + case 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: + 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: + 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: + 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; + } + } +} - if(lit & 1) { - pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi)); - have_first_bit = 1; - } +/*-----------------------------------------------------------------------* + * 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; - if(have_first_bit) { - pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi)); - pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0)); - } - lit >>= 1; - } + FENTRY; + + 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; + } + } } + /*-----------------------------------------------------------------* - * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers. + * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers. * * *-----------------------------------------------------------------*/ -void pic16_genUMult8X8_16 (operand *left, +void pic16_genUMult8X8_8 (operand *left, operand *right, - operand *result, - pCodeOpReg *result_hi) + operand *result) { + FENTRY; + - 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)); - } + 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 + W = A x B + W = W x B W = B x W + */ + /* if result == right then exchange left and right */ + if(pic16_sameRegs(AOP(result), AOP(right))) { + operand *tmp; + tmp = left; + left = right; + right = tmp; + } + + if(AOP_TYPE(left) != AOP_ACC) { + // left is not WREG + if(AOP_TYPE(right) != AOP_ACC) { + pic16_mov2w(AOP(left), 0); + pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0)); + } else { + pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0)); + } + } else { + // left is WREG, right cannot be WREG (or can?!) + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0)); + } + + /* result is in PRODL:PRODH */ + if(AOP_TYPE(result) != AOP_ACC) { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), + 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)); - } - */ + if(AOP_SIZE(result)>1) { + int i; - } else { - symbol *tlbl = newiTempLabel(NULL); - pCodeOp *temp; + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh), + pic16_popGet(AOP(result), 1))); + + for(i=2;ikey); + if(pic16_sameRegs(AOP(result), AOP(left))) { + + pct1 = pic16_popGetTempReg(1); + pct2 = pic16_popGetTempReg(1); + pct3 = pic16_popGetTempReg(1); + pct4 = pic16_popGetTempReg(1); + + 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_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_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))); + + /* 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 ); - pic16_emitpcode(POC_RRCF, pic16_popCopyReg(PCOR(temp))); - emitSKPNC; - pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi)); + } else { - pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi)); - pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),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_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_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)); + } +} - emitSKPC; - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl->key)); - pic16_popReleaseTempReg(temp); +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_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 } +#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) { - pCodeOp *result_hi = pic16_popGetTempReg(); + FENTRY; + + 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) +{ + FENTRY; + if (AOP_TYPE(right) == AOP_LIT) - pic16_genUMult8XLit_16(left,right,result,PCOR(result_hi)); + pic16_genUMult16XLit_16(left,right,result); else - pic16_genUMult8X8_16(left,right,result,PCOR(result_hi)); + 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; + + + FENTRY; + + 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; + + FENTRY; + + 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; + } - pic16_popReleaseTempReg(result_hi); + + if(pic16_sameRegs(AOP(result), AOP(left))) { + + pct1 = pic16_popGetTempReg(1); + pct2 = pic16_popGetTempReg(1); + pct3 = pic16_popGetTempReg(1); + pct4 = pic16_popGetTempReg(1); + + 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_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_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))); + + /* 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_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_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_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)); + } +} + + +/*-----------------------------------------------------------------* + * pic16_genMult32X32_32 - multiplication of two 32-bit numbers * + *-----------------------------------------------------------------*/ +void pic16_genMult32X32_32 (operand *left, + operand *right, + operand *result) +{ + FENTRY; + + 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 */