#include "SDCCglobl.h"
#include "newalloc.h"
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && (_MSC_VER < 1300)
#define __FUNCTION__ __FILE__
#endif
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 */
/*-----------------------------------------------------------------*/
}
} 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));
- } else
+ } 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));
- emitSKPNC;
- emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
- emitpcode(POC_ADDWF, popGet(AOP(result),offset));
+ 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));
emitpcode(POC_RLF, popGet(AOP(result),offset));
emitpcode(POC_MOVFW, popGet(AOP(left),offset));
emitpcode(POC_ADDWF, popGet(AOP(result),offset));
}
- offset++;
+ offset++;
}
}
}
if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
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));
- } else {
- emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0));
- if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
- emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
- }
+ 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));
}
}
}
}
/*-----------------------------------------------------------------*/
-/* 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++));
+ }
}
/*-----------------------------------------------------------------*/
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__);
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;
+ }
- if(!lit) {
- emitpcode(POC_CLRF, popGet(AOP(result),0));
- emitpcode(POC_CLRF, popCopyReg(result_hi));
- return;
}
emitpcode(POC_MOVFW, popGet(AOP(left),0));
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");
} else {
symbol *tlbl = newiTempLabel(NULL);
- pCodeOp *temp = popGetTempReg();
+ 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));