X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fgenarith.c;h=ad1a172b0e77947fc004f5233b2c04b9e94b4383;hb=d2da99feec099aa224e1db53bc5a1ed42ed51ec9;hp=2015eb59ceccf527ff61af8d749146a7a3d2512e;hpb=282ac6dc581f9490727d70a1a25b94d18a14010d;p=fw%2Fsdcc diff --git a/src/pic16/genarith.c b/src/pic16/genarith.c index 2015eb59..ad1a172b 100644 --- a/src/pic16/genarith.c +++ b/src/pic16/genarith.c @@ -48,6 +48,10 @@ #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 @@ -59,109 +63,99 @@ 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_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"; } } @@ -204,7 +198,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)); } @@ -268,6 +262,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); } @@ -534,6 +530,14 @@ 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 */ + 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; @@ -573,10 +577,11 @@ 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)); + 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)); @@ -588,9 +593,9 @@ 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)); + D_POS(">>> IMPROVED"); + pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16)); + D_POS("<<< IMPROVED"); break; } @@ -607,40 +612,22 @@ static void genAddLit (iCode *ic, int lit) 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 { @@ -716,8 +703,7 @@ static void genAddLit (iCode *ic, int lit) 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)); @@ -761,25 +747,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)); + 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++; } @@ -935,7 +922,7 @@ void pic16_genPlus (iCode *ic) 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)); @@ -979,11 +966,20 @@ void pic16_genPlus (iCode *ic) 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 @@ -1002,6 +998,8 @@ void pic16_genPlus (iCode *ic) } 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)))) { @@ -1016,7 +1014,9 @@ void pic16_genPlus (iCode *ic) // 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)); @@ -1058,22 +1058,30 @@ void pic16_genPlus (iCode *ic) 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)); } } } @@ -1082,6 +1090,7 @@ void pic16_genPlus (iCode *ic) } + assert( 0 ); // TODO: anything from here to before "release:" is probably obsolete and should be removed // when the regression tests are stable @@ -1102,15 +1111,15 @@ void pic16_genPlus (iCode *ic) /* 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)); } } @@ -1254,12 +1263,12 @@ 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_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)); @@ -1331,8 +1340,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))); @@ -1413,7 +1422,8 @@ 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)); + 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{ @@ -1429,7 +1439,8 @@ 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)); + D_POS(">>> IMPROVED removed following assignment W-->result"); + //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0)); } @@ -1469,8 +1480,9 @@ 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)); + 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)); @@ -1484,62 +1496,21 @@ void pic16_genMinus (iCode *ic) 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"); } @@ -1554,16 +1525,10 @@ void pic16_genMinus (iCode *ic) 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)); @@ -1586,7 +1551,6 @@ void pic16_genMinus (iCode *ic) pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0)); } } - } } /* @@ -1603,15 +1567,17 @@ 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)); + 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++; } @@ -1626,220 +1592,6 @@ void pic16_genMinus (iCode *ic) 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. @@ -1853,6 +1605,10 @@ void pic16_genUMult8XLit_8 (operand *left, 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); @@ -1871,11 +1627,13 @@ void pic16_genUMult8XLit_8 (operand *left, 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))); @@ -1888,11 +1646,13 @@ void pic16_genUMult8XLit_8 (operand *left, 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))); @@ -1901,99 +1661,120 @@ void pic16_genUMult8XLit_8 (operand *left, } } -/*-----------------------------------------------------------------* - * 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. * @@ -2004,12 +1785,14 @@ void pic16_genUMult8X8_8 (operand *left, 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 @@ -2041,53 +1824,413 @@ void pic16_genUMult8X8_8 (operand *left, 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;i16 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 */