#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 <sys/isa_defs.h>
-#else
-#ifdef HAVE_MACHINE_ENDIAN_H
-#include <machine/endian.h>
-#else
-#ifdef HAVE_ENDIAN_H
-#include <endian.h>
-#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"
#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)
{
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 */
/*-----------------------------------------------------------------*/
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));
}
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);
//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);
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 ;
switch(AOP_TYPE(IC_RESULT(ic))) {
case AOP_ACC:
emitpcode(POC_CLRW, NULL);
- 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));
- emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
emitpcode(POC_XORLW, popGetLit(1));
pic14_emitcode("clrw","");
break;
case AOP_REG:
emitpcode(POC_MOVLW, popGetLit(0));
- 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));
- emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
emitpcode(POC_XORLW, popGetLit(1));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
break;
default:
- 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));
+ 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,
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));
}
}
return;
}
- emitpcode(POC_MOVWF, popGet(AOP(reg),offset,FALSE,FALSE));
+ emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
}
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));
}
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;
/* 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));
*/
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));
}
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));
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;
}
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;
}
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));
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;
}
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
/* left addend is in a register */
switch(lit & 0xff) {
case 0:
- emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
+ 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,FALSE,FALSE));
+ 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,FALSE,FALSE));
+ 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,FALSE,FALSE));
+ 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_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);
- lit >>= 8;
while(--size) {
+ lit >>= 8;
if(lit & 0xff) {
- 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,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++;
}
}
}
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 */
/* 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));
DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
genAddLit (ic, lit);
+ goto release;
} else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
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,
} 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)",
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)",
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));
}
}
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","");
} 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));
//emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
emitMOVWF(IC_RIGHT(ic),0);
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));
}
+ 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:
(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));
} 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));
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;
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));
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;
}
}
/*-----------------------------------------------------------------*/
-/* 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++));
+ }
}
/*-----------------------------------------------------------------*/
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;
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++;
}
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,
} 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) ) {
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));
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;
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;
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));
}
}
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));
}
}
}
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));
}
- 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++;
}
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<<size*8)) {
+
+ if( (mask & lit) == lit) {
+ unsigned lsb;
+
+ /* We found 3 (or more) consecutive 1's */
+
+ lsb = mask & ~(mask & (mask-1)); // lsb of mask.
+
+ consecutive_bits = ((lit + lsb) & lit) ^ lit;
+
+ lit ^= consecutive_bits;
+
+ mask <<= 3;
+
+ sr3 |= (consecutive + lsb);
+
+ }
+
+ mask >>= 1;
+
+ }
+
+}
+
+#endif