X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fgen.c;h=a2482345d8cf644255cb770a7ffb6c44b8de79f4;hb=5a1d5e778e85664f4e6657019348b4756b16eacb;hp=d6da6c631e982634373539feee098fe440687381;hpb=ef1400f583d53e5091fa901ad4ed933285b9dbb3;p=fw%2Fsdcc diff --git a/src/pic/gen.c b/src/pic/gen.c index d6da6c63..a2482345 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -30,56 +30,46 @@ Made everything static -------------------------------------------------------------------------*/ -#include -#include -#include -#include -#include "SDCCglobl.h" -#include "newalloc.h" - -#include "common.h" -#include "SDCCpeeph.h" -#include "ralloc.h" -#include "pcode.h" +/* + * This is the down and dirty file with all kinds of + * kludgy & hacky stuff. This is what it is all about + * CODE GENERATION for a specific MCU . some of the + * routines may be reusable, will have to see. + */ + #include "gen.h" #include "glue.h" -/* The PIC port(s) need not differentiate between POINTER and FPOINTER. */ -#define PIC_IS_DATA_PTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x)) -#define PIC_IS_FARPTR(x) (PIC_IS_DATA_PTR(x)) - -extern void printpBlock(FILE *of, pBlock *pb); - -static int labelOffset=0; -extern int debug_verbose; -extern int pic14_hasInterrupt; -//static int optimized_for_speed = 0; +/* + * Imports + */ +extern struct dbuf_s *codeOutBuf; +extern set *externs; -/* 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; -static int pic14_inISR = 0; -pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func); -extern char *get_op( pCodeOp *pcop,char *buff,size_t buf_size); -const char *AopType(short type); +static pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func); +static pCodeOp *popRegFromString(char *str, int size, int offset); +static int aop_isLitLike(asmop *aop); -#define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0x00ff) +/* The PIC port(s) need not differentiate between POINTER and FPOINTER. */ +#define PIC_IS_DATA_PTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x)) -/* this is the down and dirty file with all kinds of -kludgy & hacky stuff. This is what it is all about -CODE GENERATION for a specific MCU . some of the -routines may be reusable, will have to see */ +/* + * 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 labelOffset = 0; +static int GpsuedoStkPtr = 0; +static int pic14_inISR = 0; static char *zero = "0x00"; static char *one = "0x01"; static char *spname = "sp"; -char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" }; unsigned fReturnSizePic = 4; /* shared with ralloc.c */ +static char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" }; static char **fReturn = fReturnpic14; static struct { @@ -90,9 +80,10 @@ static struct { set *sendSet; } _G; -/* Resolved ifx structure. This structure stores information -about an iCode ifx that makes it easier to generate code. -*/ +/* + * 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 */ @@ -100,14 +91,9 @@ typedef struct resolvedIfx { * is generated */ } resolvedIfx; -extern int pic14_nRegs; -extern struct dbuf_s *codeOutBuf; -static void saverbank (int, iCode *,bool); - static lineNode *lineHead = NULL; static lineNode *lineCurr = NULL; - -static pBlock *pb; +static pBlock *pb; /*-----------------------------------------------------------------*/ /* my_powof2(n) - If `n' is an integaer power of 2, then the */ @@ -151,7 +137,7 @@ void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *res } -void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result) +static void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result) { DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c", @@ -232,11 +218,6 @@ void emitpComment (const char *fmt, ...) Safe_vsnprintf (buffer, 4096, fmt, va); //fprintf (stderr, "%s\n" ,buffer); addpCode2pBlock (pb, newpCodeCharP (buffer)); -#if 0 - } else { - Safe_vsnprintf (buffer, 4096, fmt, va); - fprintf (stderr, "No current pBlock -- discarding comment [%s]\n", buffer); -#endif } va_end (va); } @@ -264,14 +245,11 @@ void emitpcode_real(PIC_OPCODE poc, pCodeOp *pcop) } } -void emitpcodeNULLop(PIC_OPCODE poc) +static void emitpcodeNULLop(PIC_OPCODE poc) { - addpCode2pBlock(pb,newpCode(poc,NULL)); - } - /*-----------------------------------------------------------------*/ /* pic14_emitcode - writes the code into a file : for now it is simple */ /*-----------------------------------------------------------------*/ @@ -323,7 +301,7 @@ pic14_emitDebuggerSymbol (char * debugSym) /*-----------------------------------------------------------------*/ /* newAsmop - creates a new asmOp */ /*-----------------------------------------------------------------*/ -asmop *newAsmop (short type) +static asmop *newAsmop (short type) { asmop *aop; @@ -348,10 +326,6 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx) if(!ifx) { resIfx->lbl = NULL; /* this is wrong: 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); @@ -359,28 +333,11 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx) 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 */ -/*-----------------------------------------------------------------*/ -#if 0 -static int pointerCode (sym_link *etype) -{ - - return PTR_TYPE(SPEC_OCLS(etype)); - -} -#endif /*-----------------------------------------------------------------*/ /* aopForSym - for a true symbol */ @@ -414,12 +371,6 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) PCOI(aop->aopu.pcop)->_function = 1; PCOI(aop->aopu.pcop)->index = 0; aop->size = FPTRSIZE; - /* - sym->aop = aop = newAsmop(AOP_IMMD); - 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; } @@ -502,7 +453,7 @@ static asmop *aopForRemat (operand *op) // x symbol *sym) return aop; } -int aopIdx (asmop *aop, int offset) +static int aopIdx (asmop *aop, int offset) { if(!aop) return -1; @@ -513,6 +464,7 @@ int aopIdx (asmop *aop, int offset) return aop->aopu.aop_reg[offset]->rIdx; } + /*-----------------------------------------------------------------*/ /* regsInCommon - two operands have some registers in common */ /*-----------------------------------------------------------------*/ @@ -802,6 +754,33 @@ void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) } } +/*-----------------------------------------------------------------*/ +/* pic14aopLiteral - string from a literal value */ +/*-----------------------------------------------------------------*/ +static unsigned int pic14aopLiteral (value *val, int offset) +{ + union { + float f; + unsigned char c[4]; + } fl; + + /* if it is a float then it gets tricky */ + /* otherwise it is fairly simple */ + if (!IS_FLOAT(val->type)) { + unsigned long v = ulFromVal (val); + + return ( (v >> (offset * 8)) & 0xff); + } + + /* it is type float */ + fl.f = (float) floatFromVal(val); +#ifdef WORDS_BIGENDIAN + return fl.c[3-offset]; +#else + return fl.c[offset]; +#endif +} + /*-----------------------------------------------------------------*/ /* aopGet - for fetching value of the aop */ /*-----------------------------------------------------------------*/ @@ -903,11 +882,10 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname) exit(0); } - /*-----------------------------------------------------------------*/ /* popGetTempReg - create a new temporary pCodeOp */ /*-----------------------------------------------------------------*/ -pCodeOp *popGetTempReg(void) +static pCodeOp *popGetTempReg(void) { pCodeOp *pcop; @@ -924,13 +902,14 @@ pCodeOp *popGetTempReg(void) /*-----------------------------------------------------------------*/ /* popReleaseTempReg - create a new temporary pCodeOp */ /*-----------------------------------------------------------------*/ -void popReleaseTempReg(pCodeOp *pcop) +static void popReleaseTempReg(pCodeOp *pcop) { if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) PCOR(pcop)->r->isFree = 1; } + /*-----------------------------------------------------------------*/ /* popGetLabel - create a new pCodeOp of type PO_LABEL */ /*-----------------------------------------------------------------*/ @@ -948,7 +927,7 @@ pCodeOp *popGetLabel(unsigned int key) /*-------------------------------------------------------------------*/ /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */ /*-------------------------------------------------------------------*/ -pCodeOp *popGetHighLabel(unsigned int key) +static pCodeOp *popGetHighLabel(unsigned int key) { pCodeOp *pcop; pcop = popGetLabel(key); @@ -968,18 +947,16 @@ pCodeOp *popGetLit(unsigned int lit) /*-----------------------------------------------------------------*/ /* popGetImmd - asm operator to pcode immediate conversion */ /*-----------------------------------------------------------------*/ -pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func) +static pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func) { return newpCodeOpImmd(name, offset,index, 0, is_func); } -extern set *externs; - /*-----------------------------------------------------------------*/ /* popGetWithString - asm operator to pcode operator conversion */ /*-----------------------------------------------------------------*/ -pCodeOp *popGetWithString(char *str, int isExtern) +static pCodeOp *popGetWithString(char *str, int isExtern) { pCodeOp *pcop; @@ -1027,7 +1004,7 @@ pCodeOp *popGetExternal (char *str, int isReg) /*-----------------------------------------------------------------*/ /* popRegFromString - */ /*-----------------------------------------------------------------*/ -pCodeOp *popRegFromString(char *str, int size, int offset) +static pCodeOp *popRegFromString(char *str, int size, int offset) { pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); @@ -1058,7 +1035,7 @@ pCodeOp *popRegFromString(char *str, int size, int offset) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -pCodeOp *popRegFromIdx(int rIdx) +static pCodeOp *popRegFromIdx(int rIdx) { pCodeOp *pcop; @@ -1113,24 +1090,6 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) case AOP_DIR: return popRegFromString(aop->aopu.aop_dir, aop->size, offset); -#if 0 - pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); - pcop->type = PO_DIR; - - 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 - had to alloc by reg name",__LINE__,pcop->name,offset); - } else { - DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset); - } - PCOR(pcop)->instance = offset; - - return pcop; -#endif case AOP_REG: { @@ -1164,15 +1123,6 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) case AOP_STR: DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]); 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; - - return pcop; - */ case AOP_PCODE: pcop = NULL; @@ -1285,22 +1235,6 @@ void aopPut (asmop *aop, char *s, int offset) case AOP_REG: 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 || - strcmp(s,"r1") == 0 || - strcmp(s,"r2") == 0 || - strcmp(s,"r3") == 0 || - strcmp(s,"r4") == 0 || - strcmp(s,"r5") == 0 || - strcmp(s,"r6") == 0 || - strcmp(s,"r7") == 0 ) - pic14_emitcode("mov","%s,%s ; %d", - aop->aopu.aop_reg[offset]->dname,s,__LINE__); - else - */ - if(strcmp(s,"W")==0 ) pic14_emitcode("movf","%s,w ; %d",s,__LINE__); @@ -1541,7 +1475,7 @@ void pic14_outAcc(operand *result) /*-----------------------------------------------------------------*/ /* pic14_outBitC - output a bit C */ /*-----------------------------------------------------------------*/ -void pic14_outBitC(operand *result) +static void pic14_outBitC(operand *result) { DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -1558,7 +1492,7 @@ void pic14_outBitC(operand *result) /*-----------------------------------------------------------------*/ /* pic14_toBoolean - emit code for orl a,operator(sizeop) */ /*-----------------------------------------------------------------*/ -void pic14_toBoolean(operand *oper) +static void pic14_toBoolean(operand *oper) { int size = AOP_SIZE(oper); int offset = 0; @@ -1683,30 +1617,27 @@ release: /*-----------------------------------------------------------------*/ /* genUminusFloat - unary minus for floating points */ /*-----------------------------------------------------------------*/ -static void genUminusFloat(operand *op,operand *result) +static void +genUminusFloat(operand *op, operand *result) { - int size ,offset =0 ; - char *l; - - FENTRY; + int size; - 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; - l = aopGet(AOP(op),3,FALSE,FALSE); + FENTRY; - MOVA(l); + 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; - pic14_emitcode("cpl","acc.7"); - aopPut(AOP(result),"a",3); + mov2w_op(op, size); + emitpcode(POC_XORLW, popGetLit(0x80)); + movwf(AOP(result), size); - while(size--) { - aopPut(AOP(result), - aopGet(AOP(op),offset,FALSE,FALSE), - offset); - offset++; - } + while (size--) + { + mov2w_op(op, size); + movwf(AOP(result), size); + } // while } /*-----------------------------------------------------------------*/ @@ -1769,6 +1700,56 @@ release: freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } +/*-----------------------------------------------------------------*/ +/* saverbank - saves an entire register bank on the stack */ +/*-----------------------------------------------------------------*/ +static void saverbank (int bank, iCode *ic, bool pushPsw) +{ + FENTRY; + + DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); +#if 0 + int i; + asmop *aop ; + regs *r = NULL; + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if (options.useXstack) { + + aop = newAsmop(0); + r = getFreePtr(ic,&aop,FALSE); + pic14_emitcode("mov","%s,_spx",r->name); + + } + + for (i = 0 ; i < pic14_nRegs ;i++) { + if (options.useXstack) { + pic14_emitcode("inc","%s",r->name); + //pic14_emitcode("mov","a,(%s+%d)", + // regspic14[i].base,8*bank+regspic14[i].offset); + pic14_emitcode("movx","@%s,a",r->name); + } else + pic14_emitcode("push","");// "(%s+%d)", + //regspic14[i].base,8*bank+regspic14[i].offset); + } + + if (pushPsw) { + if (options.useXstack) { + 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 + pic14_emitcode("push","psw"); + + pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff); + } + ic->bankSaved = 1; +#endif +} + /*-----------------------------------------------------------------*/ /* saveRegisters - will look for a call and save the registers */ /*-----------------------------------------------------------------*/ @@ -2033,56 +2014,6 @@ static void unsaverbank (int bank,iCode *ic,bool popPsw) #endif } -/*-----------------------------------------------------------------*/ -/* saverbank - saves an entire register bank on the stack */ -/*-----------------------------------------------------------------*/ -static void saverbank (int bank, iCode *ic, bool pushPsw) -{ - FENTRY; - - DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); -#if 0 - int i; - asmop *aop ; - regs *r = NULL; - - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (options.useXstack) { - - aop = newAsmop(0); - r = getFreePtr(ic,&aop,FALSE); - pic14_emitcode("mov","%s,_spx",r->name); - - } - - for (i = 0 ; i < pic14_nRegs ;i++) { - if (options.useXstack) { - pic14_emitcode("inc","%s",r->name); - //pic14_emitcode("mov","a,(%s+%d)", - // regspic14[i].base,8*bank+regspic14[i].offset); - pic14_emitcode("movx","@%s,a",r->name); - } else - pic14_emitcode("push","");// "(%s+%d)", - //regspic14[i].base,8*bank+regspic14[i].offset); - } - - if (pushPsw) { - if (options.useXstack) { - 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 - pic14_emitcode("push","psw"); - - pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff); - } - ic->bankSaved = 1; -#endif -} - /*-----------------------------------------------------------------*/ /* genCall - generates a call statement */ /*-----------------------------------------------------------------*/ @@ -2338,29 +2269,6 @@ static int resultRemat (iCode *ic) return 0; } -#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; - - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (options.excludeRegs[i] && - STRCASECMP(options.excludeRegs[i],"none") == 0) - return FALSE ; - - for ( i = 0 ; options.excludeRegs[i]; i++) { - if (options.excludeRegs[i] && - STRCASECMP(s,options.excludeRegs[i]) == 0) - return TRUE; - } - return FALSE ; -} -#endif - /*-----------------------------------------------------------------*/ /* genFunction - generated code for function entry */ /*-----------------------------------------------------------------*/ @@ -3154,59 +3062,6 @@ static void genIfxJump (iCode *ic, char *jval) ic->generated = 1; } -#if 0 -/*-----------------------------------------------------------------*/ -/* genSkip */ -/*-----------------------------------------------------------------*/ -static void genSkip(iCode *ifx,int status_bit) -{ - FENTRY; - if(!ifx) - return; - - if ( IC_TRUE(ifx) ) { - switch(status_bit) { - case 'z': - emitSKPNZ; - break; - - case 'c': - emitSKPNC; - break; - - case 'd': - emitSKPDC; - break; - - } - - emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); - pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); - - } else { - - switch(status_bit) { - - case 'z': - emitSKPZ; - break; - - case 'c': - emitSKPC; - break; - - case 'd': - emitSKPDC; - break; - } - emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key)); - pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); - - } - -} -#endif - /*-----------------------------------------------------------------*/ /* genSkipc */ /*-----------------------------------------------------------------*/ @@ -3226,119 +3081,22 @@ static void genSkipc(resolvedIfx *rifx) rifx->generated = 1; } -#if 0 +#define isAOP_REGlike(x) (AOP_TYPE(x) == AOP_REG || AOP_TYPE(x) == AOP_DIR || AOP_TYPE(x) == AOP_PCODE) +#define isAOP_LIT(x) (AOP_TYPE(x) == AOP_LIT) +#define DEBUGpc emitpComment + /*-----------------------------------------------------------------*/ -/* genSkipz2 */ +/* mov2w_regOrLit :- move to WREG either the offset's byte from */ +/* aop (if it's NOT a literal) or from lit (if */ +/* aop is a literal) */ /*-----------------------------------------------------------------*/ -static void genSkipz2(resolvedIfx *rifx, int invert_condition) +static void pic14_mov2w_regOrLit (asmop *aop, unsigned long lit, int offset) { - FENTRY; - if(!rifx) - return; - - if( (rifx->condition ^ invert_condition) & 1) - emitSKPZ; - else - emitSKPNZ; - - emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key)); - rifx->generated = 1; -} -#endif - -#if 0 -/*-----------------------------------------------------------------*/ -/* genSkipz */ -/*-----------------------------------------------------------------*/ -static void genSkipz(iCode *ifx, int condition) -{ - FENTRY; - assert (ifx != NULL); - - if(condition) - emitSKPNZ; - else - emitSKPZ; - - 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) ) - pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); - else - pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); - -} -#endif - -#if 0 -/*-----------------------------------------------------------------*/ -/* genSkipCond */ -/*-----------------------------------------------------------------*/ -static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit) -{ - FENTRY; - if(!rifx) - return; - - 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)); - - - emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key)); - rifx->generated = 1; -} -#endif - -#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) -{ - - int i; - int flag =1; - - while(size--) { - i = (lit >> (size*8)) & 0xff; - - if(i==0) { - if(flag) - emitpcode(POC_MOVFW, popGet(AOP(op),size)); - else - emitpcode(POC_IORFW, popGet(AOP(op),size)); - flag = 0; - } - } - - return (flag==0); -} -#endif - - -#define isAOP_REGlike(x) (AOP_TYPE(x) == AOP_REG || AOP_TYPE(x) == AOP_DIR || AOP_TYPE(x) == AOP_PCODE) -#define isAOP_LIT(x) (AOP_TYPE(x) == AOP_LIT) -#define DEBUGpc emitpComment - -/*-----------------------------------------------------------------*/ -/* mov2w_regOrLit :- move to WREG either the offset's byte from */ -/* aop (if it's NOT a literal) or from lit (if */ -/* aop is a literal) */ -/*-----------------------------------------------------------------*/ -void pic14_mov2w_regOrLit (asmop *aop, unsigned long lit, int offset) { - if (aop->type == AOP_LIT) { - emitpcode (POC_MOVLW, popGetLit((lit >> (offset*8)) & 0x00FF)); - } else { - emitpcode (POC_MOVFW, popGet (aop, offset)); - } + if (aop->type == AOP_LIT) { + emitpcode (POC_MOVLW, popGetLit((lit >> (offset*8)) & 0x00FF)); + } else { + emitpcode (POC_MOVFW, popGet (aop, offset)); + } } /* genCmp performs a left < right comparison, stores @@ -3554,3161 +3312,1621 @@ correct_result_in_carry: } // if } - -#if 0 -/* OLD VERSION -- BUGGY, DO NOT USE */ - /*-----------------------------------------------------------------*/ -/* genCmp :- greater or less than comparison */ +/* genCmpGt :- greater than comparison */ /*-----------------------------------------------------------------*/ -static void genCmp (operand *left,operand *right, - operand *result, iCode *ifx, int sign) +static void genCmpGt (iCode *ic, iCode *ifx) { - int size; //, offset = 0 ; - unsigned long lit = 0L,i = 0; - resolvedIfx rFalseIfx; - // resolvedIfx rTrueIfx; - symbol *truelbl; + operand *left, *right, *result; + sym_link *letype , *retype; + int sign ; FENTRY; 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")); - } - */ - - resolveIfx(&rFalseIfx,ifx); - truelbl = newiTempLabel(NULL); - size = max(AOP_SIZE(left),AOP_SIZE(right)); - - DEBUGpic14_AopType(__LINE__,left,right,result); - -#define _swapp - - /* if literal is on the right then swap with left */ - if ((AOP_TYPE(right) == AOP_LIT)) { - operand *tmp = right ; - unsigned long mask = (0x100 << (8*(size-1))) - 1; - lit = ulFromVal(AOP(right)->aopu.aop_lit); -#ifdef _swapp - - lit = (lit - 1) & mask; - right = left; - left = tmp; - rFalseIfx.condition ^= 1; -#endif + left = IC_LEFT(ic); + right= IC_RIGHT(ic); + result = IC_RESULT(ic); - } else if ((AOP_TYPE(left) == AOP_LIT)) { - lit = ulFromVal(AOP(left)->aopu.aop_lit); - } + letype = getSpec(operandType(left)); + retype =getSpec(operandType(right)); + sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype)); + /* assign the amsops */ + aopOp (left,ic,FALSE); + aopOp (right,ic,FALSE); + aopOp (result,ic,TRUE); + genCmp(right, left, result, ifx, sign); - //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 */ + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); +} - symbol *lbl = newiTempLabel(NULL); +/*-----------------------------------------------------------------*/ +/* genCmpLt - less than comparisons */ +/*-----------------------------------------------------------------*/ +static void genCmpLt (iCode *ic, iCode *ifx) +{ + operand *left, *right, *result; + sym_link *letype , *retype; + int sign ; -#ifndef _swapp - if(AOP_TYPE(right) == AOP_LIT) { + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + left = IC_LEFT(ic); + right= IC_RIGHT(ic); + result = IC_RESULT(ic); - //lit = ulFromVal(AOP(right)->aopu.aop_lit); + letype = getSpec(operandType(left)); + retype =getSpec(operandType(right)); + sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype)); - DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign); + /* assign the amsops */ + aopOp (left,ic,FALSE); + aopOp (right,ic,FALSE); + aopOp (result,ic,TRUE); - /* special cases */ + genCmp(left, right, result, ifx, sign); - if(lit == 0) { + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); +} - 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)); +/*-----------------------------------------------------------------*/ +/* genCmpEq - generates code for equal to */ +/*-----------------------------------------------------------------*/ +static void genCmpEq (iCode *ic, iCode *ifx) +{ + operand *left, *right, *result; + int size; + symbol *false_label; - if(ifx) ifx->generated = 1; - return; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - } - size--; + if(ifx) + DEBUGpic14_emitcode ("; ifx is non-null",""); + else + DEBUGpic14_emitcode ("; ifx is null",""); - if(size == 0) { - //i = (lit >> (size*8)) & 0xff; - DEBUGpic14_emitcode(";right lit","line = %d",__LINE__); + aopOp((left=IC_LEFT(ic)),ic,FALSE); + aopOp((right=IC_RIGHT(ic)),ic,FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE); - emitpcode(POC_MOVFW, popGet(AOP(left),size)); + DEBUGpic14_AopType(__LINE__,left,right,result); - 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,0); - } else { - emitpcode(POC_ADDLW, popGetLit(0x80)); - emitpcode(POC_ADDLW, popGetLit(i^0x80)); - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - } + /* if literal, move literal to right */ + if (op_isLitLike (IC_LEFT(ic))) { + operand *tmp = right ; + right = left; + left = tmp; + } - } else { - if(lit == 1) { - genSkipz2(&rFalseIfx,1); - } else { - emitpcode(POC_ADDLW, popGetLit(i)); - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - } - } + false_label = NULL; + if (ifx && !IC_TRUE(ifx)) + { + assert (IC_FALSE(ifx)); + false_label = IC_FALSE(ifx); + } - if(ifx) ifx->generated = 1; - return; - } + size = min(AOP_SIZE(left),AOP_SIZE(right)); + assert(!pic14_sameRegs(AOP(result),AOP(left))); + assert(!pic14_sameRegs(AOP(result),AOP(right))); - /* chars are out of the way. now do ints and longs */ + /* assume left != right */ + { + int i; + for (i=0; i < AOP_SIZE(result); i++) + { + emitpcode(POC_CLRF, popGet(AOP(result),i)); + } + } + if (AOP_TYPE(right) == AOP_LIT) + { + unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit); + int i; + size = AOP_SIZE(left); + assert(!op_isLitLike(left)); - DEBUGpic14_emitcode(";right lit","line = %d",__LINE__); + switch (lit) + { + case 0: + mov2w(AOP(left), 0); + for (i=1; i < size; i++) + emitpcode(POC_IORFW,popGet(AOP(left),i)); + /* now Z is set iff `left == right' */ + emitSKPZ; + if (!false_label) false_label = newiTempLabel(NULL); + emitpcode(POC_GOTO, popGetLabel(false_label->key)); + break; - /* special cases */ + default: + for (i=0; i < size; i++) + { + mov2w(AOP(left),i); + emitpcode(POC_XORLW, popGetLit(lit >> (8*i))); + /* now Z is cleared if `left != right' */ + emitSKPZ; + if (!false_label) false_label = newiTempLabel(NULL); + emitpcode(POC_GOTO, popGetLabel(false_label->key)); + } // for i + break; + } // switch (lit) + } + else + { + /* right is no literal */ + int i; - if(sign) { + for (i=0; i < size; i++) + { + mov2w(AOP(right),i); + emitpcode(POC_XORFW,popGet(AOP(left),i)); + /* now Z is cleared if `left != right' */ + emitSKPZ; + if (!false_label) false_label = newiTempLabel(NULL); + emitpcode(POC_GOTO, popGetLabel(false_label->key)); + } // for i + } - if(lit == 0) { - genSkipCond(&rFalseIfx,left,size,7); - if(ifx) ifx->generated = 1; - return; - } + /* if we reach here, left == right */ - if(lit <0x100) { - DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); + if (AOP_SIZE(result) > 0) + { + emitpcode(POC_INCF, popGet(AOP(result),0)); + } - //rFalseIfx.condition ^= 1; - //genSkipCond(&rFalseIfx,left,size,7); - //rFalseIfx.condition ^= 1; + if (ifx && IC_TRUE(ifx)) + { + emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); + } - 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)); + if (false_label && (!ifx || IC_TRUE(ifx))) + emitpLabel(false_label->key); - emitpcode(POC_MOVLW, popGetLit(0x100-lit)); - emitpcode(POC_ADDFW, popGet(AOP(left),0)); - emitpcode(POC_MOVFW, popGet(AOP(left),1)); + if (ifx) ifx->generated = 1; - while(size > 1) - emitpcode(POC_IORFW, popGet(AOP(left),size--)); + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); +} - if(rFalseIfx.condition) { - emitSKPZ; - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); +/*-----------------------------------------------------------------*/ +/* ifxForOp - returns the icode containing the ifx for operand */ +/*-----------------------------------------------------------------*/ +static iCode *ifxForOp ( operand *op, iCode *ic ) +{ + FENTRY; + /* if true symbol then needs to be assigned */ + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if (IS_TRUE_SYMOP(op)) + return NULL ; - } else { - emitSKPNZ; - } - - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - emitpLabel(truelbl->key); - if(ifx) ifx->generated = 1; - return; + /* if this has register type condition and + the next instruction is ifx with the same operand + and live to of the operand is upto the ifx only then */ + if (ic->next && + ic->next->op == IFX && + IC_COND(ic->next)->key == op->key && + 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; + } - if(size == 1) { + DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__); + if (ic->next && + ic->next->op == IFX) + DEBUGpic14_emitcode ("; ic-next"," is an IFX"); - 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); assert ( !"genSkipc should have inverse logic" ); + 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); + } - if(ifx) ifx->generated = 1; - return; + return NULL; +} +/*-----------------------------------------------------------------*/ +/* genAndOp - for && operation */ +/*-----------------------------------------------------------------*/ +static void genAndOp (iCode *ic) +{ + operand *left,*right, *result; + /* symbol *tlbl; */ - } - } 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); assert ( !"genSkipc should have inverse logic" ); + FENTRY; + 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 */ + 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(ifx) ifx->generated = 1; - return; + emitpcode(POC_MOVFW,popGet(AOP(left),0)); + emitpcode(POC_ANDFW,popGet(AOP(right),0)); + emitpcode(POC_MOVWF,popGet(AOP(result),0)); - } + /* if both are bit variables */ + /* if (AOP_TYPE(left) == AOP_CRY && */ + /* AOP_TYPE(right) == AOP_CRY ) { */ + /* 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); */ + /* 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)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); +} - if(lit & (0x80 << (size*8))) { - /* lit is negative */ - DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); +/*-----------------------------------------------------------------*/ +/* genOrOp - for || operation */ +/*-----------------------------------------------------------------*/ +/* +tsd pic port - +modified this code, but it doesn't appear to ever get called +*/ - //genSkipCond(&rFalseIfx,left,size,7); +static void genOrOp (iCode *ic) +{ + operand *left,*right, *result; + symbol *tlbl; + int i; - emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0)); + /* note here that || operations that are in an + if statement are taken away by backPatchLabels + only those used in arthmetic operations remain */ + FENTRY; + 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); - if(rFalseIfx.condition) - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - else - emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); + DEBUGpic14_AopType(__LINE__,left,right,result); + for (i=0; i < AOP_SIZE(result); i++) + { + emitpcode(POC_CLRF, popGet(AOP(result), i)); + } // for i - } 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)); + tlbl = newiTempLabel(NULL); + pic14_toBoolean(left); + emitSKPZ; + emitpcode(POC_GOTO, popGetLabel(tlbl->key)); + pic14_toBoolean(right); + emitpLabel(tlbl->key); + /* here Z is clear IFF `left || right' */ + emitSKPZ; + emitpcode(POC_INCF, popGet(AOP(result), 0)); - } + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); +} - /* There are no more special cases, so perform a general compare */ +/*-----------------------------------------------------------------*/ +/* isLiteralBit - test if lit == 2^n */ +/*-----------------------------------------------------------------*/ +static int isLiteralBit(unsigned long lit) +{ + unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L, + 0x100L,0x200L,0x400L,0x800L, + 0x1000L,0x2000L,0x4000L,0x8000L, + 0x10000L,0x20000L,0x40000L,0x80000L, + 0x100000L,0x200000L,0x400000L,0x800000L, + 0x1000000L,0x2000000L,0x4000000L,0x8000000L, + 0x10000000L,0x20000000L,0x40000000L,0x80000000L}; + int idx; - emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff)); - emitpcode(POC_SUBFW, popGet(AOP(left),size)); + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + for(idx = 0; idx < 32; idx++) + if(lit == pw[idx]) + return idx+1; + return 0; +} - while(size--) { +/*-----------------------------------------------------------------*/ +/* continueIfTrue - */ +/*-----------------------------------------------------------------*/ +static void continueIfTrue (iCode *ic) +{ + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(IC_TRUE(ic)) + { + // Why +100?!? + emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100)); + pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); + } + ic->generated = 1; +} - emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff)); - emitSKPNZ; - emitpcode(POC_SUBFW, popGet(AOP(left),size)); - } - //rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); +/*-----------------------------------------------------------------*/ +/* jmpIfTrue - */ +/*-----------------------------------------------------------------*/ +static void jumpIfTrue (iCode *ic) +{ + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(!IC_TRUE(ic)) + { + // Why +100?!? + emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100)); + pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); + } + ic->generated = 1; +} - emitpLabel(truelbl->key); +/*-----------------------------------------------------------------*/ +/* jmpTrueOrFalse - */ +/*-----------------------------------------------------------------*/ +static void jmpTrueOrFalse (iCode *ic, symbol *tlbl) +{ + FENTRY; + // ugly but optimized by peephole + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(IC_TRUE(ic)){ + symbol *nlbl = newiTempLabel(NULL); + 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{ + pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + } + ic->generated = 1; +} - if(ifx) ifx->generated = 1; - return; +/*-----------------------------------------------------------------*/ +/* genAnd - code for and */ +/*-----------------------------------------------------------------*/ +static void genAnd (iCode *ic, iCode *ifx) +{ + operand *left, *right, *result; + int size, offset=0; + unsigned long lit = 0L; + int bytelit = 0; + resolvedIfx rIfx; + FENTRY; + 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); - } + resolveIfx(&rIfx,ifx); + /* 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; + } - /* 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); + /* 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 = ulFromVal (AOP(right)->aopu.aop_lit); - /* General case - compare to an unsigned literal on the right.*/ + size = AOP_SIZE(result); - i = (lit >> (size*8)) & 0xff; - emitpcode(POC_MOVLW, popGetLit(i)); - emitpcode(POC_SUBFW, popGet(AOP(left),size)); - while(size--) { - i = (lit >> (size*8)) & 0xff; + DEBUGpic14_AopType(__LINE__,left,right,result); - 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)); + // 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"); } - - - emitpLabel(lbl->key); - //if(emitFinalCheck) - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - if(sign) - emitpLabel(truelbl->key); - - if(ifx) ifx->generated = 1; - return; - - - } -#endif // _swapp - - if(AOP_TYPE(left) == AOP_LIT) { - //symbol *lbl = newiTempLabel(NULL); - - //EXPERIMENTAL lit = ulFromVal(AOP(left)->aopu.aop_lit); - - - DEBUGpic14_emitcode(";left lit","lit = 0x%x,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)); - - genSkipz2(&rFalseIfx,0); - if(ifx) ifx->generated = 1; - return; + } 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(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(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){ + int offset = 0; + while (posbit > 7) { + posbit -= 8; + offset++; + } + emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS), + newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0)); + emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key)); - if(ifx) ifx->generated = 1; - return; + ifx->generated = 1; } - - if(sign) { - /* signed comparisons to a literal byte */ - - int lp1 = (lit+1) & 0xff; - - DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit); - switch (lp1) { - case 0: - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,0,7); - break; - case 0x7f: - emitpcode(POC_MOVFW, popGet(AOP(right),0)); - emitpcode(POC_XORLW, popGetLit(0x7f)); - genSkipz2(&rFalseIfx,1); - break; - default: - emitpcode(POC_MOVFW, popGet(AOP(right),0)); - emitpcode(POC_ADDLW, popGetLit(0x80)); - emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80)); - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - break; + 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){ + mov2w( AOP(left), offset); + // byte == 2^n ? + if((posbit = isLiteralBit(bytelit)) != 0) { + emitpcode(rIfx.condition ? POC_BTFSC : POC_BTFSS, // XXX: or the other way round? + newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit - 1, 0)); + pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100); } - if(ifx) ifx->generated = 1; - } else { - /* unsigned comparisons to a literal byte */ - - switch(lit & 0xff ) { - case 0: - emitpcode(POC_MOVFW, popGet(AOP(right),0)); - genSkipz2(&rFalseIfx,0); - if(ifx) ifx->generated = 1; - break; - case 0x7f: - genSkipCond(&rFalseIfx,right,0,7); - if(ifx) ifx->generated = 1; - break; + else{ + emitpcode(POC_ANDLW, newpCodeOpLit(bytelit & 0x0ff)); + if (rIfx.condition) emitSKPZ; + else emitSKPNZ; - default: - emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff)); - emitpcode(POC_SUBFW, popGet(AOP(right),0)); - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - rFalseIfx.condition ^= 1; - if (AOP_TYPE(result) == AOP_CRY) { - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - if(ifx) ifx->generated = 1; - } else { - DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition); - emitpcode(POC_CLRF, popGet(AOP(result),0)); - emitpcode(POC_RLF, popGet(AOP(result),0)); - emitpcode(POC_MOVLW, popGetLit(0x01)); - emitpcode(POC_XORWF, popGet(AOP(result),0)); + if(bytelit != 0x0FFL) + { + pic14_emitcode("anl","a,%s", + aopGet(AOP(right),offset,FALSE,TRUE)); } - break; - } - } - - //goto check_carry; - return; - - } else { - - /* Size is greater than 1 */ - - if(sign) { - int lp1 = lit+1; - - size--; - - if(lp1 == 0) { - /* this means lit = 0xffffffff, or -1 */ - - - DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__); - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,size,7); - if(ifx) ifx->generated = 1; - return; + pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); } - if(lit == 0) { - int s = size; + emitpcode(POC_GOTO, popGetLabel(rIfx.lbl->key)); + ifx->generated = 1; - if(rFalseIfx.condition) { - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - } + } + 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 ; + } + } + pic14_outBitC(result); + goto release ; + } - emitpcode(POC_MOVFW, popGet(AOP(right),size)); - while(size--) - emitpcode(POC_IORFW, popGet(AOP(right),size)); + /* 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 */ + 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; + default: + { + int p = my_powof2( (~lit) & 0xff ); + if(p>=0) { + /* only one bit is set in the literal, so use a bcf instruction */ + emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0)); - emitSKPZ; - if(rFalseIfx.condition) { - emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); - emitpLabel(truelbl->key); - }else { - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,s,7); + } else { + if(know_W != (int)(lit&0xff)) + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + know_W = lit &0xff; + emitpcode(POC_ANDWF,popGet(AOP(left),offset)); } - - if(ifx) ifx->generated = 1; - return; } + } + } else { + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_ANDWF,popGet(AOP(left),offset)); + } + } - if((size == 1) && (0 == (lp1&0xff))) { - /* lower byte of signed word is zero */ - DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit); - i = ((lp1 >> 8) & 0xff) ^0x80; - emitpcode(POC_MOVFW, popGet(AOP(right),size)); - emitpcode(POC_ADDLW, popGetLit( 0x80)); - emitpcode(POC_ADDLW, popGetLit(0x100-i)); - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - - - if(ifx) ifx->generated = 1; - return; + } 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){ + int t = (lit >> (offset*8)) & 0x0FFL; + switch(t) { + case 0x00: + emitpcode(POC_CLRF,popGet(AOP(result),offset)); + break; + case 0xff: + emitpcode(POC_MOVFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + break; + default: + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_ANDFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); } + continue; + } - 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)); + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_ANDFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + } + } + } - if(rFalseIfx.condition) - emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); - else - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); +release : + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); +} +/*-----------------------------------------------------------------*/ +/* genOr - code for or */ +/*-----------------------------------------------------------------*/ +static void genOr (iCode *ic, iCode *ifx) +{ + operand *left, *right, *result; + int size, offset=0; + unsigned long lit = 0L; - } 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; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); - //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); + aopOp((left = IC_LEFT(ic)),ic,FALSE); + aopOp((right= IC_RIGHT(ic)),ic,FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE); - 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)); + 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) || + 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; + } - emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff)); - emitpcode(POC_SUBFW, popGet(AOP(right),size)); + /* 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; + } - while(size--) { + DEBUGpic14_AopType(__LINE__,left,right,result); - emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff)); - emitSKPNZ; - emitpcode(POC_SUBFW, popGet(AOP(right),size)); - } - rFalseIfx.condition ^= 1; - //rFalseIfx.condition = 1; - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); + if(AOP_TYPE(right) == AOP_LIT) + lit = ulFromVal (AOP(right)->aopu.aop_lit); - emitpLabel(truelbl->key); + size = AOP_SIZE(result); - if(ifx) ifx->generated = 1; - return; - // end of if (sign) - } else { - - /* compare word or long to an unsigned literal on the right.*/ - - - size--; - if(lit < 0xff) { - DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit); - switch (lit) { - case 0: - break; /* handled above */ - /* - case 0xff: - emitpcode(POC_MOVFW, popGet(AOP(right),size)); - while(size--) - emitpcode(POC_IORFW, popGet(AOP(right),size)); - genSkipz2(&rFalseIfx,0); - break; - */ - default: - emitpcode(POC_MOVFW, popGet(AOP(right),size)); - while(--size) - emitpcode(POC_IORFW, popGet(AOP(right),size)); - - emitSKPZ; - if(rFalseIfx.condition) - emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); - else - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - - - emitpcode(POC_MOVLW, popGetLit(lit+1)); - emitpcode(POC_SUBFW, popGet(AOP(right),0)); - - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - } - - emitpLabel(truelbl->key); - - if(ifx) ifx->generated = 1; - return; - } - - - lit++; - DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit); - i = (lit >> (size*8)) & 0xff; - - emitpcode(POC_MOVLW, popGetLit(i)); - emitpcode(POC_SUBFW, popGet(AOP(right),size)); - - while(size--) { - i = (lit >> (size*8)) & 0xff; - - if(i) { - emitpcode(POC_MOVLW, popGetLit(i)); - emitSKPNZ; - emitpcode(POC_SUBFW, popGet(AOP(right),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(right),size)); - } - } - - - emitpLabel(lbl->key); - - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); + // if(bit | yy) + // xx = bit | yy; + if (AOP_TYPE(left) == AOP_CRY){ + if(AOP_TYPE(right) == AOP_LIT){ + // c = bit & literal; + if(lit){ + // lit != 0 => result = 1 + if(AOP_TYPE(result) == AOP_CRY){ + if(size) + 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) + continueIfTrue(ifx); + goto release; } - - 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); assert ( !"genSkipc should have inverse logic" ); - - if(ifx) ifx->generated = 1; - return; + // lit == 0 => result = left + if(size && pic14_sameRegs(AOP(result),AOP(left))) + goto release; + pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__); } - } else { + if (AOP_TYPE(right) == AOP_CRY){ + if(pic14_sameRegs(AOP(result),AOP(left))){ + // c = bit | bit; + emitpcode(POC_BCF, popGet(AOP(result),0)); + emitpcode(POC_BTFSC, popGet(AOP(right),0)); + emitpcode(POC_BSF, popGet(AOP(result),0)); - emitpcode(POC_MOVFW, popGet(AOP(right),size)); - emitpcode(POC_SUBFW, popGet(AOP(left),size)); - } - - - /* The rest of the bytes of a multi-byte compare */ - while (size) { - - emitSKPZ; - emitpcode(POC_GOTO, popGetLabel(lbl->key)); - size--; + 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); + } else { + 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)); + } + } else { + // c = bit | val; + symbol *tlbl = newiTempLabel(NULL); + pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - emitpcode(POC_MOVFW, popGet(AOP(right),size)); - emitpcode(POC_SUBFW, popGet(AOP(left),size)); + emitpcode(POC_BCF, popGet(AOP(result),0)); + if(!((AOP_TYPE(result) == AOP_CRY) && ifx)) + pic14_emitcode(";XXX setb","c"); + pic14_emitcode(";XXX jb","%s,%05d_DS_", + AOP(left)->aopu.aop_dir,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; + 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 ; + } - emitpLabel(lbl->key); - - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || - (AOP_TYPE(result) == AOP_REG)) { - emitpcode(POC_CLRF, popGet(AOP(result),0)); - emitpcode(POC_RLF, popGet(AOP(result),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)){ + if(lit){ + pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); + // result = 1 + if(size) + pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir); + else + continueIfTrue(ifx); + goto release; } else { - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); + pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); + // lit = 0, result = boolean(left) + if(size) + pic14_emitcode(";XXX setb","c"); + pic14_toBoolean(right); + if(size){ + symbol *tlbl = newiTempLabel(NULL); + pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); + CLRC; + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + } else { + genIfxJump (ifx,"a"); + goto release; + } } - //genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - if(ifx) ifx->generated = 1; - - return; - - } - - // check_carry: - if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) { - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic14_outBitC(result); - } else { - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if the result is used in the next - ifx conditional branch then generate - code a little differently */ - if (ifx ) - genIfxJump (ifx,"c"); - else - pic14_outBitC(result); - /* leave the result in acc */ + goto release ; } -} -#endif + /* 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){ + if((lit & 0xff) == 0) + /* or'ing with 0 has no effect */ + continue; + else { + 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, + newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0)); + } else { + if(know_W != (int)(lit & 0xff)) + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + know_W = lit & 0xff; + emitpcode(POC_IORWF, popGet(AOP(left),offset)); + } -/*-----------------------------------------------------------------*/ -/* genCmpGt :- greater than comparison */ -/*-----------------------------------------------------------------*/ -static void genCmpGt (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - sym_link *letype , *retype; - int sign ; + } + } else { + emitpcode(POC_MOVFW, popGet(AOP(right),offset)); + emitpcode(POC_IORWF, popGet(AOP(left),offset)); + } + } + } 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)); + pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - left = IC_LEFT(ic); - right= IC_RIGHT(ic); - result = IC_RESULT(ic); - letype = getSpec(operandType(left)); - retype =getSpec(operandType(right)); - sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype)); - /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); + if(size) + pic14_emitcode(";XXX setb","c"); + while(sizer--){ + MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode(";XXX orl","a,%s", + aopGet(AOP(left),offset,FALSE,FALSE)); + pic14_emitcode(";XXX 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)); - genCmp(right, left, result, ifx, sign); + break; + default: + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_IORFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + } + continue; + } + + // faster than result <- left, anl result,right + // and better if result is SFR + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_IORFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + } + } +release : freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ -/* genCmpLt - less than comparisons */ +/* genXor - code for xclusive or */ /*-----------------------------------------------------------------*/ -static void genCmpLt (iCode *ic, iCode *ifx) +static void genXor (iCode *ic, iCode *ifx) { operand *left, *right, *result; - sym_link *letype , *retype; - int sign ; + int size, offset=0; + unsigned long lit = 0L; FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - left = IC_LEFT(ic); - right= IC_RIGHT(ic); - result = IC_RESULT(ic); - - letype = getSpec(operandType(left)); - retype =getSpec(operandType(right)); - sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype)); - /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); - - genCmp(left, right, result, ifx, sign); - - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genCmpEq - generates code for equal to */ -/*-----------------------------------------------------------------*/ -static void genCmpEq (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - int size; - symbol *false_label; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - if(ifx) - DEBUGpic14_emitcode ("; ifx is non-null",""); - else - DEBUGpic14_emitcode ("; ifx is null",""); - - 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 literal, move literal to right */ - if (op_isLitLike (IC_LEFT(ic))) { - operand *tmp = right ; - right = left; - left = tmp; - } - - false_label = NULL; - if (ifx && !IC_TRUE(ifx)) - { - assert (IC_FALSE(ifx)); - false_label = IC_FALSE(ifx); - } - - size = min(AOP_SIZE(left),AOP_SIZE(right)); - assert(!pic14_sameRegs(AOP(result),AOP(left))); - assert(!pic14_sameRegs(AOP(result),AOP(right))); - - /* assume left != right */ - { - int i; - for (i=0; i < AOP_SIZE(result); i++) - { - emitpcode(POC_CLRF, popGet(AOP(result),i)); - } - } - - if (AOP_TYPE(right) == AOP_LIT) - { - unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit); - int i; - size = AOP_SIZE(left); - assert(!op_isLitLike(left)); - - switch (lit) - { - case 0: - mov2w(AOP(left), 0); - for (i=1; i < size; i++) - emitpcode(POC_IORFW,popGet(AOP(left),i)); - /* now Z is set iff `left == right' */ - emitSKPZ; - if (!false_label) false_label = newiTempLabel(NULL); - emitpcode(POC_GOTO, popGetLabel(false_label->key)); - break; - - default: - for (i=0; i < size; i++) - { - mov2w(AOP(left),i); - emitpcode(POC_XORLW, popGetLit(lit >> (8*i))); - /* now Z is cleared if `left != right' */ - emitSKPZ; - if (!false_label) false_label = newiTempLabel(NULL); - emitpcode(POC_GOTO, popGetLabel(false_label->key)); - } // for i - break; - } // switch (lit) - } - else - { - /* right is no literal */ - int i; - - for (i=0; i < size; i++) - { - mov2w(AOP(right),i); - emitpcode(POC_XORFW,popGet(AOP(left),i)); - /* now Z is cleared if `left != right' */ - emitSKPZ; - if (!false_label) false_label = newiTempLabel(NULL); - emitpcode(POC_GOTO, popGetLabel(false_label->key)); - } // for i - } - - /* if we reach here, left == right */ - - if (AOP_SIZE(result) > 0) - { - emitpcode(POC_INCF, popGet(AOP(result),0)); - } - - if (ifx && IC_TRUE(ifx)) - { - emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); - } - - if (false_label && (!ifx || IC_TRUE(ifx))) - emitpLabel(false_label->key); - - if (ifx) ifx->generated = 1; - - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* ifxForOp - returns the icode containing the ifx for operand */ -/*-----------------------------------------------------------------*/ -static iCode *ifxForOp ( operand *op, iCode *ic ) -{ - FENTRY; - /* if true symbol then needs to be assigned */ - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (IS_TRUE_SYMOP(op)) - return NULL ; - - /* if this has register type condition and - the next instruction is ifx with the same operand - and live to of the operand is upto the ifx only then */ - if (ic->next && - ic->next->op == IFX && - IC_COND(ic->next)->key == op->key && - 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; -} -/*-----------------------------------------------------------------*/ -/* genAndOp - for && operation */ -/*-----------------------------------------------------------------*/ -static void genAndOp (iCode *ic) -{ - operand *left,*right, *result; - /* symbol *tlbl; */ - - FENTRY; - 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 */ - 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); - - emitpcode(POC_MOVFW,popGet(AOP(left),0)); - emitpcode(POC_ANDFW,popGet(AOP(right),0)); - emitpcode(POC_MOVWF,popGet(AOP(result),0)); - - /* if both are bit variables */ - /* if (AOP_TYPE(left) == AOP_CRY && */ - /* AOP_TYPE(right) == AOP_CRY ) { */ - /* 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); */ - /* 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)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - - -/*-----------------------------------------------------------------*/ -/* genOrOp - for || operation */ -/*-----------------------------------------------------------------*/ -/* -tsd pic port - -modified this code, but it doesn't appear to ever get called -*/ - -static void genOrOp (iCode *ic) -{ - operand *left,*right, *result; - symbol *tlbl; - int i; - - /* note here that || operations that are in an - if statement are taken away by backPatchLabels - only those used in arthmetic operations remain */ - FENTRY; - 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); - - for (i=0; i < AOP_SIZE(result); i++) - { - emitpcode(POC_CLRF, popGet(AOP(result), i)); - } // for i - - tlbl = newiTempLabel(NULL); - pic14_toBoolean(left); - emitSKPZ; - emitpcode(POC_GOTO, popGetLabel(tlbl->key)); - pic14_toBoolean(right); - emitpLabel(tlbl->key); - /* here Z is clear IFF `left || right' */ - emitSKPZ; - emitpcode(POC_INCF, popGet(AOP(result), 0)); - - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* isLiteralBit - test if lit == 2^n */ -/*-----------------------------------------------------------------*/ -static int isLiteralBit(unsigned long lit) -{ - unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L, - 0x100L,0x200L,0x400L,0x800L, - 0x1000L,0x2000L,0x4000L,0x8000L, - 0x10000L,0x20000L,0x40000L,0x80000L, - 0x100000L,0x200000L,0x400000L,0x800000L, - 0x1000000L,0x2000000L,0x4000000L,0x8000000L, - 0x10000000L,0x20000000L,0x40000000L,0x80000000L}; - int idx; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - for(idx = 0; idx < 32; idx++) - if(lit == pw[idx]) - return idx+1; - return 0; -} - -/*-----------------------------------------------------------------*/ -/* continueIfTrue - */ -/*-----------------------------------------------------------------*/ -static void continueIfTrue (iCode *ic) -{ - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(IC_TRUE(ic)) - { - // Why +100?!? - emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100)); - pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); - } - ic->generated = 1; -} - -/*-----------------------------------------------------------------*/ -/* jmpIfTrue - */ -/*-----------------------------------------------------------------*/ -static void jumpIfTrue (iCode *ic) -{ - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(!IC_TRUE(ic)) - { - // Why +100?!? - emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100)); - pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); - } - ic->generated = 1; -} - -/*-----------------------------------------------------------------*/ -/* jmpTrueOrFalse - */ -/*-----------------------------------------------------------------*/ -static void jmpTrueOrFalse (iCode *ic, symbol *tlbl) -{ - FENTRY; - // ugly but optimized by peephole - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(IC_TRUE(ic)){ - symbol *nlbl = newiTempLabel(NULL); - 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{ - pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - } - ic->generated = 1; -} - -/*-----------------------------------------------------------------*/ -/* genAnd - code for and */ -/*-----------------------------------------------------------------*/ -static void genAnd (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - int size, offset=0; - unsigned long lit = 0L; - int bytelit = 0; - resolvedIfx rIfx; - - FENTRY; - 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); - - resolveIfx(&rIfx,ifx); - - /* 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 = ulFromVal (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(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){ - int offset = 0; - while (posbit > 7) { - posbit -= 8; - offset++; - } - emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS), - newpCodeOpBit(aopGet(AOP(left),offset,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){ - mov2w( AOP(left), offset); - // byte == 2^n ? - if((posbit = isLiteralBit(bytelit)) != 0) { - emitpcode(rIfx.condition ? POC_BTFSC : POC_BTFSS, // XXX: or the other way round? - newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit - 1, 0)); - pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100); - } - else{ - emitpcode(POC_ANDLW, newpCodeOpLit(bytelit & 0x0ff)); - if (rIfx.condition) emitSKPZ; - else emitSKPNZ; - - if(bytelit != 0x0FFL) - { - pic14_emitcode("anl","a,%s", - aopGet(AOP(right),offset,FALSE,TRUE)); - } - pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); - } - - emitpcode(POC_GOTO, popGetLabel(rIfx.lbl->key)); - ifx->generated = 1; - - } - 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 ; - } - } - pic14_outBitC(result); - goto release ; - } - - /* 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 */ - 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; - - default: - { - int p = my_powof2( (~lit) & 0xff ); - if(p>=0) { - /* only one bit is set in the literal, so use a bcf instruction */ - emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0)); - - } else { - if(know_W != (int)(lit&0xff)) - emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - know_W = lit &0xff; - emitpcode(POC_ANDWF,popGet(AOP(left),offset)); - } - } - } - } else { - emitpcode(POC_MOVFW,popGet(AOP(right),offset)); - emitpcode(POC_ANDWF,popGet(AOP(left),offset)); - } - } - - } 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){ - int t = (lit >> (offset*8)) & 0x0FFL; - switch(t) { - case 0x00: - emitpcode(POC_CLRF,popGet(AOP(result),offset)); - break; - case 0xff: - emitpcode(POC_MOVFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - break; - default: - emitpcode(POC_MOVLW, popGetLit(t)); - emitpcode(POC_ANDFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - } - continue; - } - - emitpcode(POC_MOVFW,popGet(AOP(right),offset)); - emitpcode(POC_ANDFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - } - } - } - -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genOr - code for or */ -/*-----------------------------------------------------------------*/ -static void genOr (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - int size, offset=0; - unsigned long lit = 0L; - - FENTRY; - 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) || - 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; - } - - DEBUGpic14_AopType(__LINE__,left,right,result); - - if(AOP_TYPE(right) == AOP_LIT) - lit = ulFromVal (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){ - // lit != 0 => result = 1 - if(AOP_TYPE(result) == AOP_CRY){ - if(size) - 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) - continueIfTrue(ifx); - goto release; - } - } else { - // lit == 0 => result = left - if(size && pic14_sameRegs(AOP(result),AOP(left))) - goto release; - pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__); - } - } else { - if (AOP_TYPE(right) == AOP_CRY){ - if(pic14_sameRegs(AOP(result),AOP(left))){ - // c = bit | bit; - 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); - } else { - 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)); - } - } else { - // c = bit | val; - symbol *tlbl = newiTempLabel(NULL); - pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - - - emitpcode(POC_BCF, popGet(AOP(result),0)); - - if(!((AOP_TYPE(result) == AOP_CRY) && ifx)) - pic14_emitcode(";XXX setb","c"); - pic14_emitcode(";XXX jb","%s,%05d_DS_", - AOP(left)->aopu.aop_dir,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; - 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 ; - } - - // 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)){ - if(lit){ - pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - // result = 1 - if(size) - pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir); - else - continueIfTrue(ifx); - goto release; - } else { - pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - // lit = 0, result = boolean(left) - if(size) - pic14_emitcode(";XXX setb","c"); - pic14_toBoolean(right); - if(size){ - symbol *tlbl = newiTempLabel(NULL); - pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); - CLRC; - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - } else { - genIfxJump (ifx,"a"); - goto release; - } - } - pic14_outBitC(result); - goto release ; - } - - /* 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){ - if((lit & 0xff) == 0) - /* or'ing with 0 has no effect */ - continue; - else { - 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, - newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0)); - } else { - if(know_W != (int)(lit & 0xff)) - emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - know_W = lit & 0xff; - emitpcode(POC_IORWF, popGet(AOP(left),offset)); - } - - } - } else { - emitpcode(POC_MOVFW, popGet(AOP(right),offset)); - emitpcode(POC_IORWF, popGet(AOP(left),offset)); - } - } - } 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)); - pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - - - if(size) - pic14_emitcode(";XXX setb","c"); - while(sizer--){ - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - pic14_emitcode(";XXX orl","a,%s", - aopGet(AOP(left),offset,FALSE,FALSE)); - pic14_emitcode(";XXX 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)); - - break; - default: - emitpcode(POC_MOVLW, popGetLit(t)); - emitpcode(POC_IORFW, popGet(AOP(left),offset)); - emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - } - continue; - } - - // faster than result <- left, anl result,right - // and better if result is SFR - emitpcode(POC_MOVFW,popGet(AOP(right),offset)); - emitpcode(POC_IORFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - } - } - -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genXor - code for xclusive or */ -/*-----------------------------------------------------------------*/ -static void genXor (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - int size, offset=0; - unsigned long lit = 0L; - - FENTRY; - 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 || - 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 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 = ulFromVal (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 { - assert ( !"incomplete genXor" ); - pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - pic14_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 ; - } - - 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 { - emitpcode(POC_MOVLW, popGetLit(t)); - emitpcode(POC_XORWF,popGet(AOP(left),offset)); - } - } else { - emitpcode(POC_MOVFW,popGet(AOP(right),offset)); - emitpcode(POC_XORWF,popGet(AOP(left),offset)); - } - } - } 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)); - break; - case 0xff: - emitpcode(POC_COMFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - break; - default: - emitpcode(POC_MOVLW, popGetLit(t)); - emitpcode(POC_XORFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - } - continue; - } - - // faster than result <- left, anl result,right - // and better if result is SFR - emitpcode(POC_MOVFW,popGet(AOP(right),offset)); - emitpcode(POC_XORFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - } - } - -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genInline - write the inline code out */ -/*-----------------------------------------------------------------*/ -static void genInline (iCode *ic) -{ - char *buffer, *bp, *bp1; - bool inComment = FALSE; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - _G.inLine += (!options.asmpeep); - - buffer = bp = bp1 = Safe_strdup (IC_INLINE (ic)); - - while (*bp) - { - switch (*bp) - { - case ';': - inComment = TRUE; - ++bp; - break; - - case '\n': - inComment = FALSE; - *bp++ = '\0'; - if (*bp1) - addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process - bp1 = bp; - break; - - default: - /* Add \n for labels, not dirs such as c:\mydir */ - if (!inComment && (*bp == ':') && (isspace((unsigned char)bp[1]))) - { - ++bp; - *bp = '\0'; - ++bp; - /* print label, use this special format with NULL directive - * to denote that the argument should not be indented with tab */ - addpCode2pBlock(pb, newpCodeAsmDir(NULL, bp1)); // inline directly, no process - bp1 = bp; - } - else - ++bp; - break; - } - } - if ((bp1 != bp) && *bp1) - addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process - - Safe_free (buffer); - - _G.inLine -= (!options.asmpeep); -} - -/*-----------------------------------------------------------------*/ -/* genRRC - rotate right with carry */ -/*-----------------------------------------------------------------*/ -static void genRRC (iCode *ic) -{ - operand *left , *result ; - int size, offset = 0, same; - - FENTRY; - /* rotate right with carry */ - left = IC_LEFT(ic); - result=IC_RESULT(ic); - aopOp (left,ic,FALSE); - aopOp (result,ic,FALSE); - - 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)); - } - - offset++; - } - - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genRLC - generate code for rotate left with carry */ -/*-----------------------------------------------------------------*/ -static void genRLC (iCode *ic) -{ - operand *left , *result ; - int size, offset = 0; - int same; - - FENTRY; - 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); - - 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)); - } - - offset++; - } - - - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genGetHbit - generates code get highest order bit */ -/*-----------------------------------------------------------------*/ -static void genGetHbit (iCode *ic) -{ - operand *left, *result; - left = IC_LEFT(ic); - result=IC_RESULT(ic); - aopOp (left,ic,FALSE); - aopOp (result,ic,FALSE); - - FENTRY; - 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){ - pic14_emitcode("rlc","a"); - pic14_outBitC(result); - } - else{ - pic14_emitcode("rl","a"); - pic14_emitcode("anl","a,#0x01"); - pic14_outAcc(result); - } - - - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* AccLsh - shift left accumulator by known count */ -/* MARK: pic14 always rotates through CARRY! */ -/*-----------------------------------------------------------------*/ -static void AccLsh (pCodeOp *pcop,int shCount) -{ - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - shCount &= 0x0007; // shCount : 0..7 - switch(shCount){ - case 0 : - return; - break; - case 1 : - emitCLRC; - emitpcode(POC_RLF,pcop); - return; - break; - case 2 : - emitpcode(POC_RLF,pcop); - emitpcode(POC_RLF,pcop); - break; - case 3 : - emitpcode(POC_RLF,pcop); - emitpcode(POC_RLF,pcop); - emitpcode(POC_RLF,pcop); - break; - case 4 : - emitpcode(POC_SWAPF,pcop); - break; - case 5 : - emitpcode(POC_SWAPF,pcop); - emitpcode(POC_RLF,pcop); - break; - case 6 : - emitpcode(POC_SWAPF,pcop); - emitpcode(POC_RLF,pcop); - emitpcode(POC_RLF,pcop); - break; - case 7 : - emitpcode(POC_RRFW,pcop); - emitpcode(POC_RRF,pcop); - break; - } - /* clear invalid bits */ - emitpcode(POC_MOVLW, popGetLit ((unsigned char)(~((1UL << shCount) - 1)))); - emitpcode(POC_ANDWF, pcop); -} - -/*-----------------------------------------------------------------*/ -/* AccRsh - shift right accumulator by known count */ -/* MARK: pic14 always rotates through CARRY! */ -/* maskmode - 0: leave invalid bits undefined (caller should mask) */ -/* 1: mask out invalid bits (zero-extend) */ -/* 2: sign-extend result (pretty slow) */ -/*-----------------------------------------------------------------*/ -static void AccRsh (pCodeOp *pcop,int shCount, int mask_mode) -{ - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - shCount &= 0x0007; // shCount : 0..7 - switch(shCount){ - case 0 : - return; - break; - case 1 : - /* load sign if needed */ - if (mask_mode == 2) emitpcode(POC_RLFW,pcop); - else if (mask_mode == 1) emitCLRC; - emitpcode(POC_RRF,pcop); - return; - break; - case 2 : - /* load sign if needed */ - if (mask_mode == 2) emitpcode(POC_RLFW,pcop); - emitpcode(POC_RRF,pcop); - /* load sign if needed */ - if (mask_mode == 2) emitpcode(POC_RLFW,pcop); - emitpcode(POC_RRF,pcop); - if (mask_mode == 2) return; - break; - case 3 : - /* load sign if needed */ - if (mask_mode == 2) emitpcode(POC_RLFW,pcop); - emitpcode(POC_RRF,pcop); - /* load sign if needed */ - if (mask_mode == 2) emitpcode(POC_RLFW,pcop); - emitpcode(POC_RRF,pcop); - /* load sign if needed */ - if (mask_mode == 2) emitpcode(POC_RLFW,pcop); - emitpcode(POC_RRF,pcop); - if (mask_mode == 2) return; - break; - case 4 : - emitpcode(POC_SWAPF,pcop); - break; - case 5 : - emitpcode(POC_SWAPF,pcop); - emitpcode(POC_RRF,pcop); - break; - case 6 : - emitpcode(POC_SWAPF,pcop); - emitpcode(POC_RRF,pcop); - emitpcode(POC_RRF,pcop); - break; - case 7 : - if (mask_mode == 2) - { - /* load sign */ - emitpcode(POC_RLFW,pcop); - emitpcode(POC_CLRF,pcop); - emitSKPNC; - emitpcode(POC_COMF,pcop); - return; - } else { - emitpcode(POC_RLFW,pcop); - emitpcode(POC_RLF,pcop); - } - break; - } - - if (mask_mode == 0) - { - /* leave invalid bits undefined */ - return; - } - - /* clear invalid bits -- zero-extend */ - emitpcode(POC_MOVLW, popGetLit (0x00ff >> shCount)); - emitpcode(POC_ANDWF, pcop); - - if (mask_mode == 2) { - /* sign-extend */ - emitpcode(POC_MOVLW, popGetLit (0x00ff << (8 - shCount))); - emitpcode(POC_BTFSC, newpCodeOpBit (get_op(pcop,NULL,0), 7 - shCount ,0)); - emitpcode(POC_IORWF, pcop); - } -} - -#if 0 -/*-----------------------------------------------------------------*/ -/* AccSRsh - signed right shift accumulator by known count */ -/*-----------------------------------------------------------------*/ -static void AccSRsh (int shCount) -{ - symbol *tlbl ; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(shCount != 0){ - if(shCount == 1){ - pic14_emitcode("mov","c,acc.7"); - pic14_emitcode("rrc","a"); - } else if(shCount == 2){ - 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 */ - 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]); - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - } - } -} - -/*-----------------------------------------------------------------*/ -/* shiftR1Left2Result - shift right one byte from left to result */ -/*-----------------------------------------------------------------*/ -static void shiftR1Left2ResultSigned (operand *left, int offl, - operand *result, int offr, - int shCount) -{ - int same; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - same = ((left == result) || (AOP(left) == AOP(result))) && (offl == 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)); - } - - break; - case 2: - - 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)); - } - - default: - break; - } -} - -/*-----------------------------------------------------------------*/ -/* shiftR1Left2Result - shift right one byte from left to result */ -/*-----------------------------------------------------------------*/ -static void shiftR1Left2Result (operand *left, int offl, - operand *result, int offr, - int shCount, int sign) -{ - int same; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr); + aopOp((left = IC_LEFT(ic)),ic,FALSE); + aopOp((right= IC_RIGHT(ic)),ic,FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE); - /* Copy the msb into the carry if signed. */ - if(sign) { - shiftR1Left2ResultSigned(left,offl,result,offr,shCount); - return; + /* 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 result = right then exchange them */ + if(pic14_sameRegs(AOP(result),AOP(right))){ + operand *tmp = right ; + right = left; + left = tmp; + } - - 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; + /* 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 = ulFromVal (AOP(right)->aopu.aop_lit); -/*-----------------------------------------------------------------*/ -/* shiftL1Left2Result - shift left one byte from left to result */ -/*-----------------------------------------------------------------*/ -static void shiftL1Left2Result (operand *left, int offl, - operand *result, int offr, int shCount) -{ - int same; + size = AOP_SIZE(result); - // char *l; - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + // 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 { + assert ( !"incomplete genXor" ); + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + pic14_emitcode("cpl","c"); + } + } + } - 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)); + // 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)); } - 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); - } - -} -#endif - -/*-----------------------------------------------------------------*/ -/* movLeft2Result - move byte from left to result */ -/*-----------------------------------------------------------------*/ -static void movLeft2Result (operand *left, int offl, - operand *result, int offr) -{ - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){ - aopGet(AOP(left),offl,FALSE,FALSE); - - emitpcode(POC_MOVFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + // bit = c + // val = c + if(size) + pic14_outBitC(result); + // if(bit | ...) + else if((AOP_TYPE(result) == AOP_CRY) && ifx) + genIfxJump(ifx, "c"); + goto release ; } -} - -/*-----------------------------------------------------------------*/ -/* shiftLeft_Left2ResultLit - shift left by known count */ -/*-----------------------------------------------------------------*/ - -static void shiftLeft_Left2ResultLit (operand *left, operand *result, int shCount) -{ - int size, same, offr, i; - - size = AOP_SIZE(left); - if (AOP_SIZE(result) < size) size = AOP_SIZE(result); - - same = pic14_sameRegs (AOP(left), AOP(result)); - - offr = shCount / 8; - shCount = shCount & 0x07; - - size -= offr; - - switch (shCount) - { - case 0: /* takes 0 or 2N cycles (for offr==0) */ - if (!same || offr) { - for (i=size-1; i >= 0; i--) - movLeft2Result (left, i, result, offr + i); - } // if - break; - - case 1: /* takes 1N+1 or 2N+1 cycles (or offr==0) */ - if (same && offr) { - shiftLeft_Left2ResultLit (left, result, 8 * offr); - shiftLeft_Left2ResultLit (result, result, shCount); - return; /* prevent clearing result again */ - } else { - emitCLRC; - for (i=0; i < size; i++) { - if (same && !offr) { - emitpcode (POC_RLF, popGet (AOP(left), i)); - } else { - emitpcode (POC_RLFW, popGet (AOP(left), i)); - emitpcode (POC_MOVWF, popGet (AOP(result), i + offr)); - } // if - } // for - } // if (offr) - break; - - case 4: /* takes 3+5(N-1) = 5N-2 cycles (for offr==0) */ - /* works in-place/with offr as well */ - emitpcode (POC_SWAPFW, popGet (AOP(left), size-1)); - emitpcode (POC_ANDLW, popGetLit (0xF0)); - emitpcode (POC_MOVWF, popGet(AOP(result), size-1+offr)); - - for (i = size - 2; i >= 0; i--) - { - emitpcode (POC_SWAPFW, popGet (AOP(left), i)); - emitpcode (POC_MOVWF, popGet (AOP(result), i + offr)); - emitpcode (POC_ANDLW, popGetLit (0x0F)); - emitpcode (POC_IORWF, popGet (AOP(result), i + offr + 1)); - emitpcode (POC_XORWF, popGet (AOP(result), i + offr)); - } // for i - break; - case 7: /* takes 2(N-1)+3 = 2N+1 cycles */ - /* works in-place/with offr as well */ - emitpcode (POC_RRFW, popGet (AOP(left), size-1)); - for (i = size-2; i >= 0; i--) { - emitpcode (POC_RRFW, popGet (AOP(left), i)); - emitpcode (POC_MOVWF, popGet (AOP(result), offr + i + 1)); - } // for i - emitpcode (POC_CLRF, popGet (AOP(result), offr)); - emitpcode (POC_RRF, popGet (AOP(result), offr)); - break; + 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 { + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_XORWF,popGet(AOP(left),offset)); + } + } else { + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_XORWF,popGet(AOP(left),offset)); + } + } + } 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)); + break; + case 0xff: + emitpcode(POC_COMFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + break; + default: + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_XORFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + } + continue; + } - default: - shiftLeft_Left2ResultLit (left, result, offr * 8 + shCount-1); - shiftLeft_Left2ResultLit (result, result, 1); - return; /* prevent clearing result again */ - break; - } // switch + // faster than result <- left, anl result,right + // and better if result is SFR + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_XORFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + } + } - while (0 < offr--) - { - emitpcode (POC_CLRF, popGet (AOP(result), offr)); - } // while +release : + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ -/* shiftRight_Left2ResultLit - shift right by known count */ +/* genInline - write the inline code out */ /*-----------------------------------------------------------------*/ - -static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign) +static void genInline (iCode *ic) { - int size, same, offr, i; - - size = AOP_SIZE(left); - if (AOP_SIZE(result) < size) size = AOP_SIZE(result); + char *buffer, *bp, *bp1; + bool inComment = FALSE; - same = pic14_sameRegs (AOP(left), AOP(result)); + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - offr = shCount / 8; - shCount = shCount & 0x07; + _G.inLine += (!options.asmpeep); - size -= offr; + buffer = bp = bp1 = Safe_strdup (IC_INLINE (ic)); - if (size) + while (*bp) { - switch (shCount) + switch (*bp) { - case 0: /* takes 0 or 2N cycles (for offr==0) */ - if (!same || offr) { - for (i=0; i < size; i++) - movLeft2Result (left, i + offr, result, i); - } // if - break; - - case 1: /* takes 1N+1(3) or 2N+1(3) cycles (or offr==0) */ - emitpComment ("%s:%d: shCount=%d, size=%d, sign=%d, same=%d, offr=%d", __FUNCTION__, __LINE__, shCount, size, sign, same, offr); - if (same && offr) { - shiftRight_Left2ResultLit (left, result, 8 * offr, sign); - shiftRight_Left2ResultLit (result, result, shCount, sign); - return; /* prevent sign-extending result again */ - } else { - emitCLRC; - if (sign) { - emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(left), AOP_SIZE(left)-1, FALSE, FALSE), 7, 0)); - emitSETC; - } - for (i = size-1; i >= 0; i--) { - if (same && !offr) { - emitpcode (POC_RRF, popGet (AOP(left), i)); - } else { - emitpcode (POC_RRFW, popGet (AOP(left), i + offr)); - emitpcode (POC_MOVWF, popGet (AOP(result), i)); - } - } // for i - } // if (offr) - break; - - case 4: /* takes 3(6)+5(N-1) = 5N-2(+1) cycles (for offr==0) */ - /* works in-place/with offr as well */ - emitpcode (POC_SWAPFW, popGet (AOP(left), offr)); - emitpcode (POC_ANDLW, popGetLit (0x0F)); - emitpcode (POC_MOVWF, popGet(AOP(result), 0)); + case ';': + inComment = TRUE; + ++bp; + break; - for (i = 1; i < size; i++) - { - emitpcode (POC_SWAPFW, popGet (AOP(left), i + offr)); - emitpcode (POC_MOVWF, popGet (AOP(result), i)); - emitpcode (POC_ANDLW, popGetLit (0xF0)); - emitpcode (POC_IORWF, popGet (AOP(result), i - 1)); - emitpcode (POC_XORWF, popGet (AOP(result), i)); - } // for i + case '\n': + inComment = FALSE; + *bp++ = '\0'; + if (*bp1) + addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process + bp1 = bp; + break; - if (sign) + default: + /* Add \n for labels, not dirs such as c:\mydir */ + if (!inComment && (*bp == ':') && (isspace((unsigned char)bp[1]))) { - emitpcode (POC_MOVLW, popGetLit (0xF0)); - emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(result), size-1, FALSE, FALSE), 3, 0)); - emitpcode (POC_IORWF, popGet (AOP(result), size-1)); - } // if - break; - - case 7: /* takes 2(N-1)+3(4) = 2N+1(2) cycles */ - /* works in-place/with offr as well */ - emitpcode (POC_RLFW, popGet (AOP(left), offr)); - for (i = 0; i < size-1; i++) { - emitpcode (POC_RLFW, popGet (AOP(left), offr + i + 1)); - emitpcode (POC_MOVWF, popGet (AOP(result), i)); - } // for i - emitpcode (POC_CLRF, popGet (AOP(result), size-1)); - if (!sign) { - emitpcode (POC_RLF, popGet (AOP(result), size-1)); - } else { - emitSKPNC; - emitpcode (POC_DECF, popGet (AOP(result), size-1)); + ++bp; + *bp = '\0'; + ++bp; + /* print label, use this special format with NULL directive + * to denote that the argument should not be indented with tab */ + addpCode2pBlock(pb, newpCodeAsmDir(NULL, bp1)); // inline directly, no process + bp1 = bp; } - break; + else + ++bp; + break; + } + } + if ((bp1 != bp) && *bp1) + addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process - default: - shiftRight_Left2ResultLit (left, result, offr * 8 + shCount-1, sign); - shiftRight_Left2ResultLit (result, result, 1, sign); - return; /* prevent sign extending result again */ - break; - } // switch - } // if + Safe_free (buffer); - addSign (result, size, sign); + _G.inLine -= (!options.asmpeep); } -#if 0 /*-----------------------------------------------------------------*/ -/* shiftL2Left2Result - shift left two bytes from left to result */ +/* genRRC - rotate right with carry */ /*-----------------------------------------------------------------*/ -static void shiftL2Left2Result (operand *left, int offl, - operand *result, int offr, int shCount) +static void genRRC (iCode *ic) { + operand *left , *result ; + int size, offset = 0, same; + FENTRY; + /* 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__); + DEBUGpic14_AopType(__LINE__,left,NULL,result); - if(pic14_sameRegs(AOP(result), AOP(left))) { - switch(shCount) { - case 0: - break; - case 1: - case 2: - case 3: + same = pic14_sameRegs(AOP(result),AOP(left)); - emitpcode(POC_MOVFW,popGet(AOP(result),offr)); - emitpcode(POC_ADDWF,popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); + size = AOP_SIZE(result); - while(--shCount) { - emitCLRC; - emitpcode(POC_RLF, popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); - } + /* get the lsb and put it into the carry */ + emitpcode(POC_RRFW, popGet(AOP(left),size-1)); - 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)); - } + offset = 0 ; - } 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; + while(size--) { - 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)); + if(same) { + emitpcode(POC_RRF, popGet(AOP(left),offset)); + } else { + emitpcode(POC_RRFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); } + + offset++; } + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ -/* shiftR2Left2Result - shift right two bytes from left to result */ -/*-----------------------------------------------------------------*/ -static void shiftR2Left2Result (operand *left, int offl, - operand *result, int offr, - int shCount, int sign) -{ - int same=0; - - FENTRY; - 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) - emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16)); - else - emitCLRC; +/* genRLC - generate code for rotate left with carry */ +/*-----------------------------------------------------------------*/ +static void genRLC (iCode *ic) +{ + operand *left , *result ; + int size, offset = 0; + int same; - 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)); - } + FENTRY; + 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); - 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) { + DEBUGpic14_AopType(__LINE__,left,NULL,result); - emitpcode(POC_MOVLW, popGetLit(0xf0)); - emitpcode(POC_ANDWF, popGet(AOP(result),offr)); - emitpcode(POC_SWAPF, popGet(AOP(result),offr)); + same = pic14_sameRegs(AOP(result),AOP(left)); - 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)); - } + /* move it to the result */ + size = AOP_SIZE(result); - if(shCount >=5) { - emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RRF, popGet(AOP(result),offr)); - } + /* get the msb and put it into the carry */ + emitpcode(POC_RLFW, popGet(AOP(left),size-1)); - 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)); - } + offset = 0 ; - break; + while(size--) { - 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)); + emitpcode(POC_RLF, popGet(AOP(left),offset)); } 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_RLF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RLF, 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+MSB16)); - //emitpcode(POC_RLF, popGet(AOP(result),offr)); + emitpcode(POC_RLFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + } + offset++; + } - } - 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)); - } + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ -/* shiftLLeftOrResult - shift left one byte from left, or to result*/ +/* genGetHbit - generates code get highest order bit */ /*-----------------------------------------------------------------*/ -static void shiftLLeftOrResult (operand *left, int offl, - operand *result, int offr, int shCount) +static void genGetHbit (iCode *ic) { + operand *left, *result; + left = IC_LEFT(ic); + result=IC_RESULT(ic); + aopOp (left,ic,FALSE); + aopOp (result,ic,FALSE); + FENTRY; 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){ + pic14_emitcode("rlc","a"); + pic14_outBitC(result); + } + else{ + pic14_emitcode("rl","a"); + pic14_emitcode("anl","a,#0x01"); + pic14_outAcc(result); + } - /* shift left accumulator */ - AccLsh(left,offl,shCount); - /* or with result */ - emitpcode (POC_IORWF, popGet (AOP(result), offr)); - assert ( !"broken (modifies left, fails for left==result))" ); + + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ -/* shiftRLeftOrResult - shift right one byte from left,or to result*/ +/* AccLsh - shift left accumulator by known count */ +/* MARK: pic14 always rotates through CARRY! */ /*-----------------------------------------------------------------*/ -static void shiftRLeftOrResult (operand *left, int offl, - operand *result, int offr, int shCount) +static void AccLsh (pCodeOp *pcop,int shCount) { FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - /* shift right accumulator */ - AccRsh(left,offl,shCount); - /* or with result */ - emitpcode (POC_IORWF, popGet (AOP(result), offr)); - assert ( !"broken (modifies left, fails for left==result))" ); + shCount &= 0x0007; // shCount : 0..7 + switch(shCount){ + case 0 : + return; + break; + case 1 : + emitCLRC; + emitpcode(POC_RLF,pcop); + return; + break; + case 2 : + emitpcode(POC_RLF,pcop); + emitpcode(POC_RLF,pcop); + break; + case 3 : + emitpcode(POC_RLF,pcop); + emitpcode(POC_RLF,pcop); + emitpcode(POC_RLF,pcop); + break; + case 4 : + emitpcode(POC_SWAPF,pcop); + break; + case 5 : + emitpcode(POC_SWAPF,pcop); + emitpcode(POC_RLF,pcop); + break; + case 6 : + emitpcode(POC_SWAPF,pcop); + emitpcode(POC_RLF,pcop); + emitpcode(POC_RLF,pcop); + break; + case 7 : + emitpcode(POC_RRFW,pcop); + emitpcode(POC_RRF,pcop); + break; + } + /* clear invalid bits */ + emitpcode(POC_MOVLW, popGetLit ((unsigned char)(~((1UL << shCount) - 1)))); + emitpcode(POC_ANDWF, pcop); } /*-----------------------------------------------------------------*/ -/* genlshOne - left shift a one byte quantity by known count */ +/* AccRsh - shift right accumulator by known count */ +/* MARK: pic14 always rotates through CARRY! */ +/* maskmode - 0: leave invalid bits undefined (caller should mask) */ +/* 1: mask out invalid bits (zero-extend) */ +/* 2: sign-extend result (pretty slow) */ /*-----------------------------------------------------------------*/ -static void genlshOne (operand *result, operand *left, int shCount) +static void AccRsh (pCodeOp *pcop,int shCount, int mask_mode) { FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - shiftL1Left2Result(left, LSB, result, LSB, shCount); + shCount &= 0x0007; // shCount : 0..7 + switch(shCount){ + case 0 : + return; + break; + case 1 : + /* load sign if needed */ + if (mask_mode == 2) emitpcode(POC_RLFW,pcop); + else if (mask_mode == 1) emitCLRC; + emitpcode(POC_RRF,pcop); + return; + break; + case 2 : + /* load sign if needed */ + if (mask_mode == 2) emitpcode(POC_RLFW,pcop); + emitpcode(POC_RRF,pcop); + /* load sign if needed */ + if (mask_mode == 2) emitpcode(POC_RLFW,pcop); + emitpcode(POC_RRF,pcop); + if (mask_mode == 2) return; + break; + case 3 : + /* load sign if needed */ + if (mask_mode == 2) emitpcode(POC_RLFW,pcop); + emitpcode(POC_RRF,pcop); + /* load sign if needed */ + if (mask_mode == 2) emitpcode(POC_RLFW,pcop); + emitpcode(POC_RRF,pcop); + /* load sign if needed */ + if (mask_mode == 2) emitpcode(POC_RLFW,pcop); + emitpcode(POC_RRF,pcop); + if (mask_mode == 2) return; + break; + case 4 : + emitpcode(POC_SWAPF,pcop); + break; + case 5 : + emitpcode(POC_SWAPF,pcop); + emitpcode(POC_RRF,pcop); + break; + case 6 : + emitpcode(POC_SWAPF,pcop); + emitpcode(POC_RRF,pcop); + emitpcode(POC_RRF,pcop); + break; + case 7 : + if (mask_mode == 2) + { + /* load sign */ + emitpcode(POC_RLFW,pcop); + emitpcode(POC_CLRF,pcop); + emitSKPNC; + emitpcode(POC_COMF,pcop); + return; + } else { + emitpcode(POC_RLFW,pcop); + emitpcode(POC_RLF,pcop); + } + break; + } + + if (mask_mode == 0) + { + /* leave invalid bits undefined */ + return; + } + + /* clear invalid bits -- zero-extend */ + emitpcode(POC_MOVLW, popGetLit (0x00ff >> shCount)); + emitpcode(POC_ANDWF, pcop); + + if (mask_mode == 2) { + /* sign-extend */ + emitpcode(POC_MOVLW, popGetLit (0x00ff << (8 - shCount))); + emitpcode(POC_BTFSC, newpCodeOpBit (get_op(pcop,NULL,0), 7 - shCount ,0)); + emitpcode(POC_IORWF, pcop); + } } /*-----------------------------------------------------------------*/ -/* genlshTwo - left shift two bytes by known amount != 0 */ +/* movLeft2Result - move byte from left to result */ /*-----------------------------------------------------------------*/ -static void genlshTwo (operand *result,operand *left, int shCount) +static void movLeft2Result (operand *left, int offl, + operand *result, int offr) { - int size; - FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - size = pic14_getDataSize(result); - - /* if shCount >= 8 */ - if (shCount >= 8) { - shCount -= 8 ; - - if (size > 1){ - if (shCount) - shiftL1Left2Result(left, LSB, result, MSB16, shCount); - else - movLeft2Result(left, LSB, result, MSB16); - } - emitpcode(POC_CLRF,popGet(AOP(result),LSB)); - } + if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){ + aopGet(AOP(left),offl,FALSE,FALSE); - /* 1 <= shCount <= 7 */ - else { - if(size == 1) - shiftL1Left2Result(left, LSB, result, LSB, shCount); - else - shiftL2Left2Result(left, LSB, result, LSB, shCount); + emitpcode(POC_MOVFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); } } /*-----------------------------------------------------------------*/ -/* shiftLLong - shift left one long from left to result */ -/* offl = LSB or MSB16 */ +/* shiftLeft_Left2ResultLit - shift left by known count */ /*-----------------------------------------------------------------*/ -static void shiftLLong (operand *left, operand *result, int offr ) + +static void shiftLeft_Left2ResultLit (operand *left, operand *result, int shCount) { - char *l; - int size = AOP_SIZE(result); + int size, same, offr, i; + + size = AOP_SIZE(left); + if (AOP_SIZE(result) < size) size = AOP_SIZE(result); + + same = pic14_sameRegs (AOP(left), AOP(result)); + + offr = shCount / 8; + shCount = shCount & 0x07; + + size -= offr; + + switch (shCount) + { + case 0: /* takes 0 or 2N cycles (for offr==0) */ + if (!same || offr) { + for (i=size-1; i >= 0; i--) + movLeft2Result (left, i, result, offr + i); + } // if + break; + + case 1: /* takes 1N+1 or 2N+1 cycles (or offr==0) */ + if (same && offr) { + shiftLeft_Left2ResultLit (left, result, 8 * offr); + shiftLeft_Left2ResultLit (result, result, shCount); + return; /* prevent clearing result again */ + } else { + emitCLRC; + for (i=0; i < size; i++) { + if (same && !offr) { + emitpcode (POC_RLF, popGet (AOP(left), i)); + } else { + emitpcode (POC_RLFW, popGet (AOP(left), i)); + emitpcode (POC_MOVWF, popGet (AOP(result), i + offr)); + } // if + } // for + } // if (offr) + break; - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(size >= LSB+offr){ - l = aopGet(AOP(left),LSB,FALSE,FALSE); - MOVA(l); - pic14_emitcode("add","a,acc"); - if (pic14_sameRegs(AOP(left),AOP(result)) && - size >= MSB16+offr && offr != LSB ) - pic14_emitcode("xch","a,%s", - aopGet(AOP(left),LSB+offr,FALSE,FALSE)); - else - aopPut(AOP(result),"a",LSB+offr); - } + case 4: /* takes 3+5(N-1) = 5N-2 cycles (for offr==0) */ + /* works in-place/with offr as well */ + emitpcode (POC_SWAPFW, popGet (AOP(left), size-1)); + emitpcode (POC_ANDLW, popGetLit (0xF0)); + emitpcode (POC_MOVWF, popGet(AOP(result), size-1+offr)); - if(size >= MSB16+offr){ - if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) { - l = aopGet(AOP(left),MSB16,FALSE,FALSE); - MOVA(l); - } - pic14_emitcode("rlc","a"); - if (pic14_sameRegs(AOP(left),AOP(result)) && - size >= MSB24+offr && offr != LSB) - pic14_emitcode("xch","a,%s", - aopGet(AOP(left),MSB16+offr,FALSE,FALSE)); - else - aopPut(AOP(result),"a",MSB16+offr); - } + for (i = size - 2; i >= 0; i--) + { + emitpcode (POC_SWAPFW, popGet (AOP(left), i)); + emitpcode (POC_MOVWF, popGet (AOP(result), i + offr)); + emitpcode (POC_ANDLW, popGetLit (0x0F)); + emitpcode (POC_IORWF, popGet (AOP(result), i + offr + 1)); + emitpcode (POC_XORWF, popGet (AOP(result), i + offr)); + } // for i + break; - if(size >= MSB24+offr){ - if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) { - l = aopGet(AOP(left),MSB24,FALSE,FALSE); - MOVA(l); - } - pic14_emitcode("rlc","a"); - if (pic14_sameRegs(AOP(left),AOP(result)) && - size >= MSB32+offr && offr != LSB ) - pic14_emitcode("xch","a,%s", - aopGet(AOP(left),MSB24+offr,FALSE,FALSE)); - else - aopPut(AOP(result),"a",MSB24+offr); - } + case 7: /* takes 2(N-1)+3 = 2N+1 cycles */ + /* works in-place/with offr as well */ + emitpcode (POC_RRFW, popGet (AOP(left), size-1)); + for (i = size-2; i >= 0; i--) { + emitpcode (POC_RRFW, popGet (AOP(left), i)); + emitpcode (POC_MOVWF, popGet (AOP(result), offr + i + 1)); + } // for i + emitpcode (POC_CLRF, popGet (AOP(result), offr)); + emitpcode (POC_RRF, popGet (AOP(result), offr)); + break; - if(size > MSB32+offr){ - if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) { - l = aopGet(AOP(left),MSB32,FALSE,FALSE); - MOVA(l); - } - pic14_emitcode("rlc","a"); - aopPut(AOP(result),"a",MSB32+offr); - } - if(offr != LSB) - aopPut(AOP(result),zero,LSB); + default: + shiftLeft_Left2ResultLit (left, result, offr * 8 + shCount-1); + shiftLeft_Left2ResultLit (result, result, 1); + return; /* prevent clearing result again */ + break; + } // switch + + while (0 < offr--) + { + emitpcode (POC_CLRF, popGet (AOP(result), offr)); + } // while } /*-----------------------------------------------------------------*/ -/* genlshFour - shift four byte by a known amount != 0 */ +/* shiftRight_Left2ResultLit - shift right by known count */ /*-----------------------------------------------------------------*/ -static void genlshFour (operand *result, operand *left, int shCount) + +static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign) { - int size; + int size, same, offr, i; - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - size = AOP_SIZE(result); + size = AOP_SIZE(left); + if (AOP_SIZE(result) < size) size = AOP_SIZE(result); - /* if shifting more that 3 bytes */ - if (shCount >= 24 ) { - shCount -= 24; - if (shCount) - /* lowest order of left goes to the highest - order of the destination */ - shiftL1Left2Result(left, LSB, result, MSB32, shCount); - else - movLeft2Result(left, LSB, result, MSB32); - aopPut(AOP(result),zero,LSB); - aopPut(AOP(result),zero,MSB16); - aopPut(AOP(result),zero,MSB32); - return; - } + same = pic14_sameRegs (AOP(left), AOP(result)); - /* more than two bytes */ - else if ( shCount >= 16 ) { - /* lower order two bytes goes to higher order two bytes */ - shCount -= 16; - /* if some more remaining */ - if (shCount) - shiftL2Left2Result(left, LSB, result, MSB24, shCount); - else { - movLeft2Result(left, MSB16, result, MSB32); - movLeft2Result(left, LSB, result, MSB24); - } - aopPut(AOP(result),zero,MSB16); - aopPut(AOP(result),zero,LSB); - return; - } + offr = shCount / 8; + shCount = shCount & 0x07; - /* if more than 1 byte */ - else if ( shCount >= 8 ) { - /* lower order three bytes goes to higher order three bytes */ - shCount -= 8; - if(size == 2){ - if(shCount) - shiftL1Left2Result(left, LSB, result, MSB16, shCount); - else - movLeft2Result(left, LSB, result, MSB16); - } - else{ /* size = 4 */ - if(shCount == 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) - shiftLLong(left, result, MSB16); - else{ - shiftL2Left2Result(left, MSB16, result, MSB24, shCount); - shiftL1Left2Result(left, LSB, result, MSB16, shCount); - shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount); - aopPut(AOP(result),zero,LSB); - } - } - } + size -= offr; - /* 1 <= shCount <= 7 */ - else if(shCount <= 2){ - shiftLLong(left, result, LSB); - if(shCount == 2) - shiftLLong(result, result, LSB); - } - /* 3 <= shCount <= 7, optimize */ - else{ - shiftL2Left2Result(left, MSB24, result, MSB24, shCount); - shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount); - shiftL2Left2Result(left, LSB, result, LSB, shCount); - } -} -#endif + if (size) + { + switch (shCount) + { + case 0: /* takes 0 or 2N cycles (for offr==0) */ + if (!same || offr) { + for (i=0; i < size; i++) + movLeft2Result (left, i + offr, result, i); + } // if + break; -#if 0 -/*-----------------------------------------------------------------*/ -/* genLeftShiftLiteral - left shifting by known count */ -/*-----------------------------------------------------------------*/ -static void genLeftShiftLiteral (operand *left, - operand *right, - operand *result, - iCode *ic) -{ - int shCount = (int) ulFromVal (AOP(right)->aopu.aop_lit); - //int size; + case 1: /* takes 1N+1(3) or 2N+1(3) cycles (or offr==0) */ + emitpComment ("%s:%d: shCount=%d, size=%d, sign=%d, same=%d, offr=%d", __FUNCTION__, __LINE__, shCount, size, sign, same, offr); + if (same && offr) { + shiftRight_Left2ResultLit (left, result, 8 * offr, sign); + shiftRight_Left2ResultLit (result, result, shCount, sign); + return; /* prevent sign-extending result again */ + } else { + emitCLRC; + if (sign) { + emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(left), AOP_SIZE(left)-1, FALSE, FALSE), 7, 0)); + emitSETC; + } + for (i = size-1; i >= 0; i--) { + if (same && !offr) { + emitpcode (POC_RRF, popGet (AOP(left), i)); + } else { + emitpcode (POC_RRFW, popGet (AOP(left), i + offr)); + emitpcode (POC_MOVWF, popGet (AOP(result), i)); + } + } // for i + } // if (offr) + break; - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - freeAsmop(right,NULL,ic,TRUE); + case 4: /* takes 3(6)+5(N-1) = 5N-2(+1) cycles (for offr==0) */ + /* works in-place/with offr as well */ + emitpcode (POC_SWAPFW, popGet (AOP(left), offr)); + emitpcode (POC_ANDLW, popGetLit (0x0F)); + emitpcode (POC_MOVWF, popGet(AOP(result), 0)); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); + for (i = 1; i < size; i++) + { + emitpcode (POC_SWAPFW, popGet (AOP(left), i + offr)); + emitpcode (POC_MOVWF, popGet (AOP(result), i)); + emitpcode (POC_ANDLW, popGetLit (0xF0)); + emitpcode (POC_IORWF, popGet (AOP(result), i - 1)); + emitpcode (POC_XORWF, popGet (AOP(result), i)); + } // for i - size = getSize(operandType(result)); + if (sign) + { + emitpcode (POC_MOVLW, popGetLit (0xF0)); + emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(result), size-1, FALSE, FALSE), 3, 0)); + emitpcode (POC_IORWF, popGet (AOP(result), size-1)); + } // if + break; -#if VIEW_SIZE - pic14_emitcode("; shift left ","result %d, left %d",size, - AOP_SIZE(left)); -#endif + case 7: /* takes 2(N-1)+3(4) = 2N+1(2) cycles */ + /* works in-place/with offr as well */ + emitpcode (POC_RLFW, popGet (AOP(left), offr)); + for (i = 0; i < size-1; i++) { + emitpcode (POC_RLFW, popGet (AOP(left), offr + i + 1)); + emitpcode (POC_MOVWF, popGet (AOP(result), i)); + } // for i + emitpcode (POC_CLRF, popGet (AOP(result), size-1)); + if (!sign) { + emitpcode (POC_RLF, popGet (AOP(result), size-1)); + } else { + emitSKPNC; + emitpcode (POC_DECF, popGet (AOP(result), size-1)); + } + break; - /* I suppose that the left size >= result size */ - if(shCount == 0){ - while(size--){ - movLeft2Result(left, size, result, size); - } - } + default: + shiftRight_Left2ResultLit (left, result, offr * 8 + shCount-1, sign); + shiftRight_Left2ResultLit (result, result, 1, sign); + return; /* prevent sign extending result again */ + break; + } // switch + } // if - else if(shCount >= (size * 8)) - while(size--) - aopPut(AOP(result),zero,size); - else{ - switch (size) { - case 1: - genlshOne (result,left,shCount); - break; - - case 2: - case 3: - genlshTwo (result,left,shCount); - break; - - case 4: - genlshFour (result,left,shCount); - break; - } - } - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); + addSign (result, size, sign); } -#endif /*-----------------------------------------------------------------* * genMultiAsm - repeat assembly instruction for size of register. @@ -6890,7 +5108,8 @@ static void genLeftShift (iCode *ic) /*-----------------------------------------------------------------*/ /* SetIrp - Set IRP bit */ /*-----------------------------------------------------------------*/ -void SetIrp(operand *result) { +static void SetIrp(operand *result) +{ FENTRY; if (AOP_TYPE(result) == AOP_LIT) { unsigned lit = (unsigned) double2ul (operandLitValue(result)); @@ -6899,8 +5118,10 @@ void SetIrp(operand *result) { else emitCLRIRP; } else { - if (PCOP(AOP(result))->type == PO_LITERAL) { - int addrs = PCOL(AOP(result))->lit; + if ((AOP_TYPE(result) == AOP_PCODE) + && (AOP(result)->aopu.pcop->type == PO_LITERAL)) + { + int addrs = PCOL(AOP(result)->aopu.pcop)->lit; if (addrs & 0x100) emitSETIRP; else @@ -7191,8 +5412,9 @@ static void genNearPointerGet (operand *left, aopOp (result,ic,FALSE); /* Check if can access directly instead of via a pointer */ - if ((PCOP(AOP(left))->type == PO_LITERAL || PCOP(AOP(left))->type == PO_IMMEDIATE) - && AOP_SIZE(result) == 1) + if ((AOP_TYPE(left) == AOP_PCODE) + && (AOP(left)->aopu.pcop->type == PO_IMMEDIATE) + && (AOP_SIZE(result) == 1)) { direct = 1; } @@ -7740,7 +5962,10 @@ static void genNearPointerSet (operand *right, DEBUGpic14_AopType(__LINE__,NULL,right,result); /* Check if can access directly instead of via a pointer */ - if (PCOP(AOP(result))->type == PO_LITERAL && AOP_SIZE(right) == 1) { + if ((AOP_TYPE(result) == AOP_PCODE) + && (AOP(result)->aopu.pcop->type == PO_IMMEDIATE) + && (AOP_SIZE(right) == 1)) + { direct = 1; } @@ -8089,35 +6314,6 @@ static void genAddrOf (iCode *ic) } -#if 0 -/*-----------------------------------------------------------------*/ -/* genFarFarAssign - assignment when both are in far space */ -/*-----------------------------------------------------------------*/ -static void genFarFarAssign (operand *result, operand *right, iCode *ic) -{ - int size = AOP_SIZE(right); - int offset = 0; - char *l ; - /* first push the right side on to the stack */ - while (size--) { - l = aopGet(AOP(right),offset++,FALSE,FALSE); - MOVA(l); - pic14_emitcode ("push","acc"); - } - - freeAsmop(right,NULL,ic,FALSE); - /* now assign DPTR to result */ - aopOp(result,ic,FALSE); - size = AOP_SIZE(result); - while (size--) { - pic14_emitcode ("pop","acc"); - aopPut(AOP(result),"a",--offset); - } - freeAsmop(result,NULL,ic,FALSE); - -} -#endif - /*-----------------------------------------------------------------*/ /* genAssign - generate code for assignment */ /*-----------------------------------------------------------------*/ @@ -8308,138 +6504,6 @@ static void genJumpTab (iCode *ic) } -/*-----------------------------------------------------------------*/ -/* genMixedOperation - gen code for operators between mixed types */ -/*-----------------------------------------------------------------*/ -/* -TSD - Written for the PIC port - but this unfortunately is buggy. -This routine is good in that it is able to efficiently promote -types to different (larger) sizes. Unfortunately, the temporary -variables that are optimized out by this routine are sometimes -used in other places. So until I know how to really parse the -iCode tree, I'm going to not be using this routine :(. -*/ -static int genMixedOperation (iCode *ic) -{ - FENTRY; -#if 0 - operand *result = IC_RESULT(ic); - sym_link *ctype = operandType(IC_LEFT(ic)); - operand *right = IC_RIGHT(ic); - int ret = 0; - int big,small; - int offset; - - iCode *nextic; - operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL; - - pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); - - nextic = ic->next; - if(!nextic) - return 0; - - nextright = IC_RIGHT(nextic); - nextleft = IC_LEFT(nextic); - nextresult = IC_RESULT(nextic); - - aopOp(right,ic,FALSE); - aopOp(result,ic,FALSE); - aopOp(nextright, nextic, FALSE); - aopOp(nextleft, nextic, FALSE); - aopOp(nextresult, nextic, FALSE); - - if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) { - - operand *t = right; - right = nextright; - nextright = t; - - pic14_emitcode(";remove right +",""); - - } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) { - /* - operand *t = right; - right = nextleft; - nextleft = t; - */ - pic14_emitcode(";remove left +",""); - } else - return 0; - - big = AOP_SIZE(nextleft); - small = AOP_SIZE(nextright); - - switch(nextic->op) { - - case '+': - pic14_emitcode(";optimize a +",""); - /* if unsigned or not an integral type */ - if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) { - pic14_emitcode(";add a bit to something",""); - } else { - - pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir); - - 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 - pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir); - - offset = 0; - while(--big) { - - offset++; - - if(--small) { - 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) ); - } - - pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE)); - emitSKPNC; - pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(nextic))->aopu.aop_dir, - AOP(IC_RIGHT(nextic))->aopu.aop_dir); - 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 { - pic14_emitcode("rlf","known_zero,w"); - - /* - if right is signed - btfsc right,7 - addlw ff - */ - 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 { - pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) ); - } - } - } - ret = 1; - } - } - ret = 1; - -release: - freeAsmop(right,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); - freeAsmop(nextright,NULL,ic,TRUE); - freeAsmop(nextleft,NULL,ic,TRUE); - if(ret) - nextic->generated = 1; - - return ret; -#else - return 0; -#endif -} /*-----------------------------------------------------------------*/ /* genCast - gen code for casting */ /*-----------------------------------------------------------------*/ @@ -8600,14 +6664,7 @@ static void genCast (iCode *ic) } /* so we now know that the size of destination is greater - than the size of the source. - Now, if the next iCode is an operator then we might be - able to optimize the operation without performing a cast. - */ - if(0 && genMixedOperation(ic)) { - /* XXX: cannot optimize: must copy regs! */ - goto release; - } + than the size of the source. */ /* we move to result for the size of source */ size = AOP_SIZE(right); @@ -8994,7 +7051,7 @@ void genpic14Code (iCode *lic) /* This is not safe, as a AOP_PCODE/PO_IMMEDIATE might be used both as literal * (meaning: representing its own address) or not (referencing its contents). * This can only be decided based on the operand's type. */ -int +static int aop_isLitLike (asmop *aop) { assert (aop);