X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fgen.c;h=8b4c6d57b988aa521bb38e47413fecf391e0b8b3;hb=3828fc04fdc24262d05bdf413ba6e7943db86fee;hp=3955885cb4cdda1d3a96c2962264022b898c3073;hpb=54f886ab573f40c4356bbc4dc97c4196da96871b;p=fw%2Fsdcc diff --git a/src/pic/gen.c b/src/pic/gen.c index 3955885c..8b4c6d57 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -36,22 +36,22 @@ #include "SDCCglobl.h" #include "newalloc.h" -#if defined(_MSC_VER) -#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) +#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" @@ -59,8 +59,28 @@ #include "pcode.h" #include "gen.h" -//char *aopLiteral (value *val, int offset); + +extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); +extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); +void genMult8X8_8 (operand *, operand *,operand *); + +static int labelOffset=0; +static int debug_verbose=1; +static int optimized_for_speed = 0; + +/* max_key keeps track of the largest label number used in + a function. This is then used to adjust the label offset + for the next function. +*/ +static int max_key=0; +static int GpsuedoStkPtr=0; + +pCodeOp *popGetImmd(char *name, unsigned int offset, int index); unsigned int pic14aopLiteral (value *val, int offset); +const char *AopType(short type); +static iCode *ifxForOp ( operand *op, iCode *ic ); + +#define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff) /* this is the down and dirty file with all kinds of kludgy & hacky stuff. This is what it is all about @@ -71,9 +91,9 @@ static char *zero = "#0x00"; static char *one = "#0x01"; static char *spname = "sp"; -char *fReturnpic14[] = {"fsr","dph","b","a" }; +char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" }; //char *fReturn390[] = {"dpl","dph","dpx", "b","a" }; -static unsigned fReturnSize = 4; /* shared with ralloc.c */ +unsigned fReturnSizePic = 4; /* shared with ralloc.c */ static char **fReturn = fReturnpic14; static char *accUse[] = {"a","b"}; @@ -90,19 +110,20 @@ static struct { set *sendSet; } _G; +/* Resolved ifx structure. This structure stores information + about an iCode ifx that makes it easier to generate code. +*/ +typedef struct resolvedIfx { + symbol *lbl; /* pointer to a label */ + int condition; /* true or false ifx */ + int generated; /* set true when the code associated with the ifx + * is generated */ +} resolvedIfx; + extern int pic14_ptrRegReq ; extern int pic14_nRegs; extern FILE *codeOutFile; static void saverbank (int, iCode *,bool); -#define RESULTONSTACK(x) \ - (IC_RESULT(x) && IC_RESULT(x)->aop && \ - IC_RESULT(x)->aop->type == AOP_STK ) - -#define MOVA(x) if (strcmp(x,"a") && strcmp(x,"acc")) emitcode(";XXX mov","a,%s %s,%d",x,__FILE__,__LINE__); -#define CLRC emitcode(";XXX clr","c %s,%d",__FILE__,__LINE__); - -#define BIT_NUMBER(x) (x & 7) -#define BIT_REGISTER(x) (x>>3) static lineNode *lineHead = NULL; static lineNode *lineCurr = NULL; @@ -112,36 +133,8 @@ static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0, static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00}; -#define LSB 0 -#define MSB16 1 -#define MSB24 2 -#define MSB32 3 - - -#define FUNCTION_LABEL_INC 20 -static int labelOffset=0; -static int debug_verbose=1; - static pBlock *pb; -/*-----------------------------------------------------------------*/ -/* Macros for emitting instructions */ -/*-----------------------------------------------------------------*/ - -#define emitSKPC emitpcode(POC_BTFSS,popCopyGPR2Bit(&pc_status,PIC_C_BIT)) -#define emitSKPNC emitpcode(POC_BTFSC,popCopyGPR2Bit(&pc_status,PIC_C_BIT)) -#define emitSKPZ emitpcode(POC_BTFSS,popCopyGPR2Bit(&pc_status,PIC_Z_BIT)) -#define emitSKPNZ emitpcode(POC_BTFSC,popCopyGPR2Bit(&pc_status,PIC_Z_BIT)) -#define emitCLRZ emitpcode(POC_BCF, popCopyGPR2Bit(&pc_status,PIC_Z_BIT)) -#define emitCLRC emitpcode(POC_BCF, popCopyGPR2Bit(&pc_status,PIC_C_BIT)) -#define emitSETZ emitpcode(POC_BSF, popCopyGPR2Bit(&pc_status,PIC_Z_BIT)) -#define emitSETC emitpcode(POC_BSF, popCopyGPR2Bit(&pc_status,PIC_C_BIT)) - -//#define emitSKPC emitcode("btfss","status,c") -//#define emitSKPNC emitcode("btfsc","status,c") -//#define emitSKPZ emitcode("btfss","status,z") -//#define emitSKPNZ emitcode("btfsc","status,z") - /*-----------------------------------------------------------------*/ /* my_powof2(n) - If `n' is an integaer power of 2, then the */ /* exponent of 2 is returned, otherwise -1 is */ @@ -167,26 +160,44 @@ static int my_powof2 (unsigned long num) return -1; } -static void emitpLabel(int key) +void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result) { - addpCode2pBlock(pb,newpCodeLabel(key)); + + DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d", + line_no, + ((result) ? AopType(AOP_TYPE(result)) : "-"), + ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"), + ((left) ? AopType(AOP_TYPE(left)) : "-"), + ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"), + ((right) ? AopType(AOP_TYPE(right)) : "-"), + ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"), + ((result) ? AOP_SIZE(result) : 0)); + } -static void emitpcode(PIC_OPCODE poc, pCodeOp *pcop) +void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result) { - addpCode2pBlock(pb,newpCode(poc,pcop)); + DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c", + line_no, + ((result) ? AopType(AOP_TYPE(result)) : "-"), + ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'), + ((left) ? AopType(AOP_TYPE(left)) : "-"), + ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'), + ((right) ? AopType(AOP_TYPE(right)) : "-"), + ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-')); } -/*-----------------------------------------------------------------*/ -/* emitcode - writes the code into a file : for now it is simple */ -/*-----------------------------------------------------------------*/ -static void emitcode (char *inst,char *fmt, ...) + +void DEBUGpic14_emitcode (char *inst,char *fmt, ...) { va_list ap; - char lb[MAX_INLINEASM]; + char lb[INITIAL_INLINEASM]; char *lbp = lb; + if(!debug_verbose) + return; + va_start(ap,fmt); if (inst && *inst) { @@ -212,15 +223,37 @@ static void emitcode (char *inst,char *fmt, ...) va_end(ap); } -static void DEBUGemitcode (char *inst,char *fmt, ...) + +void emitpLabel(int key) +{ + addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset)); +} + +void emitpcode(PIC_OPCODE poc, pCodeOp *pcop) +{ + + if(pcop) + addpCode2pBlock(pb,newpCode(poc,pcop)); + else + DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__); +} + +void emitpcodeNULLop(PIC_OPCODE poc) +{ + + addpCode2pBlock(pb,newpCode(poc,NULL)); + +} + +/*-----------------------------------------------------------------*/ +/* pic14_emitcode - writes the code into a file : for now it is simple */ +/*-----------------------------------------------------------------*/ +void pic14_emitcode (char *inst,char *fmt, ...) { va_list ap; - char lb[MAX_INLINEASM]; + char lb[INITIAL_INLINEASM]; char *lbp = lb; - if(!debug_verbose) - return; - va_start(ap,fmt); if (inst && *inst) { @@ -241,7 +274,8 @@ static void DEBUGemitcode (char *inst,char *fmt, ...) lineCurr->isInline = _G.inLine; lineCurr->isDebug = _G.debugLine; - addpCode2pBlock(pb,newpCodeCharP(lb)); + if(debug_verbose) + addpCode2pBlock(pb,newpCodeCharP(lb)); va_end(ap); } @@ -290,8 +324,8 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) if (!r0iu) { /* push it if not already pushed */ if (!_G.r0Pushed) { - emitcode ("push","%s", - pic14_regWithIdx(R0_IDX)->dname); + //pic14_emitcode ("push","%s", + // pic14_regWithIdx(R0_IDX)->dname); _G.r0Pushed++ ; } @@ -306,8 +340,8 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) if (!r1iu) { /* push it if not already pushed */ if (!_G.r1Pushed) { - emitcode ("push","%s", - pic14_regWithIdx(R1_IDX)->dname); + //pic14_emitcode ("push","%s", + // pic14_regWithIdx(R1_IDX)->dname); _G.r1Pushed++ ; } @@ -324,7 +358,6 @@ endOfWorld : return NULL; } - piCode(ic,stdout); /* other wise this is true end of the world */ werror(E_INTERNAL_ERROR,__FILE__,__LINE__, "getFreePtr should never reach here"); @@ -334,7 +367,7 @@ endOfWorld : /*-----------------------------------------------------------------*/ /* newAsmop - creates a new asmOp */ /*-----------------------------------------------------------------*/ -static asmop *newAsmop (short type) +asmop *newAsmop (short type) { asmop *aop; @@ -347,16 +380,50 @@ static void genSetDPTR(int n) { if (!n) { - emitcode(";", "Select standard DPTR"); - emitcode("mov", "dps, #0x00"); + pic14_emitcode(";", "Select standard DPTR"); + pic14_emitcode("mov", "dps, #0x00"); } else { - emitcode(";", "Select alternate DPTR"); - emitcode("mov", "dps, #0x01"); + pic14_emitcode(";", "Select alternate DPTR"); + pic14_emitcode("mov", "dps, #0x01"); } } +/*-----------------------------------------------------------------*/ +/* resolveIfx - converts an iCode ifx into a form more useful for */ +/* generating code */ +/*-----------------------------------------------------------------*/ +static void resolveIfx(resolvedIfx *resIfx, iCode *ifx) +{ + if(!resIfx) + return; + + DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + + resIfx->condition = 1; /* assume that the ifx is true */ + resIfx->generated = 0; /* indicate that the ifx has not been used */ + + if(!ifx) { + resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */ + DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d", + __FUNCTION__,__LINE__,resIfx->lbl->key); + } else { + if(IC_TRUE(ifx)) { + resIfx->lbl = IC_TRUE(ifx); + } else { + resIfx->lbl = IC_FALSE(ifx); + resIfx->condition = 0; + } + if(IC_TRUE(ifx)) + DEBUGpic14_emitcode("; ***","ifx true is non-null"); + if(IC_FALSE(ifx)) + DEBUGpic14_emitcode("; ***","ifx false is non-null"); + } + + DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset); + +} /*-----------------------------------------------------------------*/ /* pointerCode - returns the code for a pointer type */ /*-----------------------------------------------------------------*/ @@ -375,7 +442,7 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) asmop *aop; memmap *space= SPEC_OCLS(sym->etype); - DEBUGemitcode("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); /* if already has one */ if (sym->aop) return sym->aop; @@ -394,20 +461,20 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) if (sym->onStack) { if ( _G.accInUse ) - emitcode("push","acc"); + pic14_emitcode("push","acc"); - emitcode("mov","a,_bp"); - emitcode("add","a,#0x%02x", + pic14_emitcode("mov","a,_bp"); + pic14_emitcode("add","a,#0x%02x", ((sym->stack < 0) ? ((char)(sym->stack - _G.nRegsSaved )) : ((char)sym->stack)) & 0xff); - emitcode("mov","%s,a", + pic14_emitcode("mov","%s,a", aop->aopu.aop_ptr->name); if ( _G.accInUse ) - emitcode("pop","acc"); + pic14_emitcode("pop","acc"); } else - emitcode("mov","%s,#%s", + pic14_emitcode("mov","%s,#%s", aop->aopu.aop_ptr->name, sym->rname); aop->paged = space->paged; @@ -422,38 +489,38 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) * far data space. */ - //DEBUGemitcode(";","%d",__LINE__); + //DEBUGpic14_emitcode(";","%d",__LINE__); if ( _G.accInUse ) - emitcode("push","acc"); + pic14_emitcode("push","acc"); - emitcode("mov","a,_bp"); - emitcode("add","a,#0x%02x", + pic14_emitcode("mov","a,_bp"); + pic14_emitcode("add","a,#0x%02x", ((sym->stack < 0) ? ((char)(sym->stack - _G.nRegsSaved )) : ((char)sym->stack)) & 0xff); genSetDPTR(1); - emitcode ("mov","dpx1,#0x40"); - emitcode ("mov","dph1,#0x00"); - emitcode ("mov","dpl1, a"); + pic14_emitcode ("mov","dpx1,#0x40"); + pic14_emitcode ("mov","dph1,#0x00"); + pic14_emitcode ("mov","dpl1, a"); genSetDPTR(0); if ( _G.accInUse ) - emitcode("pop","acc"); + pic14_emitcode("pop","acc"); sym->aop = aop = newAsmop(AOP_DPTR2); aop->size = getSize(sym->type); return aop; } - //DEBUGemitcode(";","%d",__LINE__); + //DEBUGpic14_emitcode(";","%d",__LINE__); /* if in bit space */ if (IN_BITSPACE(space)) { sym->aop = aop = newAsmop (AOP_CRY); aop->aopu.aop_dir = sym->rname ; aop->size = getSize(sym->type); - DEBUGemitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); + //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); return aop; } /* if it is in direct space */ @@ -461,7 +528,7 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) sym->aop = aop = newAsmop (AOP_DIR); aop->aopu.aop_dir = sym->rname ; aop->size = getSize(sym->type); - DEBUGemitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); + DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); return aop; } @@ -472,17 +539,34 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1); strcpy(aop->aopu.aop_immd,sym->rname); aop->size = FPTRSIZE; + DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname); return aop; } /* only remaining is far space */ /* in which case DPTR gets the address */ + sym->aop = aop = newAsmop(AOP_PCODE); + + aop->aopu.pcop = popGetImmd(sym->rname,0,0); + PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space); + PCOI(aop->aopu.pcop)->index = 0; + + DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d", + sym->rname, 0, PCOI(aop->aopu.pcop)->_const); + + allocDirReg (IC_LEFT(ic)); + + aop->size = FPTRSIZE; +/* + DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname); sym->aop = aop = newAsmop(AOP_DPTR); - emitcode ("mov","dptr,#%s", sym->rname); + pic14_emitcode ("mov","dptr,#%s", sym->rname); aop->size = getSize(sym->type); - DEBUGemitcode(";","%d size = %d",__LINE__,aop->size); + DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size); +*/ + /* if it is in code space */ if (IN_CODESPACE(space)) aop->code = 1; @@ -493,37 +577,56 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) /*-----------------------------------------------------------------*/ /* aopForRemat - rematerialzes an object */ /*-----------------------------------------------------------------*/ -static asmop *aopForRemat (symbol *sym) +static asmop *aopForRemat (operand *op) // x symbol *sym) { - iCode *ic = sym->rematiCode; - asmop *aop = newAsmop(AOP_IMMD); - int val = 0; - DEBUGemitcode(";","%s %d",__FUNCTION__,__LINE__); + symbol *sym = OP_SYMBOL(op); + iCode *ic = NULL; + asmop *aop = newAsmop(AOP_PCODE); + int val = 0; + int offset = 0; + + ic = sym->rematiCode; + + DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__); + for (;;) { - if (ic->op == '+') - val += operandLitValue(IC_RIGHT(ic)); - else if (ic->op == '-') - val -= operandLitValue(IC_RIGHT(ic)); - else + if (ic->op == '+') { + val += (int) operandLitValue(IC_RIGHT(ic)); + } else if (ic->op == '-') { + val -= (int) operandLitValue(IC_RIGHT(ic)); + } else break; ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; } - if (val) - sprintf(buffer,"(%s %c 0x%04x)", - OP_SYMBOL(IC_LEFT(ic))->rname, - val >= 0 ? '+' : '-', - abs(val) & 0xffff); - else - strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname); + offset = OP_SYMBOL(IC_LEFT(ic))->offset; + aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val); + PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op)); + PCOI(aop->aopu.pcop)->index = val; + + DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d", + OP_SYMBOL(IC_LEFT(ic))->rname, + val, IS_PTR_CONST(operandType(op))); + + // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic)))); + + allocDirReg (IC_LEFT(ic)); - //DEBUGemitcode(";","%s",buffer); - aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1); - strcpy(aop->aopu.aop_immd,buffer); return aop; } +int aopIdx (asmop *aop, int offset) +{ + if(!aop) + return -1; + + if(aop->type != AOP_REG) + return -2; + + return aop->aopu.aop_reg[offset]->rIdx; + +} /*-----------------------------------------------------------------*/ /* regsInCommon - two operands have some registers in common */ /*-----------------------------------------------------------------*/ @@ -605,9 +708,9 @@ static bool operandsEqu ( operand *op1, operand *op2) } /*-----------------------------------------------------------------*/ -/* sameRegs - two asmops have the same registers */ +/* pic14_sameRegs - two asmops have the same registers */ /*-----------------------------------------------------------------*/ -static bool sameRegs (asmop *aop1, asmop *aop2 ) +bool pic14_sameRegs (asmop *aop1, asmop *aop2 ) { int i; @@ -632,7 +735,7 @@ static bool sameRegs (asmop *aop1, asmop *aop2 ) /*-----------------------------------------------------------------*/ /* aopOp - allocates an asmop for an operand : */ /*-----------------------------------------------------------------*/ -static void aopOp (operand *op, iCode *ic, bool result) +void aopOp (operand *op, iCode *ic, bool result) { asmop *aop; symbol *sym; @@ -641,32 +744,37 @@ static void aopOp (operand *op, iCode *ic, bool result) if (!op) return ; - DEBUGemitcode(";","%d",__LINE__); + // DEBUGpic14_emitcode(";","%d",__LINE__); /* if this a literal */ if (IS_OP_LITERAL(op)) { - DEBUGemitcode(";","%d",__LINE__); op->aop = aop = newAsmop(AOP_LIT); aop->aopu.aop_lit = op->operand.valOperand; aop->size = getSize(operandType(op)); return; } + { + sym_link *type = operandType(op); + if(IS_PTR_CONST(type)) + DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__); + } + /* if already has a asmop then continue */ if (op->aop) return ; /* if the underlying symbol has a aop */ if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) { - DEBUGemitcode(";","%d",__LINE__); + DEBUGpic14_emitcode(";","%d",__LINE__); op->aop = OP_SYMBOL(op)->aop; return; } /* if this is a true symbol */ if (IS_TRUE_SYMOP(op)) { - DEBUGemitcode(";","%d",__LINE__); - op->aop = aopForSym(ic,OP_SYMBOL(op),result); - return ; + //DEBUGpic14_emitcode(";","%d - true symop",__LINE__); + op->aop = aopForSym(ic,OP_SYMBOL(op),result); + return ; } /* this is a temporary : this has @@ -682,7 +790,6 @@ static void aopOp (operand *op, iCode *ic, bool result) /* if the type is a conditional */ if (sym->regType == REG_CND) { - DEBUGemitcode(";","%d",__LINE__); aop = op->aop = sym->aop = newAsmop(AOP_CRY); aop->size = 0; return; @@ -693,13 +800,14 @@ static void aopOp (operand *op, iCode *ic, bool result) b) has a spill location */ if (sym->isspilt || sym->nRegs == 0) { - DEBUGemitcode(";","%d",__LINE__); + DEBUGpic14_emitcode(";","%d",__LINE__); /* rematerialize it NOW */ if (sym->remat) { + sym->aop = op->aop = aop = - aopForRemat (sym); + aopForRemat (op); aop->size = getSize(sym->type); - DEBUGemitcode(";","%d",__LINE__); + //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd); return; } @@ -709,28 +817,44 @@ static void aopOp (operand *op, iCode *ic, bool result) aop->size = getSize(sym->type); for ( i = 0 ; i < 2 ; i++ ) aop->aopu.aop_str[i] = accUse[i]; - DEBUGemitcode(";","%d",__LINE__); + DEBUGpic14_emitcode(";","%d",__LINE__); return; } if (sym->ruonly ) { - int i; + unsigned i; aop = op->aop = sym->aop = newAsmop(AOP_STR); aop->size = getSize(sym->type); - for ( i = 0 ; i < fReturnSize ; i++ ) + for ( i = 0 ; i < fReturnSizePic ; i++ ) aop->aopu.aop_str[i] = fReturn[i]; - DEBUGemitcode(";","%d",__LINE__); + DEBUGpic14_emitcode(";","%d",__LINE__); return; } /* else spill location */ - DEBUGemitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname); - sym->aop = op->aop = aop = - aopForSym(ic,sym->usl.spillLoc,result); + if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) { + /* force a new aop if sizes differ */ + sym->usl.spillLoc->aop = NULL; + } + DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d", + __FUNCTION__,__LINE__, + sym->usl.spillLoc->rname, + sym->rname, sym->usl.spillLoc->offset); + // X sym->aop = op->aop = aop = aopForSym(ic,sym->usl.spillLoc,result); + sym->aop = op->aop = aop = newAsmop(AOP_PCODE); + aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset); + //allocDirReg (IC_LEFT(ic)); aop->size = getSize(sym->type); + return; } + { + sym_link *type = operandType(op); + if(IS_PTR_CONST(type)) + DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__); + } + /* must be in a register */ sym->aop = op->aop = aop = newAsmop(AOP_REG); aop->size = sym->nRegs; @@ -741,7 +865,7 @@ static void aopOp (operand *op, iCode *ic, bool result) /*-----------------------------------------------------------------*/ /* freeAsmop - free up the asmop given to an operand */ /*----------------------------------------------------------------*/ -static void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) +void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) { asmop *aop ; @@ -760,11 +884,12 @@ static void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) /* depending on the asmop type only three cases need work AOP_RO , AOP_R1 && AOP_STK */ +#if 0 switch (aop->type) { case AOP_R0 : if (_G.r0Pushed ) { if (pop) { - emitcode ("pop","ar0"); + pic14_emitcode ("pop","ar0"); _G.r0Pushed--; } } @@ -774,7 +899,7 @@ static void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) case AOP_R1 : if (_G.r1Pushed ) { if (pop) { - emitcode ("pop","ar1"); + pic14_emitcode ("pop","ar1"); _G.r1Pushed--; } } @@ -800,32 +925,33 @@ static void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) } if (stk) { - emitcode ("mov","a,_bp"); - emitcode ("add","a,#0x%02x",((char)stk) & 0xff); - emitcode ("mov","%s,a",aop->aopu.aop_ptr->name); + pic14_emitcode ("mov","a,_bp"); + pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff); + pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name); } else { - emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name); + pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name); } while (sz--) { - emitcode("pop","acc"); - emitcode("mov","@%s,a",aop->aopu.aop_ptr->name); + pic14_emitcode("pop","acc"); + pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name); if (!sz) break; - emitcode("dec","%s",aop->aopu.aop_ptr->name); + pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name); } op->aop = aop; freeAsmop(op,NULL,ic,TRUE); if (_G.r0Pushed) { - emitcode("pop","ar0"); + pic14_emitcode("pop","ar0"); _G.r0Pushed--; } if (_G.r1Pushed) { - emitcode("pop","ar1"); + pic14_emitcode("pop","ar1"); _G.r1Pushed--; } } } +#endif dealloc: /* all other cases just dealloc */ @@ -843,12 +969,12 @@ dealloc: /*-----------------------------------------------------------------*/ /* aopGet - for fetching value of the aop */ /*-----------------------------------------------------------------*/ -static char *aopGet (asmop *aop, int offset, bool bit16, bool dname) +char *aopGet (asmop *aop, int offset, bool bit16, bool dname) { char *s = buffer ; char *rs; - //DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* offset is greater than size then zero */ if (offset > (aop->size - 1) && @@ -860,21 +986,21 @@ static char *aopGet (asmop *aop, int offset, bool bit16, bool dname) case AOP_R0: case AOP_R1: - DEBUGemitcode(";","%d",__LINE__); + DEBUGpic14_emitcode(";","%d",__LINE__); /* if we need to increment it */ while (offset > aop->coff) { - emitcode ("inc","%s",aop->aopu.aop_ptr->name); + pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name); aop->coff++; } while (offset < aop->coff) { - emitcode("dec","%s",aop->aopu.aop_ptr->name); + pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name); aop->coff--; } aop->coff = offset ; if (aop->paged) { - emitcode("movx","a,@%s",aop->aopu.aop_ptr->name); + pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name); return (dname ? "acc" : "a"); } sprintf(s,"@%s",aop->aopu.aop_ptr->name); @@ -884,29 +1010,29 @@ static char *aopGet (asmop *aop, int offset, bool bit16, bool dname) case AOP_DPTR: case AOP_DPTR2: - DEBUGemitcode(";","%d",__LINE__); + DEBUGpic14_emitcode(";","%d",__LINE__); if (aop->type == AOP_DPTR2) { genSetDPTR(1); } while (offset > aop->coff) { - emitcode ("inc","dptr"); + pic14_emitcode ("inc","dptr"); aop->coff++; } while (offset < aop->coff) { - emitcode("lcall","__decdptr"); + pic14_emitcode("lcall","__decdptr"); aop->coff--; } aop->coff = offset; if (aop->code) { - emitcode("clr","a"); - emitcode("movc","a,@a+dptr"); + pic14_emitcode("clr","a"); + pic14_emitcode("movc","a,@a+dptr"); } else { - emitcode("movx","a,@dptr"); + pic14_emitcode("movx","a,@dptr"); } if (aop->type == AOP_DPTR2) @@ -918,7 +1044,6 @@ static char *aopGet (asmop *aop, int offset, bool bit16, bool dname) case AOP_IMMD: - DEBUGemitcode(";","%d",__LINE__); if (bit16) sprintf (s,"%s",aop->aopu.aop_immd); else @@ -929,52 +1054,45 @@ static char *aopGet (asmop *aop, int offset, bool bit16, bool dname) else sprintf(s,"%s", aop->aopu.aop_immd); + DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s); rs = Safe_calloc(1,strlen(s)+1); strcpy(rs,s); return rs; case AOP_DIR: - if (offset) - sprintf(s,"(%s + %d)", - aop->aopu.aop_dir, - offset); - else + if (offset) { + sprintf(s,"(%s + %d)", + aop->aopu.aop_dir, + offset); + DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s); + } else sprintf(s,"%s",aop->aopu.aop_dir); rs = Safe_calloc(1,strlen(s)+1); strcpy(rs,s); return rs; case AOP_REG: - DEBUGemitcode(";","%d",__LINE__); - if (dname) - return aop->aopu.aop_reg[offset]->dname; - else + //if (dname) + // return aop->aopu.aop_reg[offset]->dname; + //else return aop->aopu.aop_reg[offset]->name; case AOP_CRY: - emitcode(";","%d",__LINE__); - //emitcode("clr","a"); - //emitcode("mov","c,%s",aop->aopu.aop_dir); - //emitcode("rlc","a") ; - //return (dname ? "acc" : "a"); + //pic14_emitcode(";","%d",__LINE__); return aop->aopu.aop_dir; case AOP_ACC: - DEBUGemitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__); - //if (!offset && dname) - // return "acc"; - //return aop->aopu.aop_str[offset]; + DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__); return "AOP_accumulator_bug"; case AOP_LIT: - DEBUGemitcode(";","%d",__LINE__); sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset)); rs = Safe_calloc(1,strlen(s)+1); strcpy(rs,s); return rs; case AOP_STR: - DEBUGemitcode(";","%d",__LINE__); + DEBUGpic14_emitcode(";","%d",__LINE__); aop->coff = offset ; if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname) @@ -982,6 +1100,22 @@ static char *aopGet (asmop *aop, int offset, bool bit16, bool dname) return aop->aopu.aop_str[offset]; + case AOP_PCODE: + { + pCodeOp *pcop = aop->aopu.pcop; + DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE",__LINE__); + if(pcop->name) { + DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset); + //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset); + sprintf(s,"%s", pcop->name); + } else + sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset); + + } + rs = Safe_calloc(1,strlen(s)+1); + strcpy(rs,s); + return rs; + } werror(E_INTERNAL_ERROR,__FILE__,__LINE__, @@ -989,61 +1123,95 @@ static char *aopGet (asmop *aop, int offset, bool bit16, bool dname) exit(0); } + /*-----------------------------------------------------------------*/ -/* popGetLabel - create a new pCodeOp of type PO_LABEL */ +/* popGetTempReg - create a new temporary pCodeOp */ /*-----------------------------------------------------------------*/ -static pCodeOp *popGetLabel(unsigned int key) +pCodeOp *popGetTempReg(void) { - return newpCodeOpLabel(key+100+labelOffset); + + pCodeOp *pcop; + + pcop = newpCodeOp(NULL, PO_GPR_TEMP); + if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { + PCOR(pcop)->r->wasUsed=1; + PCOR(pcop)->r->isFree=0; + } + + return pcop; } /*-----------------------------------------------------------------*/ -/* popCopy - copy a pcode operator */ +/* popGetTempReg - create a new temporary pCodeOp */ /*-----------------------------------------------------------------*/ -static pCodeOp *popCopy(pCodeOp *pc) +void popReleaseTempReg(pCodeOp *pcop) { - pCodeOp *pcop; - pcop = Safe_calloc(1,sizeof(pCodeOp) ); - pcop->type = pc->type; - if(!(pcop->name = strdup(pc->name))) - fprintf(stderr,"oops %s %d",__FILE__,__LINE__); + if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) + PCOR(pcop)->r->isFree = 1; - return pcop; } - /*-----------------------------------------------------------------*/ -/* popCopy - copy a pcode operator */ +/* popGetLabel - create a new pCodeOp of type PO_LABEL */ /*-----------------------------------------------------------------*/ -static pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval) +pCodeOp *popGetLabel(unsigned int key) { - pCodeOp *pcop; - pcop = Safe_calloc(1,sizeof(pCodeOpBit) ); - pcop->type = PO_BIT; - if(!(pcop->name = strdup(pc->name))) - fprintf(stderr,"oops %s %d",__FILE__,__LINE__); - ((pCodeOpBit *)pcop)->bit = bitval; + DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset); - ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0; + if(key>max_key) + max_key = key; - return pcop; + return newpCodeOpLabel(NULL,key+100+labelOffset); } +/*-----------------------------------------------------------------*/ +/* popCopyReg - copy a pcode operator */ +/*-----------------------------------------------------------------*/ +pCodeOp *popCopyReg(pCodeOpReg *pc) +{ + pCodeOpReg *pcor; + + pcor = Safe_calloc(1,sizeof(pCodeOpReg) ); + pcor->pcop.type = pc->pcop.type; + if(pc->pcop.name) { + if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name))) + fprintf(stderr,"oops %s %d",__FILE__,__LINE__); + } else + pcor->pcop.name = NULL; + + pcor->r = pc->r; + pcor->rIdx = pc->rIdx; + pcor->r->wasUsed=1; + + //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx); + + return PCOP(pcor); +} /*-----------------------------------------------------------------*/ /* popGet - asm operator to pcode operator conversion */ /*-----------------------------------------------------------------*/ -static pCodeOp *popGetLit(unsigned int lit) +pCodeOp *popGetLit(unsigned int lit) { return newpCodeOpLit(lit); } +/*-----------------------------------------------------------------*/ +/* popGetImmd - asm operator to pcode immediate conversion */ +/*-----------------------------------------------------------------*/ +pCodeOp *popGetImmd(char *name, unsigned int offset, int index) +{ + + return newpCodeOpImmd(name, offset,index, 0); +} + + /*-----------------------------------------------------------------*/ /* popGet - asm operator to pcode operator conversion */ /*-----------------------------------------------------------------*/ -static pCodeOp *popGetWithString(char *str) +pCodeOp *popGetWithString(char *str) { pCodeOp *pcop; @@ -1053,29 +1221,53 @@ static pCodeOp *popGetWithString(char *str) exit (1); } - pcop = newpCodeOp(str); - pcop->type = PO_STR; + pcop = newpCodeOp(str,PO_STR); + + return pcop; +} + +pCodeOp *popRegFromString(char *str) +{ + + pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOp) ); + pcop->type = PO_DIR; + + DEBUGpic14_emitcode(";","%d",__LINE__); + pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING")); + + return pcop; +} + +pCodeOp *popRegFromIdx(int rIdx) +{ + pCodeOp *pcop; + + DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x", + __FUNCTION__,__LINE__,rIdx); + + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); + + PCOR(pcop)->rIdx = rIdx; + PCOR(pcop)->r = pic14_regWithIdx(rIdx); + PCOR(pcop)->r->isFree = 0; + PCOR(pcop)->r->wasUsed = 1; + + pcop->type = PCOR(pcop)->r->pc_type; + -/* - _ALLOC(pcop,sizeof(pCodeOp) ); - _ALLOC_ATOMIC(pcop->name,strlen(str)+1); - strcpy(pcop->name,str); - } else { - } -*/ return pcop; } /*-----------------------------------------------------------------*/ /* popGet - asm operator to pcode operator conversion */ /*-----------------------------------------------------------------*/ -static pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname) +pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) { - char *s = buffer ; - char *rs; + //char *s = buffer ; + //char *rs; pCodeOp *pcop; - //DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* offset is greater than size then zero */ @@ -1091,30 +1283,18 @@ static pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname) case AOP_DPTR: case AOP_DPTR2: case AOP_ACC: - DEBUGemitcode(";8051 legacy","%d",__LINE__); + DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type)); return NULL; case AOP_IMMD: - DEBUGemitcode(";","%d",__LINE__); - pcop = Safe_calloc(1,sizeof(pCodeOp) ); - pcop->type = PO_IMMEDIATE; - if (bit16) - sprintf (s,"%s",aop->aopu.aop_immd); - else - if (offset) - sprintf(s,"(%s >> %d)", - aop->aopu.aop_immd, - offset*8); - else - sprintf(s,"%s", - aop->aopu.aop_immd); - pcop->name = Safe_calloc(1,strlen(s)+1); - strcpy(pcop->name,s); - return pcop; - + DEBUGpic14_emitcode(";","%d",__LINE__); + return popGetImmd(aop->aopu.aop_immd,offset,0); + case AOP_DIR: - pcop = Safe_calloc(1,sizeof(pCodeOp) ); + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); pcop->type = PO_DIR; + + /* if (offset) sprintf(s,"(%s + %d)", aop->aopu.aop_dir, @@ -1123,45 +1303,62 @@ static pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname) sprintf(s,"%s",aop->aopu.aop_dir); pcop->name = Safe_calloc(1,strlen(s)+1); strcpy(pcop->name,s); + */ + pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1); + strcpy(pcop->name,aop->aopu.aop_dir); + PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir); + if(PCOR(pcop)->r == NULL) { + //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size); + PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size); + } + + DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset); + PCOR(pcop)->instance = offset; + return pcop; case AOP_REG: - DEBUGemitcode(";","%d",__LINE__); - pcop = Safe_calloc(1,sizeof(pCodeOp) ); - pcop->type = PO_GPR_REGISTER; - if (dname) - rs = aop->aopu.aop_reg[offset]->dname; - else - rs = aop->aopu.aop_reg[offset]->name; - - DEBUGemitcode(";","%d %s",__LINE__,rs); - pcop->name = Safe_calloc(1,(strlen(rs)+1)); - strcpy(pcop->name,rs); - return pcop; + { + int rIdx = aop->aopu.aop_reg[offset]->rIdx; + + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); + PCOR(pcop)->rIdx = rIdx; + PCOR(pcop)->r = pic14_regWithIdx(rIdx); + PCOR(pcop)->instance = offset; + pcop->type = PCOR(pcop)->r->pc_type; + //rs = aop->aopu.aop_reg[offset]->name; + //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs); + return pcop; + } case AOP_CRY: - pcop = newpCodeOpBit(aop->aopu.aop_dir,0); + pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1); + PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir); + //if(PCOR(pcop)->r == NULL) + //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir); return pcop; case AOP_LIT: - DEBUGemitcode(";","%d",__LINE__); return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset)); case AOP_STR: - DEBUGemitcode(";","%d",__LINE__); + DEBUGpic14_emitcode(";","%d",__LINE__); + return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]); + /* + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); + PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]); + PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx; + pcop->type = PCOR(pcop)->r->pc_type; + pcop->name = PCOR(pcop)->r->name; - pcop = Safe_calloc(1,sizeof(pCodeOp) ); - pcop->type = PO_STR; + return pcop; + */ - //aop->coff = offset ; - if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname) - sprintf(s,"%s","acc"); - else - sprintf(s,"%s",aop->aopu.aop_str[offset]); - pcop->name = Safe_calloc(1,strlen(s)+1); - strcpy(pcop->name,s); - return pcop; - + case AOP_PCODE: + DEBUGpic14_emitcode(";","popGet AOP_PCODE%d",__LINE__); + pcop = pCodeOpCopy(aop->aopu.pcop); + PCOI(pcop)->offset = offset; + return pcop; } werror(E_INTERNAL_ERROR,__FILE__,__LINE__, @@ -1171,12 +1368,12 @@ static pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname) /*-----------------------------------------------------------------*/ /* aopPut - puts a string for a aop */ /*-----------------------------------------------------------------*/ -static void aopPut (asmop *aop, char *s, int offset) +void aopPut (asmop *aop, char *s, int offset) { char *d = buffer ; symbol *lbl ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (aop->size && offset > ( aop->size - 1)) { werror(E_INTERNAL_ERROR,__FILE__,__LINE__, @@ -1188,29 +1385,38 @@ static void aopPut (asmop *aop, char *s, int offset) /* depending on where it is ofcourse */ switch (aop->type) { case AOP_DIR: - if (offset) - sprintf(d,"(%s + %d)", - aop->aopu.aop_dir,offset); - else + if (offset) { + sprintf(d,"(%s + %d)", + aop->aopu.aop_dir,offset); + fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s); + + } else sprintf(d,"%s",aop->aopu.aop_dir); if (strcmp(d,s)) { - DEBUGemitcode(";","%d",__LINE__); + DEBUGpic14_emitcode(";","%d",__LINE__); if(strcmp(s,"W")) - emitcode("movf","%s,w",s); - emitcode("movwf","%s",d); + pic14_emitcode("movf","%s,w",s); + pic14_emitcode("movwf","%s",d); - if(strcmp(s,"W")) - emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__); - emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE)); + if(strcmp(s,"W")) { + pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__); + if(offset >= aop->size) { + emitpcode(POC_CLRF,popGet(aop,offset)); + break; + } else + emitpcode(POC_MOVLW,popGetImmd(s,offset,0)); + } + + emitpcode(POC_MOVWF,popGet(aop,offset)); } break; case AOP_REG: - if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 && - strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){ + if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // && + //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){ /* if (*s == '@' || strcmp(s,"r0") == 0 || @@ -1221,20 +1427,29 @@ static void aopPut (asmop *aop, char *s, int offset) strcmp(s,"r5") == 0 || strcmp(s,"r6") == 0 || strcmp(s,"r7") == 0 ) - emitcode("mov","%s,%s ; %d", + pic14_emitcode("mov","%s,%s ; %d", aop->aopu.aop_reg[offset]->dname,s,__LINE__); else */ if(strcmp(s,"W")) - emitcode("movf","%s,w ; %d",s,__LINE__); + pic14_emitcode("movf","%s,w ; %d",s,__LINE__); - emitcode("movwf","%s", + pic14_emitcode("movwf","%s", aop->aopu.aop_reg[offset]->name); - if(strcmp(s,"W")) - emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__); - emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE)); + if(strcmp(s,"W")) { + pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); + pcop->type = PO_GPR_REGISTER; + + PCOR(pcop)->rIdx = -1; + PCOR(pcop)->r = NULL; + + DEBUGpic14_emitcode(";","%d",__LINE__); + pcop->name = Safe_strdup(s); + emitpcode(POC_MOVFW,pcop); + } + emitpcode(POC_MOVWF,popGet(aop,offset)); } break; @@ -1255,12 +1470,12 @@ static void aopPut (asmop *aop, char *s, int offset) while (offset > aop->coff) { aop->coff++; - emitcode ("inc","dptr"); + pic14_emitcode ("inc","dptr"); } while (offset < aop->coff) { aop->coff-- ; - emitcode("lcall","__decdptr"); + pic14_emitcode("lcall","__decdptr"); } aop->coff = offset; @@ -1268,7 +1483,7 @@ static void aopPut (asmop *aop, char *s, int offset) /* if not in accumulater */ MOVA(s); - emitcode ("movx","@dptr,a"); + pic14_emitcode ("movx","@dptr,a"); if (aop->type == AOP_DPTR2) { @@ -1280,22 +1495,22 @@ static void aopPut (asmop *aop, char *s, int offset) case AOP_R1: while (offset > aop->coff) { aop->coff++; - emitcode("inc","%s",aop->aopu.aop_ptr->name); + pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name); } while (offset < aop->coff) { aop->coff-- ; - emitcode ("dec","%s",aop->aopu.aop_ptr->name); + pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name); } aop->coff = offset; if (aop->paged) { MOVA(s); - emitcode("movx","@%s,a",aop->aopu.aop_ptr->name); + pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name); } else if (*s == '@') { MOVA(s); - emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__); + pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__); } else if (strcmp(s,"r0") == 0 || strcmp(s,"r1") == 0 || @@ -1307,46 +1522,46 @@ static void aopPut (asmop *aop, char *s, int offset) strcmp(s,"r7") == 0 ) { char buffer[10]; sprintf(buffer,"a%s",s); - emitcode("mov","@%s,%s", + pic14_emitcode("mov","@%s,%s", aop->aopu.aop_ptr->name,buffer); } else - emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s); + pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s); break; case AOP_STK: if (strcmp(s,"a") == 0) - emitcode("push","acc"); + pic14_emitcode("push","acc"); else - emitcode("push","%s",s); + pic14_emitcode("push","%s",s); break; case AOP_CRY: /* if bit variable */ if (!aop->aopu.aop_dir) { - emitcode("clr","a"); - emitcode("rlc","a"); + pic14_emitcode("clr","a"); + pic14_emitcode("rlc","a"); } else { if (s == zero) - emitcode("clr","%s",aop->aopu.aop_dir); + pic14_emitcode("clr","%s",aop->aopu.aop_dir); else if (s == one) - emitcode("setb","%s",aop->aopu.aop_dir); + pic14_emitcode("setb","%s",aop->aopu.aop_dir); else if (!strcmp(s,"c")) - emitcode("mov","%s,c",aop->aopu.aop_dir); + pic14_emitcode("mov","%s,c",aop->aopu.aop_dir); else { lbl = newiTempLabel(NULL); if (strcmp(s,"a")) { MOVA(s); } - emitcode("clr","c"); - emitcode("jz","%05d_DS_",lbl->key+100); - emitcode("cpl","c"); - emitcode("","%05d_DS_:",lbl->key+100); - emitcode("mov","%s,c",aop->aopu.aop_dir); + pic14_emitcode("clr","c"); + pic14_emitcode("jz","%05d_DS_",lbl->key+100); + pic14_emitcode("cpl","c"); + pic14_emitcode("","%05d_DS_:",lbl->key+100); + pic14_emitcode("mov","%s,c",aop->aopu.aop_dir); } } break; @@ -1354,7 +1569,7 @@ static void aopPut (asmop *aop, char *s, int offset) case AOP_STR: aop->coff = offset; if (strcmp(aop->aopu.aop_str[offset],s)) - emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__); + pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__); break; case AOP_ACC: @@ -1363,7 +1578,7 @@ static void aopPut (asmop *aop, char *s, int offset) break; if (strcmp(aop->aopu.aop_str[offset],s)) - emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__); + pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__); break; default : @@ -1381,7 +1596,7 @@ static void reAdjustPreg (asmop *aop) { int size ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aop->coff = 0; if ((size = aop->size) <= 1) return ; @@ -1390,7 +1605,7 @@ static void reAdjustPreg (asmop *aop) case AOP_R0 : case AOP_R1 : while (size--) - emitcode("dec","%s",aop->aopu.aop_ptr->name); + pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name); break; case AOP_DPTR : case AOP_DPTR2: @@ -1400,7 +1615,7 @@ static void reAdjustPreg (asmop *aop) } while (size--) { - emitcode("lcall","__decdptr"); + pic14_emitcode("lcall","__decdptr"); } if (aop->type == AOP_DPTR2) @@ -1413,20 +1628,6 @@ static void reAdjustPreg (asmop *aop) } -#define AOP(op) op->aop -#define AOP_TYPE(op) AOP(op)->type -#define AOP_SIZE(op) AOP(op)->size -#define IS_AOP_PREG(x) (AOP(x) && (AOP_TYPE(x) == AOP_R1 || \ - AOP_TYPE(x) == AOP_R0)) - -#define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY || \ - AOP_TYPE(x) == AOP_DPTR || AOP_TYPE(x) == AOP_DPTR2 || \ - AOP(x)->paged)) - -#define AOP_INPREG(x) (x && (x->type == AOP_REG && \ - (x->aopu.aop_reg[0] == pic14_regWithIdx(R0_IDX) || \ - x->aopu.aop_reg[0] == pic14_regWithIdx(R1_IDX) ))) - /*-----------------------------------------------------------------*/ /* genNotFloat - generates not for float operations */ /*-----------------------------------------------------------------*/ @@ -1436,7 +1637,7 @@ static void genNotFloat (operand *op, operand *res) char *l; symbol *tlbl ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* we will put 127 in the first byte of the result */ aopPut(AOP(res),"#127",0); @@ -1447,7 +1648,7 @@ static void genNotFloat (operand *op, operand *res) MOVA(l); while(size--) { - emitcode("orl","a,%s", + pic14_emitcode("orl","a,%s", aopGet(op->aop, offset++,FALSE,FALSE)); } @@ -1455,9 +1656,9 @@ static void genNotFloat (operand *op, operand *res) tlbl = newiTempLabel(NULL); aopPut(res->aop,one,1); - emitcode("jz","%05d_DS_",(tlbl->key+100)); + pic14_emitcode("jz","%05d_DS_",(tlbl->key+100)); aopPut(res->aop,zero,1); - emitcode("","%05d_DS_:",(tlbl->key+100)); + pic14_emitcode("","%05d_DS_:",(tlbl->key+100)); size = res->aop->size - 2; offset = 2; @@ -1475,7 +1676,7 @@ static int opIsGptr(operand *op) { sym_link *type = operandType(op); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type)) { return 1; @@ -1485,11 +1686,11 @@ static int opIsGptr(operand *op) #endif /*-----------------------------------------------------------------*/ -/* getDataSize - get the operand data size */ +/* pic14_getDataSize - get the operand data size */ /*-----------------------------------------------------------------*/ -static int getDataSize(operand *op) +int pic14_getDataSize(operand *op) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); return AOP_SIZE(op); @@ -1508,7 +1709,7 @@ static int getDataSize(operand *op) * should ignore the high byte (pointer type). */ size--; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); } } return size; @@ -1516,58 +1717,59 @@ static int getDataSize(operand *op) } /*-----------------------------------------------------------------*/ -/* outAcc - output Acc */ +/* pic14_outAcc - output Acc */ /*-----------------------------------------------------------------*/ -static void outAcc(operand *result) +void pic14_outAcc(operand *result) { - int size, offset; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - size = getDataSize(result); - if(size){ - aopPut(AOP(result),"a",0); - size--; - offset = 1; - /* unsigned or positive */ - while(size--){ - aopPut(AOP(result),zero,offset++); - } - } + int size,offset; + DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__); + DEBUGpic14_AopType(__LINE__,NULL,NULL,result); + + + size = pic14_getDataSize(result); + if(size){ + emitpcode(POC_MOVWF,popGet(AOP(result),0)); + size--; + offset = 1; + /* unsigned or positive */ + while(size--) + emitpcode(POC_CLRF,popGet(AOP(result),offset++)); + } + } /*-----------------------------------------------------------------*/ -/* outBitC - output a bit C */ +/* pic14_outBitC - output a bit C */ /*-----------------------------------------------------------------*/ -static void outBitC(operand *result) +void pic14_outBitC(operand *result) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if the result is bit */ if (AOP_TYPE(result) == AOP_CRY) aopPut(AOP(result),"c",0); else { - emitcode("clr","a ; %d", __LINE__); - emitcode("rlc","a"); - outAcc(result); + pic14_emitcode("clr","a ; %d", __LINE__); + pic14_emitcode("rlc","a"); + pic14_outAcc(result); } } /*-----------------------------------------------------------------*/ -/* toBoolean - emit code for orl a,operator(sizeop) */ +/* pic14_toBoolean - emit code for orl a,operator(sizeop) */ /*-----------------------------------------------------------------*/ -static void toBoolean(operand *oper) +void pic14_toBoolean(operand *oper) { int size = AOP_SIZE(oper) - 1; int offset = 1; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if ( AOP_TYPE(oper) != AOP_ACC) { - emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE)); - emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE)); + emitpcode(POC_MOVFW,popGet(AOP(oper),0)); } while (size--) { - emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE)); - emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE)); + emitpcode(POC_IORFW, popGet(AOP(oper),offset++)); } } @@ -1577,40 +1779,53 @@ static void toBoolean(operand *oper) /*-----------------------------------------------------------------*/ static void genNot (iCode *ic) { - symbol *tlbl; - sym_link *optype = operandType(IC_LEFT(ic)); - - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* assign asmOps to operand & result */ - aopOp (IC_LEFT(ic),ic,FALSE); - aopOp (IC_RESULT(ic),ic,TRUE); - - /* if in bit space then a special case */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) { - emitcode("movlw","1<<%s"); - //emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); - //emitcode("cpl","c"); - //outBitC(IC_RESULT(ic)); - goto release; + symbol *tlbl; + sym_link *optype = operandType(IC_LEFT(ic)); + int size; + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* assign asmOps to operand & result */ + aopOp (IC_LEFT(ic),ic,FALSE); + aopOp (IC_RESULT(ic),ic,TRUE); + + DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic)); + /* if in bit space then a special case */ + if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) { + if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) { + emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0)); + emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0)); + } else { + emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0)); + emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0)); + emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0)); } + goto release; + } - /* if type float then do float */ - if (IS_FLOAT(optype)) { - genNotFloat(IC_LEFT(ic),IC_RESULT(ic)); - goto release; - } + /* if type float then do float */ + if (IS_FLOAT(optype)) { + genNotFloat(IC_LEFT(ic),IC_RESULT(ic)); + goto release; + } - toBoolean(IC_LEFT(ic)); + size = AOP_SIZE(IC_RESULT(ic)); + if(size == 1) { + emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0)); + emitpcode(POC_ANDLW,popGetLit(1)); + emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); + goto release; + } + pic14_toBoolean(IC_LEFT(ic)); - tlbl = newiTempLabel(NULL); - emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100); - emitcode("","%05d_DS_:",tlbl->key+100); - outBitC(IC_RESULT(ic)); + tlbl = newiTempLabel(NULL); + pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_outBitC(IC_RESULT(ic)); -release: - /* release the aops */ - freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1)); - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); + release: + /* release the aops */ + freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1)); + freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } @@ -1623,7 +1838,7 @@ static void genCpl (iCode *ic) int size ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* assign asmOps to operand & result */ aopOp (IC_LEFT(ic),ic,FALSE); aopOp (IC_RESULT(ic),ic,TRUE); @@ -1633,9 +1848,9 @@ static void genCpl (iCode *ic) if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { - emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); - emitcode("cpl","c"); - emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); + pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); + pic14_emitcode("cpl","c"); + pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); goto release; } @@ -1643,7 +1858,7 @@ static void genCpl (iCode *ic) while (size--) { char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE); MOVA(l); - emitcode("cpl","a"); + pic14_emitcode("cpl","a"); aopPut(AOP(IC_RESULT(ic)),"a",offset++); } @@ -1662,7 +1877,7 @@ static void genUminusFloat(operand *op,operand *result) int size ,offset =0 ; char *l; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* for this we just need to flip the first it then copy the rest in place */ size = AOP_SIZE(op) - 1; @@ -1670,7 +1885,7 @@ static void genUminusFloat(operand *op,operand *result) MOVA(l); - emitcode("cpl","acc.7"); + pic14_emitcode("cpl","acc.7"); aopPut(AOP(result),"a",3); while(size--) { @@ -1686,64 +1901,58 @@ static void genUminusFloat(operand *op,operand *result) /*-----------------------------------------------------------------*/ static void genUminus (iCode *ic) { - int offset ,size ; - sym_link *optype, *rtype; + int size, i; + sym_link *optype, *rtype; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* assign asmops */ - aopOp(IC_LEFT(ic),ic,FALSE); - aopOp(IC_RESULT(ic),ic,TRUE); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* assign asmops */ + aopOp(IC_LEFT(ic),ic,FALSE); + aopOp(IC_RESULT(ic),ic,TRUE); - /* if both in bit space then special - case */ - if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY && - AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { + /* if both in bit space then special + case */ + if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY && + AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { - emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); - emitcode("cpl","c"); - emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); - goto release; - } + emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0)); + emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0)); + emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0)); - optype = operandType(IC_LEFT(ic)); - rtype = operandType(IC_RESULT(ic)); + goto release; + } - /* if float then do float stuff */ - if (IS_FLOAT(optype)) { - genUminusFloat(IC_LEFT(ic),IC_RESULT(ic)); - goto release; - } + optype = operandType(IC_LEFT(ic)); + rtype = operandType(IC_RESULT(ic)); - /* otherwise subtract from zero */ - size = AOP_SIZE(IC_LEFT(ic)); - offset = 0 ; - CLRC ; - while(size--) { - char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE); - if (!strcmp(l,"a")) { - emitcode("cpl","a"); - emitcode("inc","a"); - } else { - emitcode("clr","a"); - emitcode("subb","a,%s",l); - } - aopPut(AOP(IC_RESULT(ic)),"a",offset++); - } + /* if float then do float stuff */ + if (IS_FLOAT(optype)) { + genUminusFloat(IC_LEFT(ic),IC_RESULT(ic)); + goto release; + } - /* if any remaining bytes in the result */ - /* we just need to propagate the sign */ - if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) { - emitcode("rlc","a"); - emitcode("subb","a,acc"); - while (size--) - aopPut(AOP(IC_RESULT(ic)),"a",offset++); - } + /* otherwise subtract from zero by taking the 2's complement */ + size = AOP_SIZE(IC_LEFT(ic)); -release: - /* release the aops */ - freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1)); - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); + for(i=0; inext) if (ic->op == CALL || ic->op == PCALL) @@ -1769,7 +1978,7 @@ static void saveRegisters(iCode *lic) /* if the registers have been saved already then do nothing */ - if (ic->regsSaved || (OP_SYMBOL(IC_LEFT(ic))->calleeSave)) + if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type)) return ; /* find the registers in use at this time @@ -1780,34 +1989,34 @@ static void saveRegisters(iCode *lic) ic->regsSaved = 1; if (options.useXstack) { if (bitVectBitValue(rsave,R0_IDX)) - emitcode("mov","b,r0"); - emitcode("mov","r0,%s",spname); + pic14_emitcode("mov","b,r0"); + pic14_emitcode("mov","r0,%s",spname); for (i = 0 ; i < pic14_nRegs ; i++) { if (bitVectBitValue(rsave,i)) { if (i == R0_IDX) - emitcode("mov","a,b"); + pic14_emitcode("mov","a,b"); else - emitcode("mov","a,%s",pic14_regWithIdx(i)->name); - emitcode("movx","@r0,a"); - emitcode("inc","r0"); + pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name); + pic14_emitcode("movx","@r0,a"); + pic14_emitcode("inc","r0"); } } - emitcode("mov","%s,r0",spname); + pic14_emitcode("mov","%s,r0",spname); if (bitVectBitValue(rsave,R0_IDX)) - emitcode("mov","r0,b"); - } else - for (i = 0 ; i < pic14_nRegs ; i++) { - if (bitVectBitValue(rsave,i)) - emitcode("push","%s",pic14_regWithIdx(i)->dname); - } - - detype = getSpec(operandType(IC_LEFT(ic))); - if (detype && - (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) && - IS_ISR(currFunc->etype) && + pic14_emitcode("mov","r0,b"); + }// else + //for (i = 0 ; i < pic14_nRegs ; i++) { + // if (bitVectBitValue(rsave,i)) + // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname); + //} + + dtype = operandType(IC_LEFT(ic)); + if (currFunc && dtype && + (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) && + IFFUNC_ISISR(currFunc->type) && !ic->bankSaved) - saverbank(SPEC_BANK(detype),ic,TRUE); + saverbank(FUNC_REGBANK(dtype),ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -1818,33 +2027,33 @@ static void unsaveRegisters (iCode *ic) int i; bitVect *rsave; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* find the registers in use at this time and push them away to safety */ rsave = bitVectCplAnd(bitVectCopy(ic->rMask), ic->rUsed); if (options.useXstack) { - emitcode("mov","r0,%s",spname); + pic14_emitcode("mov","r0,%s",spname); for (i = pic14_nRegs ; i >= 0 ; i--) { if (bitVectBitValue(rsave,i)) { - emitcode("dec","r0"); - emitcode("movx","a,@r0"); + pic14_emitcode("dec","r0"); + pic14_emitcode("movx","a,@r0"); if (i == R0_IDX) - emitcode("mov","b,a"); + pic14_emitcode("mov","b,a"); else - emitcode("mov","%s,a",pic14_regWithIdx(i)->name); + pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name); } } - emitcode("mov","%s,r0",spname); + pic14_emitcode("mov","%s,r0",spname); if (bitVectBitValue(rsave,R0_IDX)) - emitcode("mov","r0,b"); - } else - for (i = pic14_nRegs ; i >= 0 ; i--) { - if (bitVectBitValue(rsave,i)) - emitcode("pop","%s",pic14_regWithIdx(i)->dname); - } + pic14_emitcode("mov","r0,b"); + } //else + //for (i = pic14_nRegs ; i >= 0 ; i--) { + // if (bitVectBitValue(rsave,i)) + // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname); + //} } @@ -1854,18 +2063,20 @@ static void unsaveRegisters (iCode *ic) /*-----------------------------------------------------------------*/ static void pushSide(operand * oper, int size) { +#if 0 int offset = 0; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); while (size--) { char *l = aopGet(AOP(oper),offset++,FALSE,TRUE); if (AOP_TYPE(oper) != AOP_REG && AOP_TYPE(oper) != AOP_DIR && strcmp(l,"a") ) { - emitcode("mov","a,%s",l); - emitcode("push","acc"); + pic14_emitcode("mov","a,%s",l); + pic14_emitcode("push","acc"); } else - emitcode("push","%s",l); + pic14_emitcode("push","%s",l); } +#endif } /*-----------------------------------------------------------------*/ @@ -1873,68 +2084,39 @@ static void pushSide(operand * oper, int size) /*-----------------------------------------------------------------*/ static void assignResultValue(operand * oper) { - int offset = 0; - int size = AOP_SIZE(oper); + int size = AOP_SIZE(oper); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - // The last byte in the assignment is in W - aopPut(AOP(oper),"W",size-1); + DEBUGpic14_AopType(__LINE__,oper,NULL,NULL); - if(size>1) { - while (--size) { - aopPut(AOP(oper),fReturn[offset],offset); - offset++; + if(!GpsuedoStkPtr) { + /* The last byte in the assignment is in W */ + size--; + emitpcode(POC_MOVWF, popGet(AOP(oper),size)); + GpsuedoStkPtr++; + } - } - } + while (size--) { + emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr)); + GpsuedoStkPtr++; + emitpcode(POC_MOVWF, popGet(AOP(oper),size)); + } } -/*-----------------------------------------------------------------*/ -/* genXpush - pushes onto the external stack */ -/*-----------------------------------------------------------------*/ -static void genXpush (iCode *ic) -{ - asmop *aop = newAsmop(0); - regs *r ; - int size,offset = 0; - - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - aopOp(IC_LEFT(ic),ic,FALSE); - r = getFreePtr(ic,&aop,FALSE); - - - emitcode("mov","%s,_spx",r->name); - - size = AOP_SIZE(IC_LEFT(ic)); - while(size--) { - - char *l = aopGet(AOP(IC_LEFT(ic)), - offset++,FALSE,FALSE); - MOVA(l); - emitcode("movx","@%s,a",r->name); - emitcode("inc","%s",r->name); - - } - - - emitcode("mov","_spx,%s",r->name); - - freeAsmop(NULL,aop,ic,TRUE); - freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); -} - /*-----------------------------------------------------------------*/ /* genIpush - genrate code for pushing this gets a little complex */ /*-----------------------------------------------------------------*/ static void genIpush (iCode *ic) { + + DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); +#if 0 int size, offset = 0 ; char *l; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if this is not a parm push : ie. it is spill push and spill push is always done on the local stack */ if (!ic->parmPush) { @@ -1952,7 +2134,7 @@ static void genIpush (iCode *ic) MOVA(l); l = "acc"; } - emitcode("push","%s",l); + pic14_emitcode("push","%s",l); } return ; } @@ -1962,13 +2144,6 @@ static void genIpush (iCode *ic) registers that need to be saved */ saveRegisters(ic); - /* if use external stack then call the external - stack pushing routine */ - if (options.useXstack) { - genXpush(ic); - return ; - } - /* then do the push */ aopOp(IC_LEFT(ic),ic,FALSE); @@ -1981,13 +2156,14 @@ static void genIpush (iCode *ic) if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && AOP_TYPE(IC_LEFT(ic)) != AOP_DIR && strcmp(l,"a") ) { - emitcode("mov","a,%s",l); - emitcode("push","acc"); + pic14_emitcode("mov","a,%s",l); + pic14_emitcode("push","acc"); } else - emitcode("push","%s",l); + pic14_emitcode("push","%s",l); } freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); +#endif } /*-----------------------------------------------------------------*/ @@ -1995,10 +2171,11 @@ static void genIpush (iCode *ic) /*-----------------------------------------------------------------*/ static void genIpop (iCode *ic) { + DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); +#if 0 int size,offset ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if the temp was not pushed then */ if (OP_SYMBOL(IC_LEFT(ic))->isspilt) return ; @@ -2007,10 +2184,11 @@ static void genIpop (iCode *ic) size = AOP_SIZE(IC_LEFT(ic)); offset = (size-1); while (size--) - emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--, + pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--, FALSE,TRUE)); freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); +#endif } /*-----------------------------------------------------------------*/ @@ -2018,44 +2196,47 @@ static void genIpop (iCode *ic) /*-----------------------------------------------------------------*/ static void unsaverbank (int bank,iCode *ic,bool popPsw) { + DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); +#if 0 int i; asmop *aop ; regs *r = NULL; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (popPsw) { if (options.useXstack) { aop = newAsmop(0); r = getFreePtr(ic,&aop,FALSE); - emitcode("mov","%s,_spx",r->name); - emitcode("movx","a,@%s",r->name); - emitcode("mov","psw,a"); - emitcode("dec","%s",r->name); + pic14_emitcode("mov","%s,_spx",r->name); + pic14_emitcode("movx","a,@%s",r->name); + pic14_emitcode("mov","psw,a"); + pic14_emitcode("dec","%s",r->name); }else - emitcode ("pop","psw"); + pic14_emitcode ("pop","psw"); } for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) { if (options.useXstack) { - emitcode("movx","a,@%s",r->name); - //emitcode("mov","(%s+%d),a", + pic14_emitcode("movx","a,@%s",r->name); + //pic14_emitcode("mov","(%s+%d),a", // regspic14[i].base,8*bank+regspic14[i].offset); - emitcode("dec","%s",r->name); + pic14_emitcode("dec","%s",r->name); } else - emitcode("pop",""); //"(%s+%d)", + pic14_emitcode("pop",""); //"(%s+%d)", //regspic14[i].base,8*bank); //+regspic14[i].offset); } if (options.useXstack) { - emitcode("mov","_spx,%s",r->name); + pic14_emitcode("mov","_spx,%s",r->name); freeAsmop(NULL,aop,ic,TRUE); - } + } +#endif } /*-----------------------------------------------------------------*/ @@ -2063,45 +2244,47 @@ static void unsaverbank (int bank,iCode *ic,bool popPsw) /*-----------------------------------------------------------------*/ static void saverbank (int bank, iCode *ic, bool pushPsw) { + DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); +#if 0 int i; asmop *aop ; regs *r = NULL; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (options.useXstack) { aop = newAsmop(0); r = getFreePtr(ic,&aop,FALSE); - emitcode("mov","%s,_spx",r->name); + pic14_emitcode("mov","%s,_spx",r->name); } for (i = 0 ; i < pic14_nRegs ;i++) { if (options.useXstack) { - emitcode("inc","%s",r->name); - //emitcode("mov","a,(%s+%d)", + pic14_emitcode("inc","%s",r->name); + //pic14_emitcode("mov","a,(%s+%d)", // regspic14[i].base,8*bank+regspic14[i].offset); - emitcode("movx","@%s,a",r->name); + pic14_emitcode("movx","@%s,a",r->name); } else - emitcode("push","");// "(%s+%d)", + pic14_emitcode("push","");// "(%s+%d)", //regspic14[i].base,8*bank+regspic14[i].offset); } if (pushPsw) { if (options.useXstack) { - emitcode("mov","a,psw"); - emitcode("movx","@%s,a",r->name); - emitcode("inc","%s",r->name); - emitcode("mov","_spx,%s",r->name); + pic14_emitcode("mov","a,psw"); + pic14_emitcode("movx","@%s,a",r->name); + pic14_emitcode("inc","%s",r->name); + pic14_emitcode("mov","_spx,%s",r->name); freeAsmop (NULL,aop,ic,TRUE); } else - emitcode("push","psw"); + pic14_emitcode("push","psw"); - emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff); + pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff); } ic->bankSaved = 1; - +#endif } /*-----------------------------------------------------------------*/ @@ -2109,105 +2292,129 @@ static void saverbank (int bank, iCode *ic, bool pushPsw) /*-----------------------------------------------------------------*/ static void genCall (iCode *ic) { - sym_link *detype; + sym_link *dtype; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if caller saves & we have not saved then */ - if (!ic->regsSaved) - saveRegisters(ic); + /* if caller saves & we have not saved then */ + if (!ic->regsSaved) + saveRegisters(ic); - /* if we are calling a function that is not using - the same register bank then we need to save the - destination registers on the stack */ - detype = getSpec(operandType(IC_LEFT(ic))); - if (detype && - (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) && - IS_ISR(currFunc->etype) && - !ic->bankSaved) + /* if we are calling a function that is not using + the same register bank then we need to save the + destination registers on the stack */ + dtype = operandType(IC_LEFT(ic)); + if (currFunc && dtype && + (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) && + IFFUNC_ISISR(currFunc->type) && + !ic->bankSaved) - saverbank(SPEC_BANK(detype),ic,TRUE); + saverbank(FUNC_REGBANK(dtype),ic,TRUE); - /* if send set is not empty the assign */ - if (_G.sendSet) { - iCode *sic ; + /* if send set is not empty the assign */ + if (_G.sendSet) { + iCode *sic; + /* For the Pic port, there is no data stack. + * So parameters passed to functions are stored + * in registers. (The pCode optimizer will get + * rid of most of these :). + */ + int psuedoStkPtr=-1; + int firstTimeThruLoop = 1; - for (sic = setFirstItem(_G.sendSet) ; sic ; - sic = setNextItem(_G.sendSet)) { - int size, offset = 0; + _G.sendSet = reverseSet(_G.sendSet); - aopOp(IC_LEFT(sic),sic,FALSE); - size = AOP_SIZE(IC_LEFT(sic)); - while (size--) { - char *l = aopGet(AOP(IC_LEFT(sic)),offset, - FALSE,FALSE); - DEBUGemitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type); + /* First figure how many parameters are getting passed */ + for (sic = setFirstItem(_G.sendSet) ; sic ; + sic = setNextItem(_G.sendSet)) { - if (strcmp(l,fReturn[offset])) { + aopOp(IC_LEFT(sic),sic,FALSE); + psuedoStkPtr += AOP_SIZE(IC_LEFT(sic)); + freeAsmop (IC_LEFT(sic),NULL,sic,FALSE); + } - if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) || - ((AOP(IC_LEFT(sic))->type) == AOP_LIT) ) - emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE)); - //emitcode("movlw","%s",l); - else - emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE)); - //emitcode("movf","%s,w",l); + for (sic = setFirstItem(_G.sendSet) ; sic ; + sic = setNextItem(_G.sendSet)) { + int size, offset = 0; + + aopOp(IC_LEFT(sic),sic,FALSE); + size = AOP_SIZE(IC_LEFT(sic)); + + + while (size--) { + DEBUGpic14_emitcode ("; ","%d left %s",__LINE__, + AopType(AOP_TYPE(IC_LEFT(sic)))); + + if(!firstTimeThruLoop) { + /* If this is not the first time we've been through the loop + * then we need to save the parameter in a temporary + * register. The last byte of the last parameter is + * passed in W. */ + emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr)); - // The last one is passed in W - if(size) - emitcode("movwf","%s",fReturn[offset]); - } - offset++; - } - freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); } - _G.sendSet = NULL; - } - /* make the call */ - emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ? - OP_SYMBOL(IC_LEFT(ic))->rname : - OP_SYMBOL(IC_LEFT(ic))->name)); + firstTimeThruLoop=0; - emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ? - OP_SYMBOL(IC_LEFT(ic))->rname : - OP_SYMBOL(IC_LEFT(ic))->name)); + //if (strcmp(l,fReturn[offset])) { - /* if we need assign a result value */ - if ((IS_ITEMP(IC_RESULT(ic)) && - (OP_SYMBOL(IC_RESULT(ic))->nRegs || - OP_SYMBOL(IC_RESULT(ic))->spildir )) || - IS_TRUE_SYMOP(IC_RESULT(ic)) ) { + if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) || + ((AOP(IC_LEFT(sic))->type) == AOP_LIT) ) + emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset)); + else + emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset)); - _G.accInUse++; - aopOp(IC_RESULT(ic),ic,FALSE); - _G.accInUse--; + //} + offset++; + } + freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); + } + _G.sendSet = NULL; + } + /* make the call */ + emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ? + OP_SYMBOL(IC_LEFT(ic))->rname : + OP_SYMBOL(IC_LEFT(ic))->name)); + + GpsuedoStkPtr=0; + /* if we need assign a result value */ + if ((IS_ITEMP(IC_RESULT(ic)) && + (OP_SYMBOL(IC_RESULT(ic))->nRegs || + OP_SYMBOL(IC_RESULT(ic))->spildir )) || + IS_TRUE_SYMOP(IC_RESULT(ic)) ) { + + _G.accInUse++; + aopOp(IC_RESULT(ic),ic,FALSE); + _G.accInUse--; - assignResultValue(IC_RESULT(ic)); + assignResultValue(IC_RESULT(ic)); + + DEBUGpic14_emitcode ("; ","%d left %s",__LINE__, + AopType(AOP_TYPE(IC_RESULT(ic)))); - freeAsmop(IC_RESULT(ic),NULL, ic,TRUE); - } + freeAsmop(IC_RESULT(ic),NULL, ic,TRUE); + } - /* adjust the stack for parameters if - required */ - if (ic->parmBytes) { - int i; - if (ic->parmBytes > 3) { - emitcode("mov","a,%s",spname); - emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff); - emitcode("mov","%s,a",spname); - } else - for ( i = 0 ; i < ic->parmBytes ;i++) - emitcode("dec","%s",spname); + /* adjust the stack for parameters if + required */ + if (ic->parmBytes) { + int i; + if (ic->parmBytes > 3) { + pic14_emitcode("mov","a,%s",spname); + pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff); + pic14_emitcode("mov","%s,a",spname); + } else + for ( i = 0 ; i < ic->parmBytes ;i++) + pic14_emitcode("dec","%s",spname); - } + } - /* if register bank was saved then pop them */ - if (ic->bankSaved) - unsaverbank(SPEC_BANK(detype),ic,TRUE); + /* if register bank was saved then pop them */ + if (ic->bankSaved) + unsaverbank(FUNC_REGBANK(dtype),ic,TRUE); - /* if we hade saved some registers then unsave them */ - if (ic->regsSaved && !(OP_SYMBOL(IC_LEFT(ic))->calleeSave)) - unsaveRegisters (ic); + /* if we hade saved some registers then unsave them */ + if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype)) + unsaveRegisters (ic); } @@ -2217,11 +2424,11 @@ static void genCall (iCode *ic) /*-----------------------------------------------------------------*/ static void genPcall (iCode *ic) { - sym_link *detype; + sym_link *dtype; symbol *rlbl = newiTempLabel(NULL); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if caller saves & we have not saved then */ if (!ic->regsSaved) saveRegisters(ic); @@ -2229,23 +2436,23 @@ static void genPcall (iCode *ic) /* if we are calling a function that is not using the same register bank then we need to save the destination registers on the stack */ - detype = getSpec(operandType(IC_LEFT(ic))); - if (detype && - IS_ISR(currFunc->etype) && - (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype))) - saverbank(SPEC_BANK(detype),ic,TRUE); + dtype = operandType(IC_LEFT(ic)); + if (currFunc && dtype && + IFFUNC_ISISR(currFunc->type) && + (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype))) + saverbank(FUNC_REGBANK(dtype),ic,TRUE); /* push the return address on to the stack */ - emitcode("mov","a,#%05d_DS_",(rlbl->key+100)); - emitcode("push","acc"); - emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100)); - emitcode("push","acc"); + pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100)); + pic14_emitcode("push","acc"); + pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100)); + pic14_emitcode("push","acc"); if (options.model == MODEL_FLAT24) { - emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100)); - emitcode("push","acc"); + pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100)); + pic14_emitcode("push","acc"); } /* now push the calling address */ @@ -2268,7 +2475,7 @@ static void genPcall (iCode *ic) char *l = aopGet(AOP(IC_LEFT(sic)),offset, FALSE,FALSE); if (strcmp(l,fReturn[offset])) - emitcode("mov","%s,%s", + pic14_emitcode("mov","%s,%s", fReturn[offset], l); offset++; @@ -2278,8 +2485,8 @@ static void genPcall (iCode *ic) _G.sendSet = NULL; } - emitcode("ret",""); - emitcode("","%05d_DS_:",(rlbl->key+100)); + pic14_emitcode("ret",""); + pic14_emitcode("","%05d_DS_:",(rlbl->key+100)); /* if we need assign a result value */ @@ -2302,20 +2509,19 @@ static void genPcall (iCode *ic) if (ic->parmBytes) { int i; if (ic->parmBytes > 3) { - emitcode("mov","a,%s",spname); - emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff); - emitcode("mov","%s,a",spname); + pic14_emitcode("mov","a,%s",spname); + pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff); + pic14_emitcode("mov","%s,a",spname); } else for ( i = 0 ; i < ic->parmBytes ;i++) - emitcode("dec","%s",spname); + pic14_emitcode("dec","%s",spname); } /* if register bank was saved then unsave them */ - if (detype && - (SPEC_BANK(currFunc->etype) != - SPEC_BANK(detype))) - unsaverbank(SPEC_BANK(detype),ic,TRUE); + if (currFunc && dtype && + (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype))) + unsaverbank(FUNC_REGBANK(dtype),ic,TRUE); /* if we hade saved some registers then unsave them */ @@ -2329,7 +2535,7 @@ static void genPcall (iCode *ic) /*-----------------------------------------------------------------*/ static int resultRemat (iCode *ic) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (SKIP_IC(ic) || ic->op == IFX) return 0; @@ -2348,14 +2554,16 @@ static int resultRemat (iCode *ic) #define STRCASECMP strcasecmp #endif +#if 0 /*-----------------------------------------------------------------*/ /* inExcludeList - return 1 if the string is in exclude Reg list */ /*-----------------------------------------------------------------*/ static bool inExcludeList(char *s) { + DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); int i =0; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (options.excludeRegs[i] && STRCASECMP(options.excludeRegs[i],"none") == 0) return FALSE ; @@ -2367,6 +2575,7 @@ static bool inExcludeList(char *s) } return FALSE ; } +#endif /*-----------------------------------------------------------------*/ /* genFunction - generated code for function entry */ @@ -2374,40 +2583,42 @@ static bool inExcludeList(char *s) static void genFunction (iCode *ic) { symbol *sym; - sym_link *fetype; + sym_link *ftype; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - labelOffset += FUNCTION_LABEL_INC; + DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key); + labelOffset += (max_key+4); + max_key=0; + GpsuedoStkPtr=0; _G.nRegsSaved = 0; /* create the function header */ - emitcode(";","-----------------------------------------"); - emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name); - emitcode(";","-----------------------------------------"); + pic14_emitcode(";","-----------------------------------------"); + pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name); + pic14_emitcode(";","-----------------------------------------"); - emitcode("","%s:",sym->rname); + pic14_emitcode("","%s:",sym->rname); addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname)); - fetype = getSpec(operandType(IC_LEFT(ic))); + ftype = operandType(IC_LEFT(ic)); /* if critical function then turn interrupts off */ - if (SPEC_CRTCL(fetype)) - emitcode("clr","ea"); + if (IFFUNC_ISCRITICAL(ftype)) + pic14_emitcode("clr","ea"); /* here we need to generate the equates for the register bank if required */ #if 0 - if (SPEC_BANK(fetype) != rbank) { + if (FUNC_REGBANK(ftype) != rbank) { int i ; - rbank = SPEC_BANK(fetype); + rbank = FUNC_REGBANK(ftype); for ( i = 0 ; i < pic14_nRegs ; i++ ) { if (strcmp(regspic14[i].base,"0") == 0) - emitcode("","%s = 0x%02x", + pic14_emitcode("","%s = 0x%02x", regspic14[i].dname, 8*rbank+regspic14[i].offset); else - emitcode ("","%s = %s + 0x%02x", + pic14_emitcode ("","%s = %s + 0x%02x", regspic14[i].dname, regspic14[i].base, 8*rbank+regspic14[i].offset); @@ -2417,39 +2628,49 @@ static void genFunction (iCode *ic) /* if this is an interrupt service routine then save acc, b, dpl, dph */ - if (IS_ISR(sym->etype)) { - + if (IFFUNC_ISISR(sym->type)) { + addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR))); + emitpcodeNULLop(POC_NOP); + emitpcodeNULLop(POC_NOP); + emitpcodeNULLop(POC_NOP); + emitpcode(POC_MOVWF, popCopyReg(&pc_wsave)); + emitpcode(POC_SWAPFW, popCopyReg(&pc_status)); + emitpcode(POC_CLRF, popCopyReg(&pc_status)); + emitpcode(POC_MOVWF, popCopyReg(&pc_ssave)); + + pBlockConvert2ISR(pb); +#if 0 if (!inExcludeList("acc")) - emitcode ("push","acc"); + pic14_emitcode ("push","acc"); if (!inExcludeList("b")) - emitcode ("push","b"); + pic14_emitcode ("push","b"); if (!inExcludeList("dpl")) - emitcode ("push","dpl"); + pic14_emitcode ("push","dpl"); if (!inExcludeList("dph")) - emitcode ("push","dph"); + pic14_emitcode ("push","dph"); if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) { - emitcode ("push", "dpx"); + pic14_emitcode ("push", "dpx"); /* Make sure we're using standard DPTR */ - emitcode ("push", "dps"); - emitcode ("mov", "dps, #0x00"); + pic14_emitcode ("push", "dps"); + pic14_emitcode ("mov", "dps, #0x00"); if (options.stack10bit) { /* This ISR could conceivably use DPTR2. Better save it. */ - emitcode ("push", "dpl1"); - emitcode ("push", "dph1"); - emitcode ("push", "dpx1"); + pic14_emitcode ("push", "dpl1"); + pic14_emitcode ("push", "dph1"); + pic14_emitcode ("push", "dpx1"); } } /* if this isr has no bank i.e. is going to run with bank 0 , then we need to save more registers :-) */ - if (!SPEC_BANK(sym->etype)) { + if (!FUNC_REGBANK(sym->type)) { /* if this function does not call any other function then we can be economical and save only those registers that are used */ - if (! sym->hasFcall) { + if (! IFFUNC_HASFCALL(sym->type)) { int i; /* if any registers used */ @@ -2458,7 +2679,7 @@ static void genFunction (iCode *ic) for ( i = 0 ; i < sym->regsUsed->size ; i++) { if (bitVectBitValue(sym->regsUsed,i) || (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) - emitcode("push","%s",pic14_regWithIdx(i)->dname); + pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname); } } @@ -2469,10 +2690,11 @@ static void genFunction (iCode *ic) saverbank(0,ic,FALSE); } } +#endif } else { /* if callee-save to be used for this function then save the registers being used in this function */ - if (sym->calleeSave) { + if (IFFUNC_CALLEESAVES(sym->type)) { int i; /* if any registers used */ @@ -2481,7 +2703,7 @@ static void genFunction (iCode *ic) for ( i = 0 ; i < sym->regsUsed->size ; i++) { if (bitVectBitValue(sym->regsUsed,i) || (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) { - emitcode("push","%s",pic14_regWithIdx(i)->dname); + //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname); _G.nRegsSaved++; } } @@ -2490,25 +2712,25 @@ static void genFunction (iCode *ic) } /* set the register bank to the desired value */ - if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) { - emitcode("push","psw"); - emitcode("mov","psw,#0x%02x",(SPEC_BANK(sym->etype) << 3)&0x00ff); + if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) { + pic14_emitcode("push","psw"); + pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff); } - if (IS_RENT(sym->etype) || options.stackAuto) { + if (IFFUNC_ISREENT(sym->type) || options.stackAuto) { if (options.useXstack) { - emitcode("mov","r0,%s",spname); - emitcode("mov","a,_bp"); - emitcode("movx","@r0,a"); - emitcode("inc","%s",spname); + pic14_emitcode("mov","r0,%s",spname); + pic14_emitcode("mov","a,_bp"); + pic14_emitcode("movx","@r0,a"); + pic14_emitcode("inc","%s",spname); } else { /* set up the stack */ - emitcode ("push","_bp"); /* save the callers stack */ + pic14_emitcode ("push","_bp"); /* save the callers stack */ } - emitcode ("mov","_bp,%s",spname); + pic14_emitcode ("mov","_bp,%s",spname); } /* adjust the stack for the function */ @@ -2520,21 +2742,21 @@ static void genFunction (iCode *ic) if (i > 3 && sym->recvSize < 4) { - emitcode ("mov","a,sp"); - emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff)); - emitcode ("mov","sp,a"); + pic14_emitcode ("mov","a,sp"); + pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff)); + pic14_emitcode ("mov","sp,a"); } else while(i--) - emitcode("inc","sp"); + pic14_emitcode("inc","sp"); } if (sym->xstack) { - emitcode ("mov","a,_spx"); - emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff)); - emitcode ("mov","_spx,a"); + pic14_emitcode ("mov","a,_spx"); + pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff)); + pic14_emitcode ("mov","_spx,a"); } } @@ -2546,52 +2768,52 @@ static void genEndFunction (iCode *ic) { symbol *sym = OP_SYMBOL(IC_LEFT(ic)); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (IS_RENT(sym->etype) || options.stackAuto) + if (IFFUNC_ISREENT(sym->type) || options.stackAuto) { - emitcode ("mov","%s,_bp",spname); + pic14_emitcode ("mov","%s,_bp",spname); } /* if use external stack but some variables were added to the local stack then decrement the local stack */ if (options.useXstack && sym->stack) { - emitcode("mov","a,sp"); - emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff); - emitcode("mov","sp,a"); + pic14_emitcode("mov","a,sp"); + pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff); + pic14_emitcode("mov","sp,a"); } - if ((IS_RENT(sym->etype) || options.stackAuto)) { + if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) { if (options.useXstack) { - emitcode("mov","r0,%s",spname); - emitcode("movx","a,@r0"); - emitcode("mov","_bp,a"); - emitcode("dec","%s",spname); + pic14_emitcode("mov","r0,%s",spname); + pic14_emitcode("movx","a,@r0"); + pic14_emitcode("mov","_bp,a"); + pic14_emitcode("dec","%s",spname); } else { - emitcode ("pop","_bp"); + pic14_emitcode ("pop","_bp"); } } /* restore the register bank */ - if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) - emitcode ("pop","psw"); + if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) + pic14_emitcode ("pop","psw"); - if (IS_ISR(sym->etype)) { + if (IFFUNC_ISISR(sym->type)) { /* now we need to restore the registers */ /* if this isr has no bank i.e. is going to run with bank 0 , then we need to save more registers :-) */ - if (!SPEC_BANK(sym->etype)) { + if (!FUNC_REGBANK(sym->type)) { /* if this function does not call any other function then we can be economical and save only those registers that are used */ - if (! sym->hasFcall) { + if (! IFFUNC_HASFCALL(sym->type)) { int i; /* if any registers used */ @@ -2600,7 +2822,7 @@ static void genEndFunction (iCode *ic) for ( i = sym->regsUsed->size ; i >= 0 ; i--) { if (bitVectBitValue(sym->regsUsed,i) || (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) - emitcode("pop","%s",pic14_regWithIdx(i)->dname); + pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname); } } @@ -2611,51 +2833,62 @@ static void genEndFunction (iCode *ic) unsaverbank(0,ic,FALSE); } } - +#if 0 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) { if (options.stack10bit) { - emitcode ("pop", "dpx1"); - emitcode ("pop", "dph1"); - emitcode ("pop", "dpl1"); + pic14_emitcode ("pop", "dpx1"); + pic14_emitcode ("pop", "dph1"); + pic14_emitcode ("pop", "dpl1"); } - emitcode ("pop", "dps"); - emitcode ("pop", "dpx"); + pic14_emitcode ("pop", "dps"); + pic14_emitcode ("pop", "dpx"); } if (!inExcludeList("dph")) - emitcode ("pop","dph"); + pic14_emitcode ("pop","dph"); if (!inExcludeList("dpl")) - emitcode ("pop","dpl"); + pic14_emitcode ("pop","dpl"); if (!inExcludeList("b")) - emitcode ("pop","b"); + pic14_emitcode ("pop","b"); if (!inExcludeList("acc")) - emitcode ("pop","acc"); + pic14_emitcode ("pop","acc"); - if (SPEC_CRTCL(sym->etype)) - emitcode("setb","ea"); + if (IFFUNC_ISCRITICAL(sym->type)) + pic14_emitcode("setb","ea"); +#endif /* if debug then send end of function */ /* if (options.debug && currFunc) { */ if (currFunc) { _G.debugLine = 1; - emitcode(";","C$%s$%d$%d$%d ==.", + pic14_emitcode(";","C$%s$%d$%d$%d ==.", FileBaseName(ic->filename),currFunc->lastLine, ic->level,ic->block); if (IS_STATIC(currFunc->etype)) - emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); + pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); else - emitcode(";","XG$%s$0$0 ==.",currFunc->name); + pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name); _G.debugLine = 0; } - emitcode ("reti",""); + pic14_emitcode ("reti",""); + + emitpcode(POC_CLRF, popCopyReg(&pc_status)); + emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave)); + emitpcode(POC_MOVWF, popCopyReg(&pc_status)); + emitpcode(POC_SWAPF, popCopyReg(&pc_wsave)); + emitpcode(POC_MOVFW, popCopyReg(&pc_wsave)); + addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1)); + + emitpcodeNULLop(POC_RETFIE); + } else { - if (SPEC_CRTCL(sym->etype)) - emitcode("setb","ea"); + if (IFFUNC_ISCRITICAL(sym->type)) + pic14_emitcode("setb","ea"); - if (sym->calleeSave) { + if (IFFUNC_CALLEESAVES(sym->type)) { int i; /* if any registers used */ @@ -2664,7 +2897,7 @@ static void genEndFunction (iCode *ic) for ( i = sym->regsUsed->size ; i >= 0 ; i--) { if (bitVectBitValue(sym->regsUsed,i) || (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) - emitcode("pop","%s",pic14_regWithIdx(i)->dname); + pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname); } } @@ -2673,18 +2906,18 @@ static void genEndFunction (iCode *ic) /* if debug then send end of function */ if (currFunc) { _G.debugLine = 1; - emitcode(";","C$%s$%d$%d$%d ==.", + pic14_emitcode(";","C$%s$%d$%d$%d ==.", FileBaseName(ic->filename),currFunc->lastLine, ic->level,ic->block); if (IS_STATIC(currFunc->etype)) - emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); + pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); else - emitcode(";","XG$%s$0$0 ==.",currFunc->name); + pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name); _G.debugLine = 0; } - emitcode ("return",""); - emitpcode(POC_RETURN,NULL); + pic14_emitcode ("return",""); + emitpcodeNULLop(POC_RETURN); /* Mark the end of a function */ addpCode2pBlock(pb,newpCodeFunction(NULL,NULL)); @@ -2697,61 +2930,66 @@ static void genEndFunction (iCode *ic) /*-----------------------------------------------------------------*/ static void genRet (iCode *ic) { - int size,offset = 0 , pushed = 0; + int size,offset = 0 , pushed = 0; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if we have no return value then - just generate the "ret" */ - if (!IC_LEFT(ic)) - goto jumpret; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* if we have no return value then + just generate the "ret" */ + if (!IC_LEFT(ic)) + goto jumpret; - /* we have something to return then - move the return value into place */ - aopOp(IC_LEFT(ic),ic,FALSE); - size = AOP_SIZE(IC_LEFT(ic)); + /* we have something to return then + move the return value into place */ + aopOp(IC_LEFT(ic),ic,FALSE); + size = AOP_SIZE(IC_LEFT(ic)); - while (size--) { - char *l ; - if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) { - /* #NOCHANGE */ - l = aopGet(AOP(IC_LEFT(ic)),offset++, - FALSE,TRUE); - emitcode("push","%s",l); - pushed++; - } else { - l = aopGet(AOP(IC_LEFT(ic)),offset, - FALSE,FALSE); - if (strcmp(fReturn[offset],l)) { - if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) || - ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) - emitcode("movlw","%s",l); - else - emitcode("movf","%s,w",l); - if(size) - emitcode("movwf","%s",fReturn[offset]); - offset++; - } - } - } - - if (pushed) { - while(pushed) { - pushed--; - if (strcmp(fReturn[pushed],"a")) - emitcode("pop",fReturn[pushed]); - else - emitcode("pop","acc"); + while (size--) { + char *l ; + if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) { + /* #NOCHANGE */ + l = aopGet(AOP(IC_LEFT(ic)),offset++, + FALSE,TRUE); + pic14_emitcode("push","%s",l); + pushed++; + } else { + l = aopGet(AOP(IC_LEFT(ic)),offset, + FALSE,FALSE); + if (strcmp(fReturn[offset],l)) { + if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) || + ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) { + emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset)); + }else { + emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset)); + } + if(size) { + emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr)); + pic14_emitcode("movwf","%s",fReturn[offset]); } + offset++; + } + } + } + + if (pushed) { + while(pushed) { + pushed--; + if (strcmp(fReturn[pushed],"a")) + pic14_emitcode("pop",fReturn[pushed]); + else + pic14_emitcode("pop","acc"); } - freeAsmop (IC_LEFT(ic),NULL,ic,TRUE); + } + freeAsmop (IC_LEFT(ic),NULL,ic,TRUE); jumpret: - /* generate a jump to the return label - if the next is not the return statement */ - if (!(ic->next && ic->next->op == LABEL && - IC_LABEL(ic->next) == returnLabel)) + /* generate a jump to the return label + if the next is not the return statement */ + if (!(ic->next && ic->next->op == LABEL && + IC_LABEL(ic->next) == returnLabel)) { - emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset); + emitpcode(POC_GOTO,popGetLabel(returnLabel->key)); + pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset); + } } @@ -2761,12 +2999,12 @@ static void genRet (iCode *ic) static void genLabel (iCode *ic) { /* special case never generate */ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (IC_LABEL(ic) == entryLabel) return ; - emitpLabel(IC_LABEL(ic)->key+100 + labelOffset); - emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset)); + emitpLabel(IC_LABEL(ic)->key); + pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset)); } /*-----------------------------------------------------------------*/ @@ -2775,1470 +3013,1214 @@ static void genLabel (iCode *ic) //tsd static void genGoto (iCode *ic) { - emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset); + emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key)); + pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset); } + /*-----------------------------------------------------------------*/ -/* findLabelBackwards: walks back through the iCode chain looking */ -/* for the given label. Returns number of iCode instructions */ -/* between that label and given ic. */ -/* Returns zero if label not found. */ +/* genMultbits :- multiplication of bits */ /*-----------------------------------------------------------------*/ -#if 0 -static int findLabelBackwards(iCode *ic, int key) +static void genMultbits (operand *left, + operand *right, + operand *result) { - int count = 0; - - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - while (ic->prev) - { - ic = ic->prev; - count++; - - if (ic->op == LABEL && IC_LABEL(ic)->key == key) - { - /* printf("findLabelBackwards = %d\n", count); */ - return count; - } - } - - return 0; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if(!pic14_sameRegs(AOP(result),AOP(right))) + emitpcode(POC_BSF, popGet(AOP(result),0)); + + emitpcode(POC_BTFSC,popGet(AOP(right),0)); + emitpcode(POC_BTFSS,popGet(AOP(left),0)); + emitpcode(POC_BCF, popGet(AOP(result),0)); + } -#endif + + /*-----------------------------------------------------------------*/ -/* genPlusIncr :- does addition with increment if possible */ +/* genMultOneByte : 8 bit multiplication & division */ /*-----------------------------------------------------------------*/ -static bool genPlusIncr (iCode *ic) +static void genMultOneByte (operand *left, + operand *right, + operand *result) { - unsigned int icount ; - unsigned int size = getDataSize(IC_RESULT(ic)); + sym_link *opetype = operandType(result); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - DEBUGemitcode ("; ","result %d, left %d, right %d", - AOP_TYPE(IC_RESULT(ic)), - AOP_TYPE(IC_LEFT(ic)), - AOP_TYPE(IC_RIGHT(ic))); + // symbol *lbl ; + int size,offset; - /* will try to generate an increment */ - /* if the right side is not a literal - we cannot */ - if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) - return FALSE ; - - DEBUGemitcode ("; ","%s %d",__FUNCTION__,__LINE__); - /* if the literal value of the right hand side - is greater than 1 then it is faster to add */ - if ((icount = floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2) - return FALSE ; - - /* if increment 16 bits in register */ - if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) && - (icount == 1)) { + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_AopType(__LINE__,left,right,result); + DEBUGpic14_AopTypeSign(__LINE__,left,right,result); - int offset = MSB16; + /* (if two literals, the value is computed before) */ + /* if one literal, literal on the right */ + if (AOP_TYPE(left) == AOP_LIT){ + operand *t = right; + right = left; + left = t; + } - emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); - //emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); + size = AOP_SIZE(result); + if(size == 1) { - while(--size) { - emitSKPNZ; - emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE)); - //emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE)); - } + if (AOP_TYPE(right) == AOP_LIT){ + pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", + aopGet(AOP(right),0,FALSE,FALSE), + aopGet(AOP(left),0,FALSE,FALSE), + aopGet(AOP(result),0,FALSE,FALSE)); + pic14_emitcode("call","genMultLit"); + } else { + pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", + aopGet(AOP(right),0,FALSE,FALSE), + aopGet(AOP(left),0,FALSE,FALSE), + aopGet(AOP(result),0,FALSE,FALSE)); + pic14_emitcode("call","genMult8X8_8"); - return TRUE; } - - DEBUGemitcode ("; ","%s %d",__FUNCTION__,__LINE__); - /* if left is in accumulator - probably a bit operation*/ - 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)); - emitcode("bcf","(%s >> 3), (%s & 7)", - AOP(IC_RESULT(ic))->aopu.aop_dir, - AOP(IC_RESULT(ic))->aopu.aop_dir); - if(icount) - emitpcode(POC_XORLW,popGetLit(1)); - //emitcode("xorlw","1"); - else - emitpcode(POC_ANDLW,popGetLit(1)); - //emitcode("andlw","1"); + genMult8X8_8 (left, right,result); - emitSKPZ; - emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - emitcode("bsf","(%s >> 3), (%s & 7)", - AOP(IC_RESULT(ic))->aopu.aop_dir, - AOP(IC_RESULT(ic))->aopu.aop_dir); - return TRUE; - } + /* signed or unsigned */ + //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE)); + //l = aopGet(AOP(left),0,FALSE,FALSE); + //MOVA(l); + //pic14_emitcode("mul","ab"); + /* if result size = 1, mul signed = mul unsigned */ + //aopPut(AOP(result),"a",0); + } else { // (size > 1) + pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", + aopGet(AOP(right),0,FALSE,FALSE), + aopGet(AOP(left),0,FALSE,FALSE), + aopGet(AOP(result),0,FALSE,FALSE)); - /* if the sizes are greater than 1 then we cannot */ - if (AOP_SIZE(IC_RESULT(ic)) > 1 || - AOP_SIZE(IC_LEFT(ic)) > 1 ) - return FALSE ; - - /* If we are incrementing the same register by two: */ + if (SPEC_USIGN(opetype)){ + pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result)); + genUMult8X8_16 (left, right, result, NULL); - if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - - while (icount--) - emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - //emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - - return TRUE ; + if (size > 2) { + /* for filling the MSBs */ + emitpcode(POC_CLRF, popGet(AOP(result),2)); + emitpcode(POC_CLRF, popGet(AOP(result),3)); + } } - - DEBUGemitcode ("; ","couldn't increment result-%s left-%s", - aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE), - aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - return FALSE ; -} + else{ + pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result)); -/*-----------------------------------------------------------------*/ -/* outBitAcc - output a bit in acc */ -/*-----------------------------------------------------------------*/ -static void outBitAcc(operand *result) -{ - symbol *tlbl = newiTempLabel(NULL); - /* if the result is a bit */ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic14_emitcode("mov","a,b"); - if (AOP_TYPE(result) == AOP_CRY){ - aopPut(AOP(result),"a",0); - } - else { - emitcode("jz","%05d_DS_",tlbl->key+100); - emitcode("mov","a,%s",one); - emitcode("","%05d_DS_:",tlbl->key+100); - outAcc(result); + /* adjust the MSB if left or right neg */ + + /* if one literal */ + if (AOP_TYPE(right) == AOP_LIT){ + pic14_emitcode("multiply ","right is a lit"); + /* AND literal negative */ + if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){ + /* adjust MSB (c==0 after mul) */ + pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE)); + } + } + else{ + genSMult8X8_16 (left, right, result, NULL); + } + + if(size > 2){ + pic14_emitcode("multiply ","size is greater than 2, so propogate sign"); + /* get the sign */ + pic14_emitcode("rlc","a"); + pic14_emitcode("subb","a,acc"); + } } + + size -= 2; + offset = 2; + if (size > 0) + while (size--) + pic14_emitcode("multiply ","size is way greater than 2, so propogate sign"); + //aopPut(AOP(result),"a",offset++); + } } /*-----------------------------------------------------------------*/ -/* genPlusBits - generates code for addition of two bits */ +/* genMult - generates code for multiplication */ /*-----------------------------------------------------------------*/ -static void genPlusBits (iCode *ic) +static void genMult (iCode *ic) { + operand *left = IC_LEFT(ic); + operand *right = IC_RIGHT(ic); + operand *result= IC_RESULT(ic); - DEBUGemitcode ("; ***","%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. - */ - - /* If the result is stored in the accumulator (w) */ - if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) { - //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)); - - emitcode("movlw","(1 << (%s & 7))", - AOP(IC_RESULT(ic))->aopu.aop_dir, - AOP(IC_RESULT(ic))->aopu.aop_dir); - emitcode("bcf","(%s >> 3), (%s & 7)", - AOP(IC_RESULT(ic))->aopu.aop_dir, - AOP(IC_RESULT(ic))->aopu.aop_dir); - emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - emitcode("xorwf","(%s >>3),f", - AOP(IC_RESULT(ic))->aopu.aop_dir); - emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_LEFT(ic))->aopu.aop_dir, - AOP(IC_LEFT(ic))->aopu.aop_dir); - emitcode("xorwf","(%s>>3),f", - AOP(IC_RESULT(ic))->aopu.aop_dir); - } else { + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* assign the amsops */ + aopOp (left,ic,FALSE); + aopOp (right,ic,FALSE); + aopOp (result,ic,TRUE); - 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)); + DEBUGpic14_AopType(__LINE__,left,right,result); - emitcode("clrw",""); - emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - emitcode("xorlw","1"); - emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_LEFT(ic))->aopu.aop_dir, - AOP(IC_LEFT(ic))->aopu.aop_dir); - emitcode("xorlw","1"); + /* special cases first */ + /* both are bits */ + if (AOP_TYPE(left) == AOP_CRY && + AOP_TYPE(right)== AOP_CRY) { + genMultbits(left,right,result); + goto release ; } -} - -#if 0 -/* This is the original version of this code. - * - * This is being kept around for reference, - * because I am not entirely sure I got it right... - */ -static void adjustArithmeticResult(iCode *ic) -{ - if (AOP_SIZE(IC_RESULT(ic)) == 3 && - AOP_SIZE(IC_LEFT(ic)) == 3 && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic)))) - aopPut(AOP(IC_RESULT(ic)), - aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE), - 2); - - if (AOP_SIZE(IC_RESULT(ic)) == 3 && - AOP_SIZE(IC_RIGHT(ic)) == 3 && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) - aopPut(AOP(IC_RESULT(ic)), - aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE), - 2); - - if (AOP_SIZE(IC_RESULT(ic)) == 3 && - AOP_SIZE(IC_LEFT(ic)) < 3 && - AOP_SIZE(IC_RIGHT(ic)) < 3 && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) { - char buffer[5]; - sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic))))); - aopPut(AOP(IC_RESULT(ic)),buffer,2); - } -} -//#else -/* This is the pure and virtuous version of this code. - * I'm pretty certain it's right, but not enough to toss the old - * code just yet... - */ -static void adjustArithmeticResult(iCode *ic) -{ - if (opIsGptr(IC_RESULT(ic)) && - opIsGptr(IC_LEFT(ic)) && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic)))) - { - aopPut(AOP(IC_RESULT(ic)), - aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE), - GPTRSIZE - 1); + /* if both are of size == 1 */ + if (AOP_SIZE(left) == 1 && + AOP_SIZE(right) == 1 ) { + genMultOneByte(left,right,result); + goto release ; } - if (opIsGptr(IC_RESULT(ic)) && - opIsGptr(IC_RIGHT(ic)) && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) - { - aopPut(AOP(IC_RESULT(ic)), - aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE), - GPTRSIZE - 1); - } + pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor."); + + /* should have been converted to function call */ + //assert(0) ; - if (opIsGptr(IC_RESULT(ic)) && - AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE && - AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) { - char buffer[5]; - sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic))))); - aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1); - } +release : + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); } -#endif /*-----------------------------------------------------------------*/ -/* genPlus - generates code for addition */ +/* genDivbits :- division of bits */ /*-----------------------------------------------------------------*/ -static void genPlus (iCode *ic) -{ - int size, offset = 0; - - /* special cases :- */ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - aopOp (IC_LEFT(ic),ic,FALSE); - aopOp (IC_RIGHT(ic),ic,FALSE); - aopOp (IC_RESULT(ic),ic,TRUE); +static void genDivbits (operand *left, + operand *right, + operand *result) +{ - /* if literal, literal on the right or - if left requires ACC or right is already - in ACC */ + char *l; - if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) { - operand *t = IC_RIGHT(ic); - IC_RIGHT(ic) = IC_LEFT(ic); - IC_LEFT(ic) = t; - } + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* the result must be bit */ + pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); + l = aopGet(AOP(left),0,FALSE,FALSE); - /* if both left & right are in bit space */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && - AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { - genPlusBits (ic); - goto release ; - } + MOVA(l); - /* if left in bit space & right literal */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && - AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) { - /* 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)); - if (!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)); - } - } else { - size = getDataSize(IC_RESULT(ic)); - while (size--) { - MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitcode("addc","a,#00 ;%d",__LINE__); - aopPut(AOP(IC_RESULT(ic)),"a",offset++); - } - } - goto release ; - } + pic14_emitcode("div","ab"); + pic14_emitcode("rrc","a"); + aopPut(AOP(result),"c",0); +} - /* if I can do an increment instead - of add then GOOD for ME */ - if (genPlusIncr (ic) == TRUE) - goto release; +/*-----------------------------------------------------------------*/ +/* genDivOneByte : 8 bit division */ +/*-----------------------------------------------------------------*/ +static void genDivOneByte (operand *left, + operand *right, + operand *result) +{ + sym_link *opetype = operandType(result); + char *l ; + symbol *lbl ; + int size,offset; - size = getDataSize(IC_RESULT(ic)); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + size = AOP_SIZE(result) - 1; + offset = 1; + /* signed or unsigned */ + if (SPEC_USIGN(opetype)) { + /* unsigned is easy */ + pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE)); + l = aopGet(AOP(left),0,FALSE,FALSE); + MOVA(l); + pic14_emitcode("div","ab"); + aopPut(AOP(result),"a",0); + while (size--) + aopPut(AOP(result),zero,offset++); + return ; + } - if(AOP(IC_RIGHT(ic))->type == AOP_LIT) { - /* Add a literal to something else */ - bool know_W=0; - unsigned lit = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); - unsigned l1=0; + /* signed is a little bit more difficult */ - offset = 0; - DEBUGemitcode(";","adding lit to something. size %d",size); - while(size--){ + /* save the signs of the operands */ + l = aopGet(AOP(left),0,FALSE,FALSE); + MOVA(l); + pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE)); + pic14_emitcode("push","acc"); /* save it on the stack */ - DEBUGemitcode(";","size %d",size); + /* now sign adjust for both left & right */ + l = aopGet(AOP(right),0,FALSE,FALSE); + MOVA(l); + lbl = newiTempLabel(NULL); + pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100)); + pic14_emitcode("cpl","a"); + pic14_emitcode("inc","a"); + pic14_emitcode("","%05d_DS_:",(lbl->key+100)); + pic14_emitcode("mov","b,a"); - switch (lit & 0xff) { - case 0: - break; - case 1: - if(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(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(sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) - emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,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_INCF, popGet(AOP(IC_LEFT(ic)),offset+1,FALSE,FALSE)); - } - } - } + /* sign adjust left side */ + l = aopGet(AOP(left),0,FALSE,FALSE); + MOVA(l); - l1 = lit & 0xff; - lit >>= 8; - offset++; - } + lbl = newiTempLabel(NULL); + pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100)); + pic14_emitcode("cpl","a"); + pic14_emitcode("inc","a"); + pic14_emitcode("","%05d_DS_:",(lbl->key+100)); - } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { + /* now the division */ + pic14_emitcode("div","ab"); + /* we are interested in the lower order + only */ + pic14_emitcode("mov","b,a"); + lbl = newiTempLabel(NULL); + pic14_emitcode("pop","acc"); + /* if there was an over flow we don't + adjust the sign of the result */ + pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100)); + pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100)); + CLRC; + pic14_emitcode("clr","a"); + pic14_emitcode("subb","a,b"); + pic14_emitcode("mov","b,a"); + pic14_emitcode("","%05d_DS_:",(lbl->key+100)); - emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + /* now we are done */ + aopPut(AOP(result),"b",0); + if(size > 0){ + pic14_emitcode("mov","c,b.7"); + pic14_emitcode("subb","a,acc"); + } + while (size--) + aopPut(AOP(result),"a",offset++); - /* here we are adding a bit to a char or int */ - if(size == 1) { - if (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)); +/*-----------------------------------------------------------------*/ +/* genDiv - generates code for division */ +/*-----------------------------------------------------------------*/ +static void genDiv (iCode *ic) +{ + operand *left = IC_LEFT(ic); + operand *right = IC_RIGHT(ic); + operand *result= IC_RESULT(ic); - emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - } else { + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* assign the amsops */ + aopOp (left,ic,FALSE); + aopOp (right,ic,FALSE); + aopOp (result,ic,TRUE); - if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { - emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitpcode(POC_XORLW , popGetLit(1)); + /* special cases first */ + /* both are bits */ + if (AOP_TYPE(left) == AOP_CRY && + AOP_TYPE(right)== AOP_CRY) { + genDivbits(left,right,result); + goto release ; + } - emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - 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)); - - emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - } - - if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) { - - if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) { - emitpcode(POC_ANDLW , popGetLit(1)); - emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - emitSKPZ; - emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); -/* - emitcode("andlw","1"); - emitcode("bcf","(%s >> 3), (%s & 7)", - AOP(IC_RESULT(ic))->aopu.aop_dir, - AOP(IC_RESULT(ic))->aopu.aop_dir); - emitSKPZ; - emitcode("bsf","(%s >> 3), (%s & 7)", - AOP(IC_RESULT(ic))->aopu.aop_dir, - AOP(IC_RESULT(ic))->aopu.aop_dir); -*/ + /* if both are of size == 1 */ + if (AOP_SIZE(left) == 1 && + AOP_SIZE(right) == 1 ) { + genDivOneByte(left,right,result); + goto release ; + } - } else { - emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - } - } - } + /* should have been converted to function call */ + assert(0); +release : + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); +} - } else { - int offset = 1; +/*-----------------------------------------------------------------*/ +/* genModbits :- modulus of bits */ +/*-----------------------------------------------------------------*/ +static void genModbits (operand *left, + operand *right, + operand *result) +{ - if (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)); + char *l; - emitcode("clrz",""); + /* the result must be bit */ + pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); + l = aopGet(AOP(left),0,FALSE,FALSE); - emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + MOVA(l); - } else { + pic14_emitcode("div","ab"); + pic14_emitcode("mov","a,b"); + pic14_emitcode("rrc","a"); + aopPut(AOP(result),"c",0); +} - 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)); +/*-----------------------------------------------------------------*/ +/* genModOneByte : 8 bit modulus */ +/*-----------------------------------------------------------------*/ +static void genModOneByte (operand *left, + operand *right, + operand *result) +{ + sym_link *opetype = operandType(result); + char *l ; + symbol *lbl ; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* signed or unsigned */ + if (SPEC_USIGN(opetype)) { + /* unsigned is easy */ + pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE)); + l = aopGet(AOP(left),0,FALSE,FALSE); + MOVA(l); + pic14_emitcode("div","ab"); + aopPut(AOP(result),"b",0); + return ; + } - emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + /* signed is a little bit more difficult */ - } + /* save the signs of the operands */ + l = aopGet(AOP(left),0,FALSE,FALSE); + MOVA(l); - while(--size){ - emitSKPZ; - emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE)); - //emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE)); - } + pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE)); + pic14_emitcode("push","acc"); /* save it on the stack */ - } - - } else { - - 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)); - } else { + /* now sign adjust for both left & right */ + l = aopGet(AOP(right),0,FALSE,FALSE); + MOVA(l); - if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { - emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) - emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - } else { + lbl = newiTempLabel(NULL); + pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100)); + pic14_emitcode("cpl","a"); + pic14_emitcode("inc","a"); + pic14_emitcode("","%05d_DS_:",(lbl->key+100)); + pic14_emitcode("mov","b,a"); - emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); + /* sign adjust left side */ + l = aopGet(AOP(left),0,FALSE,FALSE); + MOVA(l); - if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) - emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - 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)); - } - } - } - } + lbl = newiTempLabel(NULL); + pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100)); + pic14_emitcode("cpl","a"); + pic14_emitcode("inc","a"); + pic14_emitcode("","%05d_DS_:",(lbl->key+100)); - offset = 1; - size--; + /* now the multiplication */ + pic14_emitcode("div","ab"); + /* we are interested in the lower order + only */ + lbl = newiTempLabel(NULL); + pic14_emitcode("pop","acc"); + /* if there was an over flow we don't + adjust the sign of the result */ + pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100)); + pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100)); + CLRC ; + pic14_emitcode("clr","a"); + pic14_emitcode("subb","a,b"); + pic14_emitcode("mov","b,a"); + pic14_emitcode("","%05d_DS_:",(lbl->key+100)); - while(size--){ - if (!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)); + /* now we are done */ + aopPut(AOP(result),"b",0); - emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); - } +} - emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitSKPNC; - emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); +/*-----------------------------------------------------------------*/ +/* genMod - generates code for division */ +/*-----------------------------------------------------------------*/ +static void genMod (iCode *ic) +{ + operand *left = IC_LEFT(ic); + operand *right = IC_RIGHT(ic); + operand *result= IC_RESULT(ic); - /* - emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitSKPNC; - emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE)); - */ + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* assign the amsops */ + aopOp (left,ic,FALSE); + aopOp (right,ic,FALSE); + aopOp (result,ic,TRUE); - offset++; - } + /* special cases first */ + /* both are bits */ + if (AOP_TYPE(left) == AOP_CRY && + AOP_TYPE(right)== AOP_CRY) { + genModbits(left,right,result); + goto release ; + } + /* if both are of size == 1 */ + if (AOP_SIZE(left) == 1 && + AOP_SIZE(right) == 1 ) { + genModOneByte(left,right,result); + goto release ; } - //adjustArithmeticResult(ic); + /* should have been converted to function call */ + assert(0); - release: - freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); +release : + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ -/* genMinusDec :- does subtraction with decrement if possible */ +/* genIfxJump :- will create a jump depending on the ifx */ /*-----------------------------------------------------------------*/ -static bool genMinusDec (iCode *ic) +/* + note: May need to add parameter to indicate when a variable is in bit space. +*/ +static void genIfxJump (iCode *ic, char *jval) { - unsigned int icount ; - unsigned int size = getDataSize(IC_RESULT(ic)); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* will try to generate an increment */ - /* if the right side is not a literal - we cannot */ - if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) - return FALSE ; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* if true label then we jump if condition + supplied is true */ + if ( IC_TRUE(ic) ) { + + if(strcmp(jval,"a") == 0) + emitSKPZ; + else if (strcmp(jval,"c") == 0) + emitSKPC; + else { + DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); + emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1)); + } - DEBUGemitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)); + emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key)); + pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset); - /* if the literal value of the right hand side - is greater than 4 then it is not worth it */ - if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2) - return FALSE ; + } + else { + /* false label is present */ + if(strcmp(jval,"a") == 0) + emitSKPNZ; + else if (strcmp(jval,"c") == 0) + emitSKPNC; + else { + DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); + emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1)); + } - /* if decrement 16 bits in register */ - if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) && - (size > 1) && - (icount == 1)) { + emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key)); + pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset); - if(size == 2) { - emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); - emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); - emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE)); - } else { - /* size is 3 or 4 */ - emitcode("movlw","0xff"); - emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); + } - emitSKPNC; - emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE)); - emitSKPNC; - emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE)); - if(size > 3) { - emitcode("skpnc",""); - emitSKPNC; - emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE)); - } + /* mark the icode as generated */ + ic->generated = 1; +} - } +/*-----------------------------------------------------------------*/ +/* genSkip */ +/*-----------------------------------------------------------------*/ +static void genSkip(iCode *ifx,int status_bit) +{ + if(!ifx) + return; + + if ( IC_TRUE(ifx) ) { + switch(status_bit) { + case 'z': + emitSKPNZ; + break; - return TRUE; + case 'c': + emitSKPNC; + break; + + case 'd': + emitSKPDC; + break; } - /* if the sizes are greater than 1 then we cannot */ - if (AOP_SIZE(IC_RESULT(ic)) > 1 || - AOP_SIZE(IC_LEFT(ic)) > 1 ) - return FALSE ; + emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); + pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); - /* we can if the aops of the left & result match or - if they are in registers and the registers are the - same */ - if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) { + } else { - while (icount--) - emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + switch(status_bit) { - //emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + case 'z': + emitSKPZ; + break; - return TRUE ; - } + case 'c': + emitSKPC; + break; - DEBUGemitcode ("; returning"," result=%s, left=%s", - aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE), - aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - if(size==1) { - emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - return TRUE; + case 'd': + emitSKPDC; + break; } + emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key)); + pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); + + } - return FALSE ; } /*-----------------------------------------------------------------*/ -/* addSign - complete with sign */ +/* genSkipc */ /*-----------------------------------------------------------------*/ -static void addSign(operand *result, int offset, int sign) +static void genSkipc(resolvedIfx *rifx) { - int size = (getDataSize(result) - offset); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(size > 0){ - if(sign){ - emitcode("rlc","a"); - emitcode("subb","a,acc"); - while(size--) - aopPut(AOP(result),"a",offset++); - } else - while(size--) - aopPut(AOP(result),zero,offset++); - } + if(!rifx) + return; + + if(rifx->condition) + emitSKPC; + else + emitSKPNC; + + emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key)); + rifx->generated = 1; } /*-----------------------------------------------------------------*/ -/* genMinusBits - generates code for subtraction of two bits */ +/* genSkipz2 */ /*-----------------------------------------------------------------*/ -static void genMinusBits (iCode *ic) +static void genSkipz2(resolvedIfx *rifx) { - symbol *lbl = newiTempLabel(NULL); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){ - emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir); - emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100)); - emitcode("cpl","c"); - emitcode("","%05d_DS_:",(lbl->key+100)); - outBitC(IC_RESULT(ic)); - } - else{ - emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir); - emitcode("subb","a,acc"); - emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100)); - emitcode("inc","a"); - emitcode("","%05d_DS_:",(lbl->key+100)); - aopPut(AOP(IC_RESULT(ic)),"a",0); - addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic))))); - } + if(!rifx) + return; + + if(rifx->condition) + emitSKPZ; + else + emitSKPNZ; + + emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key)); + rifx->generated = 1; } /*-----------------------------------------------------------------*/ -/* genMinus - generates code for subtraction */ +/* genSkipz */ /*-----------------------------------------------------------------*/ -static void genMinus (iCode *ic) +static void genSkipz(iCode *ifx, int condition) { - int size, offset = 0; - unsigned long lit = 0L; + if(!ifx) + return; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - aopOp (IC_LEFT(ic),ic,FALSE); - aopOp (IC_RIGHT(ic),ic,FALSE); - aopOp (IC_RESULT(ic),ic,TRUE); + if(condition) + emitSKPNZ; + else + emitSKPZ; - /* special cases :- */ - /* if both left & right are in bit space */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && - AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { - genMinusBits (ic); - goto release ; - } + if ( IC_TRUE(ifx) ) + emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); + else + emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key)); - /* if I can do an decrement instead - of subtract then GOOD for ME */ - if (genMinusDec (ic) == TRUE) - goto release; + if ( IC_TRUE(ifx) ) + pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); + else + pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); - size = getDataSize(IC_RESULT(ic)); +} +/*-----------------------------------------------------------------*/ +/* genSkipCond */ +/*-----------------------------------------------------------------*/ +static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit) +{ + if(!rifx) + return; - if(AOP(IC_RIGHT(ic))->type == AOP_LIT) { - /* Add a literal to something else */ + if(rifx->condition) + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0)); + else + emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0)); - lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); - lit = - (long)lit; - /* add the first byte: */ - emitcode("movlw","0x%x", lit & 0xff); - emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); + emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key)); + rifx->generated = 1; +} - offset = 1; - size--; +#if 0 +/*-----------------------------------------------------------------*/ +/* genChkZeroes :- greater or less than comparison */ +/* For each byte in a literal that is zero, inclusive or the */ +/* the corresponding byte in the operand with W */ +/* returns true if any of the bytes are zero */ +/*-----------------------------------------------------------------*/ +static int genChkZeroes(operand *op, int lit, int size) +{ - while(size--){ + int i; + int flag =1; - emitcode("rlf","_known_zero,w"); - emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); + while(size--) { + i = (lit >> (size*8)) & 0xff; - lit >>= 8; - if(lit & 0xff) { - emitcode("movlw","0x%x", lit & 0xff); - emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - - } - offset++; - } + if(i==0) { + if(flag) + emitpcode(POC_MOVFW, popGet(AOP(op),size)); + else + emitpcode(POC_IORFW, popGet(AOP(op),size)); + flag = 0; + } + } - } else { + return (flag==0); +} +#endif - emitcode("movf","%s", aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE)); - emitcode("subwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); +/*-----------------------------------------------------------------*/ +/* genCmp :- greater or less than comparison */ +/*-----------------------------------------------------------------*/ +static void genCmp (operand *left,operand *right, + operand *result, iCode *ifx, int sign) +{ + int size; //, offset = 0 ; + unsigned long lit = 0L,i = 0; + resolvedIfx rFalseIfx; + // resolvedIfx rTrueIfx; + symbol *truelbl; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(ifx) { + DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true")); + DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true")); + } - offset = 1; - size--; - while(size--){ - emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitSKPNC; - emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitcode("subwf","%s,f", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - - } + resolveIfx(&rFalseIfx,ifx); + truelbl = newiTempLabel(NULL); - } + //if(IC_TRUE(ifx) == NULL) + /* if left & right are bit variables */ + if (AOP_TYPE(left) == AOP_CRY && + AOP_TYPE(right) == AOP_CRY ) { + pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); + pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir); + } else { + /* subtract right from left if at the + end the carry flag is set then we know that + left is greater than right */ + size = max(AOP_SIZE(left),AOP_SIZE(right)); + /* if unsigned char cmp with lit, do cjne left,#right,zz */ + //if((size == 1) && !sign && + // (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){ + // symbol *lbl = newiTempLabel(NULL); + // pic14_emitcode("cjne","%s,%s,%05d_DS_", + // aopGet(AOP(left),offset,FALSE,FALSE), + // aopGet(AOP(right),offset,FALSE,FALSE), + // lbl->key+100); + //pic14_emitcode("","%05d_DS_:",lbl->key+100); + //} else + { - // adjustArithmeticResult(ic); - -release: - freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); -} + symbol *lbl = newiTempLabel(NULL); + if(AOP_TYPE(right) == AOP_LIT) { -/*-----------------------------------------------------------------*/ -/* genMultbits :- multiplication of bits */ -/*-----------------------------------------------------------------*/ -static void genMultbits (operand *left, - operand *right, - operand *result) -{ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); - outBitC(result); -} + DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign); + /* special cases */ -/*-----------------------------------------------------------------*/ -/* genMultOneByte : 8 bit multiplication & division */ -/*-----------------------------------------------------------------*/ -static void genMultOneByte (operand *left, - operand *right, - operand *result) -{ - sym_link *opetype = operandType(result); - char *l ; - symbol *lbl ; - int size,offset; + if(lit == 0) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* (if two literals, the value is computed before) */ - /* if one literal, literal on the right */ - if (AOP_TYPE(left) == AOP_LIT){ - operand *t = right; - right = left; - left = t; - } + if(sign != 0) + genSkipCond(&rFalseIfx,left,size-1,7); + else + /* no need to compare to 0...*/ + /* NOTE: this is a de-generate compare that most certainly + * creates some dead code. */ + emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key)); - size = AOP_SIZE(result); - /* signed or unsigned */ - emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE)); - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("mul","ab"); - /* if result size = 1, mul signed = mul unsigned */ - aopPut(AOP(result),"a",0); - if (size > 1){ - if (SPEC_USIGN(opetype)){ - aopPut(AOP(result),"b",1); - if (size > 2) - /* for filling the MSBs */ - emitcode("clr","a"); - } - else{ - emitcode("mov","a,b"); + if(ifx) ifx->generated = 1; + return; - /* adjust the MSB if left or right neg */ + } + size--; - /* if one literal */ - if (AOP_TYPE(right) == AOP_LIT){ - /* AND literal negative */ - if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){ - /* adjust MSB (c==0 after mul) */ - emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE)); - } - } - else{ - lbl = newiTempLabel(NULL); - emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE)); - emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100)); - emitcode("","%05d_DS_:",(lbl->key+100)); - emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE)); - lbl = newiTempLabel(NULL); - emitcode("jc","%05d_DS_",(lbl->key+100)); - emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE)); - emitcode("","%05d_DS_:",(lbl->key+100)); - } + if(size == 0) { + //i = (lit >> (size*8)) & 0xff; + DEBUGpic14_emitcode(";right lit","line = %d",__LINE__); + + emitpcode(POC_MOVFW, popGet(AOP(left),size)); + + i = ((0-lit) & 0xff); + if(sign) { + if( i == 0x81) { + /* lit is 0x7f, all signed chars are less than + * this except for 0x7f itself */ + emitpcode(POC_XORLW, popGetLit(0x7f)); + genSkipz2(&rFalseIfx); + } else { + emitpcode(POC_ADDLW, popGetLit(0x80)); + emitpcode(POC_ADDLW, popGetLit(i^0x80)); + genSkipc(&rFalseIfx); + } - lbl = newiTempLabel(NULL); - emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE)); - emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100)); - emitcode("","%05d_DS_:",(lbl->key+100)); - emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE)); - lbl = newiTempLabel(NULL); - emitcode("jc","%05d_DS_",(lbl->key+100)); - emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE)); - emitcode("","%05d_DS_:",(lbl->key+100)); - - aopPut(AOP(result),"a",1); - if(size > 2){ - /* get the sign */ - emitcode("rlc","a"); - emitcode("subb","a,acc"); - } - } - size -= 2; - offset = 2; - if (size > 0) - while (size--) - aopPut(AOP(result),"a",offset++); - } -} + } else { + emitpcode(POC_ADDLW, popGetLit(i)); + genSkipc(&rFalseIfx); + + } + + if(ifx) ifx->generated = 1; + return; + } -/*-----------------------------------------------------------------*/ -/* genMult - generates code for multiplication */ -/*-----------------------------------------------------------------*/ -static void genMult (iCode *ic) -{ - operand *left = IC_LEFT(ic); - operand *right = IC_RIGHT(ic); - operand *result= IC_RESULT(ic); + /* chars are out of the way. now do ints and longs */ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); - /* special cases first */ - /* both are bits */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right)== AOP_CRY) { - genMultbits(left,right,result); - goto release ; - } + DEBUGpic14_emitcode(";right lit","line = %d",__LINE__); + + /* special cases */ - /* if both are of size == 1 */ - if (AOP_SIZE(left) == 1 && - AOP_SIZE(right) == 1 ) { - genMultOneByte(left,right,result); - goto release ; - } + if(sign) { - /* should have been converted to function call */ - assert(1) ; + if(lit == 0) { + genSkipCond(&rFalseIfx,left,size,7); + if(ifx) ifx->generated = 1; + return; + } -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} + if(lit <0x100) { + DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); -/*-----------------------------------------------------------------*/ -/* genDivbits :- division of bits */ -/*-----------------------------------------------------------------*/ -static void genDivbits (operand *left, - operand *right, - operand *result) -{ + //rFalseIfx.condition ^= 1; + //genSkipCond(&rFalseIfx,left,size,7); + //rFalseIfx.condition ^= 1; - char *l; + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0)); + if(rFalseIfx.condition) + emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); + else + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* the result must be bit */ - emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); - l = aopGet(AOP(left),0,FALSE,FALSE); + emitpcode(POC_MOVLW, popGetLit(0x100-lit)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); + emitpcode(POC_MOVFW, popGet(AOP(left),1)); - MOVA(l); + while(size > 1) + emitpcode(POC_IORFW, popGet(AOP(left),size--)); - emitcode("div","ab"); - emitcode("rrc","a"); - aopPut(AOP(result),"c",0); -} + if(rFalseIfx.condition) { + emitSKPZ; + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); -/*-----------------------------------------------------------------*/ -/* genDivOneByte : 8 bit division */ -/*-----------------------------------------------------------------*/ -static void genDivOneByte (operand *left, - operand *right, - operand *result) -{ - sym_link *opetype = operandType(result); - char *l ; - symbol *lbl ; - int size,offset; + } else { + emitSKPNZ; + } - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - size = AOP_SIZE(result) - 1; - offset = 1; - /* signed or unsigned */ - if (SPEC_USIGN(opetype)) { - /* unsigned is easy */ - emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE)); - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("div","ab"); - aopPut(AOP(result),"a",0); - while (size--) - aopPut(AOP(result),zero,offset++); - return ; - } + genSkipc(&rFalseIfx); + emitpLabel(truelbl->key); + if(ifx) ifx->generated = 1; + return; - /* signed is a little bit more difficult */ + } - /* save the signs of the operands */ - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE)); - emitcode("push","acc"); /* save it on the stack */ + if(size == 1) { - /* now sign adjust for both left & right */ - l = aopGet(AOP(right),0,FALSE,FALSE); - MOVA(l); - lbl = newiTempLabel(NULL); - emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100)); - emitcode("cpl","a"); - emitcode("inc","a"); - emitcode("","%05d_DS_:",(lbl->key+100)); - emitcode("mov","b,a"); + if( (lit & 0xff) == 0) { + /* lower byte is zero */ + DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); + i = ((lit >> 8) & 0xff) ^0x80; + emitpcode(POC_MOVFW, popGet(AOP(left),size)); + emitpcode(POC_ADDLW, popGetLit( 0x80)); + emitpcode(POC_ADDLW, popGetLit(0x100-i)); + genSkipc(&rFalseIfx); - /* sign adjust left side */ - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - lbl = newiTempLabel(NULL); - emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100)); - emitcode("cpl","a"); - emitcode("inc","a"); - emitcode("","%05d_DS_:",(lbl->key+100)); + if(ifx) ifx->generated = 1; + return; - /* now the division */ - emitcode("div","ab"); - /* we are interested in the lower order - only */ - emitcode("mov","b,a"); - lbl = newiTempLabel(NULL); - emitcode("pop","acc"); - /* if there was an over flow we don't - adjust the sign of the result */ - emitcode("jb","ov,%05d_DS_",(lbl->key+100)); - emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100)); - CLRC; - emitcode("clr","a"); - emitcode("subb","a,b"); - emitcode("mov","b,a"); - emitcode("","%05d_DS_:",(lbl->key+100)); + } + } else { + /* Special cases for signed longs */ + if( (lit & 0xffffff) == 0) { + /* lower byte is zero */ + DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); + i = ((lit >> 8*3) & 0xff) ^0x80; + emitpcode(POC_MOVFW, popGet(AOP(left),size)); + emitpcode(POC_ADDLW, popGetLit( 0x80)); + emitpcode(POC_ADDLW, popGetLit(0x100-i)); + genSkipc(&rFalseIfx); - /* now we are done */ - aopPut(AOP(result),"b",0); - if(size > 0){ - emitcode("mov","c,b.7"); - emitcode("subb","a,acc"); - } - while (size--) - aopPut(AOP(result),"a",offset++); -} + if(ifx) ifx->generated = 1; + return; -/*-----------------------------------------------------------------*/ -/* genDiv - generates code for division */ -/*-----------------------------------------------------------------*/ -static void genDiv (iCode *ic) -{ - operand *left = IC_LEFT(ic); - operand *right = IC_RIGHT(ic); - operand *result= IC_RESULT(ic); + } - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); + } - /* special cases first */ - /* both are bits */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right)== AOP_CRY) { - genDivbits(left,right,result); - goto release ; - } - /* if both are of size == 1 */ - if (AOP_SIZE(left) == 1 && - AOP_SIZE(right) == 1 ) { - genDivOneByte(left,right,result); - goto release ; - } + if(lit & (0x80 << (size*8))) { + /* lit is negative */ + DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); - /* should have been converted to function call */ - assert(1); -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} + //genSkipCond(&rFalseIfx,left,size,7); -/*-----------------------------------------------------------------*/ -/* genModbits :- modulus of bits */ -/*-----------------------------------------------------------------*/ -static void genModbits (operand *left, - operand *right, - operand *result) -{ + emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0)); - char *l; + if(rFalseIfx.condition) + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); + else + emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); - /* the result must be bit */ - emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); + } else { + /* lit is positive */ + DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0)); + if(rFalseIfx.condition) + emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); + else + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - emitcode("div","ab"); - emitcode("mov","a,b"); - emitcode("rrc","a"); - aopPut(AOP(result),"c",0); -} + //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0)); + //emitpcode(POC_GOTO, popGetLabel(truelbl->key)); + //rFalseIfx.condition ^= 1; + //genSkipCond(&rFalseIfx,left,size,7); + //rFalseIfx.condition ^= 1; + } -/*-----------------------------------------------------------------*/ -/* genModOneByte : 8 bit modulus */ -/*-----------------------------------------------------------------*/ -static void genModOneByte (operand *left, - operand *right, - operand *result) -{ - sym_link *opetype = operandType(result); - char *l ; - symbol *lbl ; + /* + This works, but is only good for ints. + It also requires a "known zero" register. + emitpcode(POC_MOVLW, popGetLit(mlit & 0xff)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); + emitpcode(POC_RLFW, popCopyReg(&pc_kzero)); + emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff))); + emitpcode(POC_ADDFW, popGet(AOP(left),1)); + genSkipc(&rFalseIfx); + + emitpLabel(truelbl->key); + if(ifx) ifx->generated = 1; + return; + **/ + + /* There are no more special cases, so perform a general compare */ + + emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff)); + emitpcode(POC_SUBFW, popGet(AOP(left),size)); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* signed or unsigned */ - if (SPEC_USIGN(opetype)) { - /* unsigned is easy */ - emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE)); - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("div","ab"); - aopPut(AOP(result),"b",0); - return ; - } + while(size--) { - /* signed is a little bit more difficult */ + emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff)); + emitSKPNZ; + emitpcode(POC_SUBFW, popGet(AOP(left),size)); + } + //rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); - /* save the signs of the operands */ - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); + emitpLabel(truelbl->key); - emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE)); - emitcode("push","acc"); /* save it on the stack */ + if(ifx) ifx->generated = 1; + return; - /* now sign adjust for both left & right */ - l = aopGet(AOP(right),0,FALSE,FALSE); - MOVA(l); - lbl = newiTempLabel(NULL); - emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100)); - emitcode("cpl","a"); - emitcode("inc","a"); - emitcode("","%05d_DS_:",(lbl->key+100)); - emitcode("mov","b,a"); + } - /* sign adjust left side */ - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - lbl = newiTempLabel(NULL); - emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100)); - emitcode("cpl","a"); - emitcode("inc","a"); - emitcode("","%05d_DS_:",(lbl->key+100)); + /* sign is out of the way. So now do an unsigned compare */ + DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit); - /* now the multiplication */ - emitcode("div","ab"); - /* we are interested in the lower order - only */ - lbl = newiTempLabel(NULL); - emitcode("pop","acc"); - /* if there was an over flow we don't - adjust the sign of the result */ - emitcode("jb","ov,%05d_DS_",(lbl->key+100)); - emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100)); - CLRC ; - emitcode("clr","a"); - emitcode("subb","a,b"); - emitcode("mov","b,a"); - emitcode("","%05d_DS_:",(lbl->key+100)); - /* now we are done */ - aopPut(AOP(result),"b",0); + //genChkZeroes(left) -} + /* General case - compare to an unsigned literal on the right.*/ -/*-----------------------------------------------------------------*/ -/* genMod - generates code for division */ -/*-----------------------------------------------------------------*/ -static void genMod (iCode *ic) -{ - operand *left = IC_LEFT(ic); - operand *right = IC_RIGHT(ic); - operand *result= IC_RESULT(ic); + i = (lit >> (size*8)) & 0xff; + emitpcode(POC_MOVLW, popGetLit(i)); + emitpcode(POC_SUBFW, popGet(AOP(left),size)); + while(size--) { + i = (lit >> (size*8)) & 0xff; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); + if(i) { + emitpcode(POC_MOVLW, popGetLit(i)); + emitSKPNZ; + emitpcode(POC_SUBFW, popGet(AOP(left),size)); + } else { + /* this byte of the lit is zero, + *if it's not the last then OR in the variable */ + if(size) + emitpcode(POC_IORFW, popGet(AOP(left),size)); + } + } - /* special cases first */ - /* both are bits */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right)== AOP_CRY) { - genModbits(left,right,result); - goto release ; - } - /* if both are of size == 1 */ - if (AOP_SIZE(left) == 1 && - AOP_SIZE(right) == 1 ) { - genModOneByte(left,right,result); - goto release ; - } + emitpLabel(lbl->key); + //if(emitFinalCheck) + genSkipc(&rFalseIfx); + if(sign) + emitpLabel(truelbl->key); - /* should have been converted to function call */ - assert(1); + if(ifx) ifx->generated = 1; + return; -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} -/*-----------------------------------------------------------------*/ -/* genIfxJump :- will create a jump depending on the ifx */ -/*-----------------------------------------------------------------*/ -static void genIfxJump (iCode *ic, char *jval) -{ + } - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if true label then we jump if condition - supplied is true */ - if ( IC_TRUE(ic) ) { + if(AOP_TYPE(left) == AOP_LIT) { + //symbol *lbl = newiTempLabel(NULL); - if(strcmp(jval,"a") == 0) - emitSKPZ; - else if (strcmp(jval,"c") == 0) - emitSKPC; - else { - //pCodeOp *p = popGetWithString(jval); - //p->type = PO_BIT; - //emitpcode(POC_BTFSC, p); - emitpcode(POC_BTFSC, newpCodeOpBit(jval,0)); - //emitcode("btfsc","(%s >> 3),(%s & 7)",jval,jval); - } + lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit)); - emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key)); - emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset); - } - else { - /* false label is present */ - if(strcmp(jval,"a") == 0) - emitSKPNZ; - else if (strcmp(jval,"c") == 0) - emitSKPNC; - else { - //pCodeOp *p = popGetWithString(jval); - //p->type = PO_BIT; - //emitpcode(POC_BTFSS, p); - emitpcode(POC_BTFSS, newpCodeOpBit(jval,0)); + DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign); + + /* Special cases */ + if((lit == 0) && (sign == 0)){ + + size--; + emitpcode(POC_MOVFW, popGet(AOP(right),size)); + while(size) + emitpcode(POC_IORFW, popGet(AOP(right),--size)); - // emitcode("btfss","(%s >> 3),(%s & 7)",jval,jval); + //rFalseIfx.condition ^= 1; + genSkipz2(&rFalseIfx); + if(ifx) ifx->generated = 1; + return; } - emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key)); - emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset); + if(size==1) { + /* Special cases */ + lit &= 0xff; + if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) { + /* degenerate compare can never be true */ + if(rFalseIfx.condition == 0) + emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key)); - } + if(ifx) ifx->generated = 1; + return; + } + if(sign) { + if((lit+1)&0xff) { + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + emitpcode(POC_ADDLW, popGetLit(0x80)); + emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80)); + rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); + } else { + rFalseIfx.condition ^= 1; + genSkipCond(&rFalseIfx,right,0,7); + } + + } else { + if(lit & 0xff) { + emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff)); + emitpcode(POC_SUBFW, popGet(AOP(right),0)); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); + } else { + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + genSkipz2(&rFalseIfx); + } + } - /* mark the icode as generated */ - ic->generated = 1; -} + if(ifx) ifx->generated = 1; + return; -/*-----------------------------------------------------------------*/ -/* genSkip */ -/*-----------------------------------------------------------------*/ -static void genSkip(iCode *ifx,int status_bit) -{ - if(!ifx) - return; + } else { - if ( IC_TRUE(ifx) ) { - switch(status_bit) { - case 'z': - emitSKPNZ; - break; + /* Size is greater than 1 */ - case 'c': - emitSKPNC; - break; - case 'd': - emitcode("skpndc",""); - break; - } + if(sign) { + int lp1 = lit+1; - emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); - emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); + size--; - } else { + if(lp1 == 0) { + /* this means lit = 0xffffffff, or -1 */ - switch(status_bit) { - case 'z': - emitSKPZ; - break; + DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__); + rFalseIfx.condition ^= 1; + genSkipCond(&rFalseIfx,right,size,7); + if(ifx) ifx->generated = 1; + return; + } - case 'c': - emitSKPC; - break; + if(lit == 0) { + int s = size; - case 'd': - emitcode("skpdc",""); - break; - } - emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key)); - emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); + if(rFalseIfx.condition) { + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); + } - } + emitpcode(POC_MOVFW, popGet(AOP(right),size)); + while(size--) + emitpcode(POC_IORFW, popGet(AOP(right),size)); -} -/*-----------------------------------------------------------------*/ -/* genSkipc */ -/*-----------------------------------------------------------------*/ -static void genSkipc(iCode *ifx, int condition) -{ - if(!ifx) - return; + emitSKPZ; + if(rFalseIfx.condition) { + emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); + emitpLabel(truelbl->key); + }else { + rFalseIfx.condition ^= 1; + genSkipCond(&rFalseIfx,right,s,7); + } - if(condition) - emitSKPNC; - else - emitSKPC; + if(ifx) ifx->generated = 1; + return; + } - if ( IC_TRUE(ifx) ) - emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); - else - emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key)); - if ( IC_TRUE(ifx) ) - emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); - else - emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); + if(lit & (0x80 << (size*8))) { + /* Lit is less than zero */ + DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit); + //rFalseIfx.condition ^= 1; + //genSkipCond(&rFalseIfx,left,size,7); + //rFalseIfx.condition ^= 1; + emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); + //emitpcode(POC_GOTO, popGetLabel(truelbl->key)); -} + if(rFalseIfx.condition) + emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); + else + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); -/*-----------------------------------------------------------------*/ -/* genSkipz */ -/*-----------------------------------------------------------------*/ -static void genSkipz(iCode *ifx, int condition) -{ - if(!ifx) - return; - if(condition) - emitSKPNZ; - else - emitSKPZ; + } else { + /* Lit is greater than or equal to zero */ + DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit); + //rFalseIfx.condition ^= 1; + //genSkipCond(&rFalseIfx,right,size,7); + //rFalseIfx.condition ^= 1; - if ( IC_TRUE(ifx) ) - emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); - else - emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key)); + //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); + //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); - if ( IC_TRUE(ifx) ) - emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); - else - emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); + if(rFalseIfx.condition) + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); + else + emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); -} -/*-----------------------------------------------------------------*/ -/* genCmp :- greater or less than comparison */ -/*-----------------------------------------------------------------*/ -static void genCmp (operand *left,operand *right, - operand *result, iCode *ifx, int sign) -{ - int size, offset = 0 ; - unsigned long lit = 0L,i = 0; + } + emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff)); + emitpcode(POC_SUBFW, popGet(AOP(right),size)); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if left & right are bit variables */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right) == AOP_CRY ) { - emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir); - } else { - /* subtract right from left if at the - end the carry flag is set then we know that - left is greater than right */ - size = max(AOP_SIZE(left),AOP_SIZE(right)); + while(size--) { - /* if unsigned char cmp with lit, do cjne left,#right,zz */ - if((size == 1) && !sign && - (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){ - symbol *lbl = newiTempLabel(NULL); - emitcode("cjne","%s,%s,%05d_DS_", - aopGet(AOP(left),offset,FALSE,FALSE), - aopGet(AOP(right),offset,FALSE,FALSE), - lbl->key+100); - emitcode("","%05d_DS_:",lbl->key+100); - } else { + emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff)); + emitSKPNZ; + emitpcode(POC_SUBFW, popGet(AOP(right),size)); + } + rFalseIfx.condition ^= 1; + //rFalseIfx.condition = 1; + genSkipc(&rFalseIfx); - if(AOP_TYPE(right) == AOP_LIT) { + emitpLabel(truelbl->key); - DEBUGemitcode(";right lit","%d",sign); + if(ifx) ifx->generated = 1; + return; - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - //default: - while(size--) { - i = (lit >> (size*8)) & 0xff; - if(i == 0) { - emitpcode(POC_MOVFW, popGet(AOP(left),size,FALSE,FALSE)); - emitcode("movf","%s,w",aopGet(AOP(left),size,FALSE,FALSE)); - genSkipz(ifx,IC_TRUE(ifx) == NULL); } else { - emitpcode(POC_MOVLW, popGetLit(i)); - emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE)); + /* Unsigned compare for sizes greater than 1 */ - emitcode("movlw","0x%x",i); - emitcode("subwf","%s,w",aopGet(AOP(left),size,FALSE,FALSE)); - genSkipc(ifx,IC_TRUE(ifx) == NULL); - } + while(size--) { + i = (lit >> (size*8)) & 0xff; - } - ifx->generated = 1; - return; - } - if(AOP_TYPE(left) == AOP_LIT) { - DEBUGemitcode(";left lit","%d",sign); + if(size) { + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + emitpcode(POC_MOVLW, popGetLit(i&0xff)); + emitpcode(POC_SUBFW, popGet(AOP(right),size)); + emitSKPZ; + emitpcode(POC_GOTO, popGetLabel(lbl->key)); + } else { + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + emitpcode(POC_MOVLW, popGetLit((i+1)&0xff)); + emitpcode(POC_SUBFW, popGet(AOP(right),size)); - lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit))+1; + } + } - //default: - while(size--) { - i = (lit >> (size*8)) & 0xff; - if(i == 0) { - emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE)); - emitcode("movf","%s,w",aopGet(AOP(right),size,FALSE,FALSE)); - genSkipz(ifx,IC_TRUE(ifx) != NULL); - } else if( i == 1 ) { - emitpcode(POC_DECFW, popGet(AOP(right),size,FALSE,FALSE)); - emitcode("decf","%s,w",aopGet(AOP(right),size,FALSE,FALSE)); - genSkipz(ifx,IC_TRUE(ifx) != NULL); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - } else { - emitpcode(POC_MOVLW, popGetLit(i)); - emitpcode(POC_SUBFW, popGet(AOP(right),size,FALSE,FALSE)); + emitpLabel(lbl->key); + + rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); - emitcode("movlw","0x%x",i); - emitcode("subwf","%s,w",aopGet(AOP(right),size,FALSE,FALSE)); - genSkipc(ifx,IC_TRUE(ifx) != NULL); } - } - ifx->generated = 1; + if(sign) + emitpLabel(truelbl->key); + if(ifx) ifx->generated = 1; return; + } } + /* Compare two variables */ + + DEBUGpic14_emitcode(";sign","%d",sign); + + size--; + if(sign) { + /* Sigh. thus sucks... */ + if(size) { + emitpcode(POC_MOVFW, popGet(AOP(left),size)); + emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr)); + emitpcode(POC_MOVLW, popGetLit(0x80)); + emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr)); + emitpcode(POC_XORFW, popGet(AOP(right),size)); + emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr)); + } else { + /* Signed char comparison */ + /* Special thanks to Nikolai Golovchenko for this snippet */ + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + emitpcode(POC_SUBFW, popGet(AOP(left),0)); + emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */ + emitpcode(POC_XORFW, popGet(AOP(left),0)); + emitpcode(POC_XORFW, popGet(AOP(right),0)); + emitpcode(POC_ADDLW, popGetLit(0x80)); + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + genSkipc(&rFalseIfx); + + if(ifx) ifx->generated = 1; + return; + } + } else { - // CLRC; - DEBUGemitcode(";sign","%d",sign); + emitpcode(POC_MOVFW, popGet(AOP(right),size)); + emitpcode(POC_SUBFW, popGet(AOP(left),size)); + } - emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++ - emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE)); - emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE)); + /* The rest of the bytes of a multi-byte compare */ + while (size) { - size--; - while (size--) { + emitSKPZ; + emitpcode(POC_GOTO, popGetLabel(lbl->key)); + size--; + + emitpcode(POC_MOVFW, popGet(AOP(right),size)); + emitpcode(POC_SUBFW, popGet(AOP(left),size)); - emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE)); - emitSKPC; - emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE)); - emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE)); -/* - emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - emitSKPC; - emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); -*/ - offset++; } + + emitpLabel(lbl->key); + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + genSkipc(&rFalseIfx); + if(ifx) ifx->generated = 1; + return; + } } //release: if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) { - outBitC(result); + pic14_outBitC(result); } else { /* if the result is used in the next ifx conditional branch then generate @@ -4246,7 +4228,7 @@ static void genCmp (operand *left,operand *right, if (ifx ) genIfxJump (ifx,"c"); else - outBitC(result); + pic14_outBitC(result); /* leave the result in acc */ } @@ -4261,7 +4243,7 @@ static void genCmpGt (iCode *ic, iCode *ifx) sym_link *letype , *retype; int sign ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); left = IC_LEFT(ic); right= IC_RIGHT(ic); result = IC_RESULT(ic); @@ -4290,7 +4272,7 @@ static void genCmpLt (iCode *ic, iCode *ifx) sym_link *letype , *retype; int sign ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); left = IC_LEFT(ic); right= IC_RIGHT(ic); result = IC_RESULT(ic); @@ -4311,105 +4293,239 @@ static void genCmpLt (iCode *ic, iCode *ifx) freeAsmop(result,NULL,ic,TRUE); } +/*-----------------------------------------------------------------*/ +/* genc16bit2lit - compare a 16 bit value to a literal */ +/*-----------------------------------------------------------------*/ +static void genc16bit2lit(operand *op, int lit, int offset) +{ + int i; + + DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit); + if( (lit&0xff) == 0) + i=1; + else + i=0; + + switch( BYTEofLONG(lit,i)) { + case 0: + emitpcode(POC_MOVFW,popGet(AOP(op),offset+i)); + break; + case 1: + emitpcode(POC_DECFW,popGet(AOP(op),offset+i)); + break; + case 0xff: + emitpcode(POC_INCFW,popGet(AOP(op),offset+i)); + break; + default: + emitpcode(POC_MOVFW,popGet(AOP(op),offset+i)); + emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i))); + } + + i ^= 1; + + switch( BYTEofLONG(lit,i)) { + case 0: + emitpcode(POC_IORFW,popGet(AOP(op),offset+i)); + break; + case 1: + emitSKPNZ; + emitpcode(POC_DECFW,popGet(AOP(op),offset+i)); + break; + case 0xff: + emitSKPNZ; + emitpcode(POC_INCFW,popGet(AOP(op),offset+i)); + break; + default: + emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i))); + emitSKPNZ; + emitpcode(POC_XORFW,popGet(AOP(op),offset+i)); + + } + +} + /*-----------------------------------------------------------------*/ /* gencjneshort - compare and jump if not equal */ /*-----------------------------------------------------------------*/ -static void gencjneshort(operand *left, operand *right, symbol *lbl) +static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) { - int size = max(AOP_SIZE(left),AOP_SIZE(right)); - int offset = 0; - unsigned long lit = 0L; + int size = max(AOP_SIZE(left),AOP_SIZE(right)); + int offset = 0; + resolvedIfx rIfx; + symbol *lbl; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if the left side is a literal or - if the right is in a pointer register and left - is not */ - if ((AOP_TYPE(left) == AOP_LIT) || - (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) { - operand *t = right; - right = left; - left = t; + unsigned long lit = 0L; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_AopType(__LINE__,left,right,NULL); + + resolveIfx(&rIfx,ifx); + lbl = newiTempLabel(NULL); + + + /* if the left side is a literal or + if the right is in a pointer register and left + is not */ + if ((AOP_TYPE(left) == AOP_LIT) || + (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) { + operand *t = right; + right = left; + left = t; + } + if(AOP_TYPE(right) == AOP_LIT) + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + + /* if the right side is a literal then anything goes */ + if (AOP_TYPE(right) == AOP_LIT && + AOP_TYPE(left) != AOP_DIR ) { + switch(size) { + case 2: + genc16bit2lit(left, lit, 0); + emitSKPNZ; + emitpcode(POC_GOTO,popGetLabel(lbl->key)); + break; + default: + while (size--) { + if(lit & 0xff) { + emitpcode(POC_MOVFW,popGet(AOP(left),offset)); + emitpcode(POC_XORLW,popGetLit(lit & 0xff)); + } else { + emitpcode(POC_MOVF,popGet(AOP(left),offset)); + } + + emitSKPNZ; + emitpcode(POC_GOTO,popGetLabel(lbl->key)); + offset++; + lit >>= 8; + } + break; } - if(AOP_TYPE(right) == AOP_LIT) - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + } - /* if the right side is a literal then anything goes */ - if (AOP_TYPE(right) == AOP_LIT && - AOP_TYPE(left) != AOP_DIR ) { - while (size--) { - if(lit & 0xff) { - emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("xorlw","0x%x",lit & 0xff); - } else - emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE)); + /* if the right side is in a register or in direct space or + if the left is a pointer register & right is not */ + else if (AOP_TYPE(right) == AOP_REG || + AOP_TYPE(right) == AOP_DIR || + (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) || + (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) { + switch(size) { + case 2: + genc16bit2lit(left, lit, 0); + emitSKPNZ; + emitpcode(POC_GOTO,popGetLabel(lbl->key)); + break; + default: + while (size--) { + int emit_skip=1; + if((AOP_TYPE(left) == AOP_DIR) && + ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) { - emitSKPNZ; - emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset); - offset++; + emitpcode(POC_MOVFW,popGet(AOP(left),offset)); + emitpcode(POC_XORFW,popGet(AOP(right),offset)); + + } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){ + + switch (lit & 0xff) { + case 0: + emitpcode(POC_MOVFW,popGet(AOP(left),offset)); + break; + case 1: + emitpcode(POC_DECFSZ,popGet(AOP(left),offset)); + emitpcode(POC_GOTO,popGetLabel(lbl->key)); + emit_skip=0; + break; + case 0xff: + emitpcode(POC_INCFSZ,popGet(AOP(left),offset)); + emitpcode(POC_GOTO,popGetLabel(lbl->key)); + emit_skip=0; + break; + default: + emitpcode(POC_MOVFW,popGet(AOP(left),offset)); + emitpcode(POC_XORLW,popGetLit(lit & 0xff)); + } lit >>= 8; - } - } - /* if the right side is in a register or in direct space or - if the left is a pointer register & right is not */ - else if (AOP_TYPE(right) == AOP_REG || - AOP_TYPE(right) == AOP_DIR || - (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) || - (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) { - while (size--) { - if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) && - ( (lit & 0xff) != 0)) { - emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("xorlw","0x%x",lit & 0xff); - lit >>= 8; - } else - emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE)); + } else { + emitpcode(POC_MOVF,popGet(AOP(left),offset)); + } + if(emit_skip) { + if(AOP_TYPE(result) == AOP_CRY) { + pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__); + if(rIfx.condition) + emitSKPNZ; + else + emitSKPZ; + emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key)); + } else { + /* fix me. probably need to check result size too */ + emitpcode(POC_CLRF,popGet(AOP(result),0)); + if(rIfx.condition) + emitSKPNZ; + else + emitSKPZ; + emitpcode(POC_INCF,popGet(AOP(result),0)); + } + if(ifx) + ifx->generated=1; + } + emit_skip++; + offset++; + } + break; + } + } else if(AOP_TYPE(right) == AOP_REG && + AOP_TYPE(left) != AOP_DIR){ - emitSKPZ; - emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset); - offset++; -/* - MOVA(aopGet(AOP(left),offset,FALSE,FALSE)); - if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) && - ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0)) - emitcode("jnz","%05d_DS_",lbl->key+100); - else - emitcode("cjne","a,%s,%05d_DS_", - aopGet(AOP(right),offset,FALSE,TRUE), - lbl->key+100); - offset++; -*/ - } - } else { - /* right is a pointer reg need both a & b */ - while(size--) { - char *l = aopGet(AOP(left),offset,FALSE,FALSE); - if(strcmp(l,"b")) - emitcode("mov","b,%s",l); - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("cjne","a,b,%05d_DS_",lbl->key+100); - offset++; - } + while(size--) { + emitpcode(POC_MOVFW,popGet(AOP(left),offset)); + emitpcode(POC_XORFW,popGet(AOP(right),offset)); + pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__); + if(rIfx.condition) + emitSKPNZ; + else + emitSKPZ; + emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key)); + offset++; + } + + }else{ + /* right is a pointer reg need both a & b */ + while(size--) { + char *l = aopGet(AOP(left),offset,FALSE,FALSE); + if(strcmp(l,"b")) + pic14_emitcode("mov","b,%s",l); + MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100); + offset++; } + } + emitpLabel(lbl->key); + + if(ifx) + ifx->generated = 1; } +#if 0 /*-----------------------------------------------------------------*/ /* gencjne - compare and jump if not equal */ /*-----------------------------------------------------------------*/ -static void gencjne(operand *left, operand *right, symbol *lbl) +static void gencjne(operand *left, operand *right, iCode *ifx) { symbol *tlbl = newiTempLabel(NULL); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); gencjneshort(left, right, lbl); - emitcode("mov","a,%s",one); - emitcode("sjmp","%05d_DS_",tlbl->key+100); - emitcode("","%05d_DS_:",lbl->key+100); - emitcode("clr","a"); - emitcode("","%05d_DS_:",tlbl->key+100); -} + pic14_emitcode("mov","a,%s",one); + pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100); + pic14_emitcode("","%05d_DS_:",lbl->key+100); + pic14_emitcode("clr","a"); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + + emitpLabel(lbl->key); + emitpLabel(tlbl->key); +} +#endif /*-----------------------------------------------------------------*/ /* genCmpEq - generates code for equal to */ @@ -4420,11 +4536,12 @@ static void genCmpEq (iCode *ic, iCode *ifx) unsigned long lit = 0L; int size,offset=0; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(ifx) - DEBUGemitcode ("; ifx is non-null",""); + DEBUGpic14_emitcode ("; ifx is non-null",""); else - DEBUGemitcode ("; ifx is null",""); + DEBUGpic14_emitcode ("; ifx is null",""); aopOp((left=IC_LEFT(ic)),ic,FALSE); aopOp((right=IC_RIGHT(ic)),ic,FALSE); @@ -4432,241 +4549,168 @@ static void genCmpEq (iCode *ic, iCode *ifx) size = max(AOP_SIZE(left),AOP_SIZE(right)); + DEBUGpic14_AopType(__LINE__,left,right,result); + /* if literal, literal on the right or if the right is in a pointer register and left is not */ if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) { - operand *t = IC_RIGHT(ic); - IC_RIGHT(ic) = IC_LEFT(ic); - IC_LEFT(ic) = t; + operand *tmp = right ; + right = left; + left = tmp; } + if(ifx && !AOP_SIZE(result)){ symbol *tlbl; /* if they are both bit variables */ if (AOP_TYPE(left) == AOP_CRY && ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) { if(AOP_TYPE(right) == AOP_LIT){ - unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); + unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); if(lit == 0L){ - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("cpl","c"); + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + pic14_emitcode("cpl","c"); } else if(lit == 1L) { - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); } else { - emitcode("clr","c"); + pic14_emitcode("clr","c"); } /* AOP_TYPE(right) == AOP_CRY */ } else { symbol *lbl = newiTempLabel(NULL); - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100)); - emitcode("cpl","c"); - emitcode("","%05d_DS_:",(lbl->key+100)); + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100)); + pic14_emitcode("cpl","c"); + pic14_emitcode("","%05d_DS_:",(lbl->key+100)); } /* if true label then we jump if condition supplied is true */ tlbl = newiTempLabel(NULL); if ( IC_TRUE(ifx) ) { - emitcode("jnc","%05d_DS_",tlbl->key+100); - emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); + pic14_emitcode("jnc","%05d_DS_",tlbl->key+100); + pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); } else { - emitcode("jc","%05d_DS_",tlbl->key+100); - emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100); + pic14_emitcode("jc","%05d_DS_",tlbl->key+100); + pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100); } - emitcode("","%05d_DS_:",tlbl->key+100+labelOffset); + pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset); + + { + /* left and right are both bit variables, result is carry */ + resolvedIfx rIfx; + + resolveIfx(&rIfx,ifx); + + emitpcode(POC_MOVLW,popGet(AOP(left),0)); + emitpcode(POC_ANDFW,popGet(AOP(left),0)); + emitpcode(POC_BTFSC,popGet(AOP(right),0)); + emitpcode(POC_ANDLW,popGet(AOP(left),0)); + genSkipz2(&rIfx); + } } else { /* They're not both bit variables. Is the right a literal? */ if(AOP_TYPE(right) == AOP_LIT) { - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - while (size--) { - - if(size >= 1) { - int l = lit & 0xff; - int h = (lit>>8) & 0xff; - int optimized=0; - - /* Check special cases for integers */ - switch(lit & 0xffff) { - case 0x0000: - emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE)); - emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE)); - //emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - //emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE)); - genSkip(ifx,'z'); - optimized++; - break; - case 0x0001: - emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE)); - emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE)); - emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE)); - genSkip(ifx,'z'); - optimized++; - break; - case 0x0100: - emitpcode(POC_DECFW,popGet(AOP(left),offset+1,FALSE,FALSE)); - emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE)); - emitcode("decf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE)); - emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - genSkip(ifx,'z'); - optimized++; - break; - case 0x00ff: - emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE)); - emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE)); - emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE)); - genSkip(ifx,'z'); - optimized++; - break; - case 0xff00: - emitpcode(POC_INCFW,popGet(AOP(left),offset+1,FALSE,FALSE)); - emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE)); - emitcode("incf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE)); - emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - genSkip(ifx,'z'); - optimized++; - break; - default: - if(h == 0) { - emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE)); - emitpcode(POC_XORLW,popGetLit(l)); - emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE)); - - emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("xorlw","0x%x",l); - emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE)); - optimized++; - genSkip(ifx,'z'); - } else if (l == 0) { - emitpcode(POC_MOVFW,popGet(AOP(left),offset+1,FALSE,FALSE)); - emitpcode(POC_XORLW,popGetLit(h)); - emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE)); - - emitcode("movf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE)); - emitcode("xorlw","0x%x",h); - emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - optimized++; - genSkip(ifx,'z'); - } else { - emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE)); - emitpcode(POC_XORLW,popGetLit(l)); - emitpcode(POC_MOVLW,popGetLit(h)); - emitSKPZ; - emitpcode(POC_XORFW,popGet(AOP(left),offset+1,FALSE,FALSE)); -/* - emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("xorlw","0x%x",l); - emitcode("movlw","0x%x",h); - emitSKPZ; - emitcode("xorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE)); -*/ - optimized++; - genSkip(ifx,'z'); - } - - } - if(optimized) { - size--; - offset+=2; - lit>>=16; + + switch(size) { - continue; - } - - } - + case 1: switch(lit & 0xff) { case 1: if ( IC_TRUE(ifx) ) { - - emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - - emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_DECFW,popGet(AOP(left),offset)); emitSKPNZ; emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); - - emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); } else { - emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_DECFSZW,popGet(AOP(left),offset)); emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key)); - - emitcode("decfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); } break; case 0xff: if ( IC_TRUE(ifx) ) { - emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - - emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_INCFW,popGet(AOP(left),offset)); emitSKPNZ; emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); - - emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); } else { - emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_INCFSZW,popGet(AOP(left),offset)); emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key)); - - emitcode("incfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); } break; default: - emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE)); - //emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW,popGet(AOP(left),offset)); if(lit) emitpcode(POC_XORLW,popGetLit(lit & 0xff)); - //emitcode("xorlw","0x%x",lit & 0xff); genSkip(ifx,'z'); } - // emitcode("goto","_%05d_DS_",tlbl->key+100+labelOffset); - //emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset); - offset++; - lit >>= 8; + /* end of size == 1 */ + break; + + case 2: + genc16bit2lit(left,lit,offset); + genSkip(ifx,'z'); + break; + /* end of size == 2 */ + + default: + /* size is 4 */ + if(lit==0) { + emitpcode(POC_MOVFW,popGet(AOP(left),0)); + emitpcode(POC_IORFW,popGet(AOP(left),1)); + emitpcode(POC_IORFW,popGet(AOP(left),2)); + emitpcode(POC_IORFW,popGet(AOP(left),3)); + + } else { + + /* search for patterns that can be optimized */ + + genc16bit2lit(left,lit,0); + lit >>= 16; + if(lit) { + genSkipz(ifx,IC_TRUE(ifx) == NULL); + //genSkip(ifx,'z'); + genc16bit2lit(left,lit,2); + } else { + emitpcode(POC_IORFW,popGet(AOP(left),2)); + emitpcode(POC_IORFW,popGet(AOP(left),3)); + + } + + } + + genSkip(ifx,'z'); } + + ifx->generated = 1; + goto release ; + } else if(AOP_TYPE(right) == AOP_CRY ) { /* we know the left is not a bit, but that the right is */ - emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW,popGet(AOP(left),offset)); emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS), - popGet(AOP(right),offset,FALSE,FALSE)); + popGet(AOP(right),offset)); emitpcode(POC_XORLW,popGetLit(1)); - emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - if ( IC_TRUE(ifx) ) - emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(right)->aopu.aop_dir, - AOP(right)->aopu.aop_dir); - else - emitcode("btfss","(%s >> 3), (%s & 7)", - AOP(right)->aopu.aop_dir, - AOP(right)->aopu.aop_dir); - - emitcode("xorlw","1"); - /* if the two are equal, then W will be 0 and the Z bit is set * we could test Z now, or go ahead and check the high order bytes if * the variable we're comparing is larger than a byte. */ while(--size) - emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE)); - //emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_IORFW,popGet(AOP(left),offset)); if ( IC_TRUE(ifx) ) { emitSKPNZ; emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); - emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); + pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); } else { emitSKPZ; emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key)); - emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); + pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); } } else { @@ -4676,32 +4720,29 @@ static void genCmpEq (iCode *ic, iCode *ifx) tlbl = newiTempLabel(NULL); while(size--) { - emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE)); - emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE)); - - emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW,popGet(AOP(left),offset)); + emitpcode(POC_XORFW,popGet(AOP(right),offset)); if ( IC_TRUE(ifx) ) { if(size) { emitSKPZ; emitpcode(POC_GOTO,popGetLabel(tlbl->key)); - emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset); + pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset); } else { emitSKPNZ; emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); - emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); + pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); } } else { emitSKPZ; emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key)); - emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); + pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); } offset++; } if(s>1 && IC_TRUE(ifx)) { - emitpLabel(tlbl->key+100+labelOffset); - emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset); + emitpLabel(tlbl->key); + pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset); } } } @@ -4714,26 +4755,26 @@ static void genCmpEq (iCode *ic, iCode *ifx) if (AOP_TYPE(left) == AOP_CRY && ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) { if(AOP_TYPE(right) == AOP_LIT){ - unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); + unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); if(lit == 0L){ - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("cpl","c"); + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + pic14_emitcode("cpl","c"); } else if(lit == 1L) { - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); } else { - emitcode("clr","c"); + pic14_emitcode("clr","c"); } /* AOP_TYPE(right) == AOP_CRY */ } else { symbol *lbl = newiTempLabel(NULL); - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100)); - emitcode("cpl","c"); - emitcode("","%05d_DS_:",(lbl->key+100)); + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100)); + pic14_emitcode("cpl","c"); + pic14_emitcode("","%05d_DS_:",(lbl->key+100)); } /* c = 1 if egal */ if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){ - outBitC(result); + pic14_outBitC(result); goto release ; } if (ifx) { @@ -4742,22 +4783,38 @@ static void genCmpEq (iCode *ic, iCode *ifx) } /* if the result is used in an arithmetic operation then put the result in place */ - outBitC(result); + pic14_outBitC(result); } else { - gencjne(left,right,newiTempLabel(NULL)); - if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) { - aopPut(AOP(result),"a",0); - goto release ; - } - if (ifx) { - genIfxJump (ifx,"a"); - goto release ; - } - /* if the result is used in an arithmetic operation - then put the result in place */ - if (AOP_TYPE(result) != AOP_CRY) - outAcc(result); - /* leave the result in acc */ + + gencjne(left,right,result,ifx); +/* + if(ifx) + gencjne(left,right,newiTempLabel(NULL)); + else { + if(IC_TRUE(ifx)->key) + gencjne(left,right,IC_TRUE(ifx)->key); + else + gencjne(left,right,IC_FALSE(ifx)->key); + ifx->generated = 1; + goto release ; + } + if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) { + aopPut(AOP(result),"a",0); + goto release ; + } + + if (ifx) { + genIfxJump (ifx,"a"); + goto release ; + } +*/ + /* if the result is used in an arithmetic operation + then put the result in place */ +/* + if (AOP_TYPE(result) != AOP_CRY) + pic14_outAcc(result); +*/ + /* leave the result in acc */ } release: @@ -4772,7 +4829,7 @@ release: static iCode *ifxForOp ( operand *op, iCode *ic ) { /* if true symbol then needs to be assigned */ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (IS_TRUE_SYMOP(op)) return NULL ; @@ -4785,6 +4842,28 @@ static iCode *ifxForOp ( operand *op, iCode *ic ) OP_SYMBOL(op)->liveTo <= ic->next->seq ) return ic->next; + if (ic->next && + ic->next->op == IFX && + IC_COND(ic->next)->key == op->key) { + DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__); + return ic->next; + } + + DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__); + if (ic->next && + ic->next->op == IFX) + DEBUGpic14_emitcode ("; ic-next"," is an IFX"); + + if (ic->next && + ic->next->op == IFX && + IC_COND(ic->next)->key == op->key) { + DEBUGpic14_emitcode ("; "," key is okay"); + DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d", + OP_SYMBOL(op)->liveTo, + ic->next->seq); + } + + return NULL; } /*-----------------------------------------------------------------*/ @@ -4795,7 +4874,7 @@ static void genAndOp (iCode *ic) operand *left,*right, *result; symbol *tlbl; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* note here that && operations that are in an if statement are taken away by backPatchLabels only those used in arthmetic operations remain */ @@ -4806,16 +4885,16 @@ static void genAndOp (iCode *ic) /* if both are bit variables */ if (AOP_TYPE(left) == AOP_CRY && AOP_TYPE(right) == AOP_CRY ) { - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); - outBitC(result); + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); + pic14_outBitC(result); } else { tlbl = newiTempLabel(NULL); - toBoolean(left); - emitcode("jz","%05d_DS_",tlbl->key+100); - toBoolean(right); - emitcode("","%05d_DS_:",tlbl->key+100); - outBitAcc(result); + pic14_toBoolean(left); + pic14_emitcode("jz","%05d_DS_",tlbl->key+100); + pic14_toBoolean(right); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_outBitAcc(result); } freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); @@ -4840,32 +4919,34 @@ static void genOrOp (iCode *ic) /* note here that || operations that are in an if statement are taken away by backPatchLabels only those used in arthmetic operations remain */ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp((left=IC_LEFT(ic)),ic,FALSE); aopOp((right=IC_RIGHT(ic)),ic,FALSE); aopOp((result=IC_RESULT(ic)),ic,FALSE); + DEBUGpic14_AopType(__LINE__,left,right,result); + /* if both are bit variables */ if (AOP_TYPE(left) == AOP_CRY && AOP_TYPE(right) == AOP_CRY ) { - emitcode("clrc",""); - emitcode("btfss","(%s >> 3), (%s & 7)", + pic14_emitcode("clrc",""); + pic14_emitcode("btfss","(%s >> 3), (%s & 7)", AOP(left)->aopu.aop_dir, AOP(left)->aopu.aop_dir); - emitcode("btfsc","(%s >> 3), (%s & 7)", + pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", AOP(right)->aopu.aop_dir, AOP(right)->aopu.aop_dir); - emitcode("setc",""); + pic14_emitcode("setc",""); } else { tlbl = newiTempLabel(NULL); - toBoolean(left); + pic14_toBoolean(left); emitSKPZ; - emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset); - toBoolean(right); - emitcode("","%05d_DS_:",tlbl->key+100+labelOffset); + pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset); + pic14_toBoolean(right); + pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset); - outBitAcc(result); + pic14_outBitAcc(result); } freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); @@ -4887,7 +4968,7 @@ static int isLiteralBit(unsigned long lit) 0x10000000L,0x20000000L,0x40000000L,0x80000000L}; int idx; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); for(idx = 0; idx < 32; idx++) if(lit == pw[idx]) return idx+1; @@ -4899,9 +4980,9 @@ static int isLiteralBit(unsigned long lit) /*-----------------------------------------------------------------*/ static void continueIfTrue (iCode *ic) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(IC_TRUE(ic)) - emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100); + pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100); ic->generated = 1; } @@ -4910,9 +4991,9 @@ static void continueIfTrue (iCode *ic) /*-----------------------------------------------------------------*/ static void jumpIfTrue (iCode *ic) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(!IC_TRUE(ic)) - emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); + pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); ic->generated = 1; } @@ -4922,17 +5003,17 @@ static void jumpIfTrue (iCode *ic) static void jmpTrueOrFalse (iCode *ic, symbol *tlbl) { // ugly but optimized by peephole - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(IC_TRUE(ic)){ symbol *nlbl = newiTempLabel(NULL); - emitcode("sjmp","%05d_DS_",nlbl->key+100); - emitcode("","%05d_DS_:",tlbl->key+100); - emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100); - emitcode("","%05d_DS_:",nlbl->key+100); + pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100); + pic14_emitcode("","%05d_DS_:",nlbl->key+100); } else{ - emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); - emitcode("","%05d_DS_:",tlbl->key+100); + pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); } ic->generated = 1; } @@ -4942,258 +5023,284 @@ static void jmpTrueOrFalse (iCode *ic, symbol *tlbl) /*-----------------------------------------------------------------*/ static void genAnd (iCode *ic, iCode *ifx) { - operand *left, *right, *result; - int size, offset=0; - unsigned long lit = 0L; - int bytelit = 0; - char buffer[10]; + operand *left, *right, *result; + int size, offset=0; + unsigned long lit = 0L; + int bytelit = 0; + resolvedIfx rIfx; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - aopOp((left = IC_LEFT(ic)),ic,FALSE); - aopOp((right= IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); -#ifdef DEBUG_TYPE - emitcode("","; Type res[%d] = l[%d]&r[%d]", - AOP_TYPE(result), - AOP_TYPE(left), AOP_TYPE(right)); - emitcode("","; Size res[%d] = l[%d]&r[%d]", - AOP_SIZE(result), - AOP_SIZE(left), AOP_SIZE(right)); -#endif + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + aopOp((left = IC_LEFT(ic)),ic,FALSE); + aopOp((right= IC_RIGHT(ic)),ic,FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE); - /* if left is a literal & right is not then exchange them */ - if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) || - AOP_NEEDSACC(left)) { - operand *tmp = right ; - right = left; - left = tmp; - } + resolveIfx(&rIfx,ifx); - /* if result = right then exchange them */ - if(sameRegs(AOP(result),AOP(right))){ - operand *tmp = right ; - right = left; - left = tmp; + /* if left is a literal & right is not then exchange them */ + if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) || + AOP_NEEDSACC(left)) { + operand *tmp = right ; + right = left; + left = tmp; + } + + /* if result = right then exchange them */ + if(pic14_sameRegs(AOP(result),AOP(right))){ + operand *tmp = right ; + right = left; + left = tmp; + } + + /* if right is bit then exchange them */ + if (AOP_TYPE(right) == AOP_CRY && + AOP_TYPE(left) != AOP_CRY){ + operand *tmp = right ; + right = left; + left = tmp; + } + if(AOP_TYPE(right) == AOP_LIT) + lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit); + + size = AOP_SIZE(result); + + DEBUGpic14_AopType(__LINE__,left,right,result); + + // if(bit & yy) + // result = bit & yy; + if (AOP_TYPE(left) == AOP_CRY){ + // c = bit & literal; + if(AOP_TYPE(right) == AOP_LIT){ + if(lit & 1) { + if(size && pic14_sameRegs(AOP(result),AOP(left))) + // no change + goto release; + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + } else { + // bit(result) = 0; + if(size && (AOP_TYPE(result) == AOP_CRY)){ + pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir); + goto release; + } + if((AOP_TYPE(result) == AOP_CRY) && ifx){ + jumpIfTrue(ifx); + goto release; + } + pic14_emitcode("clr","c"); + } + } else { + if (AOP_TYPE(right) == AOP_CRY){ + // c = bit & bit; + pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); + pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir); + } else { + // c = bit & val; + MOVA(aopGet(AOP(right),0,FALSE,FALSE)); + // c = lsb + pic14_emitcode("rrc","a"); + pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir); + } } + // bit = c + // val = c + if(size) + pic14_outBitC(result); + // if(bit & ...) + else if((AOP_TYPE(result) == AOP_CRY) && ifx) + genIfxJump(ifx, "c"); + goto release ; + } - /* if right is bit then exchange them */ - if (AOP_TYPE(right) == AOP_CRY && - AOP_TYPE(left) != AOP_CRY){ - operand *tmp = right ; - right = left; - left = tmp; + // if(val & 0xZZ) - size = 0, ifx != FALSE - + // bit = val & 0xZZ - size = 1, ifx = FALSE - + if((AOP_TYPE(right) == AOP_LIT) && + (AOP_TYPE(result) == AOP_CRY) && + (AOP_TYPE(left) != AOP_CRY)){ + int posbit = isLiteralBit(lit); + /* left & 2^n */ + if(posbit){ + posbit--; + //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE)); + // bit = left & 2^n + if(size) + pic14_emitcode("mov","c,acc.%d",posbit&0x07); + // if(left & 2^n) + else{ + if(ifx){ +/* + if(IC_TRUE(ifx)) { + emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0)); + emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key)); + } else { + emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0)); + emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key)); + } +*/ + emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS), + newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0)); + emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key)); + + ifx->generated = 1; + } + goto release; + } + } else { + symbol *tlbl = newiTempLabel(NULL); + int sizel = AOP_SIZE(left); + if(size) + pic14_emitcode("setb","c"); + while(sizel--){ + if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){ + MOVA( aopGet(AOP(left),offset,FALSE,FALSE)); + // byte == 2^n ? + if((posbit = isLiteralBit(bytelit)) != 0) + pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100); + else{ + if(bytelit != 0x0FFL) + pic14_emitcode("anl","a,%s", + aopGet(AOP(right),offset,FALSE,TRUE)); + pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); + } + } + offset++; + } + // bit = left & literal + if(size){ + pic14_emitcode("clr","c"); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + } + // if(left & literal) + else{ + if(ifx) + jmpTrueOrFalse(ifx, tlbl); + goto release ; + } } - if(AOP_TYPE(right) == AOP_LIT) - lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit); + pic14_outBitC(result); + goto release ; + } - size = AOP_SIZE(result); + /* if left is same as result */ + if(pic14_sameRegs(AOP(result),AOP(left))){ + int know_W = -1; + for(;size--; offset++,lit>>=8) { + if(AOP_TYPE(right) == AOP_LIT){ + switch(lit & 0xff) { + case 0x00: + /* and'ing with 0 has clears the result */ + pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_CLRF,popGet(AOP(result),offset)); + break; + case 0xff: + /* and'ing with 0xff is a nop when the result and left are the same */ + break; - // if(bit & yy) - // result = bit & yy; - if (AOP_TYPE(left) == AOP_CRY){ - // c = bit & literal; - if(AOP_TYPE(right) == AOP_LIT){ - if(lit & 1) { - if(size && sameRegs(AOP(result),AOP(left))) - // no change - goto release; - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - } else { - // bit(result) = 0; - if(size && (AOP_TYPE(result) == AOP_CRY)){ - emitcode("clr","%s",AOP(result)->aopu.aop_dir); - goto release; - } - if((AOP_TYPE(result) == AOP_CRY) && ifx){ - jumpIfTrue(ifx); - goto release; - } - emitcode("clr","c"); - } - } else { - if (AOP_TYPE(right) == AOP_CRY){ - // c = bit & bit; - emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - emitcode("anl","c,%s",AOP(left)->aopu.aop_dir); - } else { - // c = bit & val; - MOVA(aopGet(AOP(right),0,FALSE,FALSE)); - // c = lsb - emitcode("rrc","a"); - emitcode("anl","c,%s",AOP(left)->aopu.aop_dir); - } - } - // bit = c - // val = c - if(size) - outBitC(result); - // if(bit & ...) - else if((AOP_TYPE(result) == AOP_CRY) && ifx) - genIfxJump(ifx, "c"); - goto release ; - } + default: + { + int p = my_powof2( (~lit) & 0xff ); + if(p>=0) { + /* only one bit is set in the literal, so use a bcf instruction */ + pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p); + emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0)); - // if(val & 0xZZ) - size = 0, ifx != FALSE - - // bit = val & 0xZZ - size = 1, ifx = FALSE - - if((AOP_TYPE(right) == AOP_LIT) && - (AOP_TYPE(result) == AOP_CRY) && - (AOP_TYPE(left) != AOP_CRY)){ - int posbit = isLiteralBit(lit); - /* left & 2^n */ - if(posbit){ - posbit--; - MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE)); - // bit = left & 2^n - if(size) - emitcode("mov","c,acc.%d",posbit&0x07); - // if(left & 2^n) - else{ - if(ifx){ - sprintf(buffer,"acc.%d",posbit&0x07); - genIfxJump(ifx, buffer); - } - goto release; - } - } else { - symbol *tlbl = newiTempLabel(NULL); - int sizel = AOP_SIZE(left); - if(size) - emitcode("setb","c"); - while(sizel--){ - if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){ - MOVA( aopGet(AOP(left),offset,FALSE,FALSE)); - // byte == 2^n ? - if((posbit = isLiteralBit(bytelit)) != 0) - emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100); - else{ - if(bytelit != 0x0FFL) - emitcode("anl","a,%s", - aopGet(AOP(right),offset,FALSE,TRUE)); - emitcode("jnz","%05d_DS_",tlbl->key+100); - } - } - offset++; - } - // bit = left & literal - if(size){ - emitcode("clr","c"); - emitcode("","%05d_DS_:",tlbl->key+100); - } - // if(left & literal) - else{ - if(ifx) - jmpTrueOrFalse(ifx, tlbl); - goto release ; - } - } - outBitC(result); - goto release ; + } else { + pic14_emitcode("movlw","0x%x", (lit & 0xff)); + pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE)); + if(know_W != (lit&0xff)) + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + know_W = lit &0xff; + emitpcode(POC_ANDWF,popGet(AOP(left),offset)); + } + } + } + } else { + if (AOP_TYPE(left) == AOP_ACC) { + emitpcode(POC_ANDFW,popGet(AOP(right),offset)); + } else { + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_ANDWF,popGet(AOP(left),offset)); + + } + } } - /* if left is same as result */ - if(sameRegs(AOP(result),AOP(left))){ - for(;size--; offset++,lit>>=8) { + } else { + // left & result in different registers + if(AOP_TYPE(result) == AOP_CRY){ + // result = bit + // if(size), result in bit + // if(!size && ifx), conditional oper: if(left & right) + symbol *tlbl = newiTempLabel(NULL); + int sizer = min(AOP_SIZE(left),AOP_SIZE(right)); + if(size) + pic14_emitcode("setb","c"); + while(sizer--){ + MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode("anl","a,%s", + aopGet(AOP(left),offset,FALSE,FALSE)); + pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); + offset++; + } + if(size){ + CLRC; + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_outBitC(result); + } else if(ifx) + jmpTrueOrFalse(ifx, tlbl); + } else { + for(;(size--);offset++) { + // normal case + // result = left & right if(AOP_TYPE(right) == AOP_LIT){ - switch(lit & 0xff) { + int t = (lit >> (offset*8)) & 0x0FFL; + switch(t) { case 0x00: - /* and'ing with 0 has clears the result */ - emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); + pic14_emitcode("clrf","%s", + aopGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_CLRF,popGet(AOP(result),offset)); break; case 0xff: - emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode("movf","%s,w", + aopGet(AOP(left),offset,FALSE,FALSE)); + pic14_emitcode("movwf","%s", + aopGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); break; - default: - { - int p = my_powof2( (~lit) & 0xff ); - if(p>=0) { - /* only one bit is set in the literal, so use a bcf instruction */ - emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p); - } else { - emitcode("movlw","0x%x", (lit & 0xff)); - emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p); - } - } - } - } else { - if (AOP_TYPE(left) == AOP_ACC) - emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - else { - emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE)); - + pic14_emitcode("movlw","0x%x",t); + pic14_emitcode("andwf","%s,w", + aopGet(AOP(left),offset,FALSE,FALSE)); + pic14_emitcode("movwf","%s", + aopGet(AOP(result),offset,FALSE,FALSE)); + + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_ANDFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); } + continue; } - } - } else { - // left & result in different registers - if(AOP_TYPE(result) == AOP_CRY){ - // result = bit - // if(size), result in bit - // if(!size && ifx), conditional oper: if(left & right) - symbol *tlbl = newiTempLabel(NULL); - int sizer = min(AOP_SIZE(left),AOP_SIZE(right)); - if(size) - emitcode("setb","c"); - while(sizer--){ - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("anl","a,%s", - aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("jnz","%05d_DS_",tlbl->key+100); - offset++; - } - if(size){ - CLRC; - emitcode("","%05d_DS_:",tlbl->key+100); - outBitC(result); - } else if(ifx) - jmpTrueOrFalse(ifx, tlbl); - } else { - for(;(size--);offset++) { - // normal case - // result = left & right - if(AOP_TYPE(right) == AOP_LIT){ - int t = (lit >> (offset*8)) & 0x0FFL; - switch(t) { - case 0x00: - emitcode("clrf","%s", - aopGet(AOP(result),offset,FALSE,FALSE)); - break; - case 0xff: - emitcode("movf","%s,w", - aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("movwf","%s", - aopGet(AOP(result),offset,FALSE,FALSE)); - break; - default: - emitcode("movlw","0x%x",t); - emitcode("andwf","%s,w", + if (AOP_TYPE(left) == AOP_ACC) { + pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + emitpcode(POC_ANDFW,popGet(AOP(right),offset)); + } else { + pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode("andwf","%s,w", aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("movwf","%s", - aopGet(AOP(result),offset,FALSE,FALSE)); - - } - continue; - } - - if (AOP_TYPE(left) == AOP_ACC) - emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - else { - emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("andwf","%s,w", - aopGet(AOP(left),offset,FALSE,FALSE)); - } - emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); - } + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_ANDFW,popGet(AOP(left),offset)); } + pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + } } + } -release : + release : freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -5205,12 +5312,13 @@ static void genOr (iCode *ic, iCode *ifx) int size, offset=0; unsigned long lit = 0L; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp((left = IC_LEFT(ic)),ic,FALSE); aopOp((right= IC_RIGHT(ic)),ic,FALSE); aopOp((result=IC_RESULT(ic)),ic,TRUE); + DEBUGpic14_AopType(__LINE__,left,right,result); /* if left is a literal & right is not then exchange them */ if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) || @@ -5221,7 +5329,7 @@ static void genOr (iCode *ic, iCode *ifx) } /* if result = right then exchange them */ - if(sameRegs(AOP(result),AOP(right))){ + if(pic14_sameRegs(AOP(result),AOP(right))){ operand *tmp = right ; right = left; left = tmp; @@ -5235,6 +5343,8 @@ static void genOr (iCode *ic, iCode *ifx) left = tmp; } + DEBUGpic14_AopType(__LINE__,left,right,result); + if(AOP_TYPE(right) == AOP_LIT) lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit); @@ -5249,8 +5359,8 @@ static void genOr (iCode *ic, iCode *ifx) // lit != 0 => result = 1 if(AOP_TYPE(result) == AOP_CRY){ if(size) - emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE)); - //emitcode("bsf","(%s >> 3), (%s & 7)", + emitpcode(POC_BSF, popGet(AOP(result),0)); + //pic14_emitcode("bsf","(%s >> 3), (%s & 7)", // AOP(result)->aopu.aop_dir, // AOP(result)->aopu.aop_dir); else if(ifx) @@ -5259,71 +5369,90 @@ static void genOr (iCode *ic, iCode *ifx) } } else { // lit == 0 => result = left - if(size && sameRegs(AOP(result),AOP(left))) + if(size && pic14_sameRegs(AOP(result),AOP(left))) goto release; - emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__); + pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__); } } else { if (AOP_TYPE(right) == AOP_CRY){ - if(sameRegs(AOP(result),AOP(left))){ + if(pic14_sameRegs(AOP(result),AOP(left))){ // c = bit | bit; - emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE)); - emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE)); - emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_BCF, popGet(AOP(result),0)); + emitpcode(POC_BTFSC, popGet(AOP(right),0)); + emitpcode(POC_BSF, popGet(AOP(result),0)); - emitcode("bcf","(%s >> 3), (%s & 7)", + pic14_emitcode("bcf","(%s >> 3), (%s & 7)", AOP(result)->aopu.aop_dir, AOP(result)->aopu.aop_dir); - emitcode("btfsc","(%s >> 3), (%s & 7)", + pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", AOP(right)->aopu.aop_dir, AOP(right)->aopu.aop_dir); - emitcode("bsf","(%s >> 3), (%s & 7)", + pic14_emitcode("bsf","(%s >> 3), (%s & 7)", AOP(result)->aopu.aop_dir, AOP(result)->aopu.aop_dir); } else { + if( AOP_TYPE(result) == AOP_ACC) { + emitpcode(POC_MOVLW, popGetLit(0)); + emitpcode(POC_BTFSS, popGet(AOP(right),0)); + emitpcode(POC_BTFSC, popGet(AOP(left),0)); + emitpcode(POC_MOVLW, popGetLit(1)); - emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE)); - emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE)); - emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE)); - emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE)); + } else { - emitcode("bcf","(%s >> 3), (%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - emitcode("btfss","(%s >> 3), (%s & 7)", - AOP(right)->aopu.aop_dir, - AOP(right)->aopu.aop_dir); - emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(left)->aopu.aop_dir, - AOP(left)->aopu.aop_dir); - emitcode("bsf","(%s >> 3), (%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); + emitpcode(POC_BCF, popGet(AOP(result),0)); + emitpcode(POC_BTFSS, popGet(AOP(right),0)); + emitpcode(POC_BTFSC, popGet(AOP(left),0)); + emitpcode(POC_BSF, popGet(AOP(result),0)); + + pic14_emitcode("bcf","(%s >> 3), (%s & 7)", + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); + pic14_emitcode("btfss","(%s >> 3), (%s & 7)", + AOP(right)->aopu.aop_dir, + AOP(right)->aopu.aop_dir); + pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", + AOP(left)->aopu.aop_dir, + AOP(left)->aopu.aop_dir); + pic14_emitcode("bsf","(%s >> 3), (%s & 7)", + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); + } } - } - else{ + } else { // c = bit | val; symbol *tlbl = newiTempLabel(NULL); - emitcode(";XXX "," %s,%d",__FILE__,__LINE__); + pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); + + + emitpcode(POC_BCF, popGet(AOP(result),0)); + if( AOP_TYPE(right) == AOP_ACC) { + emitpcode(POC_IORLW, popGetLit(0)); + emitSKPNZ; + emitpcode(POC_BTFSC, popGet(AOP(left),0)); + emitpcode(POC_BSF, popGet(AOP(result),0)); + } + + + if(!((AOP_TYPE(result) == AOP_CRY) && ifx)) - emitcode(";XXX setb","c"); - emitcode(";XXX jb","%s,%05d_DS_", + pic14_emitcode(";XXX setb","c"); + pic14_emitcode(";XXX jb","%s,%05d_DS_", AOP(left)->aopu.aop_dir,tlbl->key+100); - toBoolean(right); - emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); + pic14_toBoolean(right); + pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); if((AOP_TYPE(result) == AOP_CRY) && ifx){ jmpTrueOrFalse(ifx, tlbl); goto release; } else { CLRC; - emitcode("","%05d_DS_:",tlbl->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); } } } // bit = c // val = c if(size) - outBitC(result); + pic14_outBitC(result); // if(bit | ...) else if((AOP_TYPE(result) == AOP_CRY) && ifx) genIfxJump(ifx, "c"); @@ -5336,35 +5465,36 @@ static void genOr (iCode *ic, iCode *ifx) (AOP_TYPE(result) == AOP_CRY) && (AOP_TYPE(left) != AOP_CRY)){ if(lit){ - emitcode(";XXX "," %s,%d",__FILE__,__LINE__); + pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); // result = 1 if(size) - emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir); + pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir); else continueIfTrue(ifx); goto release; } else { - emitcode(";XXX "," %s,%d",__FILE__,__LINE__); + pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); // lit = 0, result = boolean(left) if(size) - emitcode(";XXX setb","c"); - toBoolean(right); + pic14_emitcode(";XXX setb","c"); + pic14_toBoolean(right); if(size){ symbol *tlbl = newiTempLabel(NULL); - emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); + pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); CLRC; - emitcode("","%05d_DS_:",tlbl->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); } else { genIfxJump (ifx,"a"); goto release; } } - outBitC(result); + pic14_outBitC(result); goto release ; } /* if left is same as result */ - if(sameRegs(AOP(result),AOP(left))){ + if(pic14_sameRegs(AOP(result),AOP(left))){ + int know_W = -1; for(;size--; offset++,lit>>=8) { if(AOP_TYPE(right) == AOP_LIT){ if((lit & 0xff) == 0) @@ -5374,27 +5504,26 @@ static void genOr (iCode *ic, iCode *ifx) int p = my_powof2(lit & 0xff); if(p>=0) { /* only one bit is set in the literal, so use a bsf instruction */ - emitpcode(POC_BSF, popGet(AOP(left),offset,FALSE,FALSE)); - emitcode("bsf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p); + emitpcode(POC_BSF, + newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0)); } else { - emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE)); - - emitcode("movlw","0x%x", (lit & 0xff)); - emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p); + if(know_W != (lit & 0xff)) + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + know_W = lit & 0xff; + emitpcode(POC_IORWF, popGet(AOP(left),offset)); } } } else { if (AOP_TYPE(left) == AOP_ACC) { - emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE)); - emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + emitpcode(POC_IORFW, popGet(AOP(right),offset)); + pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); } else { - emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE)); - emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW, popGet(AOP(right),offset)); + emitpcode(POC_IORWF, popGet(AOP(left),offset)); - emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE)); + pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE)); } } @@ -5407,21 +5536,22 @@ static void genOr (iCode *ic, iCode *ifx) // if(!size && ifx), conditional oper: if(left | right) symbol *tlbl = newiTempLabel(NULL); int sizer = max(AOP_SIZE(left),AOP_SIZE(right)); - emitcode(";XXX "," %s,%d",__FILE__,__LINE__); + pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); + if(size) - emitcode(";XXX setb","c"); + pic14_emitcode(";XXX setb","c"); while(sizer--){ MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode(";XXX orl","a,%s", + pic14_emitcode(";XXX orl","a,%s", aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); + pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); offset++; } if(size){ CLRC; - emitcode("","%05d_DS_:",tlbl->key+100); - outBitC(result); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_outBitC(result); } else if(ifx) jmpTrueOrFalse(ifx, tlbl); } else for(;(size--);offset++){ @@ -5431,23 +5561,23 @@ static void genOr (iCode *ic, iCode *ifx) int t = (lit >> (offset*8)) & 0x0FFL; switch(t) { case 0x00: - emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE)); - emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - emitcode("movf","%s,w", + pic14_emitcode("movf","%s,w", aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("movwf","%s", + pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE)); break; default: emitpcode(POC_MOVLW, popGetLit(t)); - emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE)); - emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_IORFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - emitcode("movlw","0x%x",t); - emitcode("iorwf","%s,w", + pic14_emitcode("movlw","0x%x",t); + pic14_emitcode("iorwf","%s,w", aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("movwf","%s", + pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE)); } @@ -5457,18 +5587,18 @@ static void genOr (iCode *ic, iCode *ifx) // faster than result <- left, anl result,right // and better if result is SFR if (AOP_TYPE(left) == AOP_ACC) { - emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE)); - emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + emitpcode(POC_IORWF, popGet(AOP(right),offset)); + pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); } else { - emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE)); - emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW, popGet(AOP(right),offset)); + emitpcode(POC_IORFW, popGet(AOP(left),offset)); - emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("iorwf","%s,w", + pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode("iorwf","%s,w", aopGet(AOP(left),offset,FALSE,FALSE)); } - emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE)); - emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); } } @@ -5483,218 +5613,240 @@ release : /*-----------------------------------------------------------------*/ static void genXor (iCode *ic, iCode *ifx) { - operand *left, *right, *result; - int size, offset=0; - unsigned long lit = 0L; - - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + operand *left, *right, *result; + int size, offset=0; + unsigned long lit = 0L; - aopOp((left = IC_LEFT(ic)),ic,FALSE); - aopOp((right= IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if left is a literal & right is not || - if left needs acc & right does not */ - if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) || - (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) { - operand *tmp = right ; - right = left; - left = tmp; - } + aopOp((left = IC_LEFT(ic)),ic,FALSE); + aopOp((right= IC_RIGHT(ic)),ic,FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE); - /* if result = right then exchange them */ - if(sameRegs(AOP(result),AOP(right))){ - operand *tmp = right ; - right = left; - left = tmp; - } + /* if left is a literal & right is not || + if left needs acc & right does not */ + if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) || + (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) { + operand *tmp = right ; + right = left; + left = tmp; + } - /* if right is bit then exchange them */ - if (AOP_TYPE(right) == AOP_CRY && - AOP_TYPE(left) != AOP_CRY){ - operand *tmp = right ; - right = left; - left = tmp; - } - if(AOP_TYPE(right) == AOP_LIT) - lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit); + /* if result = right then exchange them */ + if(pic14_sameRegs(AOP(result),AOP(right))){ + operand *tmp = right ; + right = left; + left = tmp; + } - size = AOP_SIZE(result); + /* if right is bit then exchange them */ + if (AOP_TYPE(right) == AOP_CRY && + AOP_TYPE(left) != AOP_CRY){ + operand *tmp = right ; + right = left; + left = tmp; + } + if(AOP_TYPE(right) == AOP_LIT) + lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit); + + size = AOP_SIZE(result); + + // if(bit ^ yy) + // xx = bit ^ yy; + if (AOP_TYPE(left) == AOP_CRY){ + if(AOP_TYPE(right) == AOP_LIT){ + // c = bit & literal; + if(lit>>1){ + // lit>>1 != 0 => result = 1 + if(AOP_TYPE(result) == AOP_CRY){ + if(size) + {emitpcode(POC_BSF, popGet(AOP(result),offset)); + pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);} + else if(ifx) + continueIfTrue(ifx); + goto release; + } + pic14_emitcode("setb","c"); + } else{ + // lit == (0 or 1) + if(lit == 0){ + // lit == 0, result = left + if(size && pic14_sameRegs(AOP(result),AOP(left))) + goto release; + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + } else{ + // lit == 1, result = not(left) + if(size && pic14_sameRegs(AOP(result),AOP(left))){ + emitpcode(POC_MOVLW, popGet(AOP(result),offset)); + emitpcode(POC_XORWF, popGet(AOP(result),offset)); + pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir); + goto release; + } else { + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + pic14_emitcode("cpl","c"); + } + } + } - // if(bit ^ yy) - // xx = bit ^ yy; - if (AOP_TYPE(left) == AOP_CRY){ - if(AOP_TYPE(right) == AOP_LIT){ - // c = bit & literal; - if(lit>>1){ - // lit>>1 != 0 => result = 1 - if(AOP_TYPE(result) == AOP_CRY){ - if(size) - emitcode("setb","%s",AOP(result)->aopu.aop_dir); - else if(ifx) - continueIfTrue(ifx); - goto release; - } - emitcode("setb","c"); - } else{ - // lit == (0 or 1) - if(lit == 0){ - // lit == 0, result = left - if(size && sameRegs(AOP(result),AOP(left))) - goto release; - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - } else{ - // lit == 1, result = not(left) - if(size && sameRegs(AOP(result),AOP(left))){ - emitcode("cpl","%s",AOP(result)->aopu.aop_dir); - goto release; - } else { - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("cpl","c"); - } - } - } + } else { + // right != literal + symbol *tlbl = newiTempLabel(NULL); + if (AOP_TYPE(right) == AOP_CRY){ + // c = bit ^ bit; + pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); + } + else{ + int sizer = AOP_SIZE(right); + // c = bit ^ val + // if val>>1 != 0, result = 1 + pic14_emitcode("setb","c"); + while(sizer){ + MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE)); + if(sizer == 1) + // test the msb of the lsb + pic14_emitcode("anl","a,#0xfe"); + pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); + sizer--; + } + // val = (0,1) + pic14_emitcode("rrc","a"); + } + pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100)); + pic14_emitcode("cpl","c"); + pic14_emitcode("","%05d_DS_:",(tlbl->key+100)); + } + // bit = c + // val = c + if(size) + pic14_outBitC(result); + // if(bit | ...) + else if((AOP_TYPE(result) == AOP_CRY) && ifx) + genIfxJump(ifx, "c"); + goto release ; + } - } else { - // right != literal - symbol *tlbl = newiTempLabel(NULL); - if (AOP_TYPE(right) == AOP_CRY){ - // c = bit ^ bit; - emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - } - else{ - int sizer = AOP_SIZE(right); - // c = bit ^ val - // if val>>1 != 0, result = 1 - emitcode("setb","c"); - while(sizer){ - MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE)); - if(sizer == 1) - // test the msb of the lsb - emitcode("anl","a,#0xfe"); - emitcode("jnz","%05d_DS_",tlbl->key+100); - sizer--; - } - // val = (0,1) - emitcode("rrc","a"); - } - emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100)); - emitcode("cpl","c"); - emitcode("","%05d_DS_:",(tlbl->key+100)); - } - // bit = c - // val = c - if(size) - outBitC(result); - // if(bit | ...) - else if((AOP_TYPE(result) == AOP_CRY) && ifx) - genIfxJump(ifx, "c"); - goto release ; + if(pic14_sameRegs(AOP(result),AOP(left))){ + /* if left is same as result */ + for(;size--; offset++) { + if(AOP_TYPE(right) == AOP_LIT){ + int t = (lit >> (offset*8)) & 0x0FFL; + if(t == 0x00L) + continue; + else + if (IS_AOP_PREG(left)) { + MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE)); + aopPut(AOP(result),"a",offset); + } else { + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_XORWF,popGet(AOP(left),offset)); + pic14_emitcode("xrl","%s,%s", + aopGet(AOP(left),offset,FALSE,TRUE), + aopGet(AOP(right),offset,FALSE,FALSE)); + } + } else { + if (AOP_TYPE(left) == AOP_ACC) + pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE)); + else { + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_XORWF,popGet(AOP(left),offset)); +/* + if (IS_AOP_PREG(left)) { + pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE)); + aopPut(AOP(result),"a",offset); + } else + pic14_emitcode("xrl","%s,a", + aopGet(AOP(left),offset,FALSE,TRUE)); +*/ + } + } } - - if(sameRegs(AOP(result),AOP(left))){ - /* if left is same as result */ - for(;size--; offset++) { - if(AOP_TYPE(right) == AOP_LIT){ - if(((lit >> (offset*8)) & 0x0FFL) == 0x00L) - continue; - else - if (IS_AOP_PREG(left)) { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE)); - aopPut(AOP(result),"a",offset); - } else - emitcode("xrl","%s,%s", - aopGet(AOP(left),offset,FALSE,TRUE), - aopGet(AOP(right),offset,FALSE,FALSE)); - } else { - if (AOP_TYPE(left) == AOP_ACC) - emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE)); - else { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - if (IS_AOP_PREG(left)) { - emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE)); - aopPut(AOP(result),"a",offset); - } else - emitcode("xrl","%s,a", - aopGet(AOP(left),offset,FALSE,TRUE)); - } - } - } - } else { - // left & result in different registers - if(AOP_TYPE(result) == AOP_CRY){ - // result = bit - // if(size), result in bit - // if(!size && ifx), conditional oper: if(left ^ right) - symbol *tlbl = newiTempLabel(NULL); - int sizer = max(AOP_SIZE(left),AOP_SIZE(right)); - if(size) - emitcode("setb","c"); - while(sizer--){ - if((AOP_TYPE(right) == AOP_LIT) && - (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){ - MOVA(aopGet(AOP(left),offset,FALSE,FALSE)); - } else { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("xrl","a,%s", - aopGet(AOP(left),offset,FALSE,FALSE)); - } - emitcode("jnz","%05d_DS_",tlbl->key+100); - offset++; - } - if(size){ - CLRC; - emitcode("","%05d_DS_:",tlbl->key+100); - outBitC(result); - } else if(ifx) - jmpTrueOrFalse(ifx, tlbl); - } else for(;(size--);offset++){ - // normal case - // result = left & right - if(AOP_TYPE(right) == AOP_LIT){ - int t = (lit >> (offset*8)) & 0x0FFL; - switch(t) { - case 0x00: - emitcode("movf","%s,w", + } else { + // left & result in different registers + if(AOP_TYPE(result) == AOP_CRY){ + // result = bit + // if(size), result in bit + // if(!size && ifx), conditional oper: if(left ^ right) + symbol *tlbl = newiTempLabel(NULL); + int sizer = max(AOP_SIZE(left),AOP_SIZE(right)); + if(size) + pic14_emitcode("setb","c"); + while(sizer--){ + if((AOP_TYPE(right) == AOP_LIT) && + (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){ + MOVA(aopGet(AOP(left),offset,FALSE,FALSE)); + } else { + MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode("xrl","a,%s", + aopGet(AOP(left),offset,FALSE,FALSE)); + } + pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); + offset++; + } + if(size){ + CLRC; + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_outBitC(result); + } else if(ifx) + jmpTrueOrFalse(ifx, tlbl); + } else for(;(size--);offset++){ + // normal case + // result = left & right + if(AOP_TYPE(right) == AOP_LIT){ + int t = (lit >> (offset*8)) & 0x0FFL; + switch(t) { + case 0x00: + emitpcode(POC_MOVFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + pic14_emitcode("movf","%s,w", aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("movwf","%s", + pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE)); - break; - case 0xff: - emitcode("comf","%s,w", + break; + case 0xff: + emitpcode(POC_COMFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + pic14_emitcode("comf","%s,w", aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("movwf","%s", + pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE)); - break; - default: - emitcode("movlw","0x%x",t); - emitcode("xorwf","%s,w", + break; + default: + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_XORFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + pic14_emitcode("movlw","0x%x",t); + pic14_emitcode("xorwf","%s,w", aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("movwf","%s", + pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE)); - } - continue; - } + } + continue; + } - // faster than result <- left, anl result,right - // and better if result is SFR - if (AOP_TYPE(left) == AOP_ACC) - emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - else { - emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); - } - if ( AOP_TYPE(result) != AOP_ACC) - emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); - } + // faster than result <- left, anl result,right + // and better if result is SFR + if (AOP_TYPE(left) == AOP_ACC) { + emitpcode(POC_XORFW,popGet(AOP(right),offset)); + pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + } else { + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_XORFW,popGet(AOP(left),offset)); + pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); + } + if ( AOP_TYPE(result) != AOP_ACC){ + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); + } } + } -release : + release : freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -5702,35 +5854,38 @@ release : /*-----------------------------------------------------------------*/ static void genInline (iCode *ic) { - char buffer[MAX_INLINEASM]; - char *bp = buffer; - char *bp1= buffer; + char *buffer, *bp, *bp1; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); _G.inLine += (!options.asmpeep); + + buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1); strcpy(buffer,IC_INLINE(ic)); /* emit each line as a code */ while (*bp) { if (*bp == '\n') { *bp++ = '\0'; - emitcode(bp1,""); + pic14_emitcode(bp1,""); + addpCode2pBlock(pb,newpCodeInlineP(bp1)); bp1 = bp; } else { if (*bp == ':') { bp++; *bp = '\0'; bp++; - emitcode(bp1,""); + pic14_emitcode(bp1,""); bp1 = bp; } else bp++; } } - if (bp1 != bp) - emitcode(bp1,""); - /* emitcode("",buffer); */ + if (bp1 != bp) { + pic14_emitcode(bp1,""); + addpCode2pBlock(pb,newpCodeInlineP(bp1)); + } + /* pic14_emitcode("",buffer); */ _G.inLine -= (!options.asmpeep); } @@ -5739,37 +5894,40 @@ static void genInline (iCode *ic) /*-----------------------------------------------------------------*/ static void genRRC (iCode *ic) { - operand *left , *result ; - int size, offset = 0; - char *l; + operand *left , *result ; + int size, offset = 0, same; - /* rotate right with carry */ - left = IC_LEFT(ic); - result=IC_RESULT(ic); - aopOp (left,ic,FALSE); - aopOp (result,ic,FALSE); + /* rotate right with carry */ + left = IC_LEFT(ic); + result=IC_RESULT(ic); + aopOp (left,ic,FALSE); + aopOp (result,ic,FALSE); - /* move it to the result */ - size = AOP_SIZE(result); - offset = size - 1 ; - CLRC; - while (size--) { - l = aopGet(AOP(left),offset,FALSE,FALSE); - MOVA(l); - emitcode("rrc","a"); - if (AOP_SIZE(result) > 1) - aopPut(AOP(result),"a",offset--); - } - /* now we need to put the carry into the - highest order byte of the result */ - if (AOP_SIZE(result) > 1) { - l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE); - MOVA(l); + DEBUGpic14_AopType(__LINE__,left,NULL,result); + + same = pic14_sameRegs(AOP(result),AOP(left)); + + size = AOP_SIZE(result); + + /* get the lsb and put it into the carry */ + emitpcode(POC_RRFW, popGet(AOP(left),size-1)); + + offset = 0 ; + + while(size--) { + + if(same) { + emitpcode(POC_RRF, popGet(AOP(left),offset)); + } else { + emitpcode(POC_RRFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); } - emitcode("mov","acc.7,c"); - aopPut(AOP(result),"a",AOP_SIZE(result)-1); - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); + + offset++; + } + + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -5777,44 +5935,44 @@ static void genRRC (iCode *ic) /*-----------------------------------------------------------------*/ static void genRLC (iCode *ic) { - operand *left , *result ; - int size, offset = 0; - char *l; + operand *left , *result ; + int size, offset = 0; + int same; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* rotate right with carry */ - left = IC_LEFT(ic); - result=IC_RESULT(ic); - aopOp (left,ic,FALSE); - aopOp (result,ic,FALSE); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* rotate right with carry */ + left = IC_LEFT(ic); + result=IC_RESULT(ic); + aopOp (left,ic,FALSE); + aopOp (result,ic,FALSE); - /* move it to the result */ - size = AOP_SIZE(result); - offset = 0 ; - if (size--) { - l = aopGet(AOP(left),offset,FALSE,FALSE); - MOVA(l); - emitcode("add","a,acc"); - if (AOP_SIZE(result) > 1) - aopPut(AOP(result),"a",offset++); - while (size--) { - l = aopGet(AOP(left),offset,FALSE,FALSE); - MOVA(l); - emitcode("rlc","a"); - if (AOP_SIZE(result) > 1) - aopPut(AOP(result),"a",offset++); - } - } - /* now we need to put the carry into the - highest order byte of the result */ - if (AOP_SIZE(result) > 1) { - l = aopGet(AOP(result),0,FALSE,FALSE); - MOVA(l); + DEBUGpic14_AopType(__LINE__,left,NULL,result); + + same = pic14_sameRegs(AOP(result),AOP(left)); + + /* move it to the result */ + size = AOP_SIZE(result); + + /* get the msb and put it into the carry */ + emitpcode(POC_RLFW, popGet(AOP(left),size-1)); + + offset = 0 ; + + while(size--) { + + if(same) { + emitpcode(POC_RLF, popGet(AOP(left),offset)); + } else { + emitpcode(POC_RLFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); } - emitcode("mov","acc.0,c"); - aopPut(AOP(result),"a",0); - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); + + offset++; + } + + + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -5828,17 +5986,17 @@ static void genGetHbit (iCode *ic) aopOp (left,ic,FALSE); aopOp (result,ic,FALSE); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* get the highest order byte into a */ MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE)); if(AOP_TYPE(result) == AOP_CRY){ - emitcode("rlc","a"); - outBitC(result); + pic14_emitcode("rlc","a"); + pic14_outBitC(result); } else{ - emitcode("rl","a"); - emitcode("anl","a,#0x01"); - outAcc(result); + pic14_emitcode("rl","a"); + pic14_emitcode("anl","a,#0x01"); + pic14_outAcc(result); } @@ -5851,35 +6009,35 @@ static void genGetHbit (iCode *ic) /*-----------------------------------------------------------------*/ static void AccRol (int shCount) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); shCount &= 0x0007; // shCount : 0..7 switch(shCount){ case 0 : break; case 1 : - emitcode("rl","a"); + pic14_emitcode("rl","a"); break; case 2 : - emitcode("rl","a"); - emitcode("rl","a"); + pic14_emitcode("rl","a"); + pic14_emitcode("rl","a"); break; case 3 : - emitcode("swap","a"); - emitcode("rr","a"); + pic14_emitcode("swap","a"); + pic14_emitcode("rr","a"); break; case 4 : - emitcode("swap","a"); + pic14_emitcode("swap","a"); break; case 5 : - emitcode("swap","a"); - emitcode("rl","a"); + pic14_emitcode("swap","a"); + pic14_emitcode("rl","a"); break; case 6 : - emitcode("rr","a"); - emitcode("rr","a"); + pic14_emitcode("rr","a"); + pic14_emitcode("rr","a"); break; case 7 : - emitcode("rr","a"); + pic14_emitcode("rr","a"); break; } } @@ -5889,19 +6047,19 @@ static void AccRol (int shCount) /*-----------------------------------------------------------------*/ static void AccLsh (int shCount) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(shCount != 0){ if(shCount == 1) - emitcode("add","a,acc"); + pic14_emitcode("add","a,acc"); else if(shCount == 2) { - emitcode("add","a,acc"); - emitcode("add","a,acc"); + pic14_emitcode("add","a,acc"); + pic14_emitcode("add","a,acc"); } else { /* rotate left accumulator */ AccRol(shCount); /* and kill the lower order bits */ - emitcode("anl","a,#0x%02x", SLMask[shCount]); + pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]); } } } @@ -5911,322 +6069,347 @@ static void AccLsh (int shCount) /*-----------------------------------------------------------------*/ static void AccRsh (int shCount) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(shCount != 0){ if(shCount == 1){ CLRC; - emitcode("rrc","a"); + pic14_emitcode("rrc","a"); } else { /* rotate right accumulator */ AccRol(8 - shCount); /* and kill the higher order bits */ - emitcode("anl","a,#0x%02x", SRMask[shCount]); + pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]); } } } +#if 0 /*-----------------------------------------------------------------*/ /* AccSRsh - signed right shift accumulator by known count */ /*-----------------------------------------------------------------*/ static void AccSRsh (int shCount) { symbol *tlbl ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(shCount != 0){ if(shCount == 1){ - emitcode("mov","c,acc.7"); - emitcode("rrc","a"); + pic14_emitcode("mov","c,acc.7"); + pic14_emitcode("rrc","a"); } else if(shCount == 2){ - emitcode("mov","c,acc.7"); - emitcode("rrc","a"); - emitcode("mov","c,acc.7"); - emitcode("rrc","a"); + pic14_emitcode("mov","c,acc.7"); + pic14_emitcode("rrc","a"); + pic14_emitcode("mov","c,acc.7"); + pic14_emitcode("rrc","a"); } else { tlbl = newiTempLabel(NULL); /* rotate right accumulator */ AccRol(8 - shCount); /* and kill the higher order bits */ - emitcode("anl","a,#0x%02x", SRMask[shCount]); - emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); - emitcode("orl","a,#0x%02x", + pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]); + pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); + pic14_emitcode("orl","a,#0x%02x", (unsigned char)~SRMask[shCount]); - emitcode("","%05d_DS_:",tlbl->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); } } } - +#endif /*-----------------------------------------------------------------*/ /* shiftR1Left2Result - shift right one byte from left to result */ /*-----------------------------------------------------------------*/ -static void shiftR1Left2Result (operand *left, int offl, +static void shiftR1Left2ResultSigned (operand *left, int offl, operand *result, int offr, - int shCount, int sign) + int shCount) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); - /* shift right accumulator */ - if(sign) - AccSRsh(shCount); - else - AccRsh(shCount); - aopPut(AOP(result),"a",offr); -} + int same; -/*-----------------------------------------------------------------*/ -/* shiftL1Left2Result - shift left one byte from left to result */ -/*-----------------------------------------------------------------*/ -static void shiftL1Left2Result (operand *left, int offl, - operand *result, int offr, int shCount) -{ - char *l; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - l = aopGet(AOP(left),offl,FALSE,FALSE); - MOVA(l); - /* shift left accumulator */ - AccLsh(shCount); - aopPut(AOP(result),"a",offr); -} + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); -/*-----------------------------------------------------------------*/ -/* movLeft2Result - move byte from left to result */ -/*-----------------------------------------------------------------*/ -static void movLeft2Result (operand *left, int offl, - operand *result, int offr, int sign) -{ - char *l; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(!sameRegs(AOP(left),AOP(result)) || (offl != offr)){ - l = aopGet(AOP(left),offl,FALSE,FALSE); + same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr); - if (*l == '@' && (IS_AOP_PREG(result))) { - emitcode("mov","a,%s",l); - aopPut(AOP(result),"a",offr); - } else { - if(!sign) - aopPut(AOP(result),l,offr); - else{ - /* MSB sign in acc.7 ! */ - if(getDataSize(left) == offl+1){ - emitcode("mov","a,%s",l); - aopPut(AOP(result),"a",offr); - } - } - } + switch(shCount) { + case 1: + emitpcode(POC_RLFW, popGet(AOP(left),offl)); + if(same) + emitpcode(POC_RRF, popGet(AOP(result),offr)); + else { + emitpcode(POC_RRFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); } -} -/*-----------------------------------------------------------------*/ -/* AccAXRrl1 - right rotate c->a:x->c by 1 */ -/*-----------------------------------------------------------------*/ -static void AccAXRrl1 (char *x) -{ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - emitcode("rrc","a"); - emitcode("xch","a,%s", x); - emitcode("rrc","a"); - emitcode("xch","a,%s", x); -} + break; + case 2: -/*-----------------------------------------------------------------*/ -/* AccAXLrl1 - left rotate c<-a:x<-c by 1 */ -/*-----------------------------------------------------------------*/ -static void AccAXLrl1 (char *x) -{ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - emitcode("xch","a,%s",x); - emitcode("rlc","a"); - emitcode("xch","a,%s",x); - emitcode("rlc","a"); -} + emitpcode(POC_RLFW, popGet(AOP(left),offl)); + if(same) + emitpcode(POC_RRF, popGet(AOP(result),offr)); + else { + emitpcode(POC_RRFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + } + emitpcode(POC_RLFW, popGet(AOP(result),offr)); + emitpcode(POC_RRF, popGet(AOP(result),offr)); + + break; + + case 3: + if(same) + emitpcode(POC_SWAPF, popGet(AOP(result),offr)); + else { + emitpcode(POC_SWAPFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + } + + emitpcode(POC_RLFW, popGet(AOP(result),offr)); + emitpcode(POC_RLFW, popGet(AOP(result),offr)); + emitpcode(POC_ANDLW, popGetLit(0x1f)); + + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0)); + emitpcode(POC_IORLW, popGetLit(0xe0)); + + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + break; + + case 4: + emitpcode(POC_SWAPFW, popGet(AOP(left),offl)); + emitpcode(POC_ANDLW, popGetLit(0x0f)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0)); + emitpcode(POC_IORLW, popGetLit(0xf0)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + break; + case 5: + if(same) { + emitpcode(POC_SWAPF, popGet(AOP(result),offr)); + } else { + emitpcode(POC_SWAPFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + } + emitpcode(POC_RRFW, popGet(AOP(result),offr)); + emitpcode(POC_ANDLW, popGetLit(0x07)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0)); + emitpcode(POC_IORLW, popGetLit(0xf8)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + break; + + case 6: + if(same) { + emitpcode(POC_MOVLW, popGetLit(0x00)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0)); + emitpcode(POC_MOVLW, popGetLit(0xfe)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0)); + emitpcode(POC_IORLW, popGetLit(0x01)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + } else { + emitpcode(POC_CLRF, popGet(AOP(result),offr)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0)); + emitpcode(POC_DECF, popGet(AOP(result),offr)); + emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0)); + emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0)); + } + break; + + case 7: + if(same) { + emitpcode(POC_MOVLW, popGetLit(0x00)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0)); + emitpcode(POC_MOVLW, popGetLit(0xff)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + } else { + emitpcode(POC_CLRF, popGet(AOP(result),offr)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0)); + emitpcode(POC_DECF, popGet(AOP(result),offr)); + } -/*-----------------------------------------------------------------*/ -/* AccAXLsh1 - left shift a:x<-0 by 1 */ -/*-----------------------------------------------------------------*/ -static void AccAXLsh1 (char *x) -{ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - emitcode("xch","a,%s",x); - emitcode("add","a,acc"); - emitcode("xch","a,%s",x); - emitcode("rlc","a"); + default: + break; + } } /*-----------------------------------------------------------------*/ -/* AccAXLsh - left shift a:x by known count (0..7) */ +/* shiftR1Left2Result - shift right one byte from left to result */ /*-----------------------------------------------------------------*/ -static void AccAXLsh (char *x, int shCount) +static void shiftR1Left2Result (operand *left, int offl, + operand *result, int offr, + int shCount, int sign) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - switch(shCount){ - case 0 : - break; - case 1 : - AccAXLsh1(x); - break; - case 2 : - AccAXLsh1(x); - AccAXLsh1(x); - break; - case 3 : - case 4 : - case 5 : // AAAAABBB:CCCCCDDD - AccRol(shCount); // BBBAAAAA:CCCCCDDD - emitcode("anl","a,#0x%02x", - SLMask[shCount]); // BBB00000:CCCCCDDD - emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000 - AccRol(shCount); // DDDCCCCC:BBB00000 - emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC - emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC - emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC - emitcode("anl","a,#0x%02x", - SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC - emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000 - emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000 - break; - case 6 : // AAAAAABB:CCCCCCDD - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000000BB:CCCCCCDD - emitcode("mov","c,acc.0"); // c = B - emitcode("xch","a,%s",x); // CCCCCCDD:000000BB - AccAXRrl1(x); // BCCCCCCD:D000000B - AccAXRrl1(x); // BBCCCCCC:DD000000 - break; - case 7 : // a:x <<= 7 - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 0000000B:CCCCCCCD - emitcode("mov","c,acc.0"); // c = B - emitcode("xch","a,%s",x); // CCCCCCCD:0000000B - AccAXRrl1(x); // BCCCCCCC:D0000000 - break; - default : - break; + int same; + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr); + + /* Copy the msb into the carry if signed. */ + if(sign) { + shiftR1Left2ResultSigned(left,offl,result,offr,shCount); + return; + } + + + + switch(shCount) { + case 1: + emitCLRC; + if(same) + emitpcode(POC_RRF, popGet(AOP(result),offr)); + else { + emitpcode(POC_RRFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + } + break; + case 2: + emitCLRC; + if(same) { + emitpcode(POC_RRF, popGet(AOP(result),offr)); + } else { + emitpcode(POC_RRFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); } + emitCLRC; + emitpcode(POC_RRF, popGet(AOP(result),offr)); + + break; + case 3: + if(same) + emitpcode(POC_SWAPF, popGet(AOP(result),offr)); + else { + emitpcode(POC_SWAPFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + } + + emitpcode(POC_RLFW, popGet(AOP(result),offr)); + emitpcode(POC_RLFW, popGet(AOP(result),offr)); + emitpcode(POC_ANDLW, popGetLit(0x1f)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + break; + + case 4: + emitpcode(POC_SWAPFW, popGet(AOP(left),offl)); + emitpcode(POC_ANDLW, popGetLit(0x0f)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + break; + + case 5: + emitpcode(POC_SWAPFW, popGet(AOP(left),offl)); + emitpcode(POC_ANDLW, popGetLit(0x0f)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + emitCLRC; + emitpcode(POC_RRF, popGet(AOP(result),offr)); + + break; + case 6: + + emitpcode(POC_RLFW, popGet(AOP(left),offl)); + emitpcode(POC_ANDLW, popGetLit(0x80)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + emitpcode(POC_RLF, popGet(AOP(result),offr)); + emitpcode(POC_RLF, popGet(AOP(result),offr)); + break; + + case 7: + + emitpcode(POC_RLFW, popGet(AOP(left),offl)); + emitpcode(POC_CLRF, popGet(AOP(result),offr)); + emitpcode(POC_RLF, popGet(AOP(result),offr)); + + break; + + default: + break; + } } /*-----------------------------------------------------------------*/ -/* AccAXRsh - right shift a:x known count (0..7) */ +/* shiftL1Left2Result - shift left one byte from left to result */ /*-----------------------------------------------------------------*/ -static void AccAXRsh (char *x, int shCount) -{ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - switch(shCount){ - case 0 : - break; - case 1 : - CLRC; - AccAXRrl1(x); // 0->a:x - break; - case 2 : - CLRC; - AccAXRrl1(x); // 0->a:x - CLRC; - AccAXRrl1(x); // 0->a:x - break; - case 3 : - case 4 : - case 5 : // AAAAABBB:CCCCCDDD = a:x - AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC - emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA - AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000CCCCC:BBBAAAAA - emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA - emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA) - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA) - emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA - emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA - emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC - break; - case 6 : // AABBBBBB:CCDDDDDD - emitcode("mov","c,acc.7"); - AccAXLrl1(x); // ABBBBBBC:CDDDDDDA - AccAXLrl1(x); // BBBBBBCC:DDDDDDAA - emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000000AA:BBBBBBCC - break; - case 7 : // ABBBBBBB:CDDDDDDD - emitcode("mov","c,acc.7"); // c = A - AccAXLrl1(x); // BBBBBBBC:DDDDDDDA - emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 0000000A:BBBBBBBC - break; - default : - break; - } +static void shiftL1Left2Result (operand *left, int offl, + operand *result, int offr, int shCount) +{ + int same; + + // char *l; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr); + DEBUGpic14_emitcode ("; ***","same = %d",same); + // l = aopGet(AOP(left),offl,FALSE,FALSE); + // MOVA(l); + /* shift left accumulator */ + //AccLsh(shCount); // don't comment out just yet... + // aopPut(AOP(result),"a",offr); + + switch(shCount) { + case 1: + /* Shift left 1 bit position */ + emitpcode(POC_MOVFW, popGet(AOP(left),offl)); + if(same) { + emitpcode(POC_ADDWF, popGet(AOP(left),offl)); + } else { + emitpcode(POC_ADDFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + } + break; + case 2: + emitpcode(POC_RLFW, popGet(AOP(left),offl)); + emitpcode(POC_ANDLW,popGetLit(0x7e)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr)); + emitpcode(POC_ADDWF,popGet(AOP(result),offr)); + break; + case 3: + emitpcode(POC_RLFW, popGet(AOP(left),offl)); + emitpcode(POC_ANDLW,popGetLit(0x3e)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr)); + emitpcode(POC_ADDWF,popGet(AOP(result),offr)); + emitpcode(POC_RLF, popGet(AOP(result),offr)); + break; + case 4: + emitpcode(POC_SWAPFW,popGet(AOP(left),offl)); + emitpcode(POC_ANDLW, popGetLit(0xf0)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr)); + break; + case 5: + emitpcode(POC_SWAPFW,popGet(AOP(left),offl)); + emitpcode(POC_ANDLW, popGetLit(0xf0)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr)); + emitpcode(POC_ADDWF,popGet(AOP(result),offr)); + break; + case 6: + emitpcode(POC_SWAPFW,popGet(AOP(left),offl)); + emitpcode(POC_ANDLW, popGetLit(0x30)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr)); + emitpcode(POC_ADDWF,popGet(AOP(result),offr)); + emitpcode(POC_RLF, popGet(AOP(result),offr)); + break; + case 7: + emitpcode(POC_RRFW, popGet(AOP(left),offl)); + emitpcode(POC_CLRF, popGet(AOP(result),offr)); + emitpcode(POC_RRF, popGet(AOP(result),offr)); + break; + + default: + DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount); + } + } /*-----------------------------------------------------------------*/ -/* AccAXRshS - right shift signed a:x known count (0..7) */ +/* movLeft2Result - move byte from left to result */ /*-----------------------------------------------------------------*/ -static void AccAXRshS (char *x, int shCount) -{ - symbol *tlbl ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - switch(shCount){ - case 0 : - break; - case 1 : - emitcode("mov","c,acc.7"); - AccAXRrl1(x); // s->a:x - break; - case 2 : - emitcode("mov","c,acc.7"); - AccAXRrl1(x); // s->a:x - emitcode("mov","c,acc.7"); - AccAXRrl1(x); // s->a:x - break; - case 3 : - case 4 : - case 5 : // AAAAABBB:CCCCCDDD = a:x - tlbl = newiTempLabel(NULL); - AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD - emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA - AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000CCCCC:BBBAAAAA - emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA - emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA) - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA) - emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA - emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA - emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC - emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); - emitcode("orl","a,#0x%02x", - (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC - emitcode("","%05d_DS_:",tlbl->key+100); - break; // SSSSAAAA:BBBCCCCC - case 6 : // AABBBBBB:CCDDDDDD - tlbl = newiTempLabel(NULL); - emitcode("mov","c,acc.7"); - AccAXLrl1(x); // ABBBBBBC:CDDDDDDA - AccAXLrl1(x); // BBBBBBCC:DDDDDDAA - emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000000AA:BBBBBBCC - emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); - emitcode("orl","a,#0x%02x", - (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC - emitcode("","%05d_DS_:",tlbl->key+100); - break; - case 7 : // ABBBBBBB:CDDDDDDD - tlbl = newiTempLabel(NULL); - emitcode("mov","c,acc.7"); // c = A - AccAXLrl1(x); // BBBBBBBC:DDDDDDDA - emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 0000000A:BBBBBBBC - emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); - emitcode("orl","a,#0x%02x", - (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC - emitcode("","%05d_DS_:",tlbl->key+100); - break; - default : - break; +static void movLeft2Result (operand *left, int offl, + operand *result, int offr) +{ + char *l; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){ + l = aopGet(AOP(left),offl,FALSE,FALSE); + + if (*l == '@' && (IS_AOP_PREG(result))) { + pic14_emitcode("mov","a,%s",l); + aopPut(AOP(result),"a",offr); + } else { + emitpcode(POC_MOVFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); } + } } /*-----------------------------------------------------------------*/ @@ -6235,22 +6418,127 @@ static void AccAXRshS (char *x, int shCount) static void shiftL2Left2Result (operand *left, int offl, operand *result, int offr, int shCount) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(sameRegs(AOP(result), AOP(left)) && - ((offl + MSB16) == offr)){ - /* don't crash result[offr] */ - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); - emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); - } else { - movLeft2Result(left,offl, result, offr, 0); - MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); + + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if(pic14_sameRegs(AOP(result), AOP(left))) { + switch(shCount) { + case 0: + break; + case 1: + case 2: + case 3: + + emitpcode(POC_MOVFW,popGet(AOP(result),offr)); + emitpcode(POC_ADDWF,popGet(AOP(result),offr)); + emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); + + while(--shCount) { + emitCLRC; + emitpcode(POC_RLF, popGet(AOP(result),offr)); + emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); + } + + break; + case 4: + case 5: + emitpcode(POC_MOVLW, popGetLit(0x0f)); + emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_SWAPF, popGet(AOP(result),offr)); + emitpcode(POC_ANDFW, popGet(AOP(result),offr)); + emitpcode(POC_XORWF, popGet(AOP(result),offr)); + emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16)); + if(shCount >=5) { + emitpcode(POC_RLF, popGet(AOP(result),offr)); + emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); + } + break; + case 6: + emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_RRF, popGet(AOP(result),offr)); + emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_RRF, popGet(AOP(result),offr)); + emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_ANDLW,popGetLit(0xc0)); + emitpcode(POC_XORFW,popGet(AOP(result),offr)); + emitpcode(POC_XORWF,popGet(AOP(result),offr)); + emitpcode(POC_XORFW,popGet(AOP(result),offr)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); + break; + case 7: + emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_RRFW, popGet(AOP(result),offr)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); + emitpcode(POC_CLRF, popGet(AOP(result),offr)); + emitpcode(POC_RRF, popGet(AOP(result),offr)); } - /* ax << shCount (x = lsb(result))*/ - AccAXLsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount); - aopPut(AOP(result),"a",offr+MSB16); -} + } else { + switch(shCount) { + case 0: + break; + case 1: + case 2: + case 3: + /* note, use a mov/add for the shift since the mov has a + chance of getting optimized out */ + emitpcode(POC_MOVFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + emitpcode(POC_ADDWF, popGet(AOP(result),offr)); + emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16)); + + while(--shCount) { + emitCLRC; + emitpcode(POC_RLF, popGet(AOP(result),offr)); + emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); + } + break; + + case 4: + case 5: + emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16)); + emitpcode(POC_ANDLW, popGetLit(0xF0)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_SWAPFW,popGet(AOP(left),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + emitpcode(POC_ANDLW, popGetLit(0xF0)); + emitpcode(POC_XORWF, popGet(AOP(result),offr)); + emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16)); + + + if(shCount == 5) { + emitpcode(POC_RLF, popGet(AOP(result),offr)); + emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); + } + break; + case 6: + emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); + emitpcode(POC_RRFW, popGet(AOP(result),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + + emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_RRF, popGet(AOP(result),offr)); + emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_ANDLW,popGetLit(0xc0)); + emitpcode(POC_XORFW,popGet(AOP(result),offr)); + emitpcode(POC_XORWF,popGet(AOP(result),offr)); + emitpcode(POC_XORFW,popGet(AOP(result),offr)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); + break; + case 7: + emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16)); + emitpcode(POC_RRFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); + emitpcode(POC_CLRF, popGet(AOP(result),offr)); + emitpcode(POC_RRF, popGet(AOP(result),offr)); + } + } +} /*-----------------------------------------------------------------*/ /* shiftR2Left2Result - shift right two bytes from left to result */ /*-----------------------------------------------------------------*/ @@ -6258,37 +6546,159 @@ static void shiftR2Left2Result (operand *left, int offl, operand *result, int offr, int shCount, int sign) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(sameRegs(AOP(result), AOP(left)) && - ((offl + MSB16) == offr)){ - /* don't crash result[offr] */ - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); - emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); - } else { - movLeft2Result(left,offl, result, offr, 0); - MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); - } - /* a:x >> shCount (x = lsb(result))*/ + int same=0; + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + same = pic14_sameRegs(AOP(result), AOP(left)); + + if(same && ((offl + MSB16) == offr)){ + same=1; + /* don't crash result[offr] */ + MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); + pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); + } else { + movLeft2Result(left,offl, result, offr); + MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); + } + /* a:x >> shCount (x = lsb(result))*/ +/* + if(sign) + AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount); + else { + AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount); +*/ + switch(shCount) { + case 0: + break; + case 1: + case 2: + case 3: if(sign) - AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount); + emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16)); else - AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount); - if(getDataSize(result) > 1) - aopPut(AOP(result),"a",offr+MSB16); + emitCLRC; + + if(same) { + emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16)); + emitpcode(POC_RRF,popGet(AOP(result),offr)); + } else { + emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); + emitpcode(POC_RRFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr)); + } + + while(--shCount) { + if(sign) + emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16)); + else + emitCLRC; + emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16)); + emitpcode(POC_RRF,popGet(AOP(result),offr)); + } + break; + case 4: + case 5: + if(same) { + + emitpcode(POC_MOVLW, popGetLit(0xf0)); + emitpcode(POC_ANDWF, popGet(AOP(result),offr)); + emitpcode(POC_SWAPF, popGet(AOP(result),offr)); + + emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_ADDWF, popGet(AOP(result),offr)); + } else { + emitpcode(POC_SWAPFW,popGet(AOP(left),offl)); + emitpcode(POC_ANDLW, popGetLit(0x0f)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + + emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_ANDLW, popGetLit(0xf0)); + emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_ADDWF, popGet(AOP(result),offr)); + } + + if(shCount >=5) { + emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_RRF, popGet(AOP(result),offr)); + } + + if(sign) { + emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 )); + emitpcode(POC_BTFSC, + newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0)); + emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16)); + } + + break; + + case 6: + if(same) { + + emitpcode(POC_RLF, popGet(AOP(result),offr)); + emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); + + emitpcode(POC_RLF, popGet(AOP(result),offr)); + emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_RLFW, popGet(AOP(result),offr)); + emitpcode(POC_ANDLW,popGetLit(0x03)); + if(sign) { + emitpcode(POC_BTFSC, + newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0)); + emitpcode(POC_IORLW,popGetLit(0xfc)); + } + emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16)); + emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16)); + emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr)); + } else { + emitpcode(POC_RLFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); + emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr)); + emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16)); + emitpcode(POC_ANDLW,popGetLit(0x03)); + if(sign) { + emitpcode(POC_BTFSC, + newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0)); + emitpcode(POC_IORLW,popGetLit(0xfc)); + } + emitpcode(POC_MOVWF,popGet(AOP(result),offr)); + emitpcode(POC_RLF, popGet(AOP(result),offr)); + + + } + + break; + case 7: + emitpcode(POC_RLFW, popGet(AOP(left),offl)); + emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr)); + emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16)); + if(sign) { + emitSKPNC; + emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16)); + } else + emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); + } } + /*-----------------------------------------------------------------*/ /* shiftLLeftOrResult - shift left one byte from left, or to result*/ /*-----------------------------------------------------------------*/ static void shiftLLeftOrResult (operand *left, int offl, operand *result, int offr, int shCount) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); /* shift left accumulator */ AccLsh(shCount); /* or with result */ - emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE)); + pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE)); /* back to result */ aopPut(AOP(result),"a",offr); } @@ -6299,12 +6709,12 @@ static void shiftLLeftOrResult (operand *left, int offl, static void shiftRLeftOrResult (operand *left, int offl, operand *result, int offr, int shCount) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); /* shift right accumulator */ AccRsh(shCount); /* or with result */ - emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE)); + pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE)); /* back to result */ aopPut(AOP(result),"a",offr); } @@ -6314,7 +6724,7 @@ static void shiftRLeftOrResult (operand *left, int offl, /*-----------------------------------------------------------------*/ static void genlshOne (operand *result, operand *left, int shCount) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); shiftL1Left2Result(left, LSB, result, LSB, shCount); } @@ -6325,8 +6735,8 @@ static void genlshTwo (operand *result,operand *left, int shCount) { int size; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - size = getDataSize(result); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + size = pic14_getDataSize(result); /* if shCount >= 8 */ if (shCount >= 8) { @@ -6336,9 +6746,9 @@ static void genlshTwo (operand *result,operand *left, int shCount) if (shCount) shiftL1Left2Result(left, LSB, result, MSB16, shCount); else - movLeft2Result(left, LSB, result, MSB16, 0); + movLeft2Result(left, LSB, result, MSB16); } - aopPut(AOP(result),zero,LSB); + emitpcode(POC_CLRF,popGet(AOP(result),LSB)); } /* 1 <= shCount <= 7 */ @@ -6359,53 +6769,53 @@ static void shiftLLong (operand *left, operand *result, int offr ) char *l; int size = AOP_SIZE(result); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(size >= LSB+offr){ l = aopGet(AOP(left),LSB,FALSE,FALSE); MOVA(l); - emitcode("add","a,acc"); - if (sameRegs(AOP(left),AOP(result)) && + pic14_emitcode("add","a,acc"); + if (pic14_sameRegs(AOP(left),AOP(result)) && size >= MSB16+offr && offr != LSB ) - emitcode("xch","a,%s", + pic14_emitcode("xch","a,%s", aopGet(AOP(left),LSB+offr,FALSE,FALSE)); else aopPut(AOP(result),"a",LSB+offr); } if(size >= MSB16+offr){ - if (!(sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) { + if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) { l = aopGet(AOP(left),MSB16,FALSE,FALSE); MOVA(l); } - emitcode("rlc","a"); - if (sameRegs(AOP(left),AOP(result)) && + pic14_emitcode("rlc","a"); + if (pic14_sameRegs(AOP(left),AOP(result)) && size >= MSB24+offr && offr != LSB) - emitcode("xch","a,%s", + pic14_emitcode("xch","a,%s", aopGet(AOP(left),MSB16+offr,FALSE,FALSE)); else aopPut(AOP(result),"a",MSB16+offr); } if(size >= MSB24+offr){ - if (!(sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) { + if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) { l = aopGet(AOP(left),MSB24,FALSE,FALSE); MOVA(l); } - emitcode("rlc","a"); - if (sameRegs(AOP(left),AOP(result)) && + pic14_emitcode("rlc","a"); + if (pic14_sameRegs(AOP(left),AOP(result)) && size >= MSB32+offr && offr != LSB ) - emitcode("xch","a,%s", + pic14_emitcode("xch","a,%s", aopGet(AOP(left),MSB24+offr,FALSE,FALSE)); else aopPut(AOP(result),"a",MSB24+offr); } if(size > MSB32+offr){ - if (!(sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) { + if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) { l = aopGet(AOP(left),MSB32,FALSE,FALSE); MOVA(l); } - emitcode("rlc","a"); + pic14_emitcode("rlc","a"); aopPut(AOP(result),"a",MSB32+offr); } if(offr != LSB) @@ -6419,7 +6829,7 @@ static void genlshFour (operand *result, operand *left, int shCount) { int size; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); size = AOP_SIZE(result); /* if shifting more that 3 bytes */ @@ -6430,7 +6840,7 @@ static void genlshFour (operand *result, operand *left, int shCount) order of the destination */ shiftL1Left2Result(left, LSB, result, MSB32, shCount); else - movLeft2Result(left, LSB, result, MSB32, 0); + movLeft2Result(left, LSB, result, MSB32); aopPut(AOP(result),zero,LSB); aopPut(AOP(result),zero,MSB16); aopPut(AOP(result),zero,MSB32); @@ -6445,8 +6855,8 @@ static void genlshFour (operand *result, operand *left, int shCount) if (shCount) shiftL2Left2Result(left, LSB, result, MSB24, shCount); else { - movLeft2Result(left, MSB16, result, MSB32, 0); - movLeft2Result(left, LSB, result, MSB24, 0); + movLeft2Result(left, MSB16, result, MSB32); + movLeft2Result(left, LSB, result, MSB24); } aopPut(AOP(result),zero,MSB16); aopPut(AOP(result),zero,LSB); @@ -6461,13 +6871,13 @@ static void genlshFour (operand *result, operand *left, int shCount) if(shCount) shiftL1Left2Result(left, LSB, result, MSB16, shCount); else - movLeft2Result(left, LSB, result, MSB16, 0); + movLeft2Result(left, LSB, result, MSB16); } else{ /* size = 4 */ if(shCount == 0){ - movLeft2Result(left, MSB24, result, MSB32, 0); - movLeft2Result(left, MSB16, result, MSB24, 0); - movLeft2Result(left, LSB, result, MSB16, 0); + movLeft2Result(left, MSB24, result, MSB32); + movLeft2Result(left, MSB16, result, MSB24); + movLeft2Result(left, LSB, result, MSB16); aopPut(AOP(result),zero,LSB); } else if(shCount == 1) @@ -6506,7 +6916,7 @@ static void genLeftShiftLiteral (operand *left, int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit); int size; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); freeAsmop(right,NULL,ic,TRUE); aopOp(left,ic,FALSE); @@ -6515,14 +6925,14 @@ static void genLeftShiftLiteral (operand *left, size = getSize(operandType(result)); #if VIEW_SIZE - emitcode("; shift left ","result %d, left %d",size, + pic14_emitcode("; shift left ","result %d, left %d",size, AOP_SIZE(left)); #endif /* I suppose that the left size >= result size */ if(shCount == 0){ while(size--){ - movLeft2Result(left, size, result, size, 0); + movLeft2Result(left, size, result, size); } } @@ -6549,103 +6959,201 @@ static void genLeftShiftLiteral (operand *left, freeAsmop(result,NULL,ic,TRUE); } +/*-----------------------------------------------------------------* + * genMultiAsm - repeat assembly instruction for size of register. + * if endian == 1, then the high byte (i.e base address + size of + * register) is used first else the low byte is used first; + *-----------------------------------------------------------------*/ +static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian) +{ + + int offset = 0; + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if(!reg) + return; + + if(!endian) { + endian = 1; + } else { + endian = -1; + offset = size-1; + } + + while(size--) { + emitpcode(poc, popGet(AOP(reg),offset)); + offset += endian; + } + +} /*-----------------------------------------------------------------*/ /* genLeftShift - generates code for left shifting */ /*-----------------------------------------------------------------*/ static void genLeftShift (iCode *ic) { - operand *left,*right, *result; - int size, offset; - char *l; - symbol *tlbl , *tlbl1; + operand *left,*right, *result; + int size, offset; + char *l; + symbol *tlbl , *tlbl1; + pCodeOp *pctemp; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - right = IC_RIGHT(ic); - left = IC_LEFT(ic); - result = IC_RESULT(ic); + right = IC_RIGHT(ic); + left = IC_LEFT(ic); + result = IC_RESULT(ic); - aopOp(right,ic,FALSE); + aopOp(right,ic,FALSE); - /* if the shift count is known then do it - as efficiently as possible */ - if (AOP_TYPE(right) == AOP_LIT) { - genLeftShiftLiteral (left,right,result,ic); - return ; - } + /* if the shift count is known then do it + as efficiently as possible */ + if (AOP_TYPE(right) == AOP_LIT) { + genLeftShiftLiteral (left,right,result,ic); + return ; + } - /* shift count is unknown then we have to form - a loop get the loop count in B : Note: we take - only the lower order byte since shifting - more that 32 bits make no sense anyway, ( the - largest size of an object can be only 32 bits ) */ + /* shift count is unknown then we have to form + a loop get the loop count in B : Note: we take + only the lower order byte since shifting + more that 32 bits make no sense anyway, ( the + largest size of an object can be only 32 bits ) */ - emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); - emitcode("inc","b"); - freeAsmop (right,NULL,ic,TRUE); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); + + aopOp(left,ic,FALSE); + aopOp(result,ic,FALSE); - /* now move the left to the result if they are not the - same */ - if (!sameRegs(AOP(left),AOP(result)) && - AOP_SIZE(result) > 1) { + /* now move the left to the result if they are not the + same */ + if (!pic14_sameRegs(AOP(left),AOP(result)) && + AOP_SIZE(result) > 1) { - size = AOP_SIZE(result); - offset=0; - while (size--) { - l = aopGet(AOP(left),offset,FALSE,TRUE); - if (*l == '@' && (IS_AOP_PREG(result))) { + size = AOP_SIZE(result); + offset=0; + while (size--) { + l = aopGet(AOP(left),offset,FALSE,TRUE); + if (*l == '@' && (IS_AOP_PREG(result))) { - emitcode("mov","a,%s",l); - aopPut(AOP(result),"a",offset); - } else - aopPut(AOP(result),l,offset); - offset++; - } + pic14_emitcode("mov","a,%s",l); + aopPut(AOP(result),"a",offset); + } else { + emitpcode(POC_MOVFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + //aopPut(AOP(result),l,offset); + } + offset++; } + } - tlbl = newiTempLabel(NULL); - size = AOP_SIZE(result); - offset = 0 ; - tlbl1 = newiTempLabel(NULL); + size = AOP_SIZE(result); + + /* if it is only one byte then */ + if (size == 1) { + if(optimized_for_speed) { + emitpcode(POC_SWAPFW, popGet(AOP(left),0)); + emitpcode(POC_ANDLW, popGetLit(0xf0)); + emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0)); + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_MOVWF, popGet(AOP(result),0)); + emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0)); + emitpcode(POC_ADDWF, popGet(AOP(result),0)); + emitpcode(POC_RLFW, popGet(AOP(result),0)); + emitpcode(POC_ANDLW, popGetLit(0xfe)); + emitpcode(POC_ADDFW, popGet(AOP(result),0)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0)); + emitpcode(POC_ADDWF, popGet(AOP(result),0)); + } else { - /* if it is only one byte then */ - if (size == 1) { - symbol *tlbl1 = newiTempLabel(NULL); + tlbl = newiTempLabel(NULL); + if (!pic14_sameRegs(AOP(left),AOP(result))) { + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_MOVWF, popGet(AOP(result),0)); + } - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("sjmp","%05d_DS_",tlbl1->key+100); - emitcode("","%05d_DS_:",tlbl->key+100); - emitcode("add","a,acc"); - emitcode("","%05d_DS_:",tlbl1->key+100); - emitcode("djnz","b,%05d_DS_",tlbl->key+100); - aopPut(AOP(result),"a",0); - goto release ; + emitpcode(POC_COMFW, popGet(AOP(right),0)); + emitpcode(POC_RRF, popGet(AOP(result),0)); + emitpLabel(tlbl->key); + emitpcode(POC_RLF, popGet(AOP(result),0)); + emitpcode(POC_ADDLW, popGetLit(1)); + emitSKPC; + emitpcode(POC_GOTO,popGetLabel(tlbl->key)); } + goto release ; + } - reAdjustPreg(AOP(result)); + if (pic14_sameRegs(AOP(left),AOP(result))) { + + tlbl = newiTempLabel(NULL); + emitpcode(POC_COMFW, popGet(AOP(right),0)); + genMultiAsm(POC_RRF, result, size,1); + emitpLabel(tlbl->key); + genMultiAsm(POC_RLF, result, size,0); + emitpcode(POC_ADDLW, popGetLit(1)); + emitSKPC; + emitpcode(POC_GOTO,popGetLabel(tlbl->key)); + goto release; + } + + //tlbl = newiTempLabel(NULL); + //offset = 0 ; + //tlbl1 = newiTempLabel(NULL); + + //reAdjustPreg(AOP(result)); - emitcode("sjmp","%05d_DS_",tlbl1->key+100); - emitcode("","%05d_DS_:",tlbl->key+100); - l = aopGet(AOP(result),offset,FALSE,FALSE); - MOVA(l); - emitcode("add","a,acc"); - aopPut(AOP(result),"a",offset++); - while (--size) { - l = aopGet(AOP(result),offset,FALSE,FALSE); - MOVA(l); - emitcode("rlc","a"); - aopPut(AOP(result),"a",offset++); - } - reAdjustPreg(AOP(result)); + //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); + //pic14_emitcode("","%05d_DS_:",tlbl->key+100); + //l = aopGet(AOP(result),offset,FALSE,FALSE); + //MOVA(l); + //pic14_emitcode("add","a,acc"); + //aopPut(AOP(result),"a",offset++); + //while (--size) { + // l = aopGet(AOP(result),offset,FALSE,FALSE); + // MOVA(l); + // pic14_emitcode("rlc","a"); + // aopPut(AOP(result),"a",offset++); + //} + //reAdjustPreg(AOP(result)); - emitcode("","%05d_DS_:",tlbl1->key+100); - emitcode("djnz","b,%05d_DS_",tlbl->key+100); -release: - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); + //pic14_emitcode("","%05d_DS_:",tlbl1->key+100); + //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100); + + + tlbl = newiTempLabel(NULL); + tlbl1= newiTempLabel(NULL); + + size = AOP_SIZE(result); + offset = 1; + + pctemp = popGetTempReg(); /* grab a temporary working register. */ + + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + + /* offset should be 0, 1 or 3 */ + emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3))); + emitSKPNZ; + emitpcode(POC_GOTO, popGetLabel(tlbl1->key)); + + emitpcode(POC_MOVWF, pctemp); + + + emitpLabel(tlbl->key); + + emitCLRC; + emitpcode(POC_RLF, popGet(AOP(result),0)); + while(--size) + emitpcode(POC_RLF, popGet(AOP(result),offset++)); + + emitpcode(POC_DECFSZ, pctemp); + emitpcode(POC_GOTO,popGetLabel(tlbl->key)); + emitpLabel(tlbl1->key); + + popReleaseTempReg(pctemp); + + + release: + freeAsmop (right,NULL,ic,TRUE); + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -6654,7 +7162,7 @@ release: static void genrshOne (operand *result, operand *left, int shCount, int sign) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); shiftR1Left2Result(left, LSB, result, LSB, shCount, sign); } @@ -6662,23 +7170,29 @@ static void genrshOne (operand *result, operand *left, /* genrshTwo - right shift two bytes by known amount != 0 */ /*-----------------------------------------------------------------*/ static void genrshTwo (operand *result,operand *left, - int shCount, int sign) -{ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if shCount >= 8 */ - if (shCount >= 8) { - shCount -= 8 ; - if (shCount) - shiftR1Left2Result(left, MSB16, result, LSB, - shCount, sign); - else - movLeft2Result(left, MSB16, result, LSB, sign); - addSign(result, MSB16, sign); + int shCount, int sign) +{ + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* if shCount >= 8 */ + if (shCount >= 8) { + shCount -= 8 ; + if (shCount) + shiftR1Left2Result(left, MSB16, result, LSB, + shCount, sign); + else + movLeft2Result(left, MSB16, result, LSB); + + emitpcode(POC_CLRF,popGet(AOP(result),MSB16)); + + if(sign) { + emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0)); + emitpcode(POC_DECF, popGet(AOP(result),MSB16)); } + } - /* 1 <= shCount <= 7 */ - else - shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); + /* 1 <= shCount <= 7 */ + else + shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); } /*-----------------------------------------------------------------*/ @@ -6688,29 +7202,29 @@ static void genrshTwo (operand *result,operand *left, static void shiftRLong (operand *left, int offl, operand *result, int sign) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(!sign) - emitcode("clr","c"); + pic14_emitcode("clr","c"); MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE)); if(sign) - emitcode("mov","c,acc.7"); - emitcode("rrc","a"); + pic14_emitcode("mov","c,acc.7"); + pic14_emitcode("rrc","a"); aopPut(AOP(result),"a",MSB32-offl); if(offl == MSB16) /* add sign of "a" */ addSign(result, MSB32, sign); MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE)); - emitcode("rrc","a"); + pic14_emitcode("rrc","a"); aopPut(AOP(result),"a",MSB24-offl); MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE)); - emitcode("rrc","a"); + pic14_emitcode("rrc","a"); aopPut(AOP(result),"a",MSB16-offl); if(offl == LSB){ MOVA(aopGet(AOP(left),LSB,FALSE,FALSE)); - emitcode("rrc","a"); + pic14_emitcode("rrc","a"); aopPut(AOP(result),"a",LSB); } } @@ -6721,56 +7235,57 @@ static void shiftRLong (operand *left, int offl, static void genrshFour (operand *result, operand *left, int shCount, int sign) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if shifting more that 3 bytes */ - if(shCount >= 24 ) { - shCount -= 24; - if(shCount) - shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign); - else - movLeft2Result(left, MSB32, result, LSB, sign); - addSign(result, MSB16, sign); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* if shifting more that 3 bytes */ + if(shCount >= 24 ) { + shCount -= 24; + if(shCount) + shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign); + else + movLeft2Result(left, MSB32, result, LSB); + + addSign(result, MSB16, sign); + } + else if(shCount >= 16){ + shCount -= 16; + if(shCount) + shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign); + else{ + movLeft2Result(left, MSB24, result, LSB); + movLeft2Result(left, MSB32, result, MSB16); } - else if(shCount >= 16){ - shCount -= 16; - if(shCount) - shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign); - else{ - movLeft2Result(left, MSB24, result, LSB, 0); - movLeft2Result(left, MSB32, result, MSB16, sign); - } - addSign(result, MSB24, sign); + addSign(result, MSB24, sign); + } + else if(shCount >= 8){ + shCount -= 8; + if(shCount == 1) + shiftRLong(left, MSB16, result, sign); + else if(shCount == 0){ + movLeft2Result(left, MSB16, result, LSB); + movLeft2Result(left, MSB24, result, MSB16); + movLeft2Result(left, MSB32, result, MSB24); + addSign(result, MSB32, sign); } - else if(shCount >= 8){ - shCount -= 8; - if(shCount == 1) - shiftRLong(left, MSB16, result, sign); - else if(shCount == 0){ - movLeft2Result(left, MSB16, result, LSB, 0); - movLeft2Result(left, MSB24, result, MSB16, 0); - movLeft2Result(left, MSB32, result, MSB24, sign); - addSign(result, MSB32, sign); - } - else{ - shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0); - shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount); - /* the last shift is signed */ - shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign); - addSign(result, MSB32, sign); - } + else{ + shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0); + shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount); + /* the last shift is signed */ + shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign); + addSign(result, MSB32, sign); } - else{ /* 1 <= shCount <= 7 */ - if(shCount <= 2){ - shiftRLong(left, LSB, result, sign); - if(shCount == 2) - shiftRLong(result, LSB, result, sign); - } - else{ - shiftR2Left2Result(left, LSB, result, LSB, shCount, 0); - shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount); - shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign); - } + } + else{ /* 1 <= shCount <= 7 */ + if(shCount <= 2){ + shiftRLong(left, LSB, result, sign); + if(shCount == 2) + shiftRLong(result, LSB, result, sign); + } + else{ + shiftR2Left2Result(left, LSB, result, LSB, shCount, 0); + shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount); + shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign); } + } } /*-----------------------------------------------------------------*/ @@ -6782,55 +7297,75 @@ static void genRightShiftLiteral (operand *left, iCode *ic, int sign) { - int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit); - int size; + int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit); + int lsize,res_size; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - freeAsmop(right,NULL,ic,TRUE); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + freeAsmop(right,NULL,ic,TRUE); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); + aopOp(left,ic,FALSE); + aopOp(result,ic,FALSE); #if VIEW_SIZE - emitcode("; shift right ","result %d, left %d",AOP_SIZE(result), - AOP_SIZE(left)); + pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result), + AOP_SIZE(left)); #endif - size = getDataSize(left); - /* test the LEFT size !!! */ + lsize = pic14_getDataSize(left); + res_size = pic14_getDataSize(result); + /* test the LEFT size !!! */ - /* I suppose that the left size >= result size */ - if(shCount == 0){ - size = getDataSize(result); - while(size--) - movLeft2Result(left, size, result, size, 0); - } + /* I suppose that the left size >= result size */ + if(shCount == 0){ + while(res_size--) + movLeft2Result(left, lsize, result, res_size); + } - else if(shCount >= (size * 8)){ - if(sign) - /* get sign in acc.7 */ - MOVA(aopGet(AOP(left),size-1,FALSE,FALSE)); - addSign(result, LSB, sign); - } else{ - switch (size) { - case 1: - genrshOne (result,left,shCount,sign); - break; + else if(shCount >= (lsize * 8)){ - case 2: - genrshTwo (result,left,shCount,sign); - break; + if(res_size == 1) { + emitpcode(POC_CLRF, popGet(AOP(result),LSB)); + if(sign) { + emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0)); + emitpcode(POC_DECF, popGet(AOP(result),LSB)); + } + } else { - case 4: - genrshFour (result,left,shCount,sign); - break; - default : - break; - } + if(sign) { + emitpcode(POC_MOVLW, popGetLit(0)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0)); + emitpcode(POC_MOVLW, popGetLit(0xff)); + while(res_size--) + emitpcode(POC_MOVWF, popGet(AOP(result),res_size)); + + } else { + + while(res_size--) + emitpcode(POC_CLRF, popGet(AOP(result),res_size)); + } + } + } else { + + switch (res_size) { + case 1: + genrshOne (result,left,shCount,sign); + break; + + case 2: + genrshTwo (result,left,shCount,sign); + break; - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); + case 4: + genrshFour (result,left,shCount,sign); + break; + default : + break; } + + } + + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -6838,97 +7373,140 @@ static void genRightShiftLiteral (operand *left, /*-----------------------------------------------------------------*/ static void genSignedRightShift (iCode *ic) { - operand *right, *left, *result; - int size, offset; - char *l; - symbol *tlbl, *tlbl1 ; + operand *right, *left, *result; + int size, offset; + // char *l; + symbol *tlbl, *tlbl1 ; + pCodeOp *pctemp; - /* we do it the hard way put the shift count in b - and loop thru preserving the sign */ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr); - right = IC_RIGHT(ic); - left = IC_LEFT(ic); - result = IC_RESULT(ic); + /* we do it the hard way put the shift count in b + and loop thru preserving the sign */ + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - aopOp(right,ic,FALSE); + right = IC_RIGHT(ic); + left = IC_LEFT(ic); + result = IC_RESULT(ic); + aopOp(right,ic,FALSE); + aopOp(left,ic,FALSE); + aopOp(result,ic,FALSE); - if ( AOP_TYPE(right) == AOP_LIT) { - genRightShiftLiteral (left,right,result,ic,1); - return ; - } - /* shift count is unknown then we have to form - a loop get the loop count in B : Note: we take - only the lower order byte since shifting - more that 32 bits make no sense anyway, ( the - largest size of an object can be only 32 bits ) */ - emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); - emitcode("inc","b"); - freeAsmop (right,NULL,ic,TRUE); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); + if ( AOP_TYPE(right) == AOP_LIT) { + genRightShiftLiteral (left,right,result,ic,1); + return ; + } + /* shift count is unknown then we have to form + a loop get the loop count in B : Note: we take + only the lower order byte since shifting + more that 32 bits make no sense anyway, ( the + largest size of an object can be only 32 bits ) */ + + //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); + //pic14_emitcode("inc","b"); + //freeAsmop (right,NULL,ic,TRUE); + //aopOp(left,ic,FALSE); + //aopOp(result,ic,FALSE); + + /* now move the left to the result if they are not the + same */ + if (!pic14_sameRegs(AOP(left),AOP(result)) && + AOP_SIZE(result) > 1) { - /* now move the left to the result if they are not the - same */ - if (!sameRegs(AOP(left),AOP(result)) && - AOP_SIZE(result) > 1) { + size = AOP_SIZE(result); + offset=0; + while (size--) { + /* + l = aopGet(AOP(left),offset,FALSE,TRUE); + if (*l == '@' && IS_AOP_PREG(result)) { - size = AOP_SIZE(result); - offset=0; - while (size--) { - l = aopGet(AOP(left),offset,FALSE,TRUE); - if (*l == '@' && IS_AOP_PREG(result)) { + pic14_emitcode("mov","a,%s",l); + aopPut(AOP(result),"a",offset); + } else + aopPut(AOP(result),l,offset); + */ + emitpcode(POC_MOVFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - emitcode("mov","a,%s",l); - aopPut(AOP(result),"a",offset); - } else - aopPut(AOP(result),l,offset); - offset++; - } + offset++; } + } - /* mov the highest order bit to OVR */ - tlbl = newiTempLabel(NULL); - tlbl1= newiTempLabel(NULL); + /* mov the highest order bit to OVR */ + tlbl = newiTempLabel(NULL); + tlbl1= newiTempLabel(NULL); - size = AOP_SIZE(result); - offset = size - 1; - emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("rlc","a"); - emitcode("mov","ov,c"); - /* if it is only one byte then */ - if (size == 1) { - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("sjmp","%05d_DS_",tlbl1->key+100); - emitcode("","%05d_DS_:",tlbl->key+100); - emitcode("mov","c,ov"); - emitcode("rrc","a"); - emitcode("","%05d_DS_:",tlbl1->key+100); - emitcode("djnz","b,%05d_DS_",tlbl->key+100); - aopPut(AOP(result),"a",0); - goto release ; - } + size = AOP_SIZE(result); + offset = size - 1; - reAdjustPreg(AOP(result)); - emitcode("sjmp","%05d_DS_",tlbl1->key+100); - emitcode("","%05d_DS_:",tlbl->key+100); - emitcode("mov","c,ov"); - while (size--) { - l = aopGet(AOP(result),offset,FALSE,FALSE); - MOVA(l); - emitcode("rrc","a"); - aopPut(AOP(result),"a",offset--); - } - reAdjustPreg(AOP(result)); - emitcode("","%05d_DS_:",tlbl1->key+100); - emitcode("djnz","b,%05d_DS_",tlbl->key+100); + pctemp = popGetTempReg(); /* grab a temporary working register. */ -release: - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + + /* offset should be 0, 1 or 3 */ + emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3))); + emitSKPNZ; + emitpcode(POC_GOTO, popGetLabel(tlbl1->key)); + + emitpcode(POC_MOVWF, pctemp); + + + emitpLabel(tlbl->key); + + emitpcode(POC_RLFW, popGet(AOP(result),offset)); + emitpcode(POC_RRF, popGet(AOP(result),offset)); + + while(--size) { + emitpcode(POC_RRF, popGet(AOP(result),--offset)); + } + + emitpcode(POC_DECFSZ, pctemp); + emitpcode(POC_GOTO,popGetLabel(tlbl->key)); + emitpLabel(tlbl1->key); + + popReleaseTempReg(pctemp); +#if 0 + size = AOP_SIZE(result); + offset = size - 1; + pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE)); + pic14_emitcode("rlc","a"); + pic14_emitcode("mov","ov,c"); + /* if it is only one byte then */ + if (size == 1) { + l = aopGet(AOP(left),0,FALSE,FALSE); + MOVA(l); + pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_emitcode("mov","c,ov"); + pic14_emitcode("rrc","a"); + pic14_emitcode("","%05d_DS_:",tlbl1->key+100); + pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100); + aopPut(AOP(result),"a",0); + goto release ; + } + + reAdjustPreg(AOP(result)); + pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_emitcode("mov","c,ov"); + while (size--) { + l = aopGet(AOP(result),offset,FALSE,FALSE); + MOVA(l); + pic14_emitcode("rrc","a"); + aopPut(AOP(result),"a",offset--); + } + reAdjustPreg(AOP(result)); + pic14_emitcode("","%05d_DS_:",tlbl1->key+100); + pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100); + + release: +#endif + + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); + freeAsmop(right,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -6945,7 +7523,7 @@ static void genRightShift (iCode *ic) /* if signed then we do it the hard way preserve the sign bit moving it inwards */ retype = getSpec(operandType(IC_RESULT(ic))); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (!SPEC_USIGN(retype)) { genSignedRightShift (ic); @@ -6978,15 +7556,14 @@ static void genRightShift (iCode *ic) more that 32 bits make no sense anyway, ( the largest size of an object can be only 32 bits ) */ - emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); - emitcode("inc","b"); - freeAsmop (right,NULL,ic,TRUE); + pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); + pic14_emitcode("inc","b"); aopOp(left,ic,FALSE); aopOp(result,ic,FALSE); /* now move the left to the result if they are not the same */ - if (!sameRegs(AOP(left),AOP(result)) && + if (!pic14_sameRegs(AOP(left),AOP(result)) && AOP_SIZE(result) > 1) { size = AOP_SIZE(result); @@ -6995,7 +7572,7 @@ static void genRightShift (iCode *ic) l = aopGet(AOP(left),offset,FALSE,TRUE); if (*l == '@' && IS_AOP_PREG(result)) { - emitcode("mov","a,%s",l); + pic14_emitcode("mov","a,%s",l); aopPut(AOP(result),"a",offset); } else aopPut(AOP(result),l,offset); @@ -7010,35 +7587,42 @@ static void genRightShift (iCode *ic) /* if it is only one byte then */ if (size == 1) { - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("sjmp","%05d_DS_",tlbl1->key+100); - emitcode("","%05d_DS_:",tlbl->key+100); - CLRC; - emitcode("rrc","a"); - emitcode("","%05d_DS_:",tlbl1->key+100); - emitcode("djnz","b,%05d_DS_",tlbl->key+100); - aopPut(AOP(result),"a",0); - goto release ; + + tlbl = newiTempLabel(NULL); + if (!pic14_sameRegs(AOP(left),AOP(result))) { + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_MOVWF, popGet(AOP(result),0)); + } + + emitpcode(POC_COMFW, popGet(AOP(right),0)); + emitpcode(POC_RLF, popGet(AOP(result),0)); + emitpLabel(tlbl->key); + emitpcode(POC_RRF, popGet(AOP(result),0)); + emitpcode(POC_ADDLW, popGetLit(1)); + emitSKPC; + emitpcode(POC_GOTO,popGetLabel(tlbl->key)); + + goto release ; } reAdjustPreg(AOP(result)); - emitcode("sjmp","%05d_DS_",tlbl1->key+100); - emitcode("","%05d_DS_:",tlbl->key+100); + pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); CLRC; while (size--) { l = aopGet(AOP(result),offset,FALSE,FALSE); MOVA(l); - emitcode("rrc","a"); + pic14_emitcode("rrc","a"); aopPut(AOP(result),"a",offset--); } reAdjustPreg(AOP(result)); - emitcode("","%05d_DS_:",tlbl1->key+100); - emitcode("djnz","b,%05d_DS_",tlbl->key+100); + pic14_emitcode("","%05d_DS_:",tlbl1->key+100); + pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100); release: freeAsmop(left,NULL,ic,TRUE); + freeAsmop (right,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); } @@ -7052,7 +7636,7 @@ static void genUnpackBits (operand *result, char *rname, int ptype) sym_link *etype; int offset = 0 ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); etype = getSpec(operandType(result)); /* read the first byte */ @@ -7060,24 +7644,24 @@ static void genUnpackBits (operand *result, char *rname, int ptype) case POINTER: case IPOINTER: - emitcode("mov","a,@%s",rname); + pic14_emitcode("mov","a,@%s",rname); break; case PPOINTER: - emitcode("movx","a,@%s",rname); + pic14_emitcode("movx","a,@%s",rname); break; case FPOINTER: - emitcode("movx","a,@dptr"); + pic14_emitcode("movx","a,@dptr"); break; case CPOINTER: - emitcode("clr","a"); - emitcode("movc","a","@a+dptr"); + pic14_emitcode("clr","a"); + pic14_emitcode("movc","a","@a+dptr"); break; case GPOINTER: - emitcode("lcall","__gptrget"); + pic14_emitcode("lcall","__gptrget"); break; } @@ -7090,7 +7674,7 @@ static void genUnpackBits (operand *result, char *rname, int ptype) /* shift right acc */ AccRsh(shCnt); - emitcode("anl","a,#0x%02x", + pic14_emitcode("anl","a,#0x%02x", ((unsigned char) -1)>>(8 - SPEC_BLEN(etype))); aopPut(AOP(result),"a",offset); return ; @@ -7105,29 +7689,29 @@ static void genUnpackBits (operand *result, char *rname, int ptype) switch (ptype) { case POINTER: case IPOINTER: - emitcode("inc","%s",rname); - emitcode("mov","a,@%s",rname); + pic14_emitcode("inc","%s",rname); + pic14_emitcode("mov","a,@%s",rname); break; case PPOINTER: - emitcode("inc","%s",rname); - emitcode("movx","a,@%s",rname); + pic14_emitcode("inc","%s",rname); + pic14_emitcode("movx","a,@%s",rname); break; case FPOINTER: - emitcode("inc","dptr"); - emitcode("movx","a,@dptr"); + pic14_emitcode("inc","dptr"); + pic14_emitcode("movx","a,@dptr"); break; case CPOINTER: - emitcode("clr","a"); - emitcode("inc","dptr"); - emitcode("movc","a","@a+dptr"); + pic14_emitcode("clr","a"); + pic14_emitcode("inc","dptr"); + pic14_emitcode("movc","a","@a+dptr"); break; case GPOINTER: - emitcode("inc","dptr"); - emitcode("lcall","__gptrget"); + pic14_emitcode("inc","dptr"); + pic14_emitcode("lcall","__gptrget"); break; } @@ -7141,7 +7725,7 @@ static void genUnpackBits (operand *result, char *rname, int ptype) } if (rlen) { - emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen)); + pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen)); aopPut(AOP(result),"a",offset); } @@ -7156,31 +7740,36 @@ static void genDataPointerGet (operand *left, operand *result, iCode *ic) { - char *l; - char buffer[256]; - int size , offset = 0; - aopOp(result,ic,TRUE); + int size , offset = 0; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* get the string representation of the name */ - l = aopGet(AOP(left),0,FALSE,TRUE); - size = AOP_SIZE(result); - // tsd, was l+1 - the underline `_' prefix was being stripped - while (size--) { - if (offset) - sprintf(buffer,"(%s + %d)",l,offset); - else - sprintf(buffer,"%s",l); - aopPut(AOP(result),buffer,offset++); - } + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); + + /* optimization - most of the time, left and result are the same + * address, but different types. for the pic code, we could omit + * the following + */ + + aopOp(result,ic,TRUE); + + DEBUGpic14_AopType(__LINE__,left,NULL,result); + + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + + size = AOP_SIZE(result); + + while (size--) { + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + offset++; + } + + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ -/* genNearPointerGet - emitcode for near pointer fetch */ +/* genNearPointerGet - pic14_emitcode for near pointer fetch */ /*-----------------------------------------------------------------*/ static void genNearPointerGet (operand *left, operand *result, @@ -7193,7 +7782,7 @@ static void genNearPointerGet (operand *left, sym_link *ltype = operandType(left); char buffer[80]; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); rtype = operandType(result); retype= getSpec(rtype); @@ -7204,20 +7793,23 @@ static void genNearPointerGet (operand *left, result is not bit variable type and the left is pointer to data space i.e lower 128 bytes of space */ - if (AOP_TYPE(left) == AOP_IMMD && + if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD && !IS_BITVAR(retype) && DCL_TYPE(ltype) == POINTER) { - genDataPointerGet (left,result,ic); + //genDataPointerGet (left,result,ic); return ; } + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* if the value is already in a pointer register then don't need anything more */ if (!AOP_INPREG(AOP(left))) { /* otherwise get a free pointer register */ + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aop = newAsmop(0); preg = getFreePtr(ic,&aop,FALSE); - emitcode("mov","%s,%s", + pic14_emitcode("mov","%s,%s", preg->name, aopGet(AOP(left),0,FALSE,TRUE)); rname = preg->name ; @@ -7235,10 +7827,11 @@ static void genNearPointerGet (operand *left, int size = AOP_SIZE(result); int offset = 0 ; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); while (size--) { if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) { - emitcode("mov","a,@%s",rname); + pic14_emitcode("mov","a,@%s",rname); aopPut(AOP(result),"a",offset); } else { sprintf(buffer,"@%s",rname); @@ -7246,13 +7839,14 @@ static void genNearPointerGet (operand *left, } offset++ ; if (size) - emitcode("inc","%s",rname); + pic14_emitcode("inc","%s",rname); } } /* now some housekeeping stuff */ if (aop) { /* we had to allocate for this iCode */ + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); freeAsmop(NULL,aop,ic,TRUE); } else { /* we did not allocate which means left @@ -7260,13 +7854,14 @@ static void genNearPointerGet (operand *left, if size > 0 && this could be used again we have to point it back to where it belongs */ + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (AOP_SIZE(result) > 1 && !OP_SYMBOL(left)->remat && ( OP_SYMBOL(left)->liveTo > ic->seq || ic->depth )) { int size = AOP_SIZE(result) - 1; while (size--) - emitcode("dec","%s",rname); + pic14_emitcode("dec","%s",rname); } } @@ -7276,7 +7871,7 @@ static void genNearPointerGet (operand *left, } /*-----------------------------------------------------------------*/ -/* genPagedPointerGet - emitcode for paged pointer fetch */ +/* genPagedPointerGet - pic14_emitcode for paged pointer fetch */ /*-----------------------------------------------------------------*/ static void genPagedPointerGet (operand *left, operand *result, @@ -7287,7 +7882,7 @@ static void genPagedPointerGet (operand *left, char *rname ; sym_link *rtype, *retype; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); rtype = operandType(result); retype= getSpec(rtype); @@ -7300,7 +7895,7 @@ static void genPagedPointerGet (operand *left, /* otherwise get a free pointer register */ aop = newAsmop(0); preg = getFreePtr(ic,&aop,FALSE); - emitcode("mov","%s,%s", + pic14_emitcode("mov","%s,%s", preg->name, aopGet(AOP(left),0,FALSE,TRUE)); rname = preg->name ; @@ -7320,13 +7915,13 @@ static void genPagedPointerGet (operand *left, while (size--) { - emitcode("movx","a,@%s",rname); + pic14_emitcode("movx","a,@%s",rname); aopPut(AOP(result),"a",offset); offset++ ; if (size) - emitcode("inc","%s",rname); + pic14_emitcode("inc","%s",rname); } } @@ -7346,7 +7941,7 @@ static void genPagedPointerGet (operand *left, ic->depth )) { int size = AOP_SIZE(result) - 1; while (size--) - emitcode("dec","%s",rname); + pic14_emitcode("dec","%s",rname); } } @@ -7365,7 +7960,7 @@ static void genFarPointerGet (operand *left, int size, offset ; sym_link *retype = getSpec(operandType(result)); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(left,ic,FALSE); @@ -7374,13 +7969,13 @@ static void genFarPointerGet (operand *left, if (AOP_TYPE(left) != AOP_STR) { /* if this is remateriazable */ if (AOP_TYPE(left) == AOP_IMMD) - emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE)); + pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE)); else { /* we need to get it byte by byte */ - emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE)); - emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE)); + pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE)); + pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE)); if (options.model == MODEL_FLAT24) { - emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE)); + pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE)); } } } @@ -7396,26 +7991,26 @@ static void genFarPointerGet (operand *left, offset = 0 ; while (size--) { - emitcode("movx","a,@dptr"); + pic14_emitcode("movx","a,@dptr"); aopPut(AOP(result),"a",offset++); if (size) - emitcode("inc","dptr"); + pic14_emitcode("inc","dptr"); } } freeAsmop(result,NULL,ic,TRUE); } - +#if 0 /*-----------------------------------------------------------------*/ -/* emitcodePointerGet - gget value from code space */ +/* genCodePointerGet - get value from code space */ /*-----------------------------------------------------------------*/ -static void emitcodePointerGet (operand *left, +static void genCodePointerGet (operand *left, operand *result, iCode *ic) { int size, offset ; sym_link *retype = getSpec(operandType(result)); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(left,ic,FALSE); @@ -7424,13 +8019,13 @@ static void emitcodePointerGet (operand *left, if (AOP_TYPE(left) != AOP_STR) { /* if this is remateriazable */ if (AOP_TYPE(left) == AOP_IMMD) - emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE)); + pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE)); else { /* we need to get it byte by byte */ - emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE)); - emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE)); + pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE)); + pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE)); if (options.model == MODEL_FLAT24) { - emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE)); + pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE)); } } } @@ -7446,87 +8041,110 @@ static void emitcodePointerGet (operand *left, offset = 0 ; while (size--) { - emitcode("clr","a"); - emitcode("movc","a,@a+dptr"); + pic14_emitcode("clr","a"); + pic14_emitcode("movc","a,@a+dptr"); aopPut(AOP(result),"a",offset++); if (size) - emitcode("inc","dptr"); + pic14_emitcode("inc","dptr"); } } freeAsmop(result,NULL,ic,TRUE); } - +#endif /*-----------------------------------------------------------------*/ /* genGenPointerGet - gget value from generic pointer space */ /*-----------------------------------------------------------------*/ static void genGenPointerGet (operand *left, operand *result, iCode *ic) { - int size, offset ; - sym_link *retype = getSpec(operandType(result)); + int size, offset ; + sym_link *retype = getSpec(operandType(result)); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - aopOp(left,ic,FALSE); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + aopOp(left,ic,FALSE); + aopOp(result,ic,FALSE); - /* if the operand is already in dptr - then we do nothing else we move the value to dptr */ - if (AOP_TYPE(left) != AOP_STR) { - /* if this is remateriazable */ - if (AOP_TYPE(left) == AOP_IMMD) { - emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE)); - emitcode("mov","b,#%d",pointerCode(retype)); - } - else { /* we need to get it byte by byte */ - - emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE)); - emitpcode(POC_MOVWF,popCopy(&pc_fsr)); - emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE)); - emitcode("movwf","FSR"); - /* - emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE)); - emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE)); - if (options.model == MODEL_FLAT24) - { - emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE)); - emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE)); - } - else - { - emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE)); - } - */ - } + + DEBUGpic14_AopType(__LINE__,left,NULL,result); + + /* if the operand is already in dptr + then we do nothing else we move the value to dptr */ + // if (AOP_TYPE(left) != AOP_STR) { + /* if this is remateriazable */ + if (AOP_TYPE(left) == AOP_IMMD) { + pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE)); + pic14_emitcode("mov","b,#%d",pointerCode(retype)); } - /* so dptr know contains the address */ - freeAsmop(left,NULL,ic,TRUE); - aopOp(result,ic,FALSE); + else { /* we need to get it byte by byte */ - /* if bit then unpack */ - if (IS_BITVAR(retype)) - genUnpackBits(result,"dptr",GPOINTER); - else { - size = AOP_SIZE(result); - offset = 0 ; + emitpcode(POC_MOVFW,popGet(AOP(left),0)); + emitpcode(POC_MOVWF,popCopyReg(&pc_fsr)); - while (size--) { - emitpcode(POC_MOVFW,popCopy(&pc_fsr)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE)); - if(size) - emitpcode(POC_INCF,popCopy(&pc_fsr)); -/* - emitcode("movf","indf,w"); - emitcode("movwf","%s", - aopGet(AOP(result),offset++,FALSE,FALSE)); - if (size) - emitcode("incf","fsr,f"); -*/ - } + size = AOP_SIZE(result); + offset = 0 ; + + while(size--) { + emitpcode(POC_MOVFW,popCopyReg(&pc_indf)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset++)); + if(size) + emitpcode(POC_INCF,popCopyReg(&pc_fsr)); + } + goto release; } + //} + /* so dptr know contains the address */ + + /* if bit then unpack */ + //if (IS_BITVAR(retype)) + // genUnpackBits(result,"dptr",GPOINTER); + + release: + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); } +/*-----------------------------------------------------------------*/ +/* genConstPointerGet - get value from const generic pointer space */ +/*-----------------------------------------------------------------*/ +static void genConstPointerGet (operand *left, + operand *result, iCode *ic) +{ + //sym_link *retype = getSpec(operandType(result)); + symbol *albl = newiTempLabel(NULL); + symbol *blbl = newiTempLabel(NULL); + PIC_OPCODE poc; + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + aopOp(left,ic,FALSE); + aopOp(result,ic,FALSE); + + + DEBUGpic14_AopType(__LINE__,left,NULL,result); + + DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__); + + emitpcode(POC_CALL,popGetLabel(albl->key)); + emitpcode(POC_GOTO,popGetLabel(blbl->key)); + emitpLabel(albl->key); + + poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW); + + emitpcode(poc,popGet(AOP(left),1)); + emitpcode(POC_MOVWF,popCopyReg(&pc_pclath)); + emitpcode(poc,popGet(AOP(left),0)); + emitpcode(POC_MOVWF,popCopyReg(&pc_pcl)); + + emitpLabel(blbl->key); + + emitpcode(POC_MOVWF,popGet(AOP(result),0)); + + + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); + +} /*-----------------------------------------------------------------*/ /* genPointerGet - generate code for pointer get */ /*-----------------------------------------------------------------*/ @@ -7536,7 +8154,7 @@ static void genPointerGet (iCode *ic) sym_link *type, *etype; int p_type; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); left = IC_LEFT(ic); result = IC_RESULT(ic) ; @@ -7545,26 +8163,37 @@ static void genPointerGet (iCode *ic) move it to the correct pointer register */ type = operandType(left); etype = getSpec(type); + + if (IS_PTR_CONST(type)) + DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__); + /* if left is of type of pointer then it is simple */ if (IS_PTR(type) && !IS_FUNC(type->next)) p_type = DCL_TYPE(type); else { - /* we have to go by the storage class */ - p_type = PTR_TYPE(SPEC_OCLS(etype)); - -/* if (SPEC_OCLS(etype)->codesp ) { */ -/* p_type = CPOINTER ; */ -/* } */ -/* else */ -/* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */ -/* p_type = FPOINTER ; */ -/* else */ -/* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */ + /* we have to go by the storage class */ + p_type = PTR_TYPE(SPEC_OCLS(etype)); + + DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__); + + if (SPEC_OCLS(etype)->codesp ) { + DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__); + //p_type = CPOINTER ; + } + else + if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) + DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__); + /*p_type = FPOINTER ;*/ + else + if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) + DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__); /* p_type = PPOINTER; */ -/* else */ -/* if (SPEC_OCLS(etype) == idata ) */ + else + if (SPEC_OCLS(etype) == idata ) + DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__); /* p_type = IPOINTER; */ -/* else */ + else + DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__); /* p_type = POINTER ; */ } @@ -7586,12 +8215,16 @@ static void genPointerGet (iCode *ic) break; case CPOINTER: - emitcodePointerGet (left,result,ic); + genConstPointerGet (left,result,ic); + //pic14_emitcodePointerGet (left,result,ic); break; case GPOINTER: + if (IS_PTR_CONST(type)) + genConstPointerGet (left,result,ic); + else genGenPointerGet (left,result,ic); - break; + break; } } @@ -7609,7 +8242,7 @@ static void genPackBits (sym_link *etype , int blen, bstr ; char *l ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); blen = SPEC_BLEN(etype); bstr = SPEC_BSTR(etype); @@ -7629,43 +8262,43 @@ static void genPackBits (sym_link *etype , switch (p_type) { case POINTER: - emitcode ("mov","b,a"); - emitcode("mov","a,@%s",rname); + pic14_emitcode ("mov","b,a"); + pic14_emitcode("mov","a,@%s",rname); break; case FPOINTER: - emitcode ("mov","b,a"); - emitcode("movx","a,@dptr"); + pic14_emitcode ("mov","b,a"); + pic14_emitcode("movx","a,@dptr"); break; case GPOINTER: - emitcode ("push","b"); - emitcode ("push","acc"); - emitcode ("lcall","__gptrget"); - emitcode ("pop","b"); + pic14_emitcode ("push","b"); + pic14_emitcode ("push","acc"); + pic14_emitcode ("lcall","__gptrget"); + pic14_emitcode ("pop","b"); break; } - emitcode ("anl","a,#0x%02x",(unsigned char) + pic14_emitcode ("anl","a,#0x%02x",(unsigned char) ((unsigned char)(0xFF << (blen+bstr)) | (unsigned char)(0xFF >> (8-bstr)) ) ); - emitcode ("orl","a,b"); + pic14_emitcode ("orl","a,b"); if (p_type == GPOINTER) - emitcode("pop","b"); + pic14_emitcode("pop","b"); } } switch (p_type) { case POINTER: - emitcode("mov","@%s,a",rname); + pic14_emitcode("mov","@%s,a",rname); break; case FPOINTER: - emitcode("movx","@dptr,a"); + pic14_emitcode("movx","@dptr,a"); break; case GPOINTER: - DEBUGemitcode(";lcall","__gptrput"); + DEBUGpic14_emitcode(";lcall","__gptrput"); break; } @@ -7673,7 +8306,7 @@ static void genPackBits (sym_link *etype , if ( SPEC_BLEN(etype) <= 8 ) return ; - emitcode("inc","%s",rname); + pic14_emitcode("inc","%s",rname); rLen = SPEC_BLEN(etype) ; /* now generate for lengths greater than one byte */ @@ -7689,22 +8322,22 @@ static void genPackBits (sym_link *etype , case POINTER: if (*l == '@') { MOVA(l); - emitcode("mov","@%s,a",rname); + pic14_emitcode("mov","@%s,a",rname); } else - emitcode("mov","@%s,%s",rname,l); + pic14_emitcode("mov","@%s,%s",rname,l); break; case FPOINTER: MOVA(l); - emitcode("movx","@dptr,a"); + pic14_emitcode("movx","@dptr,a"); break; case GPOINTER: MOVA(l); - DEBUGemitcode(";lcall","__gptrput"); + DEBUGpic14_emitcode(";lcall","__gptrput"); break; } - emitcode ("inc","%s",rname); + pic14_emitcode ("inc","%s",rname); } MOVA(l); @@ -7714,42 +8347,42 @@ static void genPackBits (sym_link *etype , /* save the byte & read byte */ switch (p_type) { case POINTER: - emitcode ("mov","b,a"); - emitcode("mov","a,@%s",rname); + pic14_emitcode ("mov","b,a"); + pic14_emitcode("mov","a,@%s",rname); break; case FPOINTER: - emitcode ("mov","b,a"); - emitcode("movx","a,@dptr"); + pic14_emitcode ("mov","b,a"); + pic14_emitcode("movx","a,@dptr"); break; case GPOINTER: - emitcode ("push","b"); - emitcode ("push","acc"); - emitcode ("lcall","__gptrget"); - emitcode ("pop","b"); + pic14_emitcode ("push","b"); + pic14_emitcode ("push","acc"); + pic14_emitcode ("lcall","__gptrget"); + pic14_emitcode ("pop","b"); break; } - emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) ); - emitcode ("orl","a,b"); + pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) ); + pic14_emitcode ("orl","a,b"); } if (p_type == GPOINTER) - emitcode("pop","b"); + pic14_emitcode("pop","b"); switch (p_type) { case POINTER: - emitcode("mov","@%s,a",rname); + pic14_emitcode("mov","@%s,a",rname); break; case FPOINTER: - emitcode("movx","@dptr,a"); + pic14_emitcode("movx","@dptr,a"); break; case GPOINTER: - DEBUGemitcode(";lcall","__gptrput"); + DEBUGpic14_emitcode(";lcall","__gptrput"); break; } } @@ -7763,29 +8396,51 @@ static void genDataPointerSet(operand *right, int size, offset = 0 ; char *l, buffer[256]; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(right,ic,FALSE); l = aopGet(AOP(result),0,FALSE,TRUE); size = AOP_SIZE(right); +/* + if ( AOP_TYPE(result) == AOP_PCODE) { + fprintf(stderr,"genDataPointerSet %s, %d\n", + AOP(result)->aopu.pcop->name, + PCOI(AOP(result)->aopu.pcop)->offset); + } +*/ + // tsd, was l+1 - the underline `_' prefix was being stripped while (size--) { - if (offset) - sprintf(buffer,"(%s + %d)",l,offset); - else - sprintf(buffer,"%s",l); + if (offset) { + sprintf(buffer,"(%s + %d)",l,offset); + fprintf(stderr,"oops %s\n",buffer); + } else + sprintf(buffer,"%s",l); if (AOP_TYPE(right) == AOP_LIT) { - unsigned int lit = floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); + unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); lit = lit >> (8*offset); - if(lit) { - emitcode("movlw","%s",lit); - emitcode("movwf","%s",buffer); - } else - emitcode("clrf","%s",buffer); + if(lit&0xff) { + pic14_emitcode("movlw","%d",lit); + pic14_emitcode("movwf","%s",buffer); + + emitpcode(POC_MOVLW, popGetLit(lit&0xff)); + //emitpcode(POC_MOVWF, popRegFromString(buffer)); + emitpcode(POC_MOVWF, popGet(AOP(result),0)); + + } else { + pic14_emitcode("clrf","%s",buffer); + //emitpcode(POC_CLRF, popRegFromString(buffer)); + emitpcode(POC_CLRF, popGet(AOP(result),0)); + } }else { - emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("movwf","%s",buffer); + pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode("movwf","%s",buffer); + + emitpcode(POC_MOVFW, popGet(AOP(right),offset)); + //emitpcode(POC_MOVWF, popRegFromString(buffer)); + emitpcode(POC_MOVWF, popGet(AOP(result),0)); + } offset++; @@ -7796,7 +8451,7 @@ static void genDataPointerSet(operand *right, } /*-----------------------------------------------------------------*/ -/* genNearPointerSet - emitcode for near pointer put */ +/* genNearPointerSet - pic14_emitcode for near pointer put */ /*-----------------------------------------------------------------*/ static void genNearPointerSet (operand *right, operand *result, @@ -7808,21 +8463,22 @@ static void genNearPointerSet (operand *right, sym_link *ptype = operandType(result); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); retype= getSpec(operandType(right)); aopOp(result,ic,FALSE); /* if the result is rematerializable & in data space & not a bit variable */ - if (AOP_TYPE(result) == AOP_IMMD && - DCL_TYPE(ptype) == POINTER && + //if (AOP_TYPE(result) == AOP_IMMD && + if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD && + DCL_TYPE(ptype) == POINTER && !IS_BITVAR(retype)) { genDataPointerSet (right,result,ic); return; } - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if the value is already in a pointer register then don't need anything more */ @@ -7830,18 +8486,18 @@ static void genNearPointerSet (operand *right, /* otherwise get a free pointer register */ //aop = newAsmop(0); //preg = getFreePtr(ic,&aop,FALSE); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - //emitcode("mov","%s,%s", + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + //pic14_emitcode("mov","%s,%s", // preg->name, // aopGet(AOP(result),0,FALSE,TRUE)); //rname = preg->name ; - emitcode("movwf","fsr"); + pic14_emitcode("movwf","fsr"); }// else // rname = aopGet(AOP(result),0,FALSE,FALSE); freeAsmop(result,NULL,ic,TRUE); aopOp (right,ic,FALSE); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if bitfield then unpack the bits */ if (IS_BITVAR(retype)) { @@ -7855,36 +8511,36 @@ static void genNearPointerSet (operand *right, int size = AOP_SIZE(right); int offset = 0 ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); while (size--) { l = aopGet(AOP(right),offset,FALSE,TRUE); if (*l == '@' ) { //MOVA(l); - //emitcode("mov","@%s,a",rname); - emitcode("movf","indf,w ;1"); + //pic14_emitcode("mov","@%s,a",rname); + pic14_emitcode("movf","indf,w ;1"); } else { if (AOP_TYPE(right) == AOP_LIT) { - unsigned int lit = floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); + unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); if(lit) { - emitcode("movlw","%s",l); - emitcode("movwf","indf ;2"); + pic14_emitcode("movlw","%s",l); + pic14_emitcode("movwf","indf ;2"); } else - emitcode("clrf","indf"); + pic14_emitcode("clrf","indf"); }else { - emitcode("movf","%s,w",l); - emitcode("movwf","indf ;2"); + pic14_emitcode("movf","%s,w",l); + pic14_emitcode("movwf","indf ;2"); } - //emitcode("mov","@%s,%s",rname,l); + //pic14_emitcode("mov","@%s,%s",rname,l); } if (size) - emitcode("incf","fsr,f ;3"); - //emitcode("inc","%s",rname); + pic14_emitcode("incf","fsr,f ;3"); + //pic14_emitcode("inc","%s",rname); offset++; } } - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* now some housekeeping stuff */ if (aop) { /* we had to allocate for this iCode */ @@ -7895,19 +8551,19 @@ static void genNearPointerSet (operand *right, if size > 0 && this could be used again we have to point it back to where it belongs */ - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (AOP_SIZE(right) > 1 && !OP_SYMBOL(result)->remat && ( OP_SYMBOL(result)->liveTo > ic->seq || ic->depth )) { int size = AOP_SIZE(right) - 1; while (size--) - emitcode("decf","fsr,f"); - //emitcode("dec","%s",rname); + pic14_emitcode("decf","fsr,f"); + //pic14_emitcode("dec","%s",rname); } } - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* done */ freeAsmop(right,NULL,ic,TRUE); @@ -7915,7 +8571,7 @@ static void genNearPointerSet (operand *right, } /*-----------------------------------------------------------------*/ -/* genPagedPointerSet - emitcode for Paged pointer put */ +/* genPagedPointerSet - pic14_emitcode for Paged pointer put */ /*-----------------------------------------------------------------*/ static void genPagedPointerSet (operand *right, operand *result, @@ -7926,7 +8582,7 @@ static void genPagedPointerSet (operand *right, char *rname , *l; sym_link *retype; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); retype= getSpec(operandType(right)); @@ -7938,7 +8594,7 @@ static void genPagedPointerSet (operand *right, /* otherwise get a free pointer register */ aop = newAsmop(0); preg = getFreePtr(ic,&aop,FALSE); - emitcode("mov","%s,%s", + pic14_emitcode("mov","%s,%s", preg->name, aopGet(AOP(result),0,FALSE,TRUE)); rname = preg->name ; @@ -7960,10 +8616,10 @@ static void genPagedPointerSet (operand *right, l = aopGet(AOP(right),offset,FALSE,TRUE); MOVA(l); - emitcode("movx","@%s,a",rname); + pic14_emitcode("movx","@%s,a",rname); if (size) - emitcode("inc","%s",rname); + pic14_emitcode("inc","%s",rname); offset++; } @@ -7985,7 +8641,7 @@ static void genPagedPointerSet (operand *right, ic->depth )) { int size = AOP_SIZE(right) - 1; while (size--) - emitcode("dec","%s",rname); + pic14_emitcode("dec","%s",rname); } } @@ -8004,7 +8660,7 @@ static void genFarPointerSet (operand *right, int size, offset ; sym_link *retype = getSpec(operandType(right)); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(result,ic,FALSE); /* if the operand is already in dptr @@ -8012,13 +8668,13 @@ static void genFarPointerSet (operand *right, if (AOP_TYPE(result) != AOP_STR) { /* if this is remateriazable */ if (AOP_TYPE(result) == AOP_IMMD) - emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE)); + pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE)); else { /* we need to get it byte by byte */ - emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE)); - emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE)); + pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE)); + pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE)); if (options.model == MODEL_FLAT24) { - emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE)); + pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE)); } } } @@ -8036,9 +8692,9 @@ static void genFarPointerSet (operand *right, while (size--) { char *l = aopGet(AOP(right),offset++,FALSE,FALSE); MOVA(l); - emitcode("movx","@dptr,a"); + pic14_emitcode("movx","@dptr,a"); if (size) - emitcode("inc","dptr"); + pic14_emitcode("inc","dptr"); } } @@ -8051,59 +8707,92 @@ static void genFarPointerSet (operand *right, static void genGenPointerSet (operand *right, operand *result, iCode *ic) { - int size, offset ; - sym_link *retype = getSpec(operandType(right)); + int size, offset ; + sym_link *retype = getSpec(operandType(right)); - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - aopOp(result,ic,FALSE); + aopOp(result,ic,FALSE); + aopOp(right,ic,FALSE); + size = AOP_SIZE(right); - /* if the operand is already in dptr - then we do nothing else we move the value to dptr */ - if (AOP_TYPE(result) != AOP_STR) { - /* if this is remateriazable */ - if (AOP_TYPE(result) == AOP_IMMD) { - emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE)); - emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE)); - } - else { /* we need to get it byte by byte */ - char *l = aopGet(AOP(result),0,FALSE,FALSE); + DEBUGpic14_AopType(__LINE__,NULL,right,result); + + /* if the operand is already in dptr + then we do nothing else we move the value to dptr */ + if (AOP_TYPE(result) != AOP_STR) { + /* if this is remateriazable */ + if (AOP_TYPE(result) == AOP_IMMD) { + pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE)); + pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE)); + } + else { /* we need to get it byte by byte */ + //char *l = aopGet(AOP(result),0,FALSE,FALSE); + size = AOP_SIZE(right); + offset = 0 ; - if(strcmp("FSR",l)) - emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE)); - emitpcode(POC_MOVWF,popCopy(&pc_indf)); + /* hack hack! see if this the FSR. If so don't load W */ + if(AOP_TYPE(right) != AOP_ACC) { - if(strcmp("FSR",l)) - emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_MOVFW,popGet(AOP(result),0)); + emitpcode(POC_MOVWF,popCopyReg(&pc_fsr)); + + //if(size==2) + //emitpcode(POC_DECF,popCopyReg(&pc_fsr)); + //if(size==4) { + // emitpcode(POC_MOVLW,popGetLit(0xfd)); + // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr)); + //} + + while(size--) { + emitpcode(POC_MOVFW,popGet(AOP(right),offset++)); + emitpcode(POC_MOVWF,popCopyReg(&pc_indf)); + + if(size) + emitpcode(POC_INCF,popCopyReg(&pc_fsr)); + } + + + goto release; + } + + if(aopIdx(AOP(result),0) != 4) { + + emitpcode(POC_MOVWF,popCopyReg(&pc_indf)); + goto release; + } + + emitpcode(POC_MOVWF,popCopyReg(&pc_indf)); + goto release; - emitcode("movwf","INDF"); - } } - /* so dptr know contains the address */ - freeAsmop(result,NULL,ic,TRUE); - aopOp(right,ic,FALSE); + } + /* so dptr know contains the address */ - /* if bit then unpack */ - if (IS_BITVAR(retype)) - genPackBits(retype,right,"dptr",GPOINTER); - else { - size = AOP_SIZE(right); - offset = 0 ; - while (--size) { - char *l = aopGet(AOP(right),offset++,FALSE,FALSE); - if(size) - emitcode("incf","fsr,f"); - emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE)); - emitcode("movwf","indf"); - //MOVA(l); - //DEBUGemitcode(";lcall","__gptrput"); - //if (size) - // emitcode("inc","dptr"); - } + /* if bit then unpack */ + if (IS_BITVAR(retype)) + genPackBits(retype,right,"dptr",GPOINTER); + else { + size = AOP_SIZE(right); + offset = 0 ; + + while (--size) { + //char *l = aopGet(AOP(right),offset++,FALSE,FALSE); + if(size) + pic14_emitcode("incf","fsr,f"); + pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE)); + pic14_emitcode("movwf","indf"); + //MOVA(l); + //DEBUGpic14_emitcode(";lcall","__gptrput"); + //if (size) + // pic14_emitcode("inc","dptr"); } + } - freeAsmop(right,NULL,ic,TRUE); + release: + freeAsmop(right,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -8115,7 +8804,7 @@ static void genPointerSet (iCode *ic) sym_link *type, *etype; int p_type; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); right = IC_RIGHT(ic); result = IC_RESULT(ic) ; @@ -8168,8 +8857,11 @@ static void genPointerSet (iCode *ic) case GPOINTER: genGenPointerSet (right,result,ic); break; - } + default: + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "genPointerSet: illegal pointer type"); + } } /*-----------------------------------------------------------------*/ @@ -8177,44 +8869,39 @@ static void genPointerSet (iCode *ic) /*-----------------------------------------------------------------*/ static void genIfx (iCode *ic, iCode *popIc) { - operand *cond = IC_COND(ic); - int isbit =0; - - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - aopOp(cond,ic,FALSE); + operand *cond = IC_COND(ic); + int isbit =0; - /* get the value into acc */ - if (AOP_TYPE(cond) != AOP_CRY) - toBoolean(cond); - else - isbit = 1; - /* the result is now in the accumulator */ - freeAsmop(cond,NULL,ic,TRUE); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if there was something to be popped then do it */ - if (popIc) - genIpop(popIc); + aopOp(cond,ic,FALSE); - /* if the condition is a bit variable */ - if (isbit && IS_ITEMP(cond) && - SPIL_LOC(cond)) { - genIfxJump(ic,SPIL_LOC(cond)->rname); - DEBUGemitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname); - } - else { - /* - if (isbit && !IS_ITEMP(cond)) - DEBUGemitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname); - else - DEBUGemitcode ("; isbit","a"); - */ + /* get the value into acc */ + if (AOP_TYPE(cond) != AOP_CRY) + pic14_toBoolean(cond); + else + isbit = 1; + /* the result is now in the accumulator */ + freeAsmop(cond,NULL,ic,TRUE); + + /* if there was something to be popped then do it */ + if (popIc) + genIpop(popIc); + + /* if the condition is a bit variable */ + if (isbit && IS_ITEMP(cond) && + SPIL_LOC(cond)) { + genIfxJump(ic,SPIL_LOC(cond)->rname); + DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname); + } + else { + if (isbit && !IS_ITEMP(cond)) + genIfxJump(ic,OP_SYMBOL(cond)->rname); + else + genIfxJump(ic,"a"); + } + ic->generated = 1; - if (isbit && !IS_ITEMP(cond)) - genIfxJump(ic,OP_SYMBOL(cond)->rname); - else - genIfxJump(ic,"a"); - } - ic->generated = 1; } /*-----------------------------------------------------------------*/ @@ -8222,71 +8909,31 @@ static void genIfx (iCode *ic, iCode *popIc) /*-----------------------------------------------------------------*/ static void genAddrOf (iCode *ic) { - symbol *sym = OP_SYMBOL(IC_LEFT(ic)); - int size, offset ; + operand *right, *result, *left; + int size, offset ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - aopOp(IC_RESULT(ic),ic,FALSE); - /* if the operand is on the stack then we - need to get the stack offset of this - variable */ - if (sym->onStack) { - /* if it has an offset then we need to compute - it */ - if (sym->stack) { - emitcode("mov","a,_bp"); - emitcode("add","a,#0x%02x",((char) sym->stack & 0xff)); - aopPut(AOP(IC_RESULT(ic)),"a",0); - } else { - /* we can just move _bp */ - aopPut(AOP(IC_RESULT(ic)),"_bp",0); - } - /* fill the result with zero */ - size = AOP_SIZE(IC_RESULT(ic)) - 1; - - - if (options.stack10bit && size < (FPTRSIZE - 1)) - { - fprintf(stderr, - "*** warning: pointer to stack var truncated.\n"); - } - - offset = 1; - while (size--) - { - /* Yuck! */ - if (options.stack10bit && offset == 2) - { - aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++); - } - else - { - aopPut(AOP(IC_RESULT(ic)),zero,offset++); - } - } + //aopOp(IC_RESULT(ic),ic,FALSE); - goto release; - } + aopOp((left=IC_LEFT(ic)),ic,FALSE); + aopOp((right=IC_RIGHT(ic)),ic,FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE); - /* object not on stack then we need the name */ - size = AOP_SIZE(IC_RESULT(ic)); - offset = 0; + DEBUGpic14_AopType(__LINE__,left,right,result); - while (size--) { - char s[SDCC_NAME_MAX]; - if (offset) - sprintf(s,"#(%s >> %d)", - sym->rname, - offset*8); - else - sprintf(s,"#%s",sym->rname); - aopPut(AOP(IC_RESULT(ic)),s,offset++); - } + size = AOP_SIZE(IC_RESULT(ic)); + offset = 0; -release: - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); + while (size--) { + emitpcode(POC_MOVLW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + offset++; + } + + freeAsmop(left,NULL,ic,FALSE); + freeAsmop(result,NULL,ic,TRUE); } @@ -8303,7 +8950,7 @@ static void genFarFarAssign (operand *result, operand *right, iCode *ic) while (size--) { l = aopGet(AOP(right),offset++,FALSE,FALSE); MOVA(l); - emitcode ("push","acc"); + pic14_emitcode ("push","acc"); } freeAsmop(right,NULL,ic,FALSE); @@ -8311,7 +8958,7 @@ static void genFarFarAssign (operand *result, operand *right, iCode *ic) aopOp(result,ic,FALSE); size = AOP_SIZE(result); while (size--) { - emitcode ("pop","acc"); + pic14_emitcode ("pop","acc"); aopPut(AOP(result),"a",--offset); } freeAsmop(result,NULL,ic,FALSE); @@ -8324,111 +8971,127 @@ static void genFarFarAssign (operand *result, operand *right, iCode *ic) /*-----------------------------------------------------------------*/ static void genAssign (iCode *ic) { - operand *result, *right; - int size, offset ; - unsigned long lit = 0L; + operand *result, *right; + int size, offset,know_W; + unsigned long lit = 0L; - result = IC_RESULT(ic); - right = IC_RIGHT(ic) ; + result = IC_RESULT(ic); + right = IC_RIGHT(ic) ; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if they are the same */ - if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic))) - return ; + /* if they are the same */ + if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic))) + return ; - aopOp(right,ic,FALSE); - aopOp(result,ic,TRUE); + aopOp(right,ic,FALSE); + aopOp(result,ic,TRUE); - /* if they are the same registers */ - if (sameRegs(AOP(right),AOP(result))) - goto release; + DEBUGpic14_AopType(__LINE__,NULL,right,result); - /* if the result is a bit */ - if (AOP_TYPE(result) == AOP_CRY) { + /* if they are the same registers */ + if (pic14_sameRegs(AOP(right),AOP(result))) + goto release; - /* if the right size is a literal then - we know what the value is */ - if (AOP_TYPE(right) == AOP_LIT) { + /* if the result is a bit */ + if (AOP_TYPE(result) == AOP_CRY) { + + /* if the right size is a literal then + we know what the value is */ + if (AOP_TYPE(right) == AOP_LIT) { - emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF), - popGet(AOP(result),0,FALSE,FALSE)); + emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF), + popGet(AOP(result),0)); - if (((int) operandLitValue(right))) - emitcode("bsf","(%s >> 3),(%s & 7)", + if (((int) operandLitValue(right))) + pic14_emitcode("bsf","(%s >> 3),(%s & 7)", AOP(result)->aopu.aop_dir, AOP(result)->aopu.aop_dir); - else - emitcode("bcf","(%s >> 3),(%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - goto release; - } + else + pic14_emitcode("bcf","(%s >> 3),(%s & 7)", + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); + goto release; + } - /* the right is also a bit variable */ - if (AOP_TYPE(right) == AOP_CRY) { - emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE)); - emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE)); - emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE)); - - emitcode("bcf","(%s >> 3),(%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - emitcode("btfsc","(%s >> 3),(%s & 7)", - AOP(right)->aopu.aop_dir, - AOP(right)->aopu.aop_dir); - emitcode("bsf","(%s >> 3),(%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - goto release ; - } + /* the right is also a bit variable */ + if (AOP_TYPE(right) == AOP_CRY) { + emitpcode(POC_BCF, popGet(AOP(result),0)); + emitpcode(POC_BTFSC, popGet(AOP(right),0)); + emitpcode(POC_BSF, popGet(AOP(result),0)); + + pic14_emitcode("bcf","(%s >> 3),(%s & 7)", + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); + pic14_emitcode("btfsc","(%s >> 3),(%s & 7)", + AOP(right)->aopu.aop_dir, + AOP(right)->aopu.aop_dir); + pic14_emitcode("bsf","(%s >> 3),(%s & 7)", + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); + goto release ; + } + + /* we need to or */ + emitpcode(POC_BCF, popGet(AOP(result),0)); + pic14_toBoolean(right); + emitSKPZ; + emitpcode(POC_BSF, popGet(AOP(result),0)); + //aopPut(AOP(result),"a",0); + goto release ; + } - /* we need to or */ - toBoolean(right); - aopPut(AOP(result),"a",0); - goto release ; - } + /* bit variables done */ + /* general case */ + size = AOP_SIZE(result); + offset = 0 ; + if(AOP_TYPE(right) == AOP_LIT) + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + + if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) { + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(aopIdx(AOP(result),0) == 4) { + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + emitpcode(POC_MOVFW, popGet(AOP(right),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + goto release; + } else + DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__); + } - /* bit variables done */ - /* general case */ - size = AOP_SIZE(result); - offset = 0 ; - if(AOP_TYPE(right) == AOP_LIT) - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - if((AOP_TYPE(result) != AOP_REG) && - (AOP_TYPE(right) == AOP_LIT) && - !IS_FLOAT(operandType(right)) && - (lit < 256L)){ + know_W=-1; + while (size--) { + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(AOP_TYPE(right) == AOP_LIT) { + if(lit&0xff) { + if(know_W != (lit&0xff)) + emitpcode(POC_MOVLW,popGetLit(lit&0xff)); + know_W = lit&0xff; + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + } else + emitpcode(POC_CLRF, popGet(AOP(result),offset)); - while (size--) { - if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) { - //emitcode("clrf","%s", aopGet(AOP(result),size,FALSE,FALSE)); - emitpcode(POC_CLRF,popGet(AOP(result),size,FALSE,FALSE)); - }else { - emitpcode(POC_MOVLW,popGet(AOP(right),size,FALSE,FALSE)); - emitpcode(POC_MOVWF,popGet(AOP(result),size,FALSE,FALSE)); - //emitcode("movlw","%s", aopGet(AOP(right),size,FALSE,FALSE)); - //emitcode("movwf","%s", aopGet(AOP(result),size,FALSE,FALSE)); - } - } + lit >>= 8; + + } else if (AOP_TYPE(right) == AOP_CRY) { + emitpcode(POC_CLRF, popGet(AOP(result),offset)); + if(offset == 0) { + emitpcode(POC_BTFSS, popGet(AOP(right),0)); + emitpcode(POC_INCF, popGet(AOP(result),0)); + } } else { - while (size--) { - if(AOP_TYPE(right) == AOP_LIT) - emitpcode(POC_MOVLW, popGet(AOP(right),offset,FALSE,FALSE)); - //emitcode("movlw","%s", aopGet(AOP(right),offset,FALSE,FALSE)); - else - emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE)); - //emitcode("movf","%s,w", aopGet(AOP(right),offset,FALSE,FALSE)); - - emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE)); - //emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE)); - offset++; - } + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + emitpcode(POC_MOVFW, popGet(AOP(right),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); } + + offset++; + } + -release: - freeAsmop (right,NULL,ic,FALSE); - freeAsmop (result,NULL,ic,TRUE); + release: + freeAsmop (right,NULL,ic,FALSE); + freeAsmop (result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -8439,25 +9102,37 @@ static void genJumpTab (iCode *ic) symbol *jtab; char *l; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(IC_JTCOND(ic),ic,FALSE); /* get the condition into accumulator */ l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE); MOVA(l); /* multiply by three */ - emitcode("add","a,acc"); - emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE)); - freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE); + pic14_emitcode("add","a,acc"); + pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE)); jtab = newiTempLabel(NULL); - emitcode("mov","dptr,#%05d_DS_",jtab->key+100); - emitcode("jmp","@a+dptr"); - emitcode("","%05d_DS_:",jtab->key+100); + pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100); + pic14_emitcode("jmp","@a+dptr"); + pic14_emitcode("","%05d_DS_:",jtab->key+100); + + emitpcode(POC_MOVLW, popGetLabel(jtab->key)); + emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0)); + emitSKPNC; + emitpcode(POC_INCF, popCopyReg(&pc_pclath)); + emitpcode(POC_MOVWF, popCopyReg(&pc_pcl)); + emitpLabel(jtab->key); + + freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE); + /* now generate the jump labels */ for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab; - jtab = setNextItem(IC_JTLABELS(ic))) - emitcode("ljmp","%05d_DS_",jtab->key+100); + jtab = setNextItem(IC_JTLABELS(ic))) { + pic14_emitcode("ljmp","%05d_DS_",jtab->key+100); + emitpcode(POC_GOTO,popGetLabel(jtab->key)); + + } } @@ -8485,7 +9160,7 @@ static int genMixedOperation (iCode *ic) iCode *nextic; operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL; - emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); nextic = ic->next; if(!nextic) @@ -8501,21 +9176,21 @@ static int genMixedOperation (iCode *ic) aopOp(nextleft, nextic, FALSE); aopOp(nextresult, nextic, FALSE); - if (sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) { + if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) { operand *t = right; right = nextright; nextright = t; - emitcode(";remove right +",""); + pic14_emitcode(";remove right +",""); - } else if (sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) { + } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) { /* operand *t = right; right = nextleft; nextleft = t; */ - emitcode(";remove left +",""); + pic14_emitcode(";remove left +",""); } else return 0; @@ -8525,19 +9200,19 @@ static int genMixedOperation (iCode *ic) switch(nextic->op) { case '+': - emitcode(";optimize a +",""); + pic14_emitcode(";optimize a +",""); /* if unsigned or not an integral type */ if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) { - emitcode(";add a bit to something",""); + pic14_emitcode(";add a bit to something",""); } else { - emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir); + pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir); - if (!sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) { - emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir); - emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE)); + if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) { + pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir); + pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE)); } else - emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir); + pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir); offset = 0; while(--big) { @@ -8545,32 +9220,32 @@ static int genMixedOperation (iCode *ic) offset++; if(--small) { - if (!sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){ - emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE)); - emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) ); + if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){ + pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE)); + pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) ); } - emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE)); + pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE)); emitSKPNC; - emitcode("btfsc","(%s >> 3), (%s & 7)", + pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", AOP(IC_RIGHT(nextic))->aopu.aop_dir, AOP(IC_RIGHT(nextic))->aopu.aop_dir); - emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE)); - emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE)); + pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE)); + pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE)); } else { - emitcode("rlf","known_zero,w"); + pic14_emitcode("rlf","known_zero,w"); /* if right is signed btfsc right,7 addlw ff */ - if (!sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){ - emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE)); - emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) ); + if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){ + pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE)); + pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) ); } else { - emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) ); + pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) ); } } } @@ -8599,10 +9274,11 @@ static void genCast (iCode *ic) { operand *result = IC_RESULT(ic); sym_link *ctype = operandType(IC_LEFT(ic)); + sym_link *rtype = operandType(IC_RIGHT(ic)); operand *right = IC_RIGHT(ic); int size, offset ; - DEBUGemitcode("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); /* if they are equivalent then do nothing */ if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic))) return ; @@ -8610,21 +9286,24 @@ static void genCast (iCode *ic) aopOp(right,ic,FALSE) ; aopOp(result,ic,FALSE); + DEBUGpic14_AopType(__LINE__,NULL,right,result); + /* if the result is a bit */ if (AOP_TYPE(result) == AOP_CRY) { /* if the right size is a literal then we know what the value is */ + DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); if (AOP_TYPE(right) == AOP_LIT) { emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF), - popGet(AOP(result),0,FALSE,FALSE)); + popGet(AOP(result),0)); if (((int) operandLitValue(right))) - emitcode("bsf","(%s >> 3), (%s & 7)", + pic14_emitcode("bsf","(%s >> 3), (%s & 7)", AOP(result)->aopu.aop_dir, AOP(result)->aopu.aop_dir); else - emitcode("bcf","(%s >> 3), (%s & 7)", + pic14_emitcode("bcf","(%s >> 3), (%s & 7)", AOP(result)->aopu.aop_dir, AOP(result)->aopu.aop_dir); @@ -8635,10 +9314,10 @@ static void genCast (iCode *ic) if (AOP_TYPE(right) == AOP_CRY) { emitCLRC; - emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE)); + emitpcode(POC_BTFSC, popGet(AOP(right),0)); - emitcode("clrc",""); - emitcode("btfsc","(%s >> 3), (%s & 7)", + pic14_emitcode("clrc",""); + pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", AOP(right)->aopu.aop_dir, AOP(right)->aopu.aop_dir); aopPut(AOP(result),"c",0); @@ -8646,28 +9325,70 @@ static void genCast (iCode *ic) } /* we need to or */ - toBoolean(right); - aopPut(AOP(result),"a",0); + if (AOP_TYPE(right) == AOP_REG) { + emitpcode(POC_BCF, popGet(AOP(result),0)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0)); + emitpcode(POC_BSF, popGet(AOP(result),0)); + } + pic14_toBoolean(right); + aopPut(AOP(result),"a",0); goto release ; } + if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) { + int offset = 1; + size = AOP_SIZE(result); + + DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + + emitpcode(POC_CLRF, popGet(AOP(result),0)); + emitpcode(POC_BTFSC, popGet(AOP(right),0)); + emitpcode(POC_INCF, popGet(AOP(result),0)); + + while (size--) + emitpcode(POC_CLRF, popGet(AOP(result),offset++)); + + goto release; + } + /* if they are the same size : or less */ if (AOP_SIZE(result) <= AOP_SIZE(right)) { /* if they are in the same place */ - if (sameRegs(AOP(right),AOP(result))) - goto release; + if (pic14_sameRegs(AOP(right),AOP(result))) + goto release; + + DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + if (IS_PTR_CONST(rtype)) + DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__); + if (IS_PTR_CONST(operandType(IC_RESULT(ic)))) + DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__); + + if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) { + emitpcode(POC_MOVLW, popGet(AOP(right),0)); + emitpcode(POC_MOVWF, popGet(AOP(result),0)); + emitpcode(POC_MOVLW, popGet(AOP(right),1)); + emitpcode(POC_MOVWF, popGet(AOP(result),1)); + if(AOP_SIZE(result) <2) + fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__); + + } else { /* if they in different places then copy */ size = AOP_SIZE(result); offset = 0 ; while (size--) { - aopPut(AOP(result), - aopGet(AOP(right),offset,FALSE,FALSE), - offset); - offset++; + emitpcode(POC_MOVFW, popGet(AOP(right),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + + //aopPut(AOP(result), + // aopGet(AOP(right),offset,FALSE,FALSE), + // offset); + + offset++; } - goto release; + } + goto release; } @@ -8677,6 +9398,7 @@ static void genCast (iCode *ic) int p_type; sym_link *type = operandType(right); sym_link *etype = getSpec(type); + DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__); /* pointer to generic pointer */ if (IS_GENPTR(ctype)) { @@ -8707,24 +9429,30 @@ static void genCast (iCode *ic) size = GPTRSIZE - 1; offset = 0 ; while (size--) { + if(offset < AOP_SIZE(right)) aopPut(AOP(result), aopGet(AOP(right),offset,FALSE,FALSE), offset); - offset++; + else + emitpcode(POC_CLRF,popGet(AOP(result),offset)); + offset++; } /* the last byte depending on type */ switch (p_type) { case IPOINTER: case POINTER: - l = zero; + emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1)); break; case FPOINTER: + pic14_emitcode(";BUG!? ","%d",__LINE__); l = one; break; case CPOINTER: + pic14_emitcode(";BUG!? ","%d",__LINE__); l = "#0x02"; break; case PPOINTER: + pic14_emitcode(";BUG!? ","%d",__LINE__); l = "#0x03"; break; @@ -8734,7 +9462,7 @@ static void genCast (iCode *ic) "got unknown pointer type"); exit(1); } - aopPut(AOP(result),l, GPTRSIZE - 1); + //aopPut(AOP(result),l, GPTRSIZE - 1); goto release ; } @@ -8751,25 +9479,6 @@ static void genCast (iCode *ic) } - if (AOP_TYPE(right) == AOP_CRY) { - int offset = 1; - size = AOP_SIZE(right); - - emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE)); - emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE)); - emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE)); - - emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__); - emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(right)->aopu.aop_dir, - AOP(right)->aopu.aop_dir); - emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__); - while (size--) { - emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__); - emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE)); - } - goto release; - } /* so we now know that the size of destination is greater than the size of the source. @@ -8779,50 +9488,46 @@ static void genCast (iCode *ic) if(genMixedOperation(ic)) goto release; + DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); /* we move to result for the size of source */ size = AOP_SIZE(right); offset = 0 ; while (size--) { - emitcode(";","%d",__LINE__); - aopPut(AOP(result), - aopGet(AOP(right),offset,FALSE,FALSE), - offset); - offset++; + emitpcode(POC_MOVFW, popGet(AOP(right),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + offset++; } /* now depending on the sign of the destination */ size = AOP_SIZE(result) - AOP_SIZE(right); /* if unsigned or not an integral type */ - if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) { - while (size--) { - emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE)); - emitcode("clrf","%s ;%d",aopGet(AOP(result),offset++,FALSE,FALSE),__LINE__); - } + if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) { + while (size--) + emitpcode(POC_CLRF, popGet(AOP(result),offset++)); } else { /* we need to extend the sign :{ */ - //char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,FALSE,FALSE); - //MOVA(l); - emitpcode(POC_CLRW, NULL); - emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE)); - emitpcode(POC_MOVLW, popGetLit(0xff)); + if(size == 1) { + /* Save one instruction of casting char to int */ + emitpcode(POC_CLRF, popGet(AOP(result),offset)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0)); + emitpcode(POC_DECF, popGet(AOP(result),offset)); + } else { + emitpcodeNULLop(POC_CLRW); - emitcode("clrw",""); - emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(right)->aopu.aop_dir, - AOP(right)->aopu.aop_dir); - emitcode("movlw","0xff"); - while (size--) { - emitpcode(POC_MOVWF, popGet(AOP(result),offset++,FALSE,FALSE)); - emitcode("movwf","%s",aopGet(AOP(result),offset++,FALSE,FALSE)); - // aopPut(AOP(result),"a",offset++); - } + if(offset) + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0)); + else + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0)); + + emitpcode(POC_MOVLW, popGetLit(0xff)); + while (size--) + emitpcode(POC_MOVWF, popGet(AOP(result),offset++)); + } } - /* we are done hurray !!!! */ - release: freeAsmop(right,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); @@ -8835,7 +9540,7 @@ release: static int genDjnz (iCode *ic, iCode *ifx) { symbol *lbl, *lbl1; - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (!ifx) return 0; @@ -8866,24 +9571,24 @@ static int genDjnz (iCode *ic, iCode *ifx) aopOp(IC_RESULT(ic),ic,FALSE); if (IS_AOP_PREG(IC_RESULT(ic))) { - emitcode("dec","%s", + pic14_emitcode("dec","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - emitcode("jnz","%05d_DS_",lbl->key+100); + pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + pic14_emitcode("jnz","%05d_DS_",lbl->key+100); } else { - emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0)); emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); - emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset); + pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); + pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset); } -/* emitcode ("sjmp","%05d_DS_",lbl1->key+100); */ -/* emitcode ("","%05d_DS_:",lbl->key+100); */ -/* emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */ -/* emitcode ("","%05d_DS_:",lbl1->key+100); */ +/* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */ +/* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */ +/* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */ +/* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); @@ -8896,35 +9601,35 @@ static int genDjnz (iCode *ic, iCode *ifx) /*-----------------------------------------------------------------*/ static void genReceive (iCode *ic) { - DEBUGemitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (isOperandInFarSpace(IC_RESULT(ic)) && - ( OP_SYMBOL(IC_RESULT(ic))->isspilt || - IS_TRUE_SYMOP(IC_RESULT(ic))) ) { + if (isOperandInFarSpace(IC_RESULT(ic)) && + ( OP_SYMBOL(IC_RESULT(ic))->isspilt || + IS_TRUE_SYMOP(IC_RESULT(ic))) ) { - int size = getSize(operandType(IC_RESULT(ic))); - int offset = fReturnSize - size; - while (size--) { - emitcode ("push","%s", (strcmp(fReturn[fReturnSize - offset - 1],"a") ? - fReturn[fReturnSize - offset - 1] : "acc")); - offset++; - } - aopOp(IC_RESULT(ic),ic,FALSE); - size = AOP_SIZE(IC_RESULT(ic)); - offset = 0; - while (size--) { - emitcode ("pop","acc"); - aopPut (AOP(IC_RESULT(ic)),"a",offset++); - } - - } else { - _G.accInUse++; - aopOp(IC_RESULT(ic),ic,FALSE); - _G.accInUse--; - assignResultValue(IC_RESULT(ic)); + int size = getSize(operandType(IC_RESULT(ic))); + int offset = fReturnSizePic - size; + while (size--) { + pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ? + fReturn[fReturnSizePic - offset - 1] : "acc")); + offset++; + } + aopOp(IC_RESULT(ic),ic,FALSE); + size = AOP_SIZE(IC_RESULT(ic)); + offset = 0; + while (size--) { + pic14_emitcode ("pop","acc"); + aopPut (AOP(IC_RESULT(ic)),"a",offset++); } + + } else { + _G.accInUse++; + aopOp(IC_RESULT(ic),ic,FALSE); + _G.accInUse--; + assignResultValue(IC_RESULT(ic)); + } - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); + freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -8946,37 +9651,41 @@ void genpic14Code (iCode *lic) lineHead = lineCurr = NULL; - pb = newpCodeChain(GcurMemmap,newpCodeCharP("; Starting pCode block")); + pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block")); addpBlock(pb); /* if debug information required */ -/* if (options.debug && currFunc) { */ - if (currFunc) { + if (options.debug && currFunc) { + if (currFunc) { cdbSymbol(currFunc,cdbFile,FALSE,TRUE); _G.debugLine = 1; if (IS_STATIC(currFunc->etype)) { - emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__); - //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name)); + pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__); + //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name)); } else { - emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__); - //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name)); + pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__); + //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name)); } _G.debugLine = 0; + } } for (ic = lic ; ic ; ic = ic->next ) { - DEBUGemitcode(";ic",""); + DEBUGpic14_emitcode(";ic",""); if ( cln != ic->lineno ) { if ( options.debug ) { _G.debugLine = 1; - emitcode("",";C$%s$%d$%d$%d ==.", + pic14_emitcode("",";C$%s$%d$%d$%d ==.", FileBaseName(ic->filename),ic->lineno, ic->level,ic->block); _G.debugLine = 0; } - emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno); + pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno); + pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, + printCLine(ic->filename, ic->lineno)); + cln = ic->lineno ; } /* if the result is marked as @@ -9171,8 +9880,6 @@ void genpic14Code (iCode *lic) default : ic = ic; - /* piCode(ic,stdout); */ - } } @@ -9180,14 +9887,15 @@ void genpic14Code (iCode *lic) /* now we are ready to call the peep hole optimizer */ if (!options.nopeep) { - printf("peep hole optimizing\n"); - peepHole (&lineHead); + peepHole (&lineHead); } /* now do the actual printing */ printLine (lineHead,codeOutFile); - printf("printing pBlock\n\n"); +#ifdef PCODE_DEBUG + DFPRINTF((stderr,"printing pBlock\n\n")); printpBlock(stdout,pb); +#endif return; }