X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fgen.c;h=ac092203ff2f3a87528a1a7ca874d2f6fb4f7d78;hb=195ee3f3ee25ce2c5f2a59fbd2779c4cb80527c3;hp=2d70cb8263d6036cefb696ff96bff60dc120ffe2;hpb=a117b34b0cd910edcd086b326d6ef86882901765;p=fw%2Fsdcc diff --git a/src/pic/gen.c b/src/pic/gen.c index 2d70cb82..ac092203 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -42,11 +42,9 @@ #include "pcode.h" #include "gen.h" - extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); void genMult8X8_8 (operand *, operand *,operand *); -pCode *AssembleLine(char *line); extern void printpBlock(FILE *of, pBlock *pb); static int labelOffset=0; @@ -63,9 +61,8 @@ static int GpsuedoStkPtr=0; pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func); unsigned int pic14aopLiteral (value *val, int offset); const char *AopType(short type); -static iCode *ifxForOp ( operand *op, iCode *ic ); -#define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff) +#define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0x00ff) /* this is the down and dirty file with all kinds of kludgy & hacky stuff. This is what it is all about @@ -77,11 +74,10 @@ static char *one = "#0x01"; static char *spname = "sp"; char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" }; -//char *fReturn390[] = {"dpl","dph","dpx", "b","a" }; unsigned fReturnSizePic = 4; /* shared with ralloc.c */ static char **fReturn = fReturnpic14; -static char *accUse[] = {"a","b"}; +//static char *accUse[] = {"a","b"}; //static short rbank = -1; @@ -99,10 +95,10 @@ static struct { about an iCode ifx that makes it easier to generate code. */ typedef struct resolvedIfx { - symbol *lbl; /* pointer to a label */ + symbol *lbl; /* pointer to a label */ int condition; /* true or false ifx */ - int generated; /* set true when the code associated with the ifx - * is generated */ + int generated; /* set true when the code associated with the ifx + * is generated */ } resolvedIfx; extern int pic14_ptrRegReq ; @@ -178,9 +174,9 @@ void DEBUGpic14_emitcode (char *inst,char *fmt, ...) { va_list ap; char lb[INITIAL_INLINEASM]; - char *lbp = lb; + unsigned char *lbp = lb; - if(!debug_verbose) + if(!debug_verbose && !options.debug) return; va_start(ap,fmt); @@ -208,13 +204,52 @@ void DEBUGpic14_emitcode (char *inst,char *fmt, ...) va_end(ap); } +static void Safe_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap) +{ +#if defined (HAVE_VSNPRINTF) + vsnprintf (buf, size, fmt, ap); +#elif defined (HAVE_VSPRINTF) + vsprintf (buf, size, fmt, ap); + if (strlen (buf) >= size) + { + fprintf (stderr, "Safe_vsnprintf: buffer (size %u) has overflown\n", size); + } +#elif defined (HAVE_SNPRINTF) + snprintf (buf, size, "vs(n)printf required"); +#elif defined (HAVE_SRINTF) + sprintf (buf, "vs(n)printf required"); + if (strlen (buf) >= size) + { + fprintf (stderr, "Safe_vsnprintf: buffer (size %u) has overflown\n", size); + } +#else + assert ( !"neither vsnprintf nor vsprintf is present -- unable to proceed" ); +#endif +} + +void emitpComment (const char *fmt, ...) +{ + va_list va; + char buffer[4096]; + + va_start (va, fmt); + if (pb) { + Safe_vsnprintf (buffer, 4096, fmt, va); + //fprintf (stderr, "%s\n" ,buffer); + addpCode2pBlock (pb, newpCodeCharP (buffer)); + } + va_end (va); +} void emitpLabel(int key) { addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset)); } -void emitpcode(PIC_OPCODE poc, pCodeOp *pcop) +/* gen.h defines a macro emitpcode that should be used to call emitpcode + * as this allows for easy debugging (ever asked the question: where was + * this instruction geenrated? Here is the answer... */ +void emitpcode_real(PIC_OPCODE poc, pCodeOp *pcop) { if(pcop) addpCode2pBlock(pb,newpCode(poc,pcop)); @@ -237,7 +272,7 @@ void pic14_emitcode (char *inst,char *fmt, ...) { va_list ap; char lb[INITIAL_INLINEASM]; - char *lbp = lb; + unsigned char *lbp = lb; va_start(ap,fmt); @@ -402,7 +437,7 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx) resIfx->generated = 0; /* indicate that the ifx has not been used */ if(!ifx) { - resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */ + 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); @@ -486,8 +521,8 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) if (sym->onStack && options.stack10bit) { - /* It's on the 10 bit stack, which is located in - * far data space. + /* It's on the 10 bit stack, which is located in + * far data space. */ //DEBUGpic14_emitcode(";","%d",__LINE__); @@ -720,7 +755,7 @@ static bool operandsEqu ( operand *op1, operand *op2) } /*-----------------------------------------------------------------*/ -/* pic14_sameRegs - two asmops have the same registers */ +/* pic14_sameRegs - two asmops have the same registers */ /*-----------------------------------------------------------------*/ bool pic14_sameRegs (asmop *aop1, asmop *aop2 ) { @@ -745,7 +780,7 @@ bool pic14_sameRegs (asmop *aop1, asmop *aop2 ) } /*-----------------------------------------------------------------*/ -/* aopOp - allocates an asmop for an operand : */ +/* aopOp - allocates an asmop for an operand : */ /*-----------------------------------------------------------------*/ void aopOp (operand *op, iCode *ic, bool result) { @@ -756,7 +791,6 @@ void aopOp (operand *op, iCode *ic, bool result) if (!op) return ; - // DEBUGpic14_emitcode(";","%d",__LINE__); /* if this a literal */ if (IS_OP_LITERAL(op)) { op->aop = aop = newAsmop(AOP_LIT); @@ -822,6 +856,10 @@ void aopOp (operand *op, iCode *ic, bool result) return; } +#if 0 + /* WREG is not usable as an ordinary operand with PIC architecture, + * one might introduce a scratch register that can be used to make + * WREG accesible as an operand... disable WREG for now */ if (sym->accuse) { int i; aop = op->aop = sym->aop = newAsmop(AOP_ACC); @@ -831,6 +869,7 @@ void aopOp (operand *op, iCode *ic, bool result) DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size); return; } +#endif if (sym->ruonly ) { if(sym->isptr) { // && sym->uptr @@ -864,23 +903,27 @@ void aopOp (operand *op, iCode *ic, bool result) } /* else spill location */ - if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) { - /* force a new aop if sizes differ */ - sym->usl.spillLoc->aop = NULL; - } - DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d", - __FUNCTION__,__LINE__, - sym->usl.spillLoc->rname, - sym->rname, sym->usl.spillLoc->offset); - - sym->aop = op->aop = aop = newAsmop(AOP_PCODE); - //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset); - aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, - getSize(sym->type), - sym->usl.spillLoc->offset); - aop->size = getSize(sym->type); + if (sym->usl.spillLoc) + { + if (getSize(sym->type) != getSize(sym->usl.spillLoc->type)) + { + /* force a new aop if sizes differ */ + sym->usl.spillLoc->aop = NULL; + } + DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d", + __FUNCTION__,__LINE__, + sym->usl.spillLoc->rname, + sym->rname, sym->usl.spillLoc->offset); + + sym->aop = op->aop = aop = newAsmop(AOP_PCODE); + //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset); + aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, + getSize(sym->type), + sym->usl.spillLoc->offset); + aop->size = getSize(sym->type); - return; + return; + } } { @@ -1140,9 +1183,13 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname) pCodeOp *pcop = aop->aopu.pcop; DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop)); if(pcop->name) { - DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset); - //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset); - sprintf(s,"%s", pcop->name); + if (offset) { + DEBUGpic14_emitcode(";","%s offset %d",pcop->name,offset); + sprintf(s,"(%s+%d)", pcop->name,offset); + } else { + DEBUGpic14_emitcode(";","%s",pcop->name); + sprintf(s,"%s", pcop->name); + } } else sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset); @@ -1177,7 +1224,7 @@ pCodeOp *popGetTempReg(void) } /*-----------------------------------------------------------------*/ -/* popGetTempReg - create a new temporary pCodeOp */ +/* popReleaseTempReg - create a new temporary pCodeOp */ /*-----------------------------------------------------------------*/ void popReleaseTempReg(pCodeOp *pcop) { @@ -1212,7 +1259,7 @@ pCodeOp *popGetHighLabel(unsigned int key) } /*-----------------------------------------------------------------*/ -/* popGet - asm operator to pcode operator conversion */ +/* popGetLit - asm operator to pcode operator conversion */ /*-----------------------------------------------------------------*/ pCodeOp *popGetLit(unsigned int lit) { @@ -1231,7 +1278,7 @@ pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func) /*-----------------------------------------------------------------*/ -/* popGet - asm operator to pcode operator conversion */ +/* popGetWithString - asm operator to pcode operator conversion */ /*-----------------------------------------------------------------*/ pCodeOp *popGetWithString(char *str, int isExtern) { @@ -1316,7 +1363,14 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* offset is greater than size then zero */ + + if (!(offset >= 0 && ((offset < aop->size) || (aop->size == 0)))) + { + fprintf (stderr, "%s:%u: offset=%d, aop-type:%s, size:%d\n", __FILE__, __LINE__, offset, AopType (aop->type), aop->size); + } + assert (offset >= 0 && ((offset < aop->size) || (aop->size == 0))); + /* XXX: still needed for BIT operands (AOP_CRY) */ if (offset > (aop->size - 1) && aop->type != AOP_LIT) return NULL; //zero; @@ -1398,11 +1452,28 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) */ case AOP_PCODE: - DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop), + pcop = NULL; + DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s + %i) %d %s",pCodeOpType(aop->aopu.pcop), offset, __LINE__, ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name")); - pcop = pCodeOpCopy(aop->aopu.pcop); - PCOI(pcop)->offset = offset; + //emitpComment ("popGet; name %s, offset: %i, pcop-type: %s\n", aop->aopu.pcop->name, offset, pCodeOpType (aop->aopu.pcop)); + switch (aop->aopu.pcop->type) + { + case PO_IMMEDIATE: + pcop = pCodeOpCopy (aop->aopu.pcop); + /* usually we want to access the memory at " + offset" (using ->index), + * but sometimes we want to access the high byte of the symbol's address (using ->offset) */ + PCOI(pcop)->index += offset; + //PCOI(pcop)->offset = 0; + break; + case PO_DIR: + pcop = pCodeOpCopy (aop->aopu.pcop); + PCOR(pcop)->instance = offset; + break; + default: + assert ( !"unhandled pCode type" ); + break; + } // switch return pcop; } @@ -1410,6 +1481,27 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) "popGet got unsupported aop->type"); exit(0); } + +/*-----------------------------------------------------------------*/ +/* popGetAddr - access the low/high word of a symbol (immediate) */ +/* (for non-PO_IMMEDIATEs this is the same as poGet) */ +/*-----------------------------------------------------------------*/ +pCodeOp *popGetAddr (asmop *aop, int offset, int index) +{ + if (aop->type == AOP_PCODE && aop->aopu.pcop->type == PO_IMMEDIATE) + { + pCodeOp *pcop = aop->aopu.pcop; + pcop = pCodeOpCopy (pcop); + /* usually we want to access the memory at " + offset" (using ->index), + * but sometimes we want to access the high byte of the symbol's address (using ->offset) */ + PCOI(pcop)->offset += offset; + PCOI(pcop)->index += index; + return pcop; + } else { + return popGet (aop, offset + index); + } +} + /*-----------------------------------------------------------------*/ /* aopPut - puts a string for a aop */ /*-----------------------------------------------------------------*/ @@ -1652,10 +1744,8 @@ void mov2w (asmop *aop, int offset) DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset); - if ( aop->type == AOP_PCODE || - aop->type == AOP_LIT || - aop->type == AOP_IMMD ) - emitpcode(POC_MOVLW,popGet(aop,offset)); + if ( aop_isLitLike (aop) ) + emitpcode(POC_MOVLW,popGetAddr(aop,offset,0)); else emitpcode(POC_MOVFW,popGet(aop,offset)); @@ -1739,8 +1829,8 @@ int pic14_getDataSize(operand *op) sym_link *type = operandType(op); if (IS_GENPTR(type)) { - /* generic pointer; arithmetic operations - * should ignore the high byte (pointer type). + /* generic pointer; arithmetic operations + * should ignore the high byte (pointer type). */ size--; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -1813,8 +1903,10 @@ void pic14_toBoolean(operand *oper) /*-----------------------------------------------------------------*/ static void genNot (iCode *ic) { - symbol *tlbl; + //symbol *tlbl; int size; + + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* assign asmOps to operand & result */ @@ -1835,19 +1927,20 @@ static void genNot (iCode *ic) goto release; } + assert (!pic14_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))); size = AOP_SIZE(IC_LEFT(ic)); - if(size == 1) { - emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0)); - emitpcode(POC_ANDLW,popGetLit(1)); - emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); - goto release; + emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0)); + mov2w (AOP(IC_LEFT(ic)),0); + while (--size > 0) + { + if (aop_isLitLike (AOP(IC_LEFT(ic)))) + emitpcode (POC_IORLW, popGetAddr (AOP(IC_LEFT(ic)), size, 0)); + else + emitpcode (POC_IORFW, popGet (AOP(IC_LEFT(ic)), size)); } - pic14_toBoolean(IC_LEFT(ic)); - - tlbl = newiTempLabel(NULL); - pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100); - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - pic14_outBitC(IC_RESULT(ic)); + emitSKPNZ; + emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0)); + goto release; release: /* release the aops */ @@ -1864,6 +1957,7 @@ static void genCpl (iCode *ic) operand *left, *result; int size, offset=0; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp((left = IC_LEFT(ic)),ic,FALSE); @@ -1907,6 +2001,8 @@ static void genUminusFloat(operand *op,operand *result) int size ,offset =0 ; char *l; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* for this we just need to flip the first it then copy the rest in place */ @@ -1934,6 +2030,7 @@ static void genUminus (iCode *ic) int size, i; sym_link *optype, *rtype; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* assign asmops */ @@ -1995,6 +2092,8 @@ static void saveRegisters(iCode *lic) bitVect *rsave; sym_link *dtype; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* look for call */ for (ic = lic ; ic ; ic = ic->next) @@ -2057,6 +2156,8 @@ static void unsaveRegisters (iCode *ic) int i; bitVect *rsave; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* find the registers in use at this time and push them away to safety */ @@ -2116,6 +2217,8 @@ static void assignResultValue(operand * oper) { int size = AOP_SIZE(oper); + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); DEBUGpic14_AopType(__LINE__,oper,NULL,NULL); @@ -2133,6 +2236,7 @@ static void assignResultValue(operand * oper) /*-----------------------------------------------------------------*/ static void genIpush (iCode *ic) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); #if 0 @@ -2194,6 +2298,8 @@ static void genIpush (iCode *ic) /*-----------------------------------------------------------------*/ static void genIpop (iCode *ic) { + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); #if 0 int size,offset ; @@ -2219,6 +2325,8 @@ static void genIpop (iCode *ic) /*-----------------------------------------------------------------*/ static void unsaverbank (int bank,iCode *ic,bool popPsw) { + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); #if 0 int i; @@ -2267,6 +2375,8 @@ static void unsaverbank (int bank,iCode *ic,bool popPsw) /*-----------------------------------------------------------------*/ static void saverbank (int bank, iCode *ic, bool pushPsw) { + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); #if 0 int i; @@ -2320,6 +2430,8 @@ static void genCall (iCode *ic) unsigned char *name; int isExtern; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if caller saves & we have not saved then */ @@ -2371,9 +2483,9 @@ static void genCall (iCode *ic) AopType(AOP_TYPE(IC_LEFT(sic)))); if(!firstTimeThruLoop) { - /* If this is not the first time we've been through the loop - * then we need to save the parameter in a temporary - * register. The last byte of the last parameter is + /* If this is not the first time we've been through the loop + * then we need to save the parameter in a temporary + * register. The last byte of the last parameter is * passed in W. */ emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr)); @@ -2454,6 +2566,8 @@ static void genPcall (iCode *ic) pCodeOp *pcop; operand *left; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if caller saves & we have not saved then */ if (!ic->regsSaved) @@ -2500,11 +2614,11 @@ static void genPcall (iCode *ic) emitpcode(POC_GOTO,pcop); emitpLabel(albl->key); - poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW); + poc = ( aop_isLitLike (AOP(left)) ? POC_MOVLW : POC_MOVFW ); - emitpcode(poc,popGet(AOP(left),1)); + emitpcode(poc,popGetAddr(AOP(left),1,0)); emitpcode(POC_MOVWF,popCopyReg(&pc_pclath)); - emitpcode(poc,popGet(AOP(left),0)); + emitpcode(poc,popGetAddr(AOP(left),0,0)); emitpcode(POC_MOVWF,popCopyReg(&pc_pcl)); emitpLabel(blbl->key); @@ -2544,6 +2658,8 @@ static void genPcall (iCode *ic) static int resultRemat (iCode *ic) { // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + FENTRY; + if (SKIP_IC(ic) || ic->op == IFX) return 0; @@ -2593,6 +2709,8 @@ static void genFunction (iCode *ic) symbol *sym; sym_link *ftype; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key); labelOffset += (max_key+4); @@ -2676,7 +2794,7 @@ static void genFunction (iCode *ic) } /* if this isr has no bank i.e. is going to run with bank 0 , then we need to save more -registers :-) */ + registers :-) */ if (!FUNC_REGBANK(sym->type)) { /* if this function does not call any other @@ -2780,6 +2898,8 @@ static void genEndFunction (iCode *ic) { symbol *sym = OP_SYMBOL(IC_LEFT(ic)); + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (IFFUNC_ISREENT(sym->type) || options.stackAuto) @@ -2927,6 +3047,8 @@ static void genRet (iCode *ic) { int size,offset = 0 , pushed = 0; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if we have no return value then just generate the "ret" */ @@ -2954,7 +3076,7 @@ static void genRet (iCode *ic) AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) || ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) || ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) { - emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset)); + emitpcode(POC_MOVLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0)); }else { emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset)); } @@ -2978,7 +3100,7 @@ static void genRet (iCode *ic) freeAsmop (IC_LEFT(ic),NULL,ic,TRUE); jumpret: -/* generate a jump to the return label + /* generate a jump to the return label if the next is not the return statement */ if (!(ic->next && ic->next->op == LABEL && IC_LABEL(ic->next) == returnLabel)) { @@ -2994,6 +3116,8 @@ jumpret: /*-----------------------------------------------------------------*/ static void genLabel (iCode *ic) { + FENTRY; + /* special case never generate */ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (IC_LABEL(ic) == entryLabel) @@ -3009,6 +3133,8 @@ static void genLabel (iCode *ic) //tsd static void genGoto (iCode *ic) { + FENTRY; + emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key)); pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset); } @@ -3021,6 +3147,7 @@ static void genMultbits (operand *left, operand *right, operand *result) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(!pic14_sameRegs(AOP(result),AOP(right))) @@ -3045,6 +3172,8 @@ static void genMultOneByte (operand *left, // symbol *lbl ; int size,offset; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); DEBUGpic14_AopType(__LINE__,left,right,result); DEBUGpic14_AopTypeSign(__LINE__,left,right,result); @@ -3148,6 +3277,8 @@ static void genMult (iCode *ic) operand *right = IC_RIGHT(ic); operand *result= IC_RESULT(ic); + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* assign the amsops */ aopOp (left,ic,FALSE); @@ -3192,6 +3323,8 @@ static void genDivbits (operand *left, char *l; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* the result must be bit */ pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); @@ -3216,6 +3349,7 @@ static void genDivOneByte (operand *left, symbol *lbl ; int size,offset; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); size = AOP_SIZE(result) - 1; offset = 1; @@ -3297,6 +3431,7 @@ static void genDiv (iCode *ic) operand *right = IC_RIGHT(ic); operand *result= IC_RESULT(ic); + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* assign the amsops */ aopOp (left,ic,FALSE); @@ -3336,6 +3471,7 @@ static void genModbits (operand *left, char *l; + FENTRY; /* the result must be bit */ pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); l = aopGet(AOP(left),0,FALSE,FALSE); @@ -3359,6 +3495,7 @@ static void genModOneByte (operand *left, char *l ; symbol *lbl ; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* signed or unsigned */ if (SPEC_USIGN(opetype)) { @@ -3431,6 +3568,7 @@ static void genMod (iCode *ic) operand *right = IC_RIGHT(ic); operand *result= IC_RESULT(ic); + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* assign the amsops */ aopOp (left,ic,FALSE); @@ -3470,6 +3608,7 @@ note: May need to add parameter to indicate when a variable is in bit space. static void genIfxJump (iCode *ic, char *jval) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if true label then we jump if condition supplied is true */ @@ -3514,6 +3653,7 @@ static void genIfxJump (iCode *ic, char *jval) /*-----------------------------------------------------------------*/ static void genSkip(iCode *ifx,int status_bit) { + FENTRY; if(!ifx) return; @@ -3564,15 +3704,17 @@ static void genSkip(iCode *ifx,int status_bit) /*-----------------------------------------------------------------*/ static void genSkipc(resolvedIfx *rifx) { + FENTRY; if(!rifx) return; if(rifx->condition) - emitSKPC; - else emitSKPNC; + else + emitSKPC; emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key)); + emitpComment ("%s:%u: created from rifx:%p", __FUNCTION__, __LINE__, rifx); rifx->generated = 1; } @@ -3581,6 +3723,7 @@ static void genSkipc(resolvedIfx *rifx) /*-----------------------------------------------------------------*/ static void genSkipz2(resolvedIfx *rifx, int invert_condition) { + FENTRY; if(!rifx) return; @@ -3598,6 +3741,7 @@ static void genSkipz2(resolvedIfx *rifx, int invert_condition) /*-----------------------------------------------------------------*/ static void genSkipz(iCode *ifx, int condition) { + FENTRY; if(!ifx) return; @@ -3617,11 +3761,14 @@ static void genSkipz(iCode *ifx, int condition) pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); } + +#if 0 /*-----------------------------------------------------------------*/ /* genSkipCond */ /*-----------------------------------------------------------------*/ static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit) { + FENTRY; if(!rifx) return; @@ -3634,6 +3781,7 @@ static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit) emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key)); rifx->generated = 1; } +#endif #if 0 /*-----------------------------------------------------------------*/ @@ -3664,6 +3812,241 @@ static int genChkZeroes(operand *op, int lit, int size) } #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)); + } +} + +/* genCmp performs a left < right comparison, stores + * the outcome in result (if != NULL) and generates + * control flow code for the ifx (if != NULL). + * + * This version leaves in sequences like + * "B[CS]F STATUS,0; BTFS[CS] STATUS,0" + * which should be optmized by the peephole + * optimizer - RN 2005-01-01 */ +static void genCmp (operand *left,operand *right, + operand *result, iCode *ifx, int sign) +{ + resolvedIfx rIfx; + int size; + int offs; + symbol *templbl; + operand *dummy; + unsigned long lit; + unsigned long mask; + int performedLt; + int invert_result = 0; + + FENTRY; + + assert (AOP_SIZE(left) == AOP_SIZE(right)); + assert (left && right); + + size = AOP_SIZE(right) - 1; + mask = (0x100UL << (size*8)) - 1; + // in the end CARRY holds "left < right" (performedLt == 1) or "left >= right" (performedLt == 0) + performedLt = 1; + templbl = NULL; + lit = 0; + + resolveIfx (&rIfx, ifx); + + /********************************************************************** + * handle bits - bit compares are promoted to int compares seemingly! * + **********************************************************************/ +#if 0 + // THIS IS COMPLETELY UNTESTED! + if (AOP_TYPE(left) == AOP_CRY && AOP_TYPE(right) == AOP_CRY) { + pCodeOp *pcleft = pic16_popGet(AOP(left), 0); + pCodeOp *pcright = pic16_popGet(AOP(right), 0); + assert (pcleft->type == PO_GPR_BIT && pcright->type == PO_GPR_BIT); + + emitSETC; + // 1 < {0,1} is false --> clear C by skipping the next instruction + //pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit (AOP(left),0), PCORB(pcleft)->bit); + pic16_emitpcode (POC_BTFSS, pic16_popGet (AOP(left), 0)); + // {0,1} < 0 is false --> clear C by NOT skipping the next instruction + pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit (pic16_popGet(AOP(right),0), PCORB(pcright)->bit)); + emitCLRC; // only skipped for left=0 && right=1 + + goto correct_result_in_carry; + } // if +#endif + + /************************************************* + * make sure that left is register (or the like) * + *************************************************/ + if (!isAOP_REGlike(left)) { + DEBUGpc ("swapping arguments (AOP_TYPEs %d/%d)", AOP_TYPE(left), AOP_TYPE(right)); + assert (isAOP_LIT(left)); + assert (isAOP_REGlike(right)); + // swap left and right + // left < right <==> right > left <==> (right >= left + 1) + lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit); + + if ( (!sign && (lit & mask) == mask) || (sign && (lit & mask) == (mask >> 1)) ) { + // MAXVALUE < right? always false + if (performedLt) emitCLRC; else emitSETC; + goto correct_result_in_carry; + } // if + + // This fails for lit = 0xFF (unsigned) AND lit = 0x7F (signed), + // that's why we handled it above. + lit++; + + dummy = left; + left = right; + right = dummy; + + performedLt ^= 1; // instead of "left < right" we check for "right >= left+1, i.e. "right < left+1" + } else if (isAOP_LIT(right)) { + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + } // if + + assert (isAOP_REGlike(left)); // left must be register or the like + assert (isAOP_REGlike(right) || isAOP_LIT(right)); // right may be register-like or a literal + + /************************************************* + * special cases go here * + *************************************************/ + + if (isAOP_LIT(right)) { + if (!sign) { + // unsigned comparison to a literal + DEBUGpc ("unsigned compare: left %s lit(0x%X=%lu), size=%d", performedLt ? "<" : ">=", lit, lit, size+1); + if (lit == 0) { + // unsigned left < 0? always false + if (performedLt) emitCLRC; else emitSETC; + goto correct_result_in_carry; + } + } else { + // signed comparison to a literal + DEBUGpc ("signed compare: left %s lit(0x%X=%ld), size=%d, mask=%x", performedLt ? "<" : ">=", lit, lit, size+1, mask); + if ((lit & mask) == ((0x80 << (size*8)) & mask)) { + // signed left < 0x80000000? always false + if (performedLt) emitCLRC; else emitSETC; + goto correct_result_in_carry; + } else if (lit == 0) { + // compare left < 0; set CARRY if SIGNBIT(left) is set + if (performedLt) emitSETC; else emitCLRC; + emitpcode (POC_BTFSS, newpCodeOpBit (aopGet (AOP(left), size, FALSE, FALSE), 7, 0)); + if (performedLt) emitCLRC; else emitSETC; + goto correct_result_in_carry; + } + } // if (!sign) + } // right is literal + + /************************************************* + * perform a general case comparison * + * make sure we get CARRY==1 <==> left >= right * + *************************************************/ + // compare most significant bytes + //DEBUGpc ("comparing bytes at offset %d", size); + if (!sign) { + // unsigned comparison + pic14_mov2w_regOrLit (AOP(right), lit, size); + emitpcode (POC_SUBFW, popGet (AOP(left), size)); + } else { + // signed comparison + // (add 2^n to both operands then perform an unsigned comparison) + if (isAOP_LIT(right)) { + // left >= LIT <-> LIT-left <= 0 <-> LIT-left == 0 OR !(LIT-left >= 0) + unsigned char litbyte = (lit >> (8*size)) & 0xFF; + + if (litbyte == 0x80) { + // left >= 0x80 -- always true, but more bytes to come + mov2w (AOP(left), size); + emitpcode (POC_XORLW, popGetLit (0x80)); // set ZERO flag + emitSETC; + } else { + // left >= LIT <-> left + (-LIT) >= 0 <-> left + (0x100-LIT) >= 0x100 + mov2w (AOP(left), size); + emitpcode (POC_ADDLW, popGetLit (0x80)); + emitpcode (POC_ADDLW, popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF)); + } // if + } else { + pCodeOp *pctemp = popGetTempReg(); + mov2w (AOP(left), size); + emitpcode (POC_ADDLW, popGetLit (0x80)); + emitpcode (POC_MOVWF, pctemp); + mov2w (AOP(right), size); + emitpcode (POC_ADDLW, popGetLit (0x80)); + emitpcode (POC_SUBFW, pctemp); + popReleaseTempReg(pctemp); + } + } // if (!sign) + + // compare remaining bytes (treat as unsigned case from above) + templbl = newiTempLabel ( NULL ); + offs = size; + while (offs--) { + //DEBUGpc ("comparing bytes at offset %d", offs); + emitSKPZ; + emitpcode (POC_GOTO, popGetLabel (templbl->key)); + pic14_mov2w_regOrLit (AOP(right), lit, offs); + emitpcode (POC_SUBFW, popGet (AOP(left), offs)); + } // while (offs) + emitpLabel (templbl->key); + goto result_in_carry; + +result_in_carry: + + /**************************************************** + * now CARRY contains the result of the comparison: * + * SUBWF sets CARRY iff * + * F-W >= 0 <==> F >= W <==> !(F < W) * + * (F=left, W=right) * + ****************************************************/ + + if (performedLt) { + invert_result = 1; + // value will be used in the following genSkipc() + rIfx.condition ^= 1; + } // if + +correct_result_in_carry: + + // assign result to variable (if neccessary) + if (result && AOP_TYPE(result) != AOP_CRY) { + //DEBUGpc ("assign result"); + size = AOP_SIZE(result); + while (size--) { + emitpcode (POC_CLRF, popGet (AOP(result), size)); + } // while + if (invert_result) { + emitSKPC; + emitpcode (POC_BSF, newpCodeOpBit (aopGet (AOP(result), 0, FALSE, FALSE), 0, 0)); + } else { + emitpcode (POC_RLF, popGet (AOP(result), 0)); + } + } // if (result) + + // perform conditional jump + if (ifx) { + //DEBUGpc ("generate control flow"); + genSkipc (&rIfx); + ifx->generated = 1; + } // if +} + + +#if 0 +/* OLD VERSION -- BUGGY, DO NOT USE */ + /*-----------------------------------------------------------------*/ /* genCmp :- greater or less than comparison */ /*-----------------------------------------------------------------*/ @@ -3675,6 +4058,8 @@ static void genCmp (operand *left,operand *right, resolvedIfx rFalseIfx; // resolvedIfx rTrueIfx; symbol *truelbl; + + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if(ifx) { @@ -3763,7 +4148,7 @@ static void genCmp (operand *left,operand *right, } else { emitpcode(POC_ADDLW, popGetLit(0x80)); emitpcode(POC_ADDLW, popGetLit(i^0x80)); - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); } } else { @@ -3771,7 +4156,7 @@ static void genCmp (operand *left,operand *right, genSkipz2(&rFalseIfx,1); } else { emitpcode(POC_ADDLW, popGetLit(i)); - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); } } @@ -3822,7 +4207,7 @@ static void genCmp (operand *left,operand *right, emitSKPNZ; } - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); emitpLabel(truelbl->key); if(ifx) ifx->generated = 1; return; @@ -3838,7 +4223,7 @@ static void genCmp (operand *left,operand *right, emitpcode(POC_MOVFW, popGet(AOP(left),size)); emitpcode(POC_ADDLW, popGetLit( 0x80)); emitpcode(POC_ADDLW, popGetLit(0x100-i)); - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); if(ifx) ifx->generated = 1; @@ -3854,7 +4239,7 @@ static void genCmp (operand *left,operand *right, emitpcode(POC_MOVFW, popGet(AOP(left),size)); emitpcode(POC_ADDLW, popGetLit( 0x80)); emitpcode(POC_ADDLW, popGetLit(0x100-i)); - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); if(ifx) ifx->generated = 1; @@ -3902,7 +4287,7 @@ static void genCmp (operand *left,operand *right, emitpcode(POC_SUBFW, popGet(AOP(left),size)); } //rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); emitpLabel(truelbl->key); @@ -3940,7 +4325,7 @@ static void genCmp (operand *left,operand *right, emitpLabel(lbl->key); //if(emitFinalCheck) - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); if(sign) emitpLabel(truelbl->key); @@ -4005,7 +4390,7 @@ static void genCmp (operand *left,operand *right, emitpcode(POC_ADDLW, popGetLit(0x80)); emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80)); rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); break; } if(ifx) ifx->generated = 1; @@ -4029,7 +4414,7 @@ static void genCmp (operand *left,operand *right, DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); rFalseIfx.condition ^= 1; if (AOP_TYPE(result) == AOP_CRY) { - genSkipc(&rFalseIfx); + 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); @@ -4099,7 +4484,7 @@ static void genCmp (operand *left,operand *right, emitpcode(POC_ADDLW, popGetLit( 0x80)); emitpcode(POC_ADDLW, popGetLit(0x100-i)); rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); if(ifx) ifx->generated = 1; @@ -4151,7 +4536,7 @@ static void genCmp (operand *left,operand *right, } rFalseIfx.condition ^= 1; //rFalseIfx.condition = 1; - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); emitpLabel(truelbl->key); @@ -4193,7 +4578,7 @@ static void genCmp (operand *left,operand *right, emitpcode(POC_SUBFW, popGet(AOP(right),0)); rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); } emitpLabel(truelbl->key); @@ -4229,7 +4614,7 @@ static void genCmp (operand *left,operand *right, emitpLabel(lbl->key); rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); } if(sign) @@ -4263,7 +4648,7 @@ static void genCmp (operand *left,operand *right, emitpcode(POC_ADDLW, popGetLit(0x80)); DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); if(ifx) ifx->generated = 1; return; @@ -4297,9 +4682,9 @@ static void genCmp (operand *left,operand *right, emitpcode(POC_CLRF, popGet(AOP(result),0)); emitpcode(POC_RLF, popGet(AOP(result),0)); } else { - genSkipc(&rFalseIfx); + genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); } - //genSkipc(&rFalseIfx); + //genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); if(ifx) ifx->generated = 1; return; @@ -4323,6 +4708,7 @@ static void genCmp (operand *left,operand *right, } } +#endif /*-----------------------------------------------------------------*/ /* genCmpGt :- greater than comparison */ @@ -4333,6 +4719,7 @@ static void genCmpGt (iCode *ic, iCode *ifx) sym_link *letype , *retype; int sign ; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); left = IC_LEFT(ic); right= IC_RIGHT(ic); @@ -4362,6 +4749,7 @@ static void genCmpLt (iCode *ic, iCode *ifx) sym_link *letype , *retype; int sign ; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); left = IC_LEFT(ic); right= IC_RIGHT(ic); @@ -4390,6 +4778,7 @@ static void genc16bit2lit(operand *op, int lit, int offset) { int i; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit); if( (lit&0xff) == 0) i=1; @@ -4439,20 +4828,61 @@ static void genc16bit2lit(operand *op, int lit, int offset) /*-----------------------------------------------------------------*/ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) { - int size = max(AOP_SIZE(left),AOP_SIZE(right)); + int size = min(AOP_SIZE(left),AOP_SIZE(right)); int offset = 0; - int res_offset = 0; /* the result may be a different size then left or right */ - int res_size = AOP_SIZE(result); - resolvedIfx rIfx; + //resolvedIfx rIfx; symbol *lbl; - unsigned long lit = 0L; + //unsigned long lit = 0L; + FENTRY; + if (!ifx && (!result || AOP_TYPE(result) == AOP_CRY)) { + emitpComment ("gencjne: no ifx, no (real) result -- comparison ignored"); + return; + } DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); DEBUGpic14_AopType(__LINE__,left,right,result); + + assert (!pic14_sameRegs (AOP(left), AOP(result))); + assert (!pic14_sameRegs (AOP(right), AOP(result))); + if (AOP_SIZE(result)) { + for (offset = 0; offset < AOP_SIZE(result); offset++) + emitpcode (POC_CLRF, popGet (AOP(result), offset)); + } + + assert (AOP_SIZE(left) == AOP_SIZE(right)); + //resolveIfx(&rIfx,ifx); + lbl = newiTempLabel (NULL); + while (size--) + { + mov2w (AOP(right),size); + emitpcode (POC_XORFW, popGet (AOP(left), size)); + if (size) + { + emitSKPZ; + emitpcode (POC_GOTO, popGetLabel (lbl->key)); + } + } // while + emitpLabel (lbl->key); + if (AOP_SIZE(result)) { + emitSKPNZ; + emitpcode (POC_INCF, popGet (AOP(result), 0)); + } else { + assert (ifx); + genSkipz (ifx, NULL != IC_TRUE(ifx)); + ifx->generated = 1; + } + return; +#if 0 if(result) + { DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__); - resolveIfx(&rIfx,ifx); - lbl = newiTempLabel(NULL); + assert (!pic14_sameRegs (AOP(result), AOP(left))); + assert (!pic14_sameRegs (AOP(result), AOP(right))); + for (offset=0; offset < AOP_SIZE(result); offset++) + { + emitpcode (POC_CLRF, popGet (AOP(result), offset)); + } // for offset + } /* if the left side is a literal or @@ -4477,6 +4907,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) emitpcode(POC_GOTO,popGetLabel(lbl->key)); break; default: + offset = 0; while (size--) { if(lit & 0xff) { emitpcode(POC_MOVFW,popGet(AOP(left),offset)); @@ -4488,8 +4919,6 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) emitSKPNZ; emitpcode(POC_GOTO,popGetLabel(lbl->key)); offset++; - if(res_offset < res_size-1) - res_offset++; lit >>= 8; } break; @@ -4505,10 +4934,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key; int lbl_key = lbl->key; - if(result) { - emitpcode(POC_CLRF,popGet(AOP(result),res_offset)); - //emitpcode(POC_INCF,popGet(AOP(result),res_offset)); - }else { + if(!result) { DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__); fprintf(stderr, "%s %d error - expecting result to be non_null\n", __FUNCTION__,__LINE__); @@ -4522,6 +4948,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */ /* break; */ /* default: */ + offset = 0; while (size--) { int emit_skip=1; if((AOP_TYPE(left) == AOP_DIR) && @@ -4538,8 +4965,8 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) break; case 1: emitpcode(POC_DECFSZW,popGet(AOP(left),offset)); - emitpcode(POC_INCF,popGet(AOP(result),res_offset)); - //emitpcode(POC_GOTO,popGetLabel(lbl->key)); + //emitpcode(POC_INCF,popGet(AOP(result),res_offset)); + emitpcode(POC_GOTO,popGetLabel(lbl->key)); emit_skip=0; break; case 0xff: @@ -4574,21 +5001,19 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) else emitSKPNZ; emitpcode(POC_GOTO,popGetLabel(lbl_key)); - //emitpcode(POC_INCF,popGet(AOP(result),res_offset)); } if(ifx) ifx->generated=1; } emit_skip++; offset++; - if(res_offset < res_size-1) - res_offset++; } /* break; */ /* } */ } else if(AOP_TYPE(right) == AOP_REG && AOP_TYPE(left) != AOP_DIR){ - + + offset = 0; while(size--) { emitpcode(POC_MOVFW,popGet(AOP(left),offset)); emitpcode(POC_XORFW,popGet(AOP(right),offset)); @@ -4599,12 +5024,11 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) emitSKPZ; emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key)); offset++; - if(res_offset < res_size-1) - res_offset++; } }else{ /* right is a pointer reg need both a & b */ + offset = 0; while(size--) { char *l = aopGet(AOP(left),offset,FALSE,FALSE); if(strcmp(l,"b")) @@ -4615,7 +5039,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) } } - emitpcode(POC_INCF,popGet(AOP(result),res_offset)); + emitpcode(POC_INCF,popGet(AOP(result),0)); if(!rIfx.condition) emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key)); @@ -4625,6 +5049,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) if(ifx) ifx->generated = 1; +#endif } #if 0 @@ -4659,6 +5084,7 @@ static void genCmpEq (iCode *ic, iCode *ifx) unsigned long lit = 0L; int size,offset=0; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(ifx) @@ -4677,8 +5103,8 @@ static void genCmpEq (iCode *ic, iCode *ifx) /* if literal, literal on the right or if the right is in a pointer register and left is not */ - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || - (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) { + if (aop_isLitLike (AOP(IC_LEFT(ic))) + || (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) { operand *tmp = right ; right = left; left = tmp; @@ -4843,8 +5269,8 @@ static void genCmpEq (iCode *ic, iCode *ifx) tlbl = newiTempLabel(NULL); while(size--) { - emitpcode(POC_MOVFW,popGet(AOP(left),offset)); - emitpcode(POC_XORFW,popGet(AOP(right),offset)); + mov2w (AOP(right),offset); /* right might be litLike() */ + emitpcode(POC_XORFW,popGet(AOP(left),offset)); if ( IC_TRUE(ifx) ) { if(size) { @@ -4952,13 +5378,14 @@ release: /*-----------------------------------------------------------------*/ 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 + /* 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 && @@ -4998,6 +5425,7 @@ 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 @@ -5049,6 +5477,7 @@ static void genOrOp (iCode *ic) /* note here that || operations that are in an if statement are taken away by backPatchLabels only those used in arthmetic operations remain */ + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp((left=IC_LEFT(ic)),ic,FALSE); aopOp((right=IC_RIGHT(ic)),ic,FALSE); @@ -5098,6 +5527,7 @@ static int isLiteralBit(unsigned long lit) 0x10000000L,0x20000000L,0x40000000L,0x80000000L}; int idx; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); for(idx = 0; idx < 32; idx++) if(lit == pw[idx]) @@ -5110,6 +5540,7 @@ static int isLiteralBit(unsigned long lit) /*-----------------------------------------------------------------*/ static void continueIfTrue (iCode *ic) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(IC_TRUE(ic)) pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100); @@ -5121,6 +5552,7 @@ static void continueIfTrue (iCode *ic) /*-----------------------------------------------------------------*/ static void jumpIfTrue (iCode *ic) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(!IC_TRUE(ic)) pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); @@ -5132,6 +5564,7 @@ static void jumpIfTrue (iCode *ic) /*-----------------------------------------------------------------*/ static void jmpTrueOrFalse (iCode *ic, symbol *tlbl) { + FENTRY; // ugly but optimized by peephole DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(IC_TRUE(ic)){ @@ -5159,7 +5592,7 @@ static void genAnd (iCode *ic, iCode *ifx) 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); @@ -5314,7 +5747,6 @@ static void genAnd (iCode *ic, iCode *ifx) switch(lit & 0xff) { case 0x00: /* and'ing with 0 has clears the result */ - pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); emitpcode(POC_CLRF,popGet(AOP(result),offset)); break; case 0xff: @@ -5326,12 +5758,9 @@ static void genAnd (iCode *ic, iCode *ifx) int p = my_powof2( (~lit) & 0xff ); if(p>=0) { /* only one bit is set in the literal, so use a bcf instruction */ - pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p); emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0)); } else { - pic14_emitcode("movlw","0x%x", (lit & 0xff)); - pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE)); if(know_W != (int)(lit&0xff)) emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); know_W = lit &0xff; @@ -5381,16 +5810,10 @@ static void genAnd (iCode *ic, iCode *ifx) int t = (lit >> (offset*8)) & 0x0FFL; switch(t) { case 0x00: - pic14_emitcode("clrf","%s", - aopGet(AOP(result),offset,FALSE,FALSE)); emitpcode(POC_CLRF,popGet(AOP(result),offset)); break; case 0xff: if(AOP_TYPE(left) != AOP_ACC) { - pic14_emitcode("movf","%s,w", - aopGet(AOP(left),offset,FALSE,FALSE)); - pic14_emitcode("movwf","%s", - aopGet(AOP(result),offset,FALSE,FALSE)); emitpcode(POC_MOVFW,popGet(AOP(left),offset)); } emitpcode(POC_MOVWF,popGet(AOP(result),offset)); @@ -5399,12 +5822,6 @@ static void genAnd (iCode *ic, iCode *ifx) if(AOP_TYPE(left) == AOP_ACC) { emitpcode(POC_ANDLW, popGetLit(t)); } else { - pic14_emitcode("movlw","0x%x",t); - pic14_emitcode("andwf","%s,w", - aopGet(AOP(left),offset,FALSE,FALSE)); - pic14_emitcode("movwf","%s", - aopGet(AOP(result),offset,FALSE,FALSE)); - emitpcode(POC_MOVLW, popGetLit(t)); emitpcode(POC_ANDFW,popGet(AOP(left),offset)); } @@ -5414,16 +5831,11 @@ static void genAnd (iCode *ic, iCode *ifx) } if (AOP_TYPE(left) == AOP_ACC) { - pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); emitpcode(POC_ANDFW,popGet(AOP(right),offset)); } else { - pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - pic14_emitcode("andwf","%s,w", - aopGet(AOP(left),offset,FALSE,FALSE)); emitpcode(POC_MOVFW,popGet(AOP(right),offset)); emitpcode(POC_ANDFW,popGet(AOP(left),offset)); } - pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); emitpcode(POC_MOVWF,popGet(AOP(result),offset)); } } @@ -5444,6 +5856,7 @@ static void genOr (iCode *ic, iCode *ifx) int size, offset=0; unsigned long lit = 0L; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp((left = IC_LEFT(ic)),ic,FALSE); @@ -5589,150 +6002,144 @@ static void genOr (iCode *ic, iCode *ifx) 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) && + } + + // 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 { - if (AOP_TYPE(left) == AOP_ACC) { - emitpcode(POC_IORFW, popGet(AOP(right),offset)); - pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - } else { - emitpcode(POC_MOVFW, popGet(AOP(right),offset)); - emitpcode(POC_IORWF, popGet(AOP(left),offset)); - - pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE)); - - } - } - } - } 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: - if (AOP_TYPE(left) != AOP_ACC) { - emitpcode(POC_MOVFW, popGet(AOP(left),offset)); - } - emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - - break; - default: - if (AOP_TYPE(left) == AOP_ACC) { - emitpcode(POC_IORLW, popGetLit(t)); - } else { - 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 - if (AOP_TYPE(left) == AOP_ACC) { - emitpcode(POC_IORWF, popGet(AOP(right),offset)); - pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - } else { - emitpcode(POC_MOVFW, popGet(AOP(right),offset)); - emitpcode(POC_IORFW, popGet(AOP(left),offset)); - - pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - pic14_emitcode("iorwf","%s,w", - aopGet(AOP(left),offset,FALSE,FALSE)); - } - emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); - } - } - + 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 { + if (AOP_TYPE(left) == AOP_ACC) { + emitpcode(POC_IORFW, popGet(AOP(right),offset)); + pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + } else { + emitpcode(POC_MOVFW, popGet(AOP(right),offset)); + emitpcode(POC_IORWF, popGet(AOP(left),offset)); + + pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE)); + + } + } + } + } 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: + if (AOP_TYPE(left) != AOP_ACC) { + emitpcode(POC_MOVFW, popGet(AOP(left),offset)); + } + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + + break; + default: + if (AOP_TYPE(left) == AOP_ACC) { + emitpcode(POC_IORLW, popGetLit(t)); + } else { + 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 + if (AOP_TYPE(left) == AOP_ACC) { + emitpcode(POC_IORFW,popGet(AOP(right),offset)); + } else { + 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); + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -5744,6 +6151,7 @@ static void genXor (iCode *ic, iCode *ifx) int size, offset=0; unsigned long lit = 0L; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp((left = IC_LEFT(ic)),ic,FALSE); @@ -5809,6 +6217,7 @@ static void genXor (iCode *ic, iCode *ifx) 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"); } @@ -5962,16 +6371,12 @@ static void genXor (iCode *ic, iCode *ifx) // and better if result is SFR if (AOP_TYPE(left) == AOP_ACC) { emitpcode(POC_XORFW,popGet(AOP(right),offset)); - pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); } else { emitpcode(POC_MOVFW,popGet(AOP(right),offset)); emitpcode(POC_XORFW,popGet(AOP(left),offset)); - pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); } if ( AOP_TYPE(result) != AOP_ACC){ emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); } } } @@ -5987,40 +6392,45 @@ release : /*-----------------------------------------------------------------*/ static void genInline (iCode *ic) { - char *buffer, *bp, *bp1; - - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - _G.inLine += (!options.asmpeep); - - buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1); - strcpy(buffer,IC_INLINE(ic)); - - /* emit each line as a code */ - while (*bp) { - if (*bp == '\n') { - *bp++ = '\0'; - - if(*bp1) - addpCode2pBlock(pb,AssembleLine(bp1)); - bp1 = bp; - } else { - if (*bp == ':') { - bp++; - *bp = '\0'; - bp++; - pic14_emitcode(bp1,""); - bp1 = bp; - } else - bp++; - } - } - if ((bp1 != bp) && *bp1) - addpCode2pBlock(pb,AssembleLine(bp1)); - - Safe_free(buffer); - - _G.inLine -= (!options.asmpeep); + char *buffer, *bp, *bp1; + + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + _G.inLine += (!options.asmpeep); + + buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1); + strcpy(buffer,IC_INLINE(ic)); + + /* emit each line as a code */ + while (*bp) { + if (*bp == '\n') { + *bp++ = '\0'; + + if(*bp1) + addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process + bp1 = bp; + } else { + if (*bp == ':') { + 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++; + } + } + if ((bp1 != bp) && *bp1) + addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process + + Safe_free(buffer); + + _G.inLine -= (!options.asmpeep); } /*-----------------------------------------------------------------*/ @@ -6031,6 +6441,7 @@ 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); @@ -6073,6 +6484,7 @@ static void genRLC (iCode *ic) int size, offset = 0; int same; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* rotate right with carry */ left = IC_LEFT(ic); @@ -6120,6 +6532,7 @@ static void genGetHbit (iCode *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)); @@ -6141,8 +6554,9 @@ static void genGetHbit (iCode *ic) /*-----------------------------------------------------------------*/ /* AccRol - rotate left accumulator by known count */ /*-----------------------------------------------------------------*/ -static void AccRol (int shCount) +static void AccRol (operand *op,int offset,int shCount) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); shCount &= 0x0007; // shCount : 0..7 switch(shCount){ @@ -6150,28 +6564,39 @@ static void AccRol (int shCount) break; case 1 : pic14_emitcode("rl","a"); + emitpcode(POC_RLF,popGet(AOP(op),offset)); break; case 2 : pic14_emitcode("rl","a"); pic14_emitcode("rl","a"); + emitpcode(POC_RLF,popGet(AOP(op),offset)); + emitpcode(POC_RLF,popGet(AOP(op),offset)); break; case 3 : pic14_emitcode("swap","a"); pic14_emitcode("rr","a"); + emitpcode(POC_SWAPF,popGet(AOP(op),offset)); + emitpcode(POC_RRF,popGet(AOP(op),offset)); break; case 4 : pic14_emitcode("swap","a"); + emitpcode(POC_SWAPF,popGet(AOP(op),offset)); break; case 5 : pic14_emitcode("swap","a"); pic14_emitcode("rl","a"); + emitpcode(POC_SWAPF,popGet(AOP(op),offset)); + emitpcode(POC_RLF,popGet(AOP(op),offset)); break; case 6 : pic14_emitcode("rr","a"); pic14_emitcode("rr","a"); + emitpcode(POC_RRF,popGet(AOP(op),offset)); + emitpcode(POC_RRF,popGet(AOP(op),offset)); break; case 7 : pic14_emitcode("rr","a"); + emitpcode(POC_RRF,popGet(AOP(op),offset)); break; } } @@ -6179,40 +6604,42 @@ static void AccRol (int shCount) /*-----------------------------------------------------------------*/ /* AccLsh - left shift accumulator by known count */ /*-----------------------------------------------------------------*/ -static void AccLsh (int shCount) +static void AccLsh (operand *op,int offset,int shCount) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(shCount != 0){ - if(shCount == 1) - pic14_emitcode("add","a,acc"); - else - if(shCount == 2) { - pic14_emitcode("add","a,acc"); - pic14_emitcode("add","a,acc"); - } else { - /* rotate left accumulator */ - AccRol(shCount); - /* and kill the lower order bits */ - pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]); - } + if(shCount != 0) { + if (shCount == 1) + { + emitCLRC; + emitpcode (POC_RLF, popGet (AOP(op), 0)); + } else { + /* rotate left accumulator */ + AccRol(op,offset,shCount); + /* and kill the lower order bits */ + emitpcode(POC_MOVLW,popGetLit(SLMask[shCount])); + emitpcode (POC_ANDWF, popGet (AOP(op),0)); + } } } /*-----------------------------------------------------------------*/ /* AccRsh - right shift accumulator by known count */ /*-----------------------------------------------------------------*/ -static void AccRsh (int shCount) +static void AccRsh (operand *op,int offset,int shCount) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(shCount != 0){ if(shCount == 1){ - CLRC; - pic14_emitcode("rrc","a"); + emitCLRC; + emitpcode (POC_RRF, popGet (AOP(op), 0)); } else { /* rotate right accumulator */ - AccRol(8 - shCount); + AccRol(op,offset,8 - shCount); /* and kill the higher order bits */ - pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]); + emitpcode (POC_MOVLW, popGetLit (SRMask[shCount])); + emitpcode (POC_ANDWF, popGet (AOP(op),0)); } } } @@ -6247,7 +6674,7 @@ static void AccSRsh (int shCount) } } } -#endif + /*-----------------------------------------------------------------*/ /* shiftR1Left2Result - shift right one byte from left to result */ /*-----------------------------------------------------------------*/ @@ -6257,6 +6684,7 @@ static void shiftR1Left2ResultSigned (operand *left, int offl, { int same; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr); @@ -6368,6 +6796,7 @@ static void shiftR1Left2Result (operand *left, int offl, { int same; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr); @@ -6461,6 +6890,7 @@ static void shiftL1Left2Result (operand *left, int offl, int same; // char *l; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr); @@ -6524,6 +6954,7 @@ static void shiftL1Left2Result (operand *left, int offl, } } +#endif /*-----------------------------------------------------------------*/ /* movLeft2Result - move byte from left to result */ @@ -6532,6 +6963,7 @@ static void movLeft2Result (operand *left, int offl, operand *result, int offr) { char *l; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){ l = aopGet(AOP(left),offl,FALSE,FALSE); @@ -6546,13 +6978,201 @@ static void movLeft2Result (operand *left, int offl, } } +/*-----------------------------------------------------------------*/ +/* 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; + + 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 +} + +/*-----------------------------------------------------------------*/ +/* shiftRight_Left2ResultLit - shift right by known count */ +/*-----------------------------------------------------------------*/ + +static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign) +{ + 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; + + 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; + + 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)); + + 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 + + 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; + + 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; + + 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 + + addSign (result, size, sign); +} + +#if 0 /*-----------------------------------------------------------------*/ /* shiftL2Left2Result - shift left two bytes from left to result */ /*-----------------------------------------------------------------*/ static void shiftL2Left2Result (operand *left, int offl, operand *result, int offr, int shCount) { - + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -6673,6 +7293,7 @@ static void shiftL2Left2Result (operand *left, int offl, } } + /*-----------------------------------------------------------------*/ /* shiftR2Left2Result - shift right two bytes from left to result */ /*-----------------------------------------------------------------*/ @@ -6682,6 +7303,7 @@ static void shiftR2Left2Result (operand *left, int offl, { int same=0; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); same = pic14_sameRegs(AOP(result), AOP(left)); @@ -6824,21 +7446,20 @@ static void shiftR2Left2Result (operand *left, int offl, } } - /*-----------------------------------------------------------------*/ /* shiftLLeftOrResult - shift left one byte from left, or to result*/ /*-----------------------------------------------------------------*/ static void shiftLLeftOrResult (operand *left, int offl, operand *result, int offr, int shCount) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); + /* shift left accumulator */ - AccLsh(shCount); + AccLsh(left,offl,shCount); /* or with result */ - pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE)); - /* back to result */ - aopPut(AOP(result),"a",offr); + emitpcode (POC_IORWF, popGet (AOP(result), offr)); + assert ( !"broken (modifies left, fails for left==result))" ); } /*-----------------------------------------------------------------*/ @@ -6847,14 +7468,14 @@ static void shiftLLeftOrResult (operand *left, int offl, static void shiftRLeftOrResult (operand *left, int offl, operand *result, int offr, int shCount) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); + /* shift right accumulator */ - AccRsh(shCount); + AccRsh(left,offl,shCount); /* or with result */ - pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE)); - /* back to result */ - aopPut(AOP(result),"a",offr); + emitpcode (POC_IORWF, popGet (AOP(result), offr)); + assert ( !"broken (modifies left, fails for left==result))" ); } /*-----------------------------------------------------------------*/ @@ -6862,6 +7483,7 @@ static void shiftRLeftOrResult (operand *left, int offl, /*-----------------------------------------------------------------*/ static void genlshOne (operand *result, operand *left, int shCount) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); shiftL1Left2Result(left, LSB, result, LSB, shCount); } @@ -6873,6 +7495,7 @@ static void genlshTwo (operand *result,operand *left, int shCount) { int size; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); size = pic14_getDataSize(result); @@ -6907,6 +7530,7 @@ static void shiftLLong (operand *left, operand *result, int offr ) char *l; int size = AOP_SIZE(result); + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(size >= LSB+offr){ l = aopGet(AOP(left),LSB,FALSE,FALSE); @@ -6967,6 +7591,7 @@ static void genlshFour (operand *result, operand *left, int shCount) { int size; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); size = AOP_SIZE(result); @@ -7042,7 +7667,9 @@ static void genlshFour (operand *result, operand *left, int shCount) shiftL2Left2Result(left, LSB, result, LSB, shCount); } } +#endif +#if 0 /*-----------------------------------------------------------------*/ /* genLeftShiftLiteral - left shifting by known count */ /*-----------------------------------------------------------------*/ @@ -7052,14 +7679,15 @@ static void genLeftShiftLiteral (operand *left, iCode *ic) { int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit); - int size; + //int size; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); freeAsmop(right,NULL,ic,TRUE); aopOp(left,ic,FALSE); aopOp(result,ic,FALSE); - + size = getSize(operandType(result)); #if VIEW_SIZE @@ -7096,6 +7724,7 @@ static void genLeftShiftLiteral (operand *left, freeAsmop(left,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); } +#endif /*-----------------------------------------------------------------* * genMultiAsm - repeat assembly instruction for size of register. @@ -7107,6 +7736,7 @@ static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian) int offset = 0; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(!reg) @@ -7132,10 +7762,12 @@ static void genLeftShift (iCode *ic) { operand *left,*right, *result; int size, offset; + unsigned long lit = 0L; char *l; symbol *tlbl , *tlbl1; pCodeOp *pctemp; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); right = IC_RIGHT(ic); @@ -7143,11 +7775,14 @@ static void genLeftShift (iCode *ic) result = IC_RESULT(ic); aopOp(right,ic,FALSE); + aopOp(left,ic,FALSE); + aopOp(result,ic,FALSE); + /* if the shift count is known then do it as efficiently as possible */ if (AOP_TYPE(right) == AOP_LIT) { - genLeftShiftLiteral (left,right,result,ic); + shiftLeft_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit)); return ; } @@ -7157,9 +7792,8 @@ static void genLeftShift (iCode *ic) more that 32 bits make no sense anyway, ( the largest size of an object can be only 32 bits ) */ - - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); + /* this code fails for RIGHT == RESULT */ + assert (!pic14_sameRegs (AOP(right), AOP(result))); /* now move the left to the result if they are not the same */ @@ -7183,11 +7817,14 @@ static void genLeftShift (iCode *ic) } } + if(AOP_TYPE(left) == AOP_LIT) + lit = (unsigned long)floatFromVal (AOP(left)->aopu.aop_lit); + size = AOP_SIZE(result); /* if it is only one byte then */ if (size == 1) { - if(optimized_for_speed) { + if(optimized_for_speed && AOP_TYPE(left)!=AOP_LIT) { emitpcode(POC_SWAPFW, popGet(AOP(left),0)); emitpcode(POC_ANDLW, popGetLit(0xf0)); emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0)); @@ -7204,7 +7841,7 @@ static void genLeftShift (iCode *ic) tlbl = newiTempLabel(NULL); if (!pic14_sameRegs(AOP(left),AOP(result))) { - emitpcode(POC_MOVFW, popGet(AOP(left),0)); + mov2w (AOP(left), 0); emitpcode(POC_MOVWF, popGet(AOP(result),0)); } @@ -7294,12 +7931,14 @@ release: freeAsmop(result,NULL,ic,TRUE); } +#if 0 /*-----------------------------------------------------------------*/ /* genrshOne - right shift a one byte quantity by known count */ /*-----------------------------------------------------------------*/ static void genrshOne (operand *result, operand *left, int shCount, int sign) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); shiftR1Left2Result(left, LSB, result, LSB, shCount, sign); } @@ -7310,6 +7949,7 @@ static void genrshOne (operand *result, operand *left, static void genrshTwo (operand *result,operand *left, int shCount, int sign) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if shCount >= 8 */ if (shCount >= 8) { @@ -7340,31 +7980,35 @@ static void genrshTwo (operand *result,operand *left, static void shiftRLong (operand *left, int offl, operand *result, int sign) { - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(!sign) - pic14_emitcode("clr","c"); - MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE)); - if(sign) - pic14_emitcode("mov","c,acc.7"); - pic14_emitcode("rrc","a"); - aopPut(AOP(result),"a",MSB32-offl); - if(offl == MSB16) - /* add sign of "a" */ - addSign(result, MSB32, sign); + int size, same; - MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE)); - pic14_emitcode("rrc","a"); - aopPut(AOP(result),"a",MSB24-offl); + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE)); - pic14_emitcode("rrc","a"); - aopPut(AOP(result),"a",MSB16-offl); + size = AOP_SIZE(left); + if (AOP_SIZE(result) < size) size = AOP_SIZE(result); - if(offl == LSB){ - MOVA(aopGet(AOP(left),LSB,FALSE,FALSE)); - pic14_emitcode("rrc","a"); - aopPut(AOP(result),"a",LSB); - } + if (sign) + emitpcode (POC_RLFW, popGet (AOP(left), AOP_SIZE(left)-1)); + else + emitCLRC; + + assert (offl >= 0 && offl < size); + + same = pic14_sameRegs (AOP(left), AOP(result)); + + /* perform the shift */ + while (size--) + { + if (same && !offl) { + emitpcode (POC_RRF, popGet (AOP(result), size)); + } else { + emitpcode (POC_RRFW, popGet (AOP(left), size)); + emitpcode (POC_MOVWF, popGet (AOP(result), size-offl)); + } + } // while + + addSign (result, AOP_SIZE(left) - offl, sign); } /*-----------------------------------------------------------------*/ @@ -7373,6 +8017,7 @@ static void shiftRLong (operand *left, int offl, static void genrshFour (operand *result, operand *left, int shCount, int sign) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if shifting more that 3 bytes */ if(shCount >= 24 ) { @@ -7438,6 +8083,7 @@ static void genRightShiftLiteral (operand *left, int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit); int lsize,res_size; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); freeAsmop(right,NULL,ic,TRUE); @@ -7456,7 +8102,7 @@ static void genRightShiftLiteral (operand *left, /* I suppose that the left size >= result size */ if(shCount == 0){ while(res_size--) - movLeft2Result(left, lsize, result, res_size); + movLeft2Result(left, res_size, result, res_size); } else if(shCount >= (lsize * 8)){ @@ -7501,10 +8147,11 @@ static void genRightShiftLiteral (operand *left, } } - + freeAsmop(left,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); } +#endif /*-----------------------------------------------------------------*/ /* genSignedRightShift - right shift of signed number */ @@ -7521,6 +8168,7 @@ static void genSignedRightShift (iCode *ic) /* we do it the hard way put the shift count in b and loop thru preserving the sign */ + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); right = IC_RIGHT(ic); @@ -7533,7 +8181,8 @@ static void genSignedRightShift (iCode *ic) if ( AOP_TYPE(right) == AOP_LIT) { - genRightShiftLiteral (left,right,result,ic,1); + shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 1); + //genRightShiftLiteral (left,right,result,ic,1); return ; } /* shift count is unknown then we have to form @@ -7556,14 +8205,13 @@ static void genSignedRightShift (iCode *ic) size = AOP_SIZE(result); offset=0; while (size--) { - /* - l = aopGet(AOP(left),offset,FALSE,TRUE); - if (*l == '@' && IS_AOP_PREG(result)) { - - pic14_emitcode("mov","a,%s",l); - aopPut(AOP(result),"a",offset); - } else - aopPut(AOP(result),l,offset); + /* + l = aopGet(AOP(left),offset,FALSE,TRUE); + if (*l == '@' && IS_AOP_PREG(result)) { + pic14_emitcode("mov","a,%s",l); + aopPut(AOP(result),"a",offset); + } else + aopPut(AOP(result),l,offset); */ emitpcode(POC_MOVFW, popGet(AOP(left),offset)); emitpcode(POC_MOVWF, popGet(AOP(result),offset)); @@ -7658,6 +8306,7 @@ static void genRightShift (iCode *ic) char *l; symbol *tlbl, *tlbl1 ; + FENTRY; /* if signed then we do it the hard way preserve the sign bit moving it inwards */ retype = getSpec(operandType(IC_RESULT(ic))); @@ -7680,11 +8329,14 @@ static void genRightShift (iCode *ic) result = IC_RESULT(ic); aopOp(right,ic,FALSE); + aopOp(left,ic,FALSE); + aopOp(result,ic,FALSE); /* if the shift count is known then do it as efficiently as possible */ if (AOP_TYPE(right) == AOP_LIT) { - genRightShiftLiteral (left,right,result,ic, 0); + shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 0); + //genRightShiftLiteral (left,right,result,ic, 0); return ; } @@ -7696,8 +8348,6 @@ static void genRightShift (iCode *ic) pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); pic14_emitcode("inc","b"); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); /* now move the left to the result if they are not the same */ @@ -7767,22 +8417,68 @@ release: /*-----------------------------------------------------------------*/ /* genUnpackBits - generates code for unpacking bits */ /*-----------------------------------------------------------------*/ -static void genUnpackBits (operand *result, char *rname, int ptype) +static void genUnpackBits (operand *result, operand *left, char *rname, int ptype, iCode *ifx) { - int shCnt ; - int rlen = 0 ; - sym_link *etype; - int offset = 0 ; - + int shCnt; + int offset = 0; /* result byte offset */ + int rsize; /* result size */ + int rlen = 0; /* remaining bitfield length */ + sym_link *etype; /* bitfield type information */ + int blen; /* bitfield length */ + int bstr; /* bitfield starting bit within byte */ + + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); etype = getSpec(operandType(result)); - + rsize = getSize (operandType (result)); + blen = SPEC_BLEN (etype); + bstr = SPEC_BSTR (etype); + + /* single bit field case */ + if (blen == 1) { + if (ifx) { /* that is for an if statement */ + pCodeOp *pcop; + resolvedIfx rIfx; + resolveIfx(&rIfx,ifx); + if (ptype == -1) /* direct */ + pcop = newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0); + else + pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0); + emitpcode((rIfx.condition) ? POC_BTFSC : POC_BTFSS,pcop); + emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key)); + ifx->generated=1; + } else { + pCodeOp *pcop; + int i; + assert (!pic14_sameRegs (AOP(result), AOP(left))); + for (i=0; i < AOP_SIZE(result); i++) + emitpcode (POC_CLRF, popGet (AOP(result), i)); + if (ptype == -1) /* direct */ + pcop = newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0); + else + pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0); + emitpcode(POC_BTFSC,pcop); + emitpcode(POC_BSF,newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),0,0)); + } + return; + } + + { + static int has_warned=0; + if (!has_warned) + { + fprintf (stderr, "%s: bitfields with more than 1 bit are probably broken...", __FUNCTION__); + has_warned=1; + } + } + /* read the first byte */ switch (ptype) { case POINTER: case IPOINTER: - pic14_emitcode("mov","a,@%s",rname); +// pic14_emitcode("mov","a,@%s",rname); + emitpcode(POC_MOVFW, popCopyReg(&pc_indf)); break; case PPOINTER: @@ -7802,15 +8498,14 @@ static void genUnpackBits (operand *result, char *rname, int ptype) pic14_emitcode("lcall","__gptrget"); break; } - + /* if we have bitdisplacement then it fits */ /* into this byte completely or if length is */ /* less than a byte */ - if ((shCnt = SPEC_BSTR(etype)) || - (SPEC_BLEN(etype) <= 8)) { + if ((shCnt = SPEC_BSTR(etype)) || blen <= 8) { /* shift right acc */ - AccRsh(shCnt); + AccRsh(left,0,shCnt); pic14_emitcode("anl","a,#0x%02x", ((unsigned char) -1)>>(8 - SPEC_BLEN(etype))); @@ -7870,17 +8565,17 @@ static void genUnpackBits (operand *result, char *rname, int ptype) return ; } -#if 0 +#if 1 /*-----------------------------------------------------------------*/ /* genDataPointerGet - generates code when ptr offset is known */ /*-----------------------------------------------------------------*/ static void genDataPointerGet (operand *left, - operand *result, - iCode *ic) + operand *result, + iCode *ic) { int size , offset = 0; - - + + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -7888,16 +8583,20 @@ static void genDataPointerGet (operand *left, * address, but different types. for the pic code, we could omit * the following */ - aopOp(result,ic,TRUE); + if (pic14_sameRegs (AOP(left), AOP(result))) + return; + DEBUGpic14_AopType(__LINE__,left,NULL,result); - emitpcode(POC_MOVFW, popGet(AOP(left),0)); + //emitpcode(POC_MOVFW, popGet(AOP(left),0)); size = AOP_SIZE(result); + if (size > AOP_SIZE(left)) size = AOP_SIZE(left); while (size--) { + emitpcode(POC_MOVFW, popGet(AOP(left),offset)); emitpcode(POC_MOVWF, popGet(AOP(result),offset)); offset++; } @@ -7907,23 +8606,21 @@ static void genDataPointerGet (operand *left, } #endif /*-----------------------------------------------------------------*/ -/* genNearPointerGet - pic14_emitcode for near pointer fetch */ +/* genNearPointerGet - pic14_emitcode for near pointer fetch */ /*-----------------------------------------------------------------*/ static void genNearPointerGet (operand *left, operand *result, iCode *ic) { asmop *aop = NULL; - //regs *preg = NULL ; - char *rname ; - sym_link *rtype, *retype; - sym_link *ltype = operandType(left); - //char buffer[80]; - + sym_link *ltype = operandType(left); + sym_link *rtype = operandType(result); + sym_link *retype= getSpec(rtype); /* bitfield type information */ + int direct = 0; + + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - rtype = operandType(result); - retype= getSpec(rtype); aopOp(left,ic,FALSE); @@ -7934,34 +8631,34 @@ static void genNearPointerGet (operand *left, if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD && !IS_BITVAR(retype) && DCL_TYPE(ltype) == POINTER) { - //genDataPointerGet (left,result,ic); + genDataPointerGet (left,result,ic); return ; } DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + aopOp (result,ic,FALSE); - /* if the value is already in a pointer register - then don't need anything more */ - if (!AOP_INPREG(AOP(left))) { + /* Check if can access directly instead of via a pointer */ + if (PCOP(AOP(left))->type == PO_LITERAL && AOP_SIZE(result) == 1) { + direct = 1; + } + + /* If the pointer value is not in a the FSR then need to put it in */ + if (!AOP_INPREG(AOP(left)) && !direct) { /* otherwise get a free pointer register */ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* - aop = newAsmop(0); - preg = getFreePtr(ic,&aop,FALSE); - pic14_emitcode("mov","%s,%s", - preg->name, - aopGet(AOP(left),0,FALSE,TRUE)); - rname = preg->name ; - */ - rname ="BAD"; - } else - rname = aopGet(AOP(left),0,FALSE,FALSE); + if (PCOP(AOP(result))->type == PO_LITERAL) /* XXX: check me */ + emitpcode(POC_MOVLW, popGet(AOP(left),0)); + else + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_MOVWF, popCopyReg(&pc_fsr)); + } - aopOp (result,ic,FALSE); +// sym_link *etype; /* if bitfield then unpack the bits */ if (IS_BITFIELD(retype)) - genUnpackBits (result,rname,POINTER); + genUnpackBits (result,left,"indf",direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic)); else { /* we have can just get the values */ int size = AOP_SIZE(result); @@ -7969,29 +8666,20 @@ static void genNearPointerGet (operand *left, DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - emitpcode(POC_MOVFW,popGet(AOP(left),0)); - emitpcode(POC_MOVWF,popCopyReg(&pc_fsr)); while(size--) { - emitpcode(POC_MOVFW,popCopyReg(&pc_indf)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset++)); - if(size) + if (direct) + emitpcode(POC_MOVWF,popGet(AOP(left),0)); + else + emitpcode(POC_MOVFW,popCopyReg(&pc_indf)); + if (AOP_TYPE(result) == AOP_LIT) { + emitpcode(POC_MOVLW,popGet(AOP(result),offset)); + } else { + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + } + if (size && !direct) emitpcode(POC_INCF,popCopyReg(&pc_fsr)); + offset++; } - /* - while (size--) { - if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) { - - pic14_emitcode("mov","a,@%s",rname); - aopPut(AOP(result),"a",offset); - } else { - sprintf(buffer,"@%s",rname); - aopPut(AOP(result),buffer,offset); - } - offset++ ; - if (size) - pic14_emitcode("inc","%s",rname); - } - */ } /* now some housekeeping stuff */ @@ -8000,10 +8688,10 @@ static void genNearPointerGet (operand *left, DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); freeAsmop(NULL,aop,ic,TRUE); } else { - /* we did not allocate which means left - already in a pointer register, then - if size > 0 && this could be used again - we have to point it back to where it + /* we did not allocate which means left + already in a pointer register, then + if size > 0 && this could be used again + we have to point it back to where it belongs */ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (AOP_SIZE(result) > 1 && @@ -8012,14 +8700,14 @@ static void genNearPointerGet (operand *left, ic->depth )) { int size = AOP_SIZE(result) - 1; while (size--) - pic14_emitcode("dec","%s",rname); + emitpcode(POC_DECF, popCopyReg(&pc_fsr)); } } /* done */ freeAsmop(left,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); - + } /*-----------------------------------------------------------------*/ @@ -8034,6 +8722,7 @@ static void genPagedPointerGet (operand *left, char *rname ; sym_link *rtype, *retype; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); rtype = operandType(result); @@ -8059,7 +8748,7 @@ static void genPagedPointerGet (operand *left, /* if bitfield then unpack the bits */ if (IS_BITFIELD(retype)) - genUnpackBits (result,rname,PPOINTER); + genUnpackBits (result,left,rname,PPOINTER,0); else { /* we have can just get the values */ int size = AOP_SIZE(result); @@ -8112,6 +8801,7 @@ static void genFarPointerGet (operand *left, int size, offset ; sym_link *retype = getSpec(operandType(result)); + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(left,ic,FALSE); @@ -8137,7 +8827,7 @@ static void genFarPointerGet (operand *left, /* if bit then unpack */ if (IS_BITFIELD(retype)) - genUnpackBits(result,"dptr",FPOINTER); + genUnpackBits(result,left,"dptr",FPOINTER,0); else { size = AOP_SIZE(result); offset = 0 ; @@ -8187,7 +8877,7 @@ static void genCodePointerGet (operand *left, /* if bit then unpack */ if (IS_BITFIELD(retype)) - genUnpackBits(result,"dptr",CPOINTER); + genUnpackBits(result,left,"dptr",CPOINTER,0); else { size = AOP_SIZE(result); offset = 0 ; @@ -8213,6 +8903,7 @@ static void genGenPointerGet (operand *left, int size, offset ; sym_link *retype = getSpec(operandType(result)); + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(left,ic,FALSE); aopOp(result,ic,FALSE); @@ -8264,37 +8955,85 @@ static void genConstPointerGet (operand *left, operand *result, iCode *ic) { //sym_link *retype = getSpec(operandType(result)); - symbol *albl = newiTempLabel(NULL); - symbol *blbl = newiTempLabel(NULL); + symbol *albl, *blbl;//, *clbl; PIC_OPCODE poc; + int i, size, lit; pCodeOp *pcop; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(left,ic,FALSE); aopOp(result,ic,FALSE); + size = AOP_SIZE(result); DEBUGpic14_AopType(__LINE__,left,NULL,result); DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__); - - emitpcode(POC_CALL,popGetLabel(albl->key)); - pcop = popGetLabel(blbl->key); - emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */ - emitpcode(POC_GOTO,pcop); - emitpLabel(albl->key); - - poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW); - - emitpcode(poc,popGet(AOP(left),1)); - emitpcode(POC_MOVWF,popCopyReg(&pc_pclath)); - emitpcode(poc,popGet(AOP(left),0)); - emitpcode(POC_MOVWF,popCopyReg(&pc_pcl)); - - emitpLabel(blbl->key); - - emitpcode(POC_MOVWF,popGet(AOP(result),0)); - + + lit = aop_isLitLike (AOP(left)); + poc = lit ? POC_MOVLW : POC_MOVFW; + + if (lit) + { + for (i = 0; i < size; i++) + { + albl = newiTempLabel(NULL); + blbl = newiTempLabel(NULL); + + emitpcode(POC_CALL,popGetLabel(albl->key)); + pcop = popGetLabel(blbl->key); + emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */ + emitpcode(POC_GOTO,pcop); + + emitpLabel(albl->key); + emitpcode(poc,popGetAddr(AOP(left),1,i)); + emitpcode(POC_MOVWF,popCopyReg(&pc_pclath)); + emitpcode(poc,popGetAddr(AOP(left),0,i)); + emitpcode(POC_MOVWF,popCopyReg(&pc_pcl)); + + emitpLabel(blbl->key); + emitpcode(POC_MOVWF,popGet(AOP(result),i)); + } // for + } else { + albl = newiTempLabel(NULL); + blbl = newiTempLabel(NULL); + //clbl = newiTempLabel(NULL); + + emitpcode (POC_GOTO, popGetLabel (blbl->key)); + + emitpLabel(albl->key); + emitpcode(poc,popGet(AOP(left),1)); + emitpcode(POC_MOVWF,popCopyReg(&pc_pclath)); + emitpcode(poc,popGet(AOP(left),0)); + emitpcode(POC_MOVWF,popCopyReg(&pc_pcl)); + + emitpLabel(blbl->key); + + for (i = 0; i < size; i++) + { + emitpcode(POC_CALL,popGetLabel(albl->key)); + /* the next two instructions (plus clbl) might be useless... */ + //pcop = popGetLabel(clbl->key); + //emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */ + //emitpcode(POC_GOTO,pcop); + //emitpLabel(clbl->key); + + if (i+1 < size) { + emitpcode (POC_INCF, popGet (AOP(left), 0)); + emitSKPNZ; + emitpcode (POC_INCF, popGet (AOP(left), 1)); + } + emitpcode(POC_MOVWF,popGet(AOP(result),i)); + } // for + if (size > 1) { + /* restore left's value */ + emitpcode (POC_MOVLW, popGetLit (size-1)); + emitpcode (POC_SUBWF, popGet (AOP(left), 0)); + emitSKPC; + emitpcode (POC_DECF, popGet (AOP(left), 1)); + } // if + } // if (lit) freeAsmop(left,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); @@ -8307,8 +9046,9 @@ static void genPointerGet (iCode *ic) { operand *left, *result ; sym_link *type, *etype; - int p_type; + int p_type = -1; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); left = IC_LEFT(ic); @@ -8375,186 +9115,311 @@ static void genPointerGet (iCode *ic) break; case GPOINTER: - if (IS_PTR_CONST(type)) + if (IS_CODEPTR(type) || IS_PTR_CONST(type) || SPEC_CONST(etype)) genConstPointerGet (left,result,ic); else genGenPointerGet (left,result,ic); break; + default: + assert ( !"unhandled pointer type" ); + break; } } /*-----------------------------------------------------------------*/ -/* genPackBits - generates code for packed bit storage */ +/* emitPtrByteGet - for legacy 8051 emits code to get a byte into */ +/* A through a pointer register (R0, R1, or DPTR). The original */ +/* value of A can be preserved in B. */ +/* PIC has to use INDF register. */ /*-----------------------------------------------------------------*/ -static void genPackBits (sym_link *etype , - operand *right , - char *rname, int p_type) -{ - int shCount = 0 ; - int offset = 0 ; - int rLen = 0 ; - int blen, bstr ; - char *l ; - - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - blen = SPEC_BLEN(etype); - bstr = SPEC_BSTR(etype); - - l = aopGet(AOP(right),offset++,FALSE,FALSE); - MOVA(l); - - /* if the bit lenth is less than or */ - /* it exactly fits a byte then */ - if (SPEC_BLEN(etype) <= 8 ) { - shCount = SPEC_BSTR(etype) ; +static void +emitPtrByteGet (char *rname, int p_type, bool preserveAinB) +{ + FENTRY; + switch (p_type) + { + case IPOINTER: + case POINTER: + if (preserveAinB) + pic14_emitcode ("mov", "b,a"); +// pic14_emitcode ("mov", "a,@%s", rname); + emitpcode(POC_MOVFW, popCopyReg(&pc_indf)); + break; - /* shift left acc */ - AccLsh(shCount); + case PPOINTER: + if (preserveAinB) + pic14_emitcode ("mov", "b,a"); + pic14_emitcode ("movx", "a,@%s", rname); + break; - if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */ - - - switch (p_type) { - case POINTER: - pic14_emitcode ("mov","b,a"); - pic14_emitcode("mov","a,@%s",rname); - break; - - case FPOINTER: - pic14_emitcode ("mov","b,a"); - pic14_emitcode("movx","a,@dptr"); - break; - - case GPOINTER: - pic14_emitcode ("push","b"); - pic14_emitcode ("push","acc"); - pic14_emitcode ("lcall","__gptrget"); - pic14_emitcode ("pop","b"); - break; - } - - pic14_emitcode ("anl","a,#0x%02x",(unsigned char) - ((unsigned char)(0xFF << (blen+bstr)) | - (unsigned char)(0xFF >> (8-bstr)) ) ); - pic14_emitcode ("orl","a,b"); - if (p_type == GPOINTER) - pic14_emitcode("pop","b"); - } - } - - switch (p_type) { - case POINTER: - pic14_emitcode("mov","@%s,a",rname); + case FPOINTER: + if (preserveAinB) + pic14_emitcode ("mov", "b,a"); + pic14_emitcode ("movx", "a,@dptr"); break; - case FPOINTER: - pic14_emitcode("movx","@dptr,a"); + case CPOINTER: + if (preserveAinB) + pic14_emitcode ("mov", "b,a"); + pic14_emitcode ("clr", "a"); + pic14_emitcode ("movc", "a,@a+dptr"); break; - case GPOINTER: - DEBUGpic14_emitcode(";lcall","__gptrput"); + case GPOINTER: + if (preserveAinB) + { + pic14_emitcode ("push", "b"); + pic14_emitcode ("push", "acc"); + } + pic14_emitcode ("lcall", "__gptrget"); + if (preserveAinB) + pic14_emitcode ("pop", "b"); + break; + } +} + +/*-----------------------------------------------------------------*/ +/* emitPtrByteSet - emits code to set a byte from src through a */ +/* pointer register INDF (legacy 8051 uses R0, R1, or DPTR). */ +/*-----------------------------------------------------------------*/ +static void +emitPtrByteSet (char *rname, int p_type, char *src) +{ + FENTRY; + switch (p_type) + { + case IPOINTER: + case POINTER: + if (*src=='@') + { + MOVA (src); + pic14_emitcode ("mov", "@%s,a", rname); + } + else +// pic14_emitcode ("mov", "@%s,%s", rname, src); + emitpcode(POC_MOVWF,popCopyReg(&pc_indf)); break; - } - - /* if we r done */ - if ( SPEC_BLEN(etype) <= 8 ) - return ; - - pic14_emitcode("inc","%s",rname); - rLen = SPEC_BLEN(etype) ; - - /* now generate for lengths greater than one byte */ - while (1) { - l = aopGet(AOP(right),offset++,FALSE,TRUE); + case PPOINTER: + MOVA (src); + pic14_emitcode ("movx", "@%s,a", rname); + break; - rLen -= 8 ; - if (rLen <= 0 ) - break ; + case FPOINTER: + MOVA (src); + pic14_emitcode ("movx", "@dptr,a"); + break; - switch (p_type) { - case POINTER: - if (*l == '@') { - MOVA(l); - pic14_emitcode("mov","@%s,a",rname); - } else - pic14_emitcode("mov","@%s,%s",rname,l); - break; - - case FPOINTER: - MOVA(l); - pic14_emitcode("movx","@dptr,a"); - break; - - case GPOINTER: - MOVA(l); - DEBUGpic14_emitcode(";lcall","__gptrput"); - break; - } - pic14_emitcode ("inc","%s",rname); - } + case GPOINTER: + MOVA (src); + pic14_emitcode ("lcall", "__gptrput"); + break; + } +} + +/*-----------------------------------------------------------------*/ +/* genPackBits - generates code for packed bit storage */ +/*-----------------------------------------------------------------*/ +static void genPackBits(sym_link *etype,operand *result,operand *right,char *rname,int p_type) +{ + int offset = 0; /* source byte offset */ + int rlen = 0; /* remaining bitfield length */ + int blen; /* bitfield length */ + int bstr; /* bitfield starting bit within byte */ + int litval; /* source literal value (if AOP_LIT) */ + unsigned char mask; /* bitmask within current byte */ + + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - MOVA(l); + blen = SPEC_BLEN (etype); + bstr = SPEC_BSTR (etype); - /* last last was not complete */ - if (rLen) { - /* save the byte & read byte */ - switch (p_type) { - case POINTER: - pic14_emitcode ("mov","b,a"); - pic14_emitcode("mov","a,@%s",rname); - break; + /* If the bitfield length is less than a byte */ + if (blen < 8) + { + mask = ((unsigned char) (0xFF << (blen + bstr)) | + (unsigned char) (0xFF >> (8 - bstr))); + + if (AOP_TYPE (right) == AOP_LIT) + { + /* Case with a bitfield length <8 and literal source + */ + int lit = (int) floatFromVal (AOP (right)->aopu.aop_lit); + if (blen == 1) { + if (p_type == -1) { + pCodeOp *pcop; + if (AOP(result)->type == AOP_PCODE) + pcop = newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),bstr,0); + else + pcop = popGet(AOP(result),0); + emitpcode(lit?POC_BSF:POC_BCF,pcop); + } else { + emitpcode(lit?POC_BSF:POC_BCF,popCopyReg(&pc_indf)); + } + return; + } else { + litval = lit << bstr; + litval &= (~mask) & 0xff; + if (p_type == -1) + emitpcode(POC_MOVFW,popGet(AOP(result),0)); + else + emitPtrByteGet (rname, p_type, FALSE); + if ((mask|litval)!=0xff) + emitpcode(POC_ANDLW,popGetLit(mask)); + if (litval) + emitpcode(POC_IORLW,popGetLit(litval)); + } + } + else + { + if (blen==1) { + if (p_type == -1) { + /* Note more efficient code, of pre clearing bit then only setting it if required, can only be done if it is known that the result is not a SFR */ + emitpcode(POC_RRFW,popGet(AOP(right),0)); + emitSKPC; + emitpcode(POC_BCF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0)); + emitSKPNC; + emitpcode(POC_BSF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0)); + return; + } else if (p_type!=GPOINTER) { + /* Case with a bitfield length == 1 and no generic pointer + */ + if (AOP_TYPE (right) == AOP_CRY) + pic14_emitcode ("mov", "c,%s", AOP(right)->aopu.aop_dir); + else + { + MOVA (aopGet (AOP (right), 0, FALSE, FALSE)); + pic14_emitcode ("rrc","a"); + } + emitPtrByteGet (rname, p_type, FALSE); + pic14_emitcode ("mov","acc.%d,c",bstr); + } + } + else + { + //bool pushedB; + /* Case with a bitfield length < 8 and arbitrary source + */ + MOVA (aopGet (AOP (right), 0, FALSE, FALSE)); + /* shift and mask source value */ + AccLsh (right,0,bstr); + pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff); + emitpcode(POC_ANDLW, popGetLit((~mask) & 0xff)); + + //pushedB = pushB (); + if (p_type == -1) + emitpcode(POC_MOVFW,popGet(AOP(result),0)); + else + emitPtrByteGet (rname, p_type, TRUE); + + pic14_emitcode ("anl", "a,#0x%02x", mask); + pic14_emitcode ("orl", "a,b"); + emitpcode(POC_ANDLW,popGetLit(mask)); + emitpcode(POC_IORFW,popGet(AOP(right),0)); + if (p_type == GPOINTER) + pic14_emitcode ("pop", "b"); + + //popB (pushedB); + } + } + + if (p_type == -1) + emitpcode(POC_MOVWF,popGet(AOP(result),0)); + else + emitPtrByteSet (rname, p_type, "a"); + return; + } + + /* Bit length is greater than 7 bits. In this case, copy */ + /* all except the partial byte at the end */ + for (rlen=blen;rlen>=8;rlen-=8) + { + emitPtrByteSet (rname, p_type, + aopGet (AOP (right), offset++, FALSE, TRUE) ); + if (rlen>8) + pic14_emitcode ("inc", "%s", rname); + } + + /* If there was a partial byte at the end */ + if (rlen) + { + mask = (((unsigned char) -1 << rlen) & 0xff); + + if (AOP_TYPE (right) == AOP_LIT) + { + /* Case with partial byte and literal source + */ + litval = (int) floatFromVal (AOP (right)->aopu.aop_lit); + litval >>= (blen-rlen); + litval &= (~mask) & 0xff; + emitPtrByteGet (rname, p_type, FALSE); + if ((mask|litval)!=0xff) + pic14_emitcode ("anl","a,#0x%02x", mask); + if (litval) + pic14_emitcode ("orl","a,#0x%02x", litval); + } + else + { + //bool pushedB; + /* Case with partial byte and arbitrary source + */ + MOVA (aopGet (AOP (right), offset++, FALSE, FALSE)); + pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff); - case FPOINTER: - pic14_emitcode ("mov","b,a"); - pic14_emitcode("movx","a,@dptr"); - break; + //pushedB = pushB (); + /* transfer A to B and get next byte */ + emitPtrByteGet (rname, p_type, TRUE); - case GPOINTER: - pic14_emitcode ("push","b"); - pic14_emitcode ("push","acc"); - pic14_emitcode ("lcall","__gptrget"); - pic14_emitcode ("pop","b"); - break; - } - - pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) ); - pic14_emitcode ("orl","a,b"); - } - - if (p_type == GPOINTER) - pic14_emitcode("pop","b"); + pic14_emitcode ("anl", "a,#0x%02x", mask); + pic14_emitcode ("orl", "a,b"); + if (p_type == GPOINTER) + pic14_emitcode ("pop", "b"); + + //popB (pushedB); + } + emitPtrByteSet (rname, p_type, "a"); + } - switch (p_type) { - - case POINTER: - pic14_emitcode("mov","@%s,a",rname); - break; - - case FPOINTER: - pic14_emitcode("movx","@dptr,a"); - break; - - case GPOINTER: - DEBUGpic14_emitcode(";lcall","__gptrput"); - break; +} + +/*-----------------------------------------------------------------*/ +/* SetIrp - Set IRP bit */ +/*-----------------------------------------------------------------*/ +void SetIrp(operand *result) { + FENTRY; + if (AOP_TYPE(result) == AOP_LIT) { + unsigned lit = (unsigned)operandLitValue(result); + emitpcode((lit&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); + } else { + if (PCOP(AOP(result))->type == PO_LITERAL) { + int addrs = PCOL(AOP(result))->lit; + emitpcode((addrs&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); + } else { + emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); /* always ensure this is clear as it may have previouly been set */ + if(AOP_SIZE(result) > 1) { + emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0)); + emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); + } + } } } + /*-----------------------------------------------------------------*/ /* genDataPointerSet - remat pointer to data space */ /*-----------------------------------------------------------------*/ static void genDataPointerSet(operand *right, - operand *result, - iCode *ic) + operand *result, + iCode *ic) { int size, offset = 0 ; - char *l, buffer[256]; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(right,ic,FALSE); + aopOp(result,ic,FALSE); - l = aopGet(AOP(result),0,FALSE,TRUE); size = AOP_SIZE(right); /* if ( AOP_TYPE(result) == AOP_PCODE) { @@ -8566,36 +9431,20 @@ static void genDataPointerSet(operand *right, // tsd, was l+1 - the underline `_' prefix was being stripped while (size--) { - if (offset) { - sprintf(buffer,"(%s + %d)",l,offset); - fprintf(stderr,"oops %s\n",buffer); - } else - sprintf(buffer,"%s",l); + emitpComment ("%s:%u: size=%i, offset=%i", __FILE__,__LINE__, size, offset); if (AOP_TYPE(right) == AOP_LIT) { unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); lit = lit >> (8*offset); if(lit&0xff) { - pic14_emitcode("movlw","%d",lit); - pic14_emitcode("movwf","%s",buffer); - emitpcode(POC_MOVLW, popGetLit(lit&0xff)); - //emitpcode(POC_MOVWF, popRegFromString(buffer)); - emitpcode(POC_MOVWF, popGet(AOP(result),0)); - + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); } else { - pic14_emitcode("clrf","%s",buffer); - //emitpcode(POC_CLRF, popRegFromString(buffer)); - emitpcode(POC_CLRF, popGet(AOP(result),0)); + emitpcode(POC_CLRF, popGet(AOP(result),offset)); } - }else { - pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - pic14_emitcode("movwf","%s",buffer); - + } else { emitpcode(POC_MOVFW, popGet(AOP(right),offset)); - //emitpcode(POC_MOVWF, popRegFromString(buffer)); - emitpcode(POC_MOVWF, popGet(AOP(result),0)); - + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); } offset++; @@ -8606,98 +9455,86 @@ static void genDataPointerSet(operand *right, } /*-----------------------------------------------------------------*/ -/* genNearPointerSet - pic14_emitcode for near pointer put */ +/* genNearPointerSet - pic14_emitcode for near pointer put */ /*-----------------------------------------------------------------*/ static void genNearPointerSet (operand *right, operand *result, iCode *ic) { asmop *aop = NULL; - char *l; - sym_link *retype; sym_link *ptype = operandType(result); + sym_link *retype = getSpec(operandType(right)); + sym_link *letype = getSpec(ptype); + int direct = 0; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - retype= getSpec(operandType(right)); - aopOp(result,ic,FALSE); /* if the result is rematerializable & in data space & not a bit variable */ //if (AOP_TYPE(result) == AOP_IMMD && - if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD && + if (AOP_TYPE(result) == AOP_PCODE && DCL_TYPE(ptype) == POINTER && - !IS_BITFIELD(retype)) { + !IS_BITVAR (retype) && + !IS_BITVAR (letype)) { genDataPointerSet (right,result,ic); freeAsmop(result,NULL,ic,TRUE); return; } - + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(right,ic,FALSE); DEBUGpic14_AopType(__LINE__,NULL,right,result); - /* if the value is already in a pointer register - then don't need anything more */ - if (!AOP_INPREG(AOP(result))) { - /* otherwise get a free pointer register */ - //aop = newAsmop(0); - //preg = getFreePtr(ic,&aop,FALSE); + /* Check if can access directly instead of via a pointer */ + if (PCOP(AOP(result))->type == PO_LITERAL && AOP_SIZE(right) == 1) { + direct = 1; + } + + /* If the pointer value is not in a the FSR then need to put it in */ + if (!AOP_INPREG(AOP(result)) && !direct) { DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - //pic14_emitcode("mov","%s,%s", - // preg->name, - // aopGet(AOP(result),0,FALSE,TRUE)); - //rname = preg->name ; - //pic14_emitcode("movwf","fsr"); - emitpcode(POC_MOVFW, popGet(AOP(result),0)); + if (PCOP(AOP(result))->type == PO_LITERAL) + emitpcode(POC_MOVLW, popGet(AOP(result),0)); + else + emitpcode(POC_MOVFW, popGet(AOP(result),0)); emitpcode(POC_MOVWF, popCopyReg(&pc_fsr)); - emitpcode(POC_MOVFW, popGet(AOP(right),0)); - emitpcode(POC_MOVWF, popCopyReg(&pc_indf)); - goto release; - - }// else - // rname = aopGet(AOP(result),0,FALSE,FALSE); - - - /* if bitfield then unpack the bits */ - if (IS_BITFIELD(retype)) { - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "The programmer is obviously confused"); - //genPackBits (retype,right,rname,POINTER); - exit(1); } - else { + + /* Must set/reset IRP bit for use with FSR. */ + /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */ + if (!direct) + SetIrp(result); + + /* if bitfield then unpack the bits */ + if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) { + genPackBits ((IS_BITFIELD (retype) ? retype : letype), result, right, "indf", direct?-1:POINTER); + } else { /* we have can just get the values */ int size = AOP_SIZE(right); int offset = 0 ; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); while (size--) { - l = aopGet(AOP(right),offset,FALSE,TRUE); + char *l = aopGet(AOP(right),offset,FALSE,TRUE); if (*l == '@' ) { - //MOVA(l); - //pic14_emitcode("mov","@%s,a",rname); - pic14_emitcode("movf","indf,w ;1"); + emitpcode(POC_MOVFW,popCopyReg(&pc_indf)); } else { - if (AOP_TYPE(right) == AOP_LIT) { - unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); - if(lit) { - pic14_emitcode("movlw","%s",l); - pic14_emitcode("movwf","indf ;2"); - } else - pic14_emitcode("clrf","indf"); - }else { - pic14_emitcode("movf","%s,w",l); - pic14_emitcode("movwf","indf ;2"); + emitpcode(POC_MOVLW,popGet(AOP(right),offset)); + } else { + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); } - //pic14_emitcode("mov","@%s,%s",rname,l); + if (direct) + emitpcode(POC_MOVWF,popGet(AOP(result),0)); + else + emitpcode(POC_MOVWF,popCopyReg(&pc_indf)); } - if (size) - pic14_emitcode("incf","fsr,f ;3"); - //pic14_emitcode("inc","%s",rname); + if (size && !direct) + emitpcode(POC_INCF,popCopyReg(&pc_fsr)); offset++; } } @@ -8708,10 +9545,10 @@ static void genNearPointerSet (operand *right, /* we had to allocate for this iCode */ freeAsmop(NULL,aop,ic,TRUE); } else { - /* we did not allocate which means left - already in a pointer register, then - if size > 0 && this could be used again - we have to point it back to where it + /* we did not allocate which means left + already in a pointer register, then + if size > 0 && this could be used again + we have to point it back to where it belongs */ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (AOP_SIZE(right) > 1 && @@ -8720,14 +9557,13 @@ static void genNearPointerSet (operand *right, ic->depth )) { int size = AOP_SIZE(right) - 1; while (size--) - pic14_emitcode("decf","fsr,f"); - //pic14_emitcode("dec","%s",rname); + emitpcode(POC_DECF, popCopyReg(&pc_fsr)); } } DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* done */ -release: + freeAsmop(right,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); } @@ -8744,6 +9580,7 @@ static void genPagedPointerSet (operand *right, char *rname , *l; sym_link *retype; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); retype= getSpec(operandType(right)); @@ -8768,7 +9605,7 @@ static void genPagedPointerSet (operand *right, /* if bitfield then unpack the bits */ if (IS_BITFIELD(retype)) - genPackBits (retype,right,rname,PPOINTER); + genPackBits (retype,result,right,rname,PPOINTER); else { /* we have can just get the values */ int size = AOP_SIZE(right); @@ -8822,6 +9659,7 @@ static void genFarPointerSet (operand *right, int size, offset ; sym_link *retype = getSpec(operandType(right)); + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(result,ic,FALSE); @@ -8846,7 +9684,7 @@ static void genFarPointerSet (operand *right, /* if bit then unpack */ if (IS_BITFIELD(retype)) - genPackBits(retype,right,"dptr",FPOINTER); + genPackBits(retype,result,right,"dptr",FPOINTER); else { size = AOP_SIZE(right); offset = 0 ; @@ -8869,14 +9707,15 @@ static void genFarPointerSet (operand *right, static void genGenPointerSet (operand *right, operand *result, iCode *ic) { - int size, offset ; + sym_link *ptype = operandType(result); sym_link *retype = getSpec(operandType(right)); + sym_link *letype = getSpec (ptype); + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(result,ic,FALSE); aopOp(right,ic,FALSE); - size = AOP_SIZE(right); DEBUGpic14_AopType(__LINE__,NULL,right,result); @@ -8888,84 +9727,43 @@ static void genGenPointerSet (operand *right, pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE)); pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE)); } - else { /* we need to get it byte by byte */ - //char *l = aopGet(AOP(result),0,FALSE,FALSE); - size = AOP_SIZE(right); - offset = 0 ; - - /* hack hack! see if this the FSR. If so don't load W */ - if(AOP_TYPE(right) != AOP_ACC) { - - - emitpcode(POC_MOVFW,popGet(AOP(result),0)); - emitpcode(POC_MOVWF,popCopyReg(&pc_fsr)); - - if(AOP_SIZE(result) > 1) { - emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); - emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0)); - emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); - - } - - //if(size==2) - //emitpcode(POC_DECF,popCopyReg(&pc_fsr)); - //if(size==4) { - // emitpcode(POC_MOVLW,popGetLit(0xfd)); - // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr)); - //} - - while(size--) { - emitpcode(POC_MOVFW,popGet(AOP(right),offset++)); - emitpcode(POC_MOVWF,popCopyReg(&pc_indf)); - - if(size) - emitpcode(POC_INCF,popCopyReg(&pc_fsr)); - } - - - goto release; - } - - if(aopIdx(AOP(result),0) != 4) { - - emitpcode(POC_MOVWF,popCopyReg(&pc_indf)); - goto release; - } - - emitpcode(POC_MOVWF,popCopyReg(&pc_indf)); - goto release; - + else { + emitpcode(POC_MOVFW,popGet(AOP(result),0)); + emitpcode(POC_MOVWF,popCopyReg(&pc_fsr)); + + /* Must set/reset IRP bit for use with FSR. */ + /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */ + SetIrp(result); } } - /* so dptr know contains the address */ - - - /* if bit then unpack */ - if (IS_BITFIELD(retype)) - genPackBits(retype,right,"dptr",GPOINTER); - else { - size = AOP_SIZE(right); - offset = 0 ; - - DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size); + + /* if bitfield then unpack the bits */ + if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) { + genPackBits ((IS_BITFIELD (retype) ? retype : letype),result, right, "indf", POINTER); + } else { + /* we have can just get the values */ + int size = AOP_SIZE(right); + int offset = 0 ; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); while (size--) { - - emitpcode(POC_MOVFW,popGet(AOP(result),offset)); - emitpcode(POC_MOVWF,popCopyReg(&pc_fsr)); - - if (AOP_TYPE(right) == AOP_LIT) - emitpcode(POC_MOVLW, popGet(AOP(right),offset)); - else - emitpcode(POC_MOVFW, popGet(AOP(right),offset)); - - emitpcode(POC_MOVWF,popCopyReg(&pc_indf)); - + char *l = aopGet(AOP(right),offset,FALSE,TRUE); + if (*l == '@' ) { + emitpcode(POC_MOVFW,popCopyReg(&pc_indf)); + } else { + if (AOP_TYPE(right) == AOP_LIT) { + emitpcode(POC_MOVLW,popGet(AOP(right),offset)); + } else { + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + } + emitpcode(POC_MOVWF,popCopyReg(&pc_indf)); + } + if (size) + emitpcode(POC_INCF,popCopyReg(&pc_fsr)); offset++; } } -release: freeAsmop(right,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); } @@ -8979,6 +9777,7 @@ static void genPointerSet (iCode *ic) sym_link *type, *etype; int p_type; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); right = IC_RIGHT(ic); @@ -9047,6 +9846,7 @@ static void genIfx (iCode *ic, iCode *popIc) operand *cond = IC_COND(ic); int isbit =0; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(cond,ic,FALSE); @@ -9087,6 +9887,7 @@ static void genAddrOf (iCode *ic) operand *right, *result, *left; int size, offset ; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -9097,6 +9898,27 @@ static void genAddrOf (iCode *ic) aopOp((result=IC_RESULT(ic)),ic,TRUE); DEBUGpic14_AopType(__LINE__,left,right,result); + assert (IS_SYMOP (left)); + + /* sanity check: generic pointers to code space are not yet supported, + * pionters to codespace must not be assigned addresses of __data values. */ + #if 0 + fprintf (stderr, "result: %s, left: %s\n", OP_SYMBOL(result)->name, OP_SYMBOL(left)->name); + fprintf (stderr, "result->type : "); printTypeChain (OP_SYM_TYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(result)))), IS_CODEPTR(OP_SYM_TYPE(result)), IS_PTR_CONST(OP_SYM_TYPE(result))); + fprintf (stderr, "result->etype: "); printTypeChain (OP_SYM_ETYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(result)))), IS_CODEPTR(OP_SYM_ETYPE(result)), IS_PTR_CONST(OP_SYM_ETYPE(result))); + fprintf (stderr, "left->type : "); printTypeChain (OP_SYM_TYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left)))), IS_CODEPTR(OP_SYM_TYPE(left)), IS_PTR_CONST(OP_SYM_TYPE(left))); + fprintf (stderr, "left->etype : "); printTypeChain (OP_SYM_ETYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n",IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(left)))), IS_CODEPTR(OP_SYM_ETYPE(left)), IS_PTR_CONST(OP_SYM_ETYPE(left))); +#endif + + if (IS_CODEPTR(OP_SYM_TYPE(result)) && !IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left))))) { + fprintf (stderr, "trying to assign __code pointer (%s) an address in __data space (&%s) -- expect trouble\n", + IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown", + OP_SYMBOL(left)->name); + } else if (!IS_CODEPTR (OP_SYM_TYPE(result)) && IN_CODESPACE(SPEC_OCLS(getSpec(OP_SYM_TYPE(left))))) { + fprintf (stderr, "trying to assign __data pointer (%s) an address in __code space (&%s) -- expect trouble\n", + IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown", + OP_SYMBOL(left)->name); + } size = AOP_SIZE(IC_RESULT(ic)); offset = 0; @@ -9159,6 +9981,7 @@ static void genAssign (iCode *ic) result = IC_RESULT(ic); right = IC_RIGHT(ic) ; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if they are the same */ @@ -9173,7 +9996,27 @@ static void genAssign (iCode *ic) /* if they are the same registers */ if (pic14_sameRegs(AOP(right),AOP(result))) goto release; + + /* special case: assign from __code */ + if (!IS_ITEMP(right) /* --> iTemps never reside in __code */ + && IS_SYMOP (right) /* --> must be an immediate (otherwise we would be in genConstPointerGet) */ + && !IS_FUNC(OP_SYM_TYPE(right)) /* --> we would want its address instead of the first instruction */ + && !IS_CODEPTR(OP_SYM_TYPE(right)) /* --> get symbols address instread */ + && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(right))))) + { + emitpComment ("genAssign from CODESPACE"); + genConstPointerGet (right, result, ic); + goto release; + } + /* just for symmetry reasons... */ + if (!IS_ITEMP(result) + && IS_SYMOP (result) + && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(result))))) + { + assert ( !"cannot write to CODESPACE" ); + } + /* if the result is a bit */ if (AOP_TYPE(result) == AOP_CRY) { @@ -9282,6 +10125,7 @@ static void genJumpTab (iCode *ic) symbol *jtab; char *l; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp(IC_JTCOND(ic),ic,FALSE); @@ -9331,6 +10175,7 @@ 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)); @@ -9460,6 +10305,7 @@ static void genCast (iCode *ic) operand *right = IC_RIGHT(ic); int size, offset ; + FENTRY; DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); /* if they are equivalent then do nothing */ if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic))) @@ -9547,9 +10393,9 @@ static void genCast (iCode *ic) DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__); if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) { - emitpcode(POC_MOVLW, popGet(AOP(right),0)); + emitpcode(POC_MOVLW, popGetAddr(AOP(right),0,0)); emitpcode(POC_MOVWF, popGet(AOP(result),0)); - emitpcode(POC_MOVLW, popGet(AOP(right),1)); + emitpcode(POC_MOVLW, popGetAddr(AOP(right),1,0)); emitpcode(POC_MOVWF, popGet(AOP(result),1)); if(AOP_SIZE(result) <2) fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__); @@ -9616,7 +10462,7 @@ static void genCast (iCode *ic) DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__); if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) { - emitpcode(POC_MOVLW, popGet(AOP(right),offset)); + emitpcode(POC_MOVLW, popGetAddr(AOP(right),offset,0)); emitpcode(POC_MOVWF, popGet(AOP(result),offset)); } else { aopPut(AOP(result), @@ -9730,6 +10576,7 @@ release: static int genDjnz (iCode *ic, iCode *ifx) { symbol *lbl, *lbl1; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (!ifx) @@ -9791,6 +10638,7 @@ static int genDjnz (iCode *ic, iCode *ifx) /*-----------------------------------------------------------------*/ static void genReceive (iCode *ic) { + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (isOperandInFarSpace(IC_RESULT(ic)) && @@ -9828,6 +10676,7 @@ static void genReceive (iCode *ic) static void genDummyRead (iCode * ic) { + FENTRY; pic14_emitcode ("; genDummyRead",""); pic14_emitcode ("; not implemented",""); @@ -9850,7 +10699,9 @@ void genpic14Code (iCode *lic) { iCode *ic; int cln = 0; + const char *cline; + FENTRY; lineHead = lineCurr = NULL; pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block")); @@ -9866,28 +10717,23 @@ void genpic14Code (iCode *lic) for (ic = lic ; ic ; ic = ic->next ) { - DEBUGpic14_emitcode(";ic",""); - if ( cln != ic->lineno ) { - if ( options.debug ) { - debugFile->writeCLine (ic); - } - /* - pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno); - pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, - printCLine(ic->filename, ic->lineno)); - */ - if (!options.noCcodeInAsm) { - addpCode2pBlock(pb, - newpCodeCSource(ic->lineno, - ic->filename, - printCLine(ic->filename, ic->lineno))); - } - - cln = ic->lineno ; - } + //DEBUGpic14_emitcode(";ic",""); + //fprintf (stderr, "in ic loop\n"); + //pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, + //ic->lineno, printCLine(ic->filename, ic->lineno)); - // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :) + if (!options.noCcodeInAsm && (cln != ic->lineno)) { + cln = ic->lineno; + //fprintf (stderr, "%s\n", printCLine (ic->filename, ic->lineno)); + cline = printCLine (ic->filename, ic->lineno); + if (!cline || strlen (cline) == 0) cline = printCLine (ic->filename, ic->lineno); + addpCode2pBlock (pb, newpCodeCSource (ic->lineno, ic->filename, cline)); + //emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, cline); + } + if (options.iCodeInAsm) { + emitpComment ("[ICODE] %s:%d: %s", ic->filename, ic->lineno, printILine (ic)); + } /* if the result is marked as spilt and rematerializable or code for this has already been generated then @@ -9914,12 +10760,12 @@ void genpic14Code (iCode *lic) break; case IPOP: - /* IPOP happens only when trying to restore a - spilt live range, if there is an ifx statement - following this pop then the if statement might - be using some of the registers being popped which - would destory the contents of the register so - we need to check for this condition and handle it */ + /* IPOP happens only when trying to restore a + spilt live range, if there is an ifx statement + following this pop then the if statement might + be using some of the registers being popped which + would destory the contents of the register so + we need to check for this condition and handle it */ if (ic->next && ic->next->op == IFX && regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) @@ -9989,7 +10835,7 @@ void genpic14Code (iCode *lic) case GE_OP: case NE_OP: - /* note these two are xlated by algebraic equivalence + /* note these two are xlated by algebraic equivalence during parsing SDCC.y */ werror(E_INTERNAL_ERROR,__FILE__,__LINE__, "got '>=' or '<=' shouldn't have come here"); @@ -10103,3 +10949,27 @@ void genpic14Code (iCode *lic) return; } + +int +aop_isLitLike (asmop *aop) +{ + assert (aop); + if (aop->type == AOP_LIT) return 1; + if (aop->type == AOP_IMMD) return 1; + if ((aop->type == AOP_PCODE) && + ((aop->aopu.pcop->type == PO_LITERAL) || (aop->aopu.pcop->type == PO_IMMEDIATE))) + { + /* this should be treated like a literal/immediate (use MOVLW/ADDLW/SUBLW + * instead of MOVFW/ADDFW/SUBFW, use popGetAddr instead of popGet) */ + return 1; + } + return 0; +} + +int +op_isLitLike (operand *op) +{ + assert (op); + if (aop_isLitLike (AOP(op))) return 1; + return 0; +}