#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"
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_POINTER:
+ return "PO_GPR_POINTER";
+ 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++;
}
}
}
else {
PIC_OPCODE poc = POC_ADDFW;
- if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL)
+ 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)
offset = 1;
- while(size--){
- if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
- 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));
+ if(size){
+ if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
+ 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))) {
+ while(size--){
+ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitSKPNC;
+ emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ offset++;
+ }
+ } else {
+ while(size--){
+ emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
+ emitSKPNC;
+ emitpcode(POC_INCFSZW, popGet(AOP(IC_LEFT(ic)),offset));
+ emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
+ offset++;
+ }
+ }
+ } else {
+ PIC_OPCODE poc = POC_MOVFW;
+ 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_MOVLW;
+ while(size--){
+ if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
+ emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ }
+ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitSKPNC;
+ emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
+ offset++;
+ }
}
-
- emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
- emitSKPNC;
- 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));
- emitSKPNC;
- pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
- pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
- */
-
- offset++;
}
-
}
if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
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 (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
+ int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
+ PIC_OPCODE poc = POC_MOVFW;
+ 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_MOVLW;
+ while(leftsize-- > 0) {
+ emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ emitSKPNC;
+ emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset));
+ offset++;
+ if (size)
+ size--;
+ else
+ break;
+ }
+ } else {
+ emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
+ emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
+ }
if(sign) {
}
}
- /*
- emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
-
- if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
- emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- } else {
- emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- }
- */
+ 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));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ if(size){
+ if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
+ 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))) {
+ while(size--){
+ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitSKPC;
+ emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ offset++;
+ }
+ } else {
+ while(size--){
+ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitSKPC;
+ emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ offset++;
+ }
+ }
+ } else {
+ PIC_OPCODE poc = POC_MOVFW;
+ 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_MOVLW;
+ while(size--){
+ if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
+ 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));
+ emitSKPC;
+ emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
+ emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
+ offset++;
+ }
}
- emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
- emitSKPC;
- emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
- emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
-
- offset++;
}
-
}
-
// adjustArithmeticResult(ic);
release:
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__);
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_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 {