X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fgenarith.c;h=f998a7c4af8a20e65ca715572b1c03cc4a88b13c;hb=2de847a479c5a08a4e0dc8205a340809be8815f4;hp=99e3b661c4226d07a5375bc3cc1386f85ebaccf7;hpb=9a8dddc06cfddf1d3fcbfe00a114c48170eb15c0;p=fw%2Fsdcc diff --git a/src/pic/genarith.c b/src/pic/genarith.c index 99e3b661..f998a7c4 100644 --- a/src/pic/genarith.c +++ b/src/pic/genarith.c @@ -36,27 +36,10 @@ #include "SDCCglobl.h" #include "newalloc.h" -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER < 1300) #define __FUNCTION__ __FILE__ #endif -#ifdef HAVE_SYS_ISA_DEFS_H -#include -#else -#ifdef HAVE_MACHINE_ENDIAN_H -#include -#else -#ifdef HAVE_ENDIAN_H -#include -#else -#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__) -#warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN" -#warning "If you running sdcc on an INTEL 80x86 Platform you are okay" -#endif -#endif -#endif -#endif - #include "common.h" #include "SDCCpeeph.h" #include "ralloc.h" @@ -65,6 +48,7 @@ #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff) +void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result); const char *AopType(short type) { @@ -105,10 +89,67 @@ const char *AopType(short type) case AOP_ACC: return "AOP_ACC"; break; + case AOP_PCODE: + return "AOP_PCODE"; + break; } return "BAD TYPE"; } + +const char *pCodeOpType( pCodeOp *pcop) +{ + + if(pcop) { + + switch(pcop->type) { + + case PO_NONE: + return "PO_NONE"; + case PO_W: + return "PO_W"; + case PO_STATUS: + return "PO_STATUS"; + case PO_FSR: + return "PO_FSR"; + case PO_INDF: + return "PO_INDF"; + 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_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"; +} + /*-----------------------------------------------------------------*/ /* genPlusIncr :- does addition with increment if possible */ /*-----------------------------------------------------------------*/ @@ -118,10 +159,10 @@ bool genPlusIncr (iCode *ic) unsigned int size = pic14_getDataSize(IC_RESULT(ic)); DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - DEBUGpic14_emitcode ("; ","result %d, left %d, right %d", - AOP_TYPE(IC_RESULT(ic)), - AOP_TYPE(IC_LEFT(ic)), - AOP_TYPE(IC_RIGHT(ic))); + DEBUGpic14_emitcode ("; ","result %s, left %s, right %s", + AopType(AOP_TYPE(IC_RESULT(ic))), + AopType(AOP_TYPE(IC_LEFT(ic))), + AopType(AOP_TYPE(IC_RIGHT(ic)))); /* will try to generate an increment */ /* if the right side is not a literal @@ -141,12 +182,12 @@ bool genPlusIncr (iCode *ic) int offset = MSB16; - emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB)); //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); while(--size) { emitSKPNZ; - emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++)); //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE)); } @@ -158,7 +199,7 @@ bool genPlusIncr (iCode *ic) if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") && (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) { - emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0)); pic14_emitcode("bcf","(%s >> 3), (%s & 7)", AOP(IC_RESULT(ic))->aopu.aop_dir, AOP(IC_RESULT(ic))->aopu.aop_dir); @@ -170,7 +211,7 @@ bool genPlusIncr (iCode *ic) //pic14_emitcode("andlw","1"); emitSKPZ; - emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0)); pic14_emitcode("bsf","(%s >> 3), (%s & 7)", AOP(IC_RESULT(ic))->aopu.aop_dir, AOP(IC_RESULT(ic))->aopu.aop_dir); @@ -190,15 +231,14 @@ bool genPlusIncr (iCode *ic) if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { while (icount--) - emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0)); //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); return TRUE ; } - DEBUGpic14_emitcode ("; ","couldn't increment result-%s left-%s", - aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE), - aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + DEBUGpic14_emitcode ("; ","couldn't increment "); + return FALSE ; } @@ -228,61 +268,73 @@ void pic14_outBitAcc(operand *result) void genPlusBits (iCode *ic) { - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* - The following block of code will add two bits. - Note that it'll even work if the destination is - the carry (C in the status register). - It won't work if the 'Z' bit is a source or destination. - */ + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* If the result is stored in the accumulator (w) */ - //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) { - if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) { - //emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF), - // popGet(AOP(result),0,FALSE,FALSE)); - - emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - - pic14_emitcode("movlw","(1 << (%s & 7))", - AOP(IC_RESULT(ic))->aopu.aop_dir, - AOP(IC_RESULT(ic))->aopu.aop_dir); - pic14_emitcode("bcf","(%s >> 3), (%s & 7)", - AOP(IC_RESULT(ic))->aopu.aop_dir, - AOP(IC_RESULT(ic))->aopu.aop_dir); - pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic14_emitcode("xorwf","(%s >>3),f", - AOP(IC_RESULT(ic))->aopu.aop_dir); - pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_LEFT(ic))->aopu.aop_dir, - AOP(IC_LEFT(ic))->aopu.aop_dir); - pic14_emitcode("xorwf","(%s>>3),f", - AOP(IC_RESULT(ic))->aopu.aop_dir); - } else { - - emitpcode(POC_CLRW, NULL); - emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitpcode(POC_XORLW, popGetLit(1)); - emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitpcode(POC_XORLW, popGetLit(1)); - - pic14_emitcode("clrw",""); - pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic14_emitcode("xorlw","1"); - pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_LEFT(ic))->aopu.aop_dir, - AOP(IC_LEFT(ic))->aopu.aop_dir); - pic14_emitcode("xorlw","1"); - } + DEBUGpic14_emitcode ("; ","result %s, left %s, right %s", + AopType(AOP_TYPE(IC_RESULT(ic))), + AopType(AOP_TYPE(IC_LEFT(ic))), + AopType(AOP_TYPE(IC_RIGHT(ic)))); + /* + The following block of code will add two bits. + Note that it'll even work if the destination is + the carry (C in the status register). + It won't work if the 'Z' bit is a source or destination. + */ + + /* If the result is stored in the accumulator (w) */ + //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) { + switch(AOP_TYPE(IC_RESULT(ic))) { + case AOP_ACC: + emitpcode(POC_CLRW, NULL); + emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_XORLW, popGetLit(1)); + emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0)); + emitpcode(POC_XORLW, popGetLit(1)); + + pic14_emitcode("clrw",""); + pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", + AOP(IC_RIGHT(ic))->aopu.aop_dir, + AOP(IC_RIGHT(ic))->aopu.aop_dir); + pic14_emitcode("xorlw","1"); + pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", + AOP(IC_LEFT(ic))->aopu.aop_dir, + AOP(IC_LEFT(ic))->aopu.aop_dir); + pic14_emitcode("xorlw","1"); + break; + case AOP_REG: + emitpcode(POC_MOVLW, popGetLit(0)); + emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_XORLW, popGetLit(1)); + emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0)); + emitpcode(POC_XORLW, popGetLit(1)); + emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0)); + break; + default: + emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0)); + emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0)); + emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0)); + emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0)); + emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0)); + + pic14_emitcode("movlw","(1 << (%s & 7))", + AOP(IC_RESULT(ic))->aopu.aop_dir, + AOP(IC_RESULT(ic))->aopu.aop_dir); + pic14_emitcode("bcf","(%s >> 3), (%s & 7)", + AOP(IC_RESULT(ic))->aopu.aop_dir, + AOP(IC_RESULT(ic))->aopu.aop_dir); + pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", + AOP(IC_RIGHT(ic))->aopu.aop_dir, + AOP(IC_RIGHT(ic))->aopu.aop_dir); + pic14_emitcode("xorwf","(%s >>3),f", + AOP(IC_RESULT(ic))->aopu.aop_dir); + pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", + AOP(IC_LEFT(ic))->aopu.aop_dir, + AOP(IC_LEFT(ic))->aopu.aop_dir); + pic14_emitcode("xorwf","(%s>>3),f", + AOP(IC_RESULT(ic))->aopu.aop_dir); + break; + } } @@ -365,28 +417,48 @@ static void genAddLit2byte (operand *result, int offr, int lit) case 0: break; case 1: - emitpcode(POC_INCF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(result),offr)); break; case 0xff: - emitpcode(POC_DECF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_DECF, popGet(AOP(result),offr)); break; default: emitpcode(POC_MOVLW,popGetLit(lit&0xff)); - emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_ADDWF,popGet(AOP(result),offr)); } } -static void genAddLit (operand *result,operand *left, int lit) +static void emitMOVWF(operand *reg, int offset) +{ + if(!reg) + return; + + if (AOP_TYPE(reg) == AOP_ACC) { + DEBUGpic14_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__); + return; + } + + emitpcode(POC_MOVWF, popGet(AOP(reg),offset)); + +} + +static void genAddLit (iCode *ic, int lit) { int size,same; int lo; + operand *result; + operand *left; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - size = pic14_getDataSize(result); - same = ((left == result) || (AOP(left) == AOP(result))); + + left = IC_LEFT(ic); + result = IC_RESULT(ic); + same = pic14_sameRegs(AOP(left), AOP(result)); + size = pic14_getDataSize(result); if(same) { @@ -407,21 +479,21 @@ static void genAddLit (operand *result,operand *left, int lit) case 0: break; case 1: - emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(result),0)); emitSKPNZ; - emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(result),MSB16)); break; case 0xff: - emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE)); - emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE)); - emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE)); + emitpcode(POC_DECF, popGet(AOP(result),0)); + emitpcode(POC_INCFSZW, popGet(AOP(result),0)); + emitpcode(POC_INCF, popGet(AOP(result),MSB16)); break; default: emitpcode(POC_MOVLW,popGetLit(lit&0xff)); - emitpcode(POC_ADDWF,popGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_ADDWF,popGet(AOP(result),0)); emitSKPNC; - emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(result),MSB16)); } @@ -432,19 +504,19 @@ static void genAddLit (operand *result,operand *left, int lit) DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__); switch(lo) { case 0: /* 0x0100 */ - emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(result),MSB16)); break; case 1: /* 0x0101 */ - emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE)); - emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(result),MSB16)); + emitpcode(POC_INCF, popGet(AOP(result),0)); emitSKPNZ; - emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(result),MSB16)); break; case 0xff: /* 0x01ff */ - emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE)); - emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE)); - emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE)); - emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE)); + emitpcode(POC_DECF, popGet(AOP(result),0)); + emitpcode(POC_INCFSZW, popGet(AOP(result),0)); + emitpcode(POC_INCF, popGet(AOP(result),MSB16)); + emitpcode(POC_INCF, popGet(AOP(result),MSB16)); } break; @@ -453,11 +525,11 @@ static void genAddLit (operand *result,operand *left, int lit) /* lit = 0xffLL */ switch(lo) { case 0: /* 0xff00 */ - emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE)); + emitpcode(POC_DECF, popGet(AOP(result),MSB16)); break; case 1: /*0xff01 */ - emitpcode(POC_INCFSZ, popGet(AOP(result),0,FALSE,FALSE)); - emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE)); + emitpcode(POC_INCFSZ, popGet(AOP(result),0)); + emitpcode(POC_DECF, popGet(AOP(result),MSB16)); break; /* case 0xff: * 0xffff * emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE)); @@ -467,9 +539,9 @@ static void genAddLit (operand *result,operand *left, int lit) */ default: emitpcode(POC_MOVLW,popGetLit(lo)); - emitpcode(POC_ADDWF,popGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_ADDWF,popGet(AOP(result),0)); emitSKPC; - emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE)); + emitpcode(POC_DECF, popGet(AOP(result),MSB16)); } @@ -485,9 +557,9 @@ static void genAddLit (operand *result,operand *left, int lit) break; case 1: /* 0xHH01 */ emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff)); - emitpcode(POC_INCFSZ, popGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_INCFSZ, popGet(AOP(result),0)); emitpcode(POC_MOVLW,popGetLit(hi)); - emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE)); + emitpcode(POC_ADDWF,popGet(AOP(result),MSB16)); break; /* case 0xff: * 0xHHff * emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE)); @@ -497,11 +569,11 @@ static void genAddLit (operand *result,operand *left, int lit) break; */ default: /* 0xHHLL */ emitpcode(POC_MOVLW,popGetLit(lo)); - emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(result),0)); emitpcode(POC_MOVLW,popGetLit(hi)); emitSKPNC; emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff)); - emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE)); + emitpcode(POC_ADDWF,popGet(AOP(result),MSB16)); break; } @@ -521,16 +593,16 @@ static void genAddLit (operand *result,operand *left, int lit) switch(carry_info) { case 1: emitSKPNZ; - emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(result),offset)); break; case 2: - emitpcode(POC_RLFW, popGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_RLFW, popGet(AOP(result),offset)); emitpcode(POC_ANDLW,popGetLit(1)); - emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(result),offset)); break; default: /* carry_info = 3 */ emitSKPNC; - emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(result),offset)); carry_info = 1; break; } @@ -541,7 +613,7 @@ static void genAddLit (operand *result,operand *left, int lit) emitSKPZ; else emitSKPC; - emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(result),offset)); break; default: emitpcode(POC_MOVLW,popGetLit(lo)); @@ -550,7 +622,7 @@ static void genAddLit (operand *result,operand *left, int lit) else emitSKPNC; emitpcode(POC_MOVLW,popGetLit(lo+1)); - emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(result),offset)); carry_info=2; break; } @@ -561,12 +633,12 @@ static void genAddLit (operand *result,operand *left, int lit) case 0: break; case 1: - emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(result),offset)); carry_info=1; break; default: emitpcode(POC_MOVLW,popGetLit(lo)); - emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(result),offset)); if(lit <0x100) carry_info = 3; /* Were adding only one byte and propogating the carry */ else @@ -609,52 +681,90 @@ static void genAddLit (operand *result,operand *left, int lit) if(size == 1) { - switch(lit & 0xff) { - case 0: - emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE)); - emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); - break; - case 1: - emitpcode(POC_INCFW, popGet(AOP(left),0,FALSE,FALSE)); - emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); - break; - case 0xff: - emitpcode(POC_DECFW, popGet(AOP(left),0,FALSE,FALSE)); - emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); - break; - default: - emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - emitpcode(POC_ADDFW, popGet(AOP(left),0,FALSE,FALSE)); - emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + if(AOP_TYPE(left) == AOP_ACC) { + /* left addend is already in accumulator */ + switch(lit & 0xff) { + case 0: + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + break; + default: + emitpcode(POC_ADDLW, popGetLit(lit & 0xff)); + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + } + } else { + /* left addend is in a register */ + switch(lit & 0xff) { + case 0: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitMOVWF(result, 0); + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + break; + case 1: + emitpcode(POC_INCFW, popGet(AOP(left),0)); + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + break; + case 0xff: + emitpcode(POC_DECFW, popGet(AOP(left),0)); + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + break; + default: + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + } } - } else { + int clear_carry=0; + /* left is not the accumulator */ if(lit & 0xff) { emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - emitpcode(POC_ADDFW, popGet(AOP(left),0,FALSE,FALSE)); - } else - emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE)); - - emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); - lit >>= 8; + emitpcode(POC_ADDFW, popGet(AOP(left),0)); + } else { + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + /* We don't know the state of the carry bit at this point */ + clear_carry = 1; + } + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); while(--size) { + lit >>= 8; if(lit & 0xff) { - emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE)); - emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE)); - emitSKPNC; - emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE)); - emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE)); + if(clear_carry) { + /* The ls byte of the lit must've been zero - that + means we don't have to deal with carry */ + + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + emitpcode(POC_ADDFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(left),offset)); + + clear_carry = 0; + + } else { + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE)); + emitMOVWF(result,offset); + emitpcode(POC_MOVFW, popGet(AOP(left),offset)); + emitSKPNC; + emitpcode(POC_INCFSZW,popGet(AOP(left),offset)); + emitpcode(POC_ADDWF, popGet(AOP(result),offset)); + } + } else { - emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE)); - emitpcode(POC_RLF, popGet(AOP(result),offset,FALSE,FALSE)); - emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE)); - emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_CLRF, popGet(AOP(result),offset)); + emitpcode(POC_RLF, popGet(AOP(result),offset)); + emitpcode(POC_MOVFW, popGet(AOP(left),offset)); + emitpcode(POC_ADDWF, popGet(AOP(result),offset)); } - offset++; + offset++; } } } @@ -674,6 +784,8 @@ void genPlus (iCode *ic) aopOp (IC_RIGHT(ic),ic,FALSE); aopOp (IC_RESULT(ic),ic,TRUE); + DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic)); + /* if literal, literal on the right or if left requires ACC or right is already in ACC */ @@ -697,10 +809,10 @@ void genPlus (iCode *ic) /* 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) { - emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0)); if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) - emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0)); + emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0)); } } else { size = pic14_getDataSize(IC_RESULT(ic)); @@ -729,63 +841,8 @@ void genPlus (iCode *ic) // offset = 0; DEBUGpic14_emitcode(";","adding lit to something. size %d",size); - genAddLit ( IC_RESULT(ic),IC_LEFT(ic), lit); -#if 0 - while(size--){ - - DEBUGpic14_emitcode(";","size %d",size); - - switch (lit & 0xff) { - case 0: - break; - case 1: - if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) - emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - else { - know_W = 0; - emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); - } - break; - case 0xff: - if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) - emitpcode(POC_DECF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - else { - know_W = 0; - emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); - } - break; - default: - if( !know_W || ( (lit&0xff) != l1) ) { - know_W = 1; - emitpcode(POC_MOVLW,popGetLit(lit&0xff)); - } - if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) { - emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - if(size) { - emitSKPNC; - emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset+1,FALSE,FALSE)); - } - - } else { - know_W = 0; - emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); - if(size) { - emitSKPNC; - emitpcode(POC_INCFW, popGet(AOP(IC_RESULT(ic)),offset+1,FALSE,FALSE)); - } - } - } - - l1 = lit & 0xff; - lit >>= 8; - offset++; - } -#endif + genAddLit (ic, lit); + goto release; } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { @@ -797,8 +854,8 @@ void genPlus (iCode *ic) if(size == 1) { if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0)); pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", AOP(IC_RIGHT(ic))->aopu.aop_dir, @@ -807,7 +864,7 @@ void genPlus (iCode *ic) } else { if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { - emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0)); emitpcode(POC_XORLW , popGetLit(1)); pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", @@ -815,9 +872,9 @@ void genPlus (iCode *ic) AOP(IC_RIGHT(ic))->aopu.aop_dir); pic14_emitcode(" xorlw","1"); } else { - emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0)); + emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0)); pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", @@ -830,11 +887,11 @@ void genPlus (iCode *ic) if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) { emitpcode(POC_ANDLW , popGetLit(1)); - emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0)); emitSKPZ; - emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0)); } else { - emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0)); pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); } } @@ -842,11 +899,11 @@ void genPlus (iCode *ic) } else { int offset = 1; - + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { emitCLRZ; - emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0)); pic14_emitcode("clrz",""); @@ -857,11 +914,11 @@ void genPlus (iCode *ic) } else { - emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - + emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0)); + emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0)); + //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitMOVWF(IC_RIGHT(ic),0); pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", @@ -874,58 +931,63 @@ void genPlus (iCode *ic) while(--size){ emitSKPZ; - emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE)); + emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++)); //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE)); } } } else { - + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + /* Add the first bytes */ + if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) { - emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); } else { if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { - emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0)); if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) - emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); } else { - emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0)); if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) - emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0)); else { - if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || - (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) { - emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - } else { - emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) - emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - } + PIC_OPCODE poc = POC_ADDFW; + + if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && ( + (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || + (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) + poc = POC_ADDLW; + emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0)); + if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) + emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); } } } + size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1; offset = 1; - size--; + while(size--){ if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset)); + emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); } - emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); emitSKPNC; - emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset)); + emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset)); /* pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); @@ -939,6 +1001,49 @@ void genPlus (iCode *ic) } + 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 */ + emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset)); + emitpcode(POC_RLF, 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 */ + + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0)); + emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0)); + emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset)); + + /* if chars or ints or being signed extended to longs: */ + if(size) { + emitpcode(POC_MOVLW, popGetLit(0)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0)); + emitpcode(POC_MOVLW, popGetLit(0xff)); + } + } + + offset++; + while(size--) { + + if(sign) + emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); + else + emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset)); + + offset++; + } + } + + //adjustArithmeticResult(ic); release: @@ -977,10 +1082,10 @@ bool genMinusDec (iCode *ic) (icount == 1)) { if(size == 2) { - emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); - emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); - emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE)); - emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE)); + emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB)); + emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB)); + emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16)); + emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16)); pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); @@ -988,11 +1093,11 @@ bool genMinusDec (iCode *ic) } else { /* size is 3 or 4 */ emitpcode(POC_MOVLW, popGetLit(0xff)); - emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB)); emitSKPNC; - emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16)); emitSKPNC; - emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24)); pic14_emitcode("movlw","0xff"); pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); @@ -1004,7 +1109,7 @@ bool genMinusDec (iCode *ic) if(size > 3) { emitSKPNC; - emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32)); pic14_emitcode("skpnc",""); emitSKPNC; @@ -1028,7 +1133,7 @@ bool genMinusDec (iCode *ic) if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) { while (icount--) - emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0)); //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); @@ -1043,8 +1148,8 @@ bool genMinusDec (iCode *ic) pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0)); + emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0)); return TRUE; } @@ -1053,22 +1158,33 @@ bool genMinusDec (iCode *ic) } /*-----------------------------------------------------------------*/ -/* addSign - complete with sign */ +/* addSign - propogate sign bit to higher bytes */ /*-----------------------------------------------------------------*/ void addSign(operand *result, int offset, int sign) { - int size = (pic14_getDataSize(result) - offset); - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(size > 0){ - if(sign){ - pic14_emitcode("rlc","a"); - pic14_emitcode("subb","a,acc"); - while(size--) - aopPut(AOP(result),"a",offset++); - } else - while(size--) - aopPut(AOP(result),"#0",offset++); - } + int size = (pic14_getDataSize(result) - offset); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if(size > 0){ + if(sign && offset) { + + if(size == 1) { + emitpcode(POC_CLRF,popGet(AOP(result),offset)); + emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0)); + emitpcode(POC_DECF, popGet(AOP(result),offset)); + } else { + + emitpcode(POC_MOVLW, popGetLit(0)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0)); + emitpcode(POC_MOVLW, popGetLit(0xff)); + while(size--) + emitpcode(POC_MOVWF, popGet(AOP(result),size)); + + } + } else + while(size--) + emitpcode(POC_CLRF,popGet(AOP(result),offset++)); + } } /*-----------------------------------------------------------------*/ @@ -1101,7 +1217,7 @@ void genMinusBits (iCode *ic) /*-----------------------------------------------------------------*/ void genMinus (iCode *ic) { - int size, offset = 0,same; + int size, offset = 0, same=0; unsigned long lit = 0L; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -1143,14 +1259,14 @@ void genMinus (iCode *ic) lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); lit = - (long)lit; - genAddLit ( IC_RESULT(ic),IC_LEFT(ic), lit); + genAddLit ( ic, lit); #if 0 /* add the first byte: */ pic14_emitcode("movlw","0x%x", lit & 0xff); pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0)); offset = 1; @@ -1165,19 +1281,19 @@ void genMinus (iCode *ic) if((lit & 0xff) == 0xff) { emitpcode(POC_MOVLW, popGetLit(0xff)); emitSKPC; - emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset)); } else { emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); emitSKPNC; emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff)); - emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset)); } } else { /* do the rlf known zero trick here */ emitpcode(POC_MOVLW, popGetLit(1)); emitSKPNC; - emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset)); } offset++; } @@ -1193,8 +1309,8 @@ void genMinus (iCode *ic) if(size == 1) { if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0)); pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", AOP(IC_RIGHT(ic))->aopu.aop_dir, @@ -1203,7 +1319,7 @@ void genMinus (iCode *ic) } else { if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { - emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0)); emitpcode(POC_XORLW , popGetLit(1)); }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) { @@ -1213,35 +1329,35 @@ void genMinus (iCode *ic) if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) { if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) { if(lit & 1) { - emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0)); } }else{ - emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0)); if(lit & 1) - emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0)); else - emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0)); } goto release; } else { emitpcode(POC_MOVLW , popGetLit(lit & 0xff)); - emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0)); emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff)); - emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0)); } } else { - emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0)); + emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0)); } if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) { - emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0)); } else { emitpcode(POC_ANDLW , popGetLit(1)); @@ -1269,17 +1385,19 @@ void genMinus (iCode *ic) if( (size == 1) && ((lit & 0xff) == 0) ) { /* res = 0 - right */ if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) { - emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0)); } else { - emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0)); + emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0)); + emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0)); } goto release; } - emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0)); emitpcode(POC_SUBLW, popGetLit(lit & 0xff)); - emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); offset = 1; @@ -1293,21 +1411,21 @@ void genMinus (iCode *ic) if(lit == 0xff) { /* 0xff - x == ~x */ if(same) { - emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset)); emitSKPC; - emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset)); } else { - emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset)); + emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); emitSKPC; - emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset)); } } else { - emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); emitSKPC; - emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset)); emitpcode(POC_SUBLW, popGetLit(lit & 0xff)); - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); } goto release; @@ -1319,24 +1437,24 @@ void genMinus (iCode *ic) emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); emitSKPC; emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1)); - emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset)); } else { emitSKPNC; - emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset)); } } else { if(lit & 0xff) { emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); } else - emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset)); - emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); emitSKPC; - emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset)); + emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset)); } } @@ -1350,38 +1468,38 @@ void genMinus (iCode *ic) if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) { DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0)); emitpcode(POC_SUBLW, popGetLit(0)); - emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); } else { if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { - emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0)); emitpcode(POC_SUBLW, popGetLit(0)); if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) - emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); } else { DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) - emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0)); if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) - emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0)); else { if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) { - emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0)); } else { - emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0)); } if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) { if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) { - emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0)); emitSKPZ; - emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0)); }else - emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); } } } @@ -1402,13 +1520,13 @@ void genMinus (iCode *ic) while(size--){ if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset)); + emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); } - emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); emitSKPC; - emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); + emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset)); + emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset)); offset++; } @@ -1423,5 +1541,407 @@ void genMinus (iCode *ic) freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } +/*-----------------------------------------------------------------* + * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers. + * + * + *-----------------------------------------------------------------*/ +void genUMult8XLit_16 (operand *left, + operand *right, + operand *result, + pCodeOpReg *result_hi) + +{ + + unsigned int lit; + unsigned int i,have_first_bit; + int same; + pCodeOp *temp; + + if (AOP_TYPE(right) != AOP_LIT){ + fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__); + exit(1); + } + + + if(!result_hi) { + result_hi = PCOR(popGet(AOP(result),1)); + } + + lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit); + lit &= 0xff; + pic14_emitcode(";","Unrolled 8 X 8 multiplication"); + + same = pic14_sameRegs(AOP(left), AOP(result)); + + if(same) { + switch(lit) { + case 0: + emitpcode(POC_CLRF, popGet(AOP(left),0)); + return; + case 2: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + return; + case 3: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + return; + case 4: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + return; + case 5: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F + return; + case 6: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + return; + case 7: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F + return; + case 8: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F + return; + case 9: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + return; + case 10: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + return; + case 11: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F + return; + case 12: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + return; + case 13: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*F + return; + case 14: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F + emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F + emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F + return; + case 15: + temp = popGetTempReg(); + if(!temp) { + fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__); + exit(1); + } + emitpcode(POC_SWAPFW, popGet(AOP(left),0)); + emitpcode(POC_MOVWF, temp); + emitpcode(POC_ANDLW, popGetLit(0xf0)); + emitpcode(POC_MOVWF, popGet(AOP(left),0)); + emitpcode(POC_SWAPFW, temp); + emitpcode(POC_SUBWF, popGet(AOP(left),0)); + popReleaseTempReg(temp); + return; + case 16: + emitpcode(POC_SWAPFW, popGet(AOP(left),0)); + emitpcode(POC_ANDLW, popGetLit(0xf0)); + emitpcode(POC_MOVWF, popGet(AOP(left),0)); + return; + case 17: + emitpcode(POC_SWAPFW, popGet(AOP(left),0)); + emitpcode(POC_ANDLW, popGetLit(0xf0)); + emitpcode(POC_ADDWF, popGet(AOP(left),0)); + return; + case 32: + emitpcode(POC_SWAPF, popGet(AOP(left),0)); + emitpcode(POC_RLFW, popGet(AOP(left),0)); + emitpcode(POC_ANDLW, popGetLit(0xe0)); + emitpcode(POC_MOVWF, popGet(AOP(left),0)); + return; + case 64: + emitpcode(POC_SWAPF, popGet(AOP(left),0)); + emitpcode(POC_RLF, popGet(AOP(left),0)); + emitpcode(POC_RLFW, popGet(AOP(left),0)); + emitpcode(POC_ANDLW, popGetLit(0xc0)); + emitpcode(POC_MOVWF, popGet(AOP(left),0)); + return; + case 128: + emitpcode(POC_RRFW, popGet(AOP(left),0)); + emitpcode(POC_CLRF, popGet(AOP(left),0)); + emitpcode(POC_RRF, popGet(AOP(left),0)); + return; + + } + } else { + + switch(lit) { + case 0: + emitpcode(POC_CLRF, popGet(AOP(result),0)); + emitpcode(POC_CLRF, popCopyReg(result_hi)); + return; + case 2: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_MOVWF, popGet(AOP(result),0)); + emitpcode(POC_ADDWF, popGet(AOP(result),0)); + emitpcode(POC_CLRF, popCopyReg(result_hi)); + emitpcode(POC_RLF, popCopyReg(result_hi)); + return; + } + + } + + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_CLRF, popGet(AOP(result),0)); + emitpcode(POC_CLRF, popCopyReg(result_hi)); + + have_first_bit = 0; + for(i=0; i<8; i++) { + + if(lit & 1) { + emitpcode(POC_ADDWF, popCopyReg(result_hi)); + have_first_bit = 1; + } + + if(have_first_bit) { + emitpcode(POC_RRF, popCopyReg(result_hi)); + emitpcode(POC_RRF, popGet(AOP(result),0)); + } + + lit >>= 1; + } + +} + +/*-----------------------------------------------------------------* + * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers. + * + * + *-----------------------------------------------------------------*/ +void genUMult8X8_16 (operand *left, + operand *right, + operand *result, + pCodeOpReg *result_hi) + +{ + + int i; + int looped = 1; + + if(!result_hi) { + result_hi = PCOR(popGet(AOP(result),1)); + } + + if (AOP_TYPE(right) == AOP_LIT) { + genUMult8XLit_16(left,right,result,result_hi); + return; + } + + if(!looped) { + pic14_emitcode(";","Unrolled 8 X 8 multiplication"); + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + emitpcode(POC_CLRF, popGet(AOP(result),0)); + emitpcode(POC_CLRF, popCopyReg(result_hi)); + emitCLRC; + for(i=0; i<8; i++) { + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0)); + emitpcode(POC_ADDWF, popCopyReg(result_hi)); + emitpcode(POC_RRF, popCopyReg(result_hi)); + emitpcode(POC_RRF, popGet(AOP(result),0)); + } + + + /* + Here's another version that does the same thing and takes the + same number of instructions. The one above is slightly better + because the entry instructions have a higher probability of + being optimized out. + */ + /* + emitpcode(POC_CLRF, popCopyReg(result_hi)); + emitpcode(POC_RRFW, popGet(AOP(left),0)); + emitpcode(POC_MOVWF, popGet(AOP(result),0)); + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + + for(i=0; i<8; i++) { + emitSKPNC; + emitpcode(POC_ADDWF, popCopyReg(result_hi)); + emitpcode(POC_RRF, popCopyReg(result_hi)); + emitpcode(POC_RRF, popGet(AOP(result),0)); + } + */ + + } else { + symbol *tlbl = newiTempLabel(NULL); + pCodeOp *temp; + + + pic14_emitcode(";","Looped 8 X 8 multiplication"); + + emitpcode(POC_CLRF, popGet(AOP(result),0)); + emitpcode(POC_CLRF, popCopyReg(result_hi)); + + emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0)); + + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + + temp = popGetTempReg(); + emitpcode(POC_MOVWF, popCopyReg(PCOR(temp))); + + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + + emitpLabel(tlbl->key); + + emitpcode(POC_RRF, popCopyReg(PCOR(temp))); + emitSKPNC; + emitpcode(POC_ADDWF, popCopyReg(result_hi)); + + emitpcode(POC_RRF, popCopyReg(result_hi)); + emitpcode(POC_RRF, popGet(AOP(result),0)); + + emitSKPC; + emitpcode(POC_GOTO, popGetLabel(tlbl->key)); + + popReleaseTempReg(temp); + + } +} + +/*-----------------------------------------------------------------* + * genSMult8X8_16 - signed multiplication of two 8-bit numbers + * + * this routine will call the unsigned multiply routine and then + * post-fix the sign bit. + *-----------------------------------------------------------------*/ +void genSMult8X8_16 (operand *left, + operand *right, + operand *result, + pCodeOpReg *result_hi) +{ + + if(!result_hi) { + result_hi = PCOR(popGet(AOP(result),1)); + } + + genUMult8X8_16(left,right,result,result_hi); + + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0)); + emitpcode(POC_SUBWF, popCopyReg(result_hi)); + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0)); + emitpcode(POC_SUBWF, popGet(AOP(result),1)); + +} + +/*-----------------------------------------------------------------* + * 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. + * + *-----------------------------------------------------------------*/ +void genMult8X8_8 (operand *left, + operand *right, + operand *result) +{ + pCodeOp *result_hi = popGetTempReg(); + + if (AOP_TYPE(right) == AOP_LIT) + genUMult8XLit_16(left,right,result,PCOR(result_hi)); + else + genUMult8X8_16(left,right,result,PCOR(result_hi)); + + popReleaseTempReg(result_hi); +} +#if 0 +/*-----------------------------------------------------------------*/ +/* constMult - generates code for multiplication by a constant */ +/*-----------------------------------------------------------------*/ +void genMultConst(unsigned C) +{ + + unsigned lit; + unsigned sr3; // Shift right 3 + unsigned mask; + + int size = 1; + + /* + Convert a string of 3 binary 1's in the lit into + 0111 = 1000 - 1; + */ + + mask = 7 << ( (size*8) - 3); + lit = C; + sr3 = 0; + + while(mask < (1<>= 1; + + } + +} + +#endif