static void mov2w (asmop *aop, int offset);
static void mov2f(asmop *dst, asmop *src, int offset);
static void mov2fp(pCodeOp *dst, asmop *src, int offset);
+static pCodeOp *pic16_popRegFromIdx(int rIdx);
+
//static int aopIdx (asmop *aop, int offset);
int pic16_labelOffset=0;
static int GpsuedoStkPtr=0;
pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
-pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst);
unsigned int pic16aopLiteral (value *val, int offset);
const char *pic16_AopType(short type);
int usefastretfie;
bitVect *fregsUsed;
int stack_lat; /* stack offset latency */
+ int resDirect;
+ int useWreg; /* flag when WREG is used to pass function parameter */
} _G;
/* Resolved ifx structure. This structure stores information
pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
else
DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
-
-// fprintf(stderr, "%s\n", pcop->name);
}
+void pic16_emitpinfo(INFO_TYPE itype, pCodeOp *pcop)
+{
+ if(pcop)
+ pic16_addpCode2pBlock(pb, pic16_newpCodeInfo(itype, pcop));
+ else
+ DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
+}
+
void pic16_emitpcodeNULLop(PIC_OPCODE poc)
{
DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+ _G.resDirect = 0; /* clear flag that instructs the result is loaded directly from aopForSym */
+
// sym = OP_SYMBOL(op);
/* if already has one */
aop->aopu.stk.stk = sym->stack;
aop->size = getSize(sym->type);
- for(i=0;i<aop->size;i++) {
- aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond( _G.fregsUsed, 0 );
- _G.fregsUsed = bitVectSetBit(_G.fregsUsed, PCOR(pcop[i])->r->rIdx);
- }
+
+ DEBUGpic16_emitcode("; +++", "%s:%d", __FILE__, __LINE__);
+ pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) ));
+ if((ic->op == '=') && IC_RESULT(ic) && AOP( IC_RESULT(ic) )
+ && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG) ) {
+
+ for(i=0;i<aop->size;i++)
+ aop->aopu.stk.pop[i] = pcop[i] = pic16_popRegFromIdx( AOP(IC_RESULT(ic))->aopu.aop_reg[i]->rIdx);
+ _G.resDirect = 1; /* notify that result will be loaded directly from aopForSym */
+ } else
+ for(i=0;i<aop->size;i++) {
+ aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond( _G.fregsUsed, 0 );
+ _G.fregsUsed = bitVectSetBit(_G.fregsUsed, PCOR(pcop[i])->r->rIdx);
+ }
+
// fprintf(stderr, "%s:%d\t%s\tsym size %d\n", __FILE__, __LINE__, __FUNCTION__, aop->size);
return aop;
}
#endif
+
+#if 0
+ /* special case for a function */
+ if (IS_FUNC(sym->type)) {
+ sym->aop = aop = newAsmop(AOP_PCODE);
+ //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
+ aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
+ PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+ PCOI(aop->aopu.pcop)->index = 0;
+ aop->size = FPTRSIZE;
+ DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
+ return aop;
+ }
+#endif
+
+
+
//DEBUGpic16_emitcode(";","%d",__LINE__);
/* if in bit space */
if (IN_BITSPACE(space)) {
return aop;
}
- if (IN_FARSPACE(space)) {
+
+ if (IN_FARSPACE(space) && !IN_CODESPACE(space)) {
sym->aop = aop = newAsmop (AOP_DIR);
aop->aopu.aop_dir = sym->rname ;
aop->size = getSize(sym->type);
return aop;
}
-#if 0 // patch 14
- /* special case for a function */
- if (IS_FUNC(sym->type)) {
- sym->aop = aop = newAsmop(AOP_IMMD);
- //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
- aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
- strcpy(aop->aopu.aop_immd,sym->rname);
- aop->size = FPTRSIZE;
- DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
- return aop;
- }
-#endif // patch 14
-
/* only remaining is far space */
- /* in which case DPTR gets the address */
sym->aop = aop = newAsmop(AOP_PCODE);
/* change the next if to 1 to revert to good old immediate code */
static asmop *aopForRemat (operand *op) // x symbol *sym)
{
symbol *sym = OP_SYMBOL(op);
+ operand *refop;
iCode *ic = NULL, *oldic;
asmop *aop = newAsmop(AOP_PCODE);
int val = 0;
}
offset = OP_SYMBOL(IC_LEFT(ic))->offset;
+ refop = IC_LEFT(ic);
if(!op->isaddr)viaimmd++; else viaimmd=0;
/* set the following if to 1 to revert to good old immediate code */
- if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
+ if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(refop)))
|| viaimmd) {
- DEBUGpic16_emitcode("%s:%d immediate", __FILE__, __LINE__);
+ DEBUGpic16_emitcode(";", "%s:%d immediate", __FILE__, __LINE__);
aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
PCOI(aop->aopu.pcop)->index = val;
} else {
- DEBUGpic16_emitcode("%s:%d dir", __FILE__, __LINE__);
+ DEBUGpic16_emitcode(";", "%s:%d dir", __FILE__, __LINE__);
aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname,
getSize( OP_SYMBOL( IC_LEFT(ic))->type), val, op);
if(aop1->type == AOP_ACC && aop2->type == AOP_ACC)return TRUE;
-#if 0
if (aop1->type != AOP_REG ||
aop2->type != AOP_REG )
return FALSE ;
-#endif
if (aop1->size != aop2->size )
return FALSE ;
- for (i = 0 ; i < aop1->size ; i++ )
- if (aop1->aopu.aop_reg[i] !=
- aop2->aopu.aop_reg[i] )
+ for (i = 0 ; i < aop1->size ; i++ ) {
+// if(aop1->aopu.aop_reg[i]->type != aop2->aopu.aop_reg[i]->type)return FALSE;
+
+// if(aop1->aopu.aop_reg[i]->type == AOP_REG)
+ if (strcmp(aop1->aopu.aop_reg[i]->name, aop2->aopu.aop_reg[i]->name ))
return FALSE ;
+ }
return TRUE ;
}
+bool pic16_sameRegsOfs(asmop *aop1, asmop *aop2, int offset)
+{
+ DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s (offset = %d)\n", __FUNCTION__,
+ pic16_AopType(aop1->type), pic16_AopType(aop2->type), offset);
+
+ if(aop1 == aop2)return TRUE;
+ if(aop1->type != AOP_REG || aop2->type != AOP_REG)return FALSE;
+
+ if(strcmp(aop1->aopu.aop_reg[offset]->name, aop2->aopu.aop_reg[offset]->name))return FALSE;
+
+ return TRUE;
+}
+
+
/*-----------------------------------------------------------------*/
/* pic16_aopOp - allocates an asmop for an operand : */
/*-----------------------------------------------------------------*/
/* rematerialize it NOW */
if (sym->remat) {
- sym->aop = op->aop = aop =
- aopForRemat (op);
+ sym->aop = op->aop = aop = aopForRemat (op);
aop->size = getSize(sym->type);
//DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
return;
if(_G.accInUse)pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
}
- for(i=0;i<aop->size;i++)
- PCOR(aop->aopu.stk.pop[i] )->r->isFree = 1;
+ if(!_G.resDirect) {
+ for(i=0;i<aop->size;i++)
+ PCOR(aop->aopu.stk.pop[i] )->r->isFree = 1;
+ }
+ _G.resDirect = 0;
}
break;
#if 0
PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
/* make sure that register doesn't exist,
- * and operand isn't NULL */
+ * and operand isn't NULL
+ * and symbol isn't in codespace (codespace symbols are handled elsewhere) */
if((PCOR(pcop)->r == NULL)
- && (op)) {
+ && (op)
+ && !IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(op)))) {
// fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
// __FUNCTION__, __LINE__, str, size, offset);
pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
pic16_emitpcode(POC_MOVWF, pic16_popGet(dst, offset));
} else {
+ if(pic16_sameRegsOfs(src, dst, offset))return;
pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popGet(src, offset),
pic16_popGet(dst, offset)));
}
int areg = 0; /* matching argument register */
areg = SPEC_ARGREG( OP_SYM_ETYPE( oper ) ) - 1;
- /* its called from genReceive (probably) */
- if(!GpsuedoStkPtr) {
+
+
+ /* its called from genReceive (probably) -- VR */
+ if(!GpsuedoStkPtr && _G.useWreg) {
// DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
+
/* The last byte in the assignment is in W */
if(areg <= GpsuedoStkPtr) {
size--;
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), offset /*size*/));
offset++;
}
- GpsuedoStkPtr++;
- _G.stack_lat = AOP_SIZE(oper)-1;
}
+// GpsuedoStkPtr++;
+ _G.stack_lat = AOP_SIZE(oper)-1;
while (size) {
-// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
-// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
- if(areg <= GpsuedoStkPtr) {
- size--;
- popaopidx(AOP(oper), offset, GpsuedoStkPtr);
- offset++;
- }
- GpsuedoStkPtr++;
+ size--;
+ GpsuedoStkPtr++;
+ popaopidx(AOP(oper), offset, GpsuedoStkPtr);
+ offset++;
}
}
}
/*-----------------------------------------------------------------*/
-/* genIpush - genrate code for pushing this gets a little complex */
+/* genIpush - generate code for pushing this gets a little complex */
/*-----------------------------------------------------------------*/
static void genIpush (iCode *ic)
{
sym_link *ftype;
int stackParms=0;
int use_wreg=0;
+ char *fname;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* initialise stackParms for IPUSH pushes */
// stackParms = psuedoStkPtr;
// fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes);
+ fname = OP_SYMBOL(IC_LEFT(ic))->rname[0]?OP_SYMBOL(IC_LEFT(ic))->rname:OP_SYMBOL(IC_LEFT(ic))->name;
+
+#if 0
+ gpsimDebug_StackDump(__FILE__, __LINE__, fname );
+#endif
/* if send set is not empty the assign */
if (_G.sendSet) {
}
*/
+
// stackParms = psuedoStkPtr;
stackParms = 0;
-
+ use_wreg = 0;
+
for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
int size, offset = 0;
}
/* save last parameter to stack if functions has varargs */
- if(IFFUNC_HASVARARGS(ftype))
- pushw();
- else
- use_wreg = 1; /* last parameter in WREG */
+ if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw();
+ else use_wreg = 1; /* last parameter in WREG */
_G.stackRegSet = _G.sendSet;
_G.sendSet = NULL;
- }
+ }
- /* make the call */
- pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
- OP_SYMBOL(IC_LEFT(ic))->rname :
- OP_SYMBOL(IC_LEFT(ic))->name));
+ /* make the call */
+ pic16_emitpcode(POC_CALL,pic16_popGetWithString(fname));
- GpsuedoStkPtr=0;
- /* if we need to assign a result value */
- if ((IS_ITEMP(IC_RESULT(ic))
- && (OP_SYMBOL(IC_RESULT(ic))->nRegs
- || OP_SYMBOL(IC_RESULT(ic))->spildir ))
- || IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
+ GpsuedoStkPtr=0;
+ /* if we need to assign a result value */
+ if ((IS_ITEMP(IC_RESULT(ic))
+ && (OP_SYMBOL(IC_RESULT(ic))->nRegs
+ || OP_SYMBOL(IC_RESULT(ic))->spildir ))
+ || IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
- _G.accInUse++;
- pic16_aopOp(IC_RESULT(ic),ic,FALSE);
- _G.accInUse--;
+ _G.accInUse++;
+ pic16_aopOp(IC_RESULT(ic),ic,FALSE);
+ _G.accInUse--;
- assignResultValue(IC_RESULT(ic), 1);
+ assignResultValue(IC_RESULT(ic), 1);
- DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
- pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
+ DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
+ pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
- pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
- }
+ pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
+ }
- if(!stackParms && ic->parmBytes) {
- stackParms = ic->parmBytes;
- }
+ if(!stackParms && ic->parmBytes) {
+ stackParms = ic->parmBytes;
+ }
- stackParms -= use_wreg;
+ stackParms -= use_wreg;
- if(stackParms>0) {
+ if(stackParms>0) {
+ if(stackParms == 1) {
+ pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1l));
+ } else {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
- if(STACK_MODEL_LARGE) {
- emitSKPNC;
- pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
- }
}
+ if(STACK_MODEL_LARGE) {
+ emitSKPNC;
+ pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
+ }
+ }
+
+#if 0
+ gpsimDebug_StackDump(__FILE__, __LINE__, fname);
+#endif
- /* adjust the stack for parameters if required */
-// fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
+ /* adjust the stack for parameters if required */
+// fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
#if 0
/* if register bank was saved then pop them */
pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
}
- if(IFFUNC_HASVARARGS(ftype))
- pushw();
- else
- use_wreg = 1; /* last parameter in WREG */
+ if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw();
+ else use_wreg = 1; /* last parameter in WREG */
_G.stackRegSet = _G.sendSet;
_G.sendSet = NULL;
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh));
pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0));
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
-
+
/* make the call by writing the pointer into pc */
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
symbol *sym;
sym_link *ftype;
- DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key);
+ DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key);
- pic16_labelOffset += (max_key+4);
- max_key=0;
- GpsuedoStkPtr=0;
- _G.nRegsSaved = 0;
+ pic16_labelOffset += (max_key+4);
+ max_key=0;
+ GpsuedoStkPtr=0;
+ _G.nRegsSaved = 0;
- ftype = operandType(IC_LEFT(ic));
- sym = OP_SYMBOL(IC_LEFT(ic));
+ ftype = operandType(IC_LEFT(ic));
+ sym = OP_SYMBOL(IC_LEFT(ic));
- if(IFFUNC_ISISR(sym->type /*ftype*/)) {
- /* create an absolute section at the interrupt vector:
- * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
- symbol *asym;
- char asymname[128];
- pBlock *apb;
+ if(IFFUNC_ISISR(sym->type /*ftype*/)) {
+ /* create an absolute section at the interrupt vector:
+ * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
+ symbol *asym;
+ char asymname[128];
+ pBlock *apb;
- {
- int i, found=-1;
-
- sym = OP_SYMBOL( IC_LEFT(ic));
- for(i=0;i<=2;i++) {
- if(interrupts[i]->name
- && !STRCASECMP(interrupts[i]->name, sym->name)) {
- found = i;
- break;
- }
- }
+ {
+ int i, found=-1;
+
+ sym = OP_SYMBOL( IC_LEFT(ic));
+ for(i=0;i<=2;i++) {
+ if(interrupts[i]->name
+ && !STRCASECMP(interrupts[i]->name, sym->name)) {
+ found = i;
+ break;
+ }
+ }
- if(found == -1) {
- fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
- __FILE__, __LINE__, sym->name);
- assert( 0 );
- }
- _G.interruptvector = found;
- }
-
- sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
- asym = newSymbol(asymname, 0);
-
- apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
- pic16_addpBlock( apb );
-
- pic16_addpCode2pBlock(apb,
- pic16_newpCodeCharP(";-----------------------------------------"));
+ if(found == -1) {
+ fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
+ __FILE__, __LINE__, sym->name);
+ assert( 0 );
+ }
+ _G.interruptvector = found;
+ }
+ sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
+ asym = newSymbol(asymname, 0);
- pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
+ apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
+ pic16_addpBlock( apb );
- pic16_addpCode2pBlock(apb,
- pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
+ pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------"));
+ pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
+ pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
- /* mark the end of this tiny function */
- pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
-
- {
- absSym *abSym;
+ /* mark the end of this tiny function */
+ pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
- abSym = Safe_calloc(1, sizeof(absSym));
- abSym->name = Safe_strdup( asymname );
-
- switch( _G.interruptvector ) {
- case 0: abSym->address = 0x000000; break;
- case 1: abSym->address = 0x000008; break;
- case 2: abSym->address = 0x000018; break;
- }
-
- /* relocate interrupt vectors if needed */
- abSym->address += pic16_options.ivt_loc;
-
- addSet(&absSymSet, abSym);
- }
- }
+ {
+ absSym *abSym;
+ abSym = Safe_calloc(1, sizeof(absSym));
+ strcpy(abSym->name, asymname);
- /* create the function header */
- pic16_emitcode(";","-----------------------------------------");
- pic16_emitcode(";"," function %s",sym->name);
- pic16_emitcode(";","-----------------------------------------");
+ switch( _G.interruptvector ) {
+ case 0: abSym->address = 0x000000; break;
+ case 1: abSym->address = 0x000008; break;
+ case 2: abSym->address = 0x000018; break;
+ }
- pic16_emitcode("","%s:",sym->rname);
- pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
+ /* relocate interrupt vectors if needed */
+ abSym->address += pic16_options.ivt_loc;
+ addSet(&absSymSet, abSym);
+ }
+ }
- {
- absSym *ab;
+ /* create the function header */
+ pic16_emitcode(";","-----------------------------------------");
+ pic16_emitcode(";"," function %s",sym->name);
+ pic16_emitcode(";","-----------------------------------------");
- for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
- if(!strcmp(ab->name, sym->name)) {
- pic16_pBlockConvert2Absolute(pb);
- break;
- }
+ pic16_emitcode("","%s:",sym->rname);
+ pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
- }
+ {
+ absSym *ab;
- if(IFFUNC_ISNAKED(ftype)) {
- DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
- return;
- }
-
- /* if critical function then turn interrupts off */
- if (IFFUNC_ISCRITICAL(ftype)) {
- //pic16_emitcode("clr","ea");
+ for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet)) {
+ if(!strcmp(ab->name, sym->rname)) {
+ pic16_pBlockConvert2Absolute(pb);
+ break;
+ }
}
+ }
- _G.fregsUsed = sym->regsUsed;
-
- /* if this is an interrupt service routine then
- * save acc, b, dpl, dph */
- if (IFFUNC_ISISR(sym->type)) {
- int i;
-
- _G.usefastretfie = 1; /* use shadow registers by default */
- /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
- if(!(_G.interruptvector == 1)) {
- /* do not save WREG,STATUS,BSR for high priority interrupts
- * because they are stored in the hardware shadow registers already */
- _G.usefastretfie = 0;
- pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
- pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
- pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
- }
+ if(IFFUNC_ISNAKED(ftype)) {
+ DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
+ return;
+ }
+
+ /* if critical function then turn interrupts off */
+ if (IFFUNC_ISCRITICAL(ftype)) {
+ //pic16_emitcode("clr","ea");
+ }
+ _G.fregsUsed = sym->regsUsed;
- /* these should really be optimized somehow, because not all
- * interrupt handlers modify them */
- pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
- pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
- pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
- pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
+ /* if this is an interrupt service routine then
+ * save wreg, status, bsr, prodl, prodh, fsr0l, fsr0h */
+ if (IFFUNC_ISISR(sym->type)) {
+ _G.usefastretfie = 1; /* use shadow registers by default */
+
+ /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
+ if(!(_G.interruptvector == 1)) {
+ /* do not save WREG,STATUS,BSR for high priority interrupts
+ * because they are stored in the hardware shadow registers already */
+ _G.usefastretfie = 0;
+ pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
+ pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
+ pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
+ }
-// pic16_pBlockConvert2ISR(pb);
+ /* these should really be optimized somehow, because not all
+ * interrupt handlers modify them */
+ pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
+ pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
+ pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
+ pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
+
+// pic16_pBlockConvert2ISR(pb);
- /* if any registers used */
- if (sym->regsUsed) {
- /* save the registers used */
- DEBUGpic16_emitcode("; **", "Saving used registers in stack");
- for ( i = 0 ; i < sym->regsUsed->size ; i++) {
- if (bitVectBitValue(sym->regsUsed,i)) {
-#if 0
- fprintf(stderr, "%s:%d function %s uses register %s\n",
- __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
- pic16_regWithIdx(i)->name);
-#endif
-
- pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
- _G.nRegsSaved++;
-
- if(!pic16_regWithIdx(i)->wasUsed) {
- fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
- __FILE__, __LINE__, pic16_regWithIdx(i)->name);
+ }
- pic16_regWithIdx(i)->wasUsed = 1;
- }
- }
- }
- }
- } else {
- /* emit code to setup stack frame if user enabled,
- * and function is not main() */
+ /* emit code to setup stack frame if user enabled,
+ * and function is not main() */
-// fprintf(stderr, "function name: %s\n", sym->name);
- if(strcmp(sym->name, "main")) {
- if(/*!options.ommitFramePtr || sym->regsUsed*/1) {
- /* setup the stack frame */
- pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
- pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
- if(STACK_MODEL_LARGE)
- pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
- }
- }
-
- /* if callee-save to be used for this function
- * then save the registers being used in this function */
-// if (IFFUNC_CALLEESAVES(sym->type))
- {
- int i;
-
-// fprintf(stderr, "%s:%d function sym->regsUsed= %d\n", __FILE__, __LINE__, sym->regsUsed->size);
-
-// pic16_emitpcomment("entry regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
-
- /* if any registers used */
- if (sym->regsUsed) {
- /* save the registers used */
- DEBUGpic16_emitcode("; **", "Saving used registers in stack");
- for ( i = 0 ; i < sym->regsUsed->size ; i++) {
- if (bitVectBitValue(sym->regsUsed,i)) {
-
-#if 0
- fprintf(stderr, "%s:%d function %s uses register %s (wasUsed: %d, %p)\n",
- __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
- pic16_regWithIdx(i)->name,
- pic16_regWithIdx(i)->wasUsed,
- pic16_regWithIdx(i));
-#endif
-
- pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
-
-// pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
-// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
-// &pic16_pc_postdec1, 0));
+ //fprintf(stderr, "function name: %s\n", sym->name);
+ if(strcmp(sym->name, "main")) {
+ if(1 /*!options.ommitFramePtr || sym->regsUsed*/) {
+ /* setup the stack frame */
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
+ if(STACK_MODEL_LARGE)
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
+ }
+ }
- _G.nRegsSaved++;
+ if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
+ && sym->stack) {
- if(!pic16_regWithIdx(i)->wasUsed) {
- fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
- __FILE__, __LINE__, pic16_regWithIdx(i)->name);
+ if (sym->stack > 127)werror(W_STACK_OVERFLOW, sym->name);
- pic16_regWithIdx(i)->wasUsed = 1;
- }
-
- }
- }
- }
- }
- }
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
+ pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_fsr1l));
+ emitSKPNC;
+ pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_fsr1h));
+ }
+
+ if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type))
+ _G.useWreg = 0;
+ else _G.useWreg = 1;
+ /* if callee-save to be used for this function
+ * then save the registers being used in this function */
+// if (IFFUNC_CALLEESAVES(sym->type))
+ {
+ int i;
+ /* if any registers used */
+ if (sym->regsUsed) {
+ /* save the registers used */
+ DEBUGpic16_emitcode("; **", "Saving used registers in stack");
+ pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
+ for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+ if (bitVectBitValue(sym->regsUsed,i)) {
+ pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
+ _G.nRegsSaved++;
+
+ if(!pic16_regWithIdx(i)->wasUsed) {
+ fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
+ __FILE__, __LINE__, pic16_regWithIdx(i)->name);
+ pic16_regWithIdx(i)->wasUsed = 1;
+ }
+ }
+ }
+ pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_END));
+ }
+ }
-#if 0
- if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
-
- if (options.useXstack) {
- pic16_emitcode("mov","r0,%s",spname);
- pic16_emitcode("mov","a,_bp");
- pic16_emitcode("movx","@r0,a");
- pic16_emitcode("inc","%s",spname);
- } else {
- /* set up the stack */
- pic16_emitcode ("push","_bp"); /* save the callers stack */
- }
- pic16_emitcode ("mov","_bp,%s",spname);
- }
-#endif
- DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
-
- /* adjust the stack for the function */
- if (sym->stack) {
- int i = sym->stack;
-
- if (i > 127 )
- werror(W_STACK_OVERFLOW,sym->name);
-
- if (i > 3 && sym->recvSize < 4) {
- pic16_emitcode ("mov","a,sp");
- pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
- pic16_emitcode ("mov","sp,a");
- } else
- while(i--)
- pic16_emitcode("inc","sp");
- }
-
- if (sym->xstack) {
- DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
-
- pic16_emitcode ("mov","a,_spx");
- pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
- pic16_emitcode ("mov","_spx,a");
- }
-
+ DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
+// fprintf(stderr, "Function '%s' uses %d bytes of stack\n", sym->name, sym->stack);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genEndFunction (iCode *ic)
{
- symbol *sym = OP_SYMBOL(IC_LEFT(ic));
+ symbol *sym = OP_SYMBOL(IC_LEFT(ic));
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(IFFUNC_ISNAKED(sym->type)) {
- DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
- return;
+ DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
+ return;
}
_G.stack_lat = 0;
/* TODO: add code here -- VR */
}
-
-#if 0
- if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
- {
- pic16_emitcode ("mov","%s,_bp",spname);
+ if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
+ && sym->stack) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
+ pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(&pic16_pc_fsr1l));
+ emitSKPNC;
+ pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h));
}
-#endif
- /* if use external stack but some variables were
- added to the local stack then decrement the
- local stack */
- if (options.useXstack && sym->stack) {
- pic16_emitcode("mov","a,sp");
- pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
- pic16_emitcode("mov","sp,a");
- }
+ /* now we need to restore the registers */
+ /* if any registers used */
+ if (sym->regsUsed) {
+ int i;
+ pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_BEGIN));
+ /* restore registers used */
+ DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
+ for ( i = sym->regsUsed->size; i >= 0; i--) {
+ if (bitVectBitValue(sym->regsUsed,i)) {
+ pic16_poppCodeOp( pic16_popRegFromIdx(i) );
+ _G.nRegsSaved--;
+ }
+ }
+ pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END));
-#if 0
- if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
- if (options.useXstack) {
- pic16_emitcode("mov","r0,%s",spname);
- pic16_emitcode("movx","a,@r0");
- pic16_emitcode("mov","_bp,a");
- pic16_emitcode("dec","%s",spname);
- }
- else
- {
- pic16_emitcode ("pop","_bp");
- }
}
-#endif
- if (IFFUNC_ISISR(sym->type)) {
- /* now we need to restore the registers */
- /* if any registers used */
- if (sym->regsUsed) {
- int i;
-
- /* restore registers used */
- DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
- for ( i = sym->regsUsed->size; i >= 0; i--) {
- if (bitVectBitValue(sym->regsUsed,i)) {
-
-// fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
-// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
-// pic16_regWithIdx(i)->name);
-
- pic16_poppCodeOp( pic16_popRegFromIdx(i) );
+ if(strcmp(sym->name, "main")) {
+ if(1/*!options.ommitFramePtr ||*/ /*sym->regsUsed*/) {
+ /* restore stack frame */
+ if(STACK_MODEL_LARGE)
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
+ }
+ }
-// pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
-// &pic16_pc_preinc1,
-// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+ _G.useWreg = 0;
- }
- }
- }
-
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
-
- if(!(_G.interruptvector == 1)) {
- /* do not restore interrupt vector for WREG,STATUS,BSR
- * for high priority interrupt, see genFunction */
-
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
- }
-
- _G.interruptvector = 0; /* sanity check */
+ if (IFFUNC_ISISR(sym->type)) {
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
-// pic16_pBlockConvert2ISR(pb);
+ if(!(_G.interruptvector == 1)) {
+ /* do not restore interrupt vector for WREG,STATUS,BSR
+ * for high priority interrupt, see genFunction */
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
+ }
+ _G.interruptvector = 0; /* sanity check */
- /* if debug then send end of function */
-/* if (options.debug && currFunc) */
- if (currFunc) {
- debugFile->writeEndFunction (currFunc, ic, 1);
- }
-
- if(_G.usefastretfie)
- pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1));
- else
- pic16_emitpcodeNULLop(POC_RETFIE);
- _G.usefastretfie = 0;
- } else {
- if (IFFUNC_ISCRITICAL(sym->type))
- pic16_emitcode("setb","ea");
+ /* if debug then send end of function */
+/* if (options.debug && currFunc) */
+ if (currFunc) {
+ debugFile->writeEndFunction (currFunc, ic, 1);
+ }
+ if(_G.usefastretfie)
+ pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1));
+ else
+ pic16_emitpcodeNULLop(POC_RETFIE);
-// pic16_emitpcomment("exit regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
+ pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
+
+ _G.usefastretfie = 0;
+ return;
+ }
- /* if any registers used */
- if (sym->regsUsed) {
- int i;
- /* save the registers used */
- DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
- for ( i = sym->regsUsed->size; i >= 0; i--) {
- if (bitVectBitValue(sym->regsUsed,i)) {
-
-// fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
-// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
-// pic16_regWithIdx(i)->name);
-
- pic16_poppCodeOp( pic16_popRegFromIdx(i) );
-
-// pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
-// &pic16_pc_preinc1,
-// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+ if (IFFUNC_ISCRITICAL(sym->type)) {
+ pic16_emitcode("setb","ea");
+ }
- _G.nRegsSaved--;
- }
- }
- }
-
-// pic16_emitpcomment("%s: _G.nRegsSaved upon exit from function: %d\n", __FUNCTION__, _G.nRegsSaved);
- /* if debug then send end of function */
- if (currFunc) {
- debugFile->writeEndFunction (currFunc, ic, 1);
- }
+ /* if debug then send end of function */
+ if (currFunc) {
+ debugFile->writeEndFunction (currFunc, ic, 1);
+ }
- /* insert code to restore stack frame, if user enabled it
- * and function is not main() */
+ /* insert code to restore stack frame, if user enabled it
+ * and function is not main() */
- if(strcmp(sym->name, "main")) {
- if(1/*!options.ommitFramePtr ||*/ /*sym->regsUsed*/) {
- /* restore stack frame */
- if(STACK_MODEL_LARGE)
- pic16_emitpcode(POC_MOVFF,
- pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
- pic16_emitpcode(POC_MOVFF,
- pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
- }
- }
-
- pic16_emitpcodeNULLop(POC_RETURN);
-
- /* Mark the end of a function */
- pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
- }
+ pic16_emitpcodeNULLop(POC_RETURN);
+ /* Mark the end of a function */
+ pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
}
void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
{
-
- if(is_LitOp(op)) {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset)); // patch 12
-
- if(dest->type != PO_WREG)
- pic16_emitpcode(POC_MOVWF, dest);
- } else {
- if(dest->type == PO_WREG && (offset == 0)) {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
- return;
- }
-
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popGet(AOP(op), offset), dest));
- }
-}
+ if(is_LitOp(op)) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset));
+ if(dest->type != PO_WREG)pic16_emitpcode(POC_MOVWF, dest);
+ } else {
+ if(dest->type == PO_WREG && (offset == 0)) {
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
+ return;
+ }
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op), offset), dest));
+ }
+}
/*-----------------------------------------------------------------*/
/* genRet - generate code for return statement */
/*-----------------------------------------------------------------*/
/* genCmp :- greater or less than comparison */
/*-----------------------------------------------------------------*/
+#if 1
static void genCmp (operand *left,operand *right,
operand *result, iCode *ifx, int sign)
{
}
- if(size == 1) {
+ if(size == 1) {
+
+ if( (lit & 0xff) == 0) {
+ /* lower byte is zero */
+ DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+ i = ((lit >> 8) & 0xff) ^0x80;
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
+ genSkipc(&rFalseIfx);
+
+
+ if(ifx) ifx->generated = 1;
+ return;
+
+ }
+ } else {
+ /* Special cases for signed longs */
+ if( (lit & 0xffffff) == 0) {
+ /* lower byte is zero */
+ DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+ i = ((lit >> 8*3) & 0xff) ^0x80;
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
+ genSkipc(&rFalseIfx);
+
+
+ if(ifx) ifx->generated = 1;
+ return;
+
+ }
+
+ }
+
+
+ if(lit & (0x80 << (size*8))) {
+ /* lit is negative */
+ DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+
+ //genSkipCond(&rFalseIfx,left,size,7);
+
+ pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+
+ if(rFalseIfx.condition)
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+ else
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+
+
+ } else {
+ /* lit is positive */
+ DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ if(rFalseIfx.condition)
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ else
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+
+ }
+
+ /*
+ This works, but is only good for ints.
+ It also requires a "known zero" register.
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
+ pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
+ pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
+ genSkipc(&rFalseIfx);
+
+ pic16_emitpLabel(truelbl->key);
+ if(ifx) ifx->generated = 1;
+ return;
+ **/
+
+ /* There are no more special cases, so perform a general compare */
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+
+ while(size--) {
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
+ emitSKPNZ;
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+ }
+ //rFalseIfx.condition ^= 1;
+ genSkipc(&rFalseIfx);
+
+ pic16_emitpLabel(truelbl->key);
+
+ if(ifx) ifx->generated = 1;
+ return;
+
+
+ }
+
+
+ /* sign is out of the way. So now do an unsigned compare */
+ DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
+
+
+ /* General case - compare to an unsigned literal on the right.*/
+
+ i = (lit >> (size*8)) & 0xff;
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+ while(size--) {
+ i = (lit >> (size*8)) & 0xff;
+
+ if(i) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
+ emitSKPNZ;
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+ } else {
+ /* this byte of the lit is zero,
+ *if it's not the last then OR in the variable */
+ if(size)
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
+ }
+ }
+
+
+ pic16_emitpLabel(lbl->key);
+// pic16_emitpLabel(truelbl->key);
+ //if(emitFinalCheck)
+ genSkipc(&rFalseIfx);
+ if(sign)
+ pic16_emitpLabel(truelbl->key);
+
+ if(ifx) ifx->generated = 1;
+ return;
+
+
+ }
+#endif // _swapp
+
+ if(AOP_TYPE(left) == AOP_LIT) {
+ //symbol *lbl = newiTempLabel(NULL);
+
+ //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
+
+
+ DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
+
+ /* Special cases */
+ if((lit == 0) && (sign == 0)){
+
+ size--;
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+ while(size)
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
+
+ genSkipz2(&rFalseIfx,0);
+ if(ifx) ifx->generated = 1;
+ return;
+ }
+
+ if(size==1) {
+ /* Special cases */
+ lit &= 0xff;
+ if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
+ /* degenerate compare can never be true */
+ if(rFalseIfx.condition == 0)
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
+
+ if(ifx) ifx->generated = 1;
+ return;
+ }
+
+ if(sign) {
+ /* signed comparisons to a literal byte */
+
+ int lp1 = (lit+1) & 0xff;
+
+ DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
+ switch (lp1) {
+ case 0:
+ rFalseIfx.condition ^= 1;
+ genSkipCond(&rFalseIfx,right,0,7);
+ break;
+ case 0x7f:
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
+ genSkipz2(&rFalseIfx,1);
+ break;
+ default:
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
+ rFalseIfx.condition ^= 1;
+ genSkipc(&rFalseIfx);
+ break;
+ }
+ } else {
+ /* unsigned comparisons to a literal byte */
+
+ switch(lit & 0xff ) {
+ case 0:
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
+ genSkipz2(&rFalseIfx,0);
+ break;
+ case 0x7f:
+ rFalseIfx.condition ^= 1;
+ genSkipCond(&rFalseIfx,right,0,7);
+ break;
+
+ default:
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ rFalseIfx.condition ^= 1;
+ if (AOP_TYPE(result) == AOP_CRY)
+ genSkipc(&rFalseIfx);
+ else {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
+ }
+ break;
+ }
+ }
+
+ if(ifx) ifx->generated = 1;
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ goto check_carry;
+ return;
+
+ } else {
+
+ /* Size is greater than 1 */
+
+ if(sign) {
+ int lp1 = lit+1;
+
+ size--;
+
+ if(lp1 == 0) {
+ /* this means lit = 0xffffffff, or -1 */
+
+
+ DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
+ rFalseIfx.condition ^= 1;
+ genSkipCond(&rFalseIfx,right,size,7);
+ if(ifx) ifx->generated = 1;
+
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ goto check_carry;
+
+ return;
+ }
+
+ if(lit == 0) {
+ int s = size;
+
+ if(rFalseIfx.condition) {
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+ }
+
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+ while(size--)
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
+
+
+ emitSKPZ;
+ if(rFalseIfx.condition) {
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ pic16_emitpLabel(truelbl->key);
+ }else {
+ rFalseIfx.condition ^= 1;
+ genSkipCond(&rFalseIfx,right,s,7);
+ }
+
+ if(ifx) ifx->generated = 1;
+
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ goto check_carry;
+
+ return;
+ }
+
+ if((size == 1) && (0 == (lp1&0xff))) {
+ /* lower byte of signed word is zero */
+ DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
+ i = ((lp1 >> 8) & 0xff) ^0x80;
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
+ rFalseIfx.condition ^= 1;
+ genSkipc(&rFalseIfx);
+
+
+ if(ifx) ifx->generated = 1;
+
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ goto check_carry;
+
+ return;
+ }
+
+ if(lit & (0x80 << (size*8))) {
+ /* Lit is less than zero */
+ DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
+ //rFalseIfx.condition ^= 1;
+ //genSkipCond(&rFalseIfx,left,size,7);
+ //rFalseIfx.condition ^= 1;
+ pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+
+ if(rFalseIfx.condition)
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ else
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+
+
+ } else {
+ /* Lit is greater than or equal to zero */
+ DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
+ //rFalseIfx.condition ^= 1;
+ //genSkipCond(&rFalseIfx,right,size,7);
+ //rFalseIfx.condition ^= 1;
+
+ //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
+ //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ if(rFalseIfx.condition)
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+ else
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+
+ }
+
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
+
+ while(size--) {
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
+ emitSKPNZ;
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
+ }
+ rFalseIfx.condition ^= 1;
+ //rFalseIfx.condition = 1;
+ genSkipc(&rFalseIfx);
+
+ pic16_emitpLabel(truelbl->key);
+
+ if(ifx) ifx->generated = 1;
+
+
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ goto check_carry;
+
+ return;
+ // end of if (sign)
+ } else {
+
+ /* compare word or long to an unsigned literal on the right.*/
+
+
+ size--;
+ if(lit < 0xff) {
+ DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
+ switch (lit) {
+ case 0:
+ break; /* handled above */
+/*
+ case 0xff:
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+ while(size--)
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
+ genSkipz2(&rFalseIfx,0);
+ break;
+*/
+ default:
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+ while(--size)
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
+
+ emitSKPZ;
+ if(rFalseIfx.condition)
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ else
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
+
+ rFalseIfx.condition ^= 1;
+ genSkipc(&rFalseIfx);
+ }
+
+ pic16_emitpLabel(truelbl->key);
+
+ if(ifx) ifx->generated = 1;
+
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ goto check_carry;
+
+ return;
+ }
+
+
+ lit++;
+ DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
+ i = (lit >> (size*8)) & 0xff;
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
+
+ while(size--) {
+ i = (lit >> (size*8)) & 0xff;
+
+ if(i) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
+ emitSKPNZ;
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
+ } else {
+ /* this byte of the lit is zero,
+ * if it's not the last then OR in the variable */
+ if(size)
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
+ }
+ }
+
+
+ pic16_emitpLabel(lbl->key);
+
+ rFalseIfx.condition ^= 1;
+
+ genSkipc(&rFalseIfx);
+ }
+
+ if(sign)
+ pic16_emitpLabel(truelbl->key);
+ if(ifx) ifx->generated = 1;
- if( (lit & 0xff) == 0) {
- /* lower byte is zero */
- DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
- i = ((lit >> 8) & 0xff) ^0x80;
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
- genSkipc(&rFalseIfx);
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ goto check_carry;
+ return;
+ }
+ }
+ /* Compare two variables */
- if(ifx) ifx->generated = 1;
- return;
+ DEBUGpic16_emitcode(";sign","%d",sign);
- }
- } else {
- /* Special cases for signed longs */
- if( (lit & 0xffffff) == 0) {
- /* lower byte is zero */
- DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
- i = ((lit >> 8*3) & 0xff) ^0x80;
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
- genSkipc(&rFalseIfx);
+ size--;
+ if(sign) {
+ /* Sigh. thus sucks... */
+ if(size) {
+ pCodeOp *pctemp;
+
+ pctemp = pic16_popGetTempReg(1);
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
+ pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
+ pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
+ pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_popReleaseTempReg(pctemp, 1);
+ } else {
+ /* Signed char comparison */
+ /* Special thanks to Nikolai Golovchenko for this snippet */
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
+ pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ genSkipc(&rFalseIfx);
+
+ if(ifx) ifx->generated = 1;
- if(ifx) ifx->generated = 1;
- return;
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ goto check_carry;
- }
+ return;
+ }
- }
+ } else {
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+ }
- if(lit & (0x80 << (size*8))) {
- /* lit is negative */
- DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
- //genSkipCond(&rFalseIfx,left,size,7);
+ /* The rest of the bytes of a multi-byte compare */
+ while (size) {
- pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ emitSKPZ;
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
+ size--;
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
- } else {
- /* lit is positive */
- DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+ }
- }
+ pic16_emitpLabel(lbl->key);
- /*
- This works, but is only good for ints.
- It also requires a "known zero" register.
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
- genSkipc(&rFalseIfx);
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
+ (AOP_TYPE(result) == AOP_REG)) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
+ } else {
+ genSkipc(&rFalseIfx);
+ }
+ //genSkipc(&rFalseIfx);
+ if(ifx) ifx->generated = 1;
- pic16_emitpLabel(truelbl->key);
- if(ifx) ifx->generated = 1;
- return;
- **/
-
- /* There are no more special cases, so perform a general compare */
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
- while(size--) {
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ goto check_carry;
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
- emitSKPNZ;
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
- }
- //rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
+ return;
- pic16_emitpLabel(truelbl->key);
+ }
- if(ifx) ifx->generated = 1;
- return;
+check_carry:
+ if ((AOP_TYPE(result) != AOP_CRY)
+ && AOP_SIZE(result)) {
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
- }
+ pic16_outBitC(result);
+ } else {
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* if the result is used in the next
+ ifx conditional branch then generate
+ code a little differently */
+ if (ifx )
+ genIfxJump (ifx,"c");
+ else
+ pic16_outBitC(result);
+ /* leave the result in acc */
+ }
+}
- /* sign is out of the way. So now do an unsigned compare */
- DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
+#else /* old version of genCmp() */
+/* new version of genCmp -- VR 20041012 */
+static void genCmp (operand *left,operand *right,
+ operand *result, iCode *ifx, int sign)
+{
+ int size; //, offset = 0 ;
+ unsigned long lit = 0L,i = 0;
+ resolvedIfx rFalseIfx;
+ int willCheckCarry=0;
+ // resolvedIfx rTrueIfx;
+ symbol *truelbl;
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* General case - compare to an unsigned literal on the right.*/
- i = (lit >> (size*8)) & 0xff;
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
- while(size--) {
- i = (lit >> (size*8)) & 0xff;
+ /* General concept:
+ * subtract right from left if at the end the carry flag is set then we
+ * know that left is greater than right */
+
+ resolveIfx(&rFalseIfx,ifx);
+ truelbl = newiTempLabel(NULL);
+ size = max(AOP_SIZE(left),AOP_SIZE(right));
- if(i) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
- emitSKPNZ;
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
- } else {
- /* this byte of the lit is zero,
- *if it's not the last then OR in the variable */
- if(size)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
- }
- }
+ DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+ /* POC_CPFSGT compare f, wreg, skip if f greater than wreg
+ * POC_CPFSLT compare f, wreg, skip if f less then wreg */
+
- pic16_emitpLabel(lbl->key);
-// pic16_emitpLabel(truelbl->key);
- //if(emitFinalCheck)
- genSkipc(&rFalseIfx);
- if(sign)
- pic16_emitpLabel(truelbl->key);
+ /* if literal is on the right then swap with left */
+ if ((AOP_TYPE(right) == AOP_LIT)) {
+ operand *tmp = right ;
+ unsigned long mask = (0x100 << (8*(size-1))) - 1;
- if(ifx) ifx->generated = 1;
- return;
+ lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+// lit = (lit - 1) & mask;
+ right = left;
+ left = tmp;
+ rFalseIfx.condition ^= 1;
+ } else
+ if ((AOP_TYPE(left) == AOP_LIT)) {
+ /* float compares are handled by support functions */
+ lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
+ }
- }
-#endif // _swapp
- if(AOP_TYPE(left) == AOP_LIT) {
- //symbol *lbl = newiTempLabel(NULL);
+ //if(IC_TRUE(ifx) == NULL)
+ /* if left & right are bit variables */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ AOP_TYPE(right) == AOP_CRY ) {
+ pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+ pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
- //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
+ } else {
+ symbol *lbl = newiTempLabel(NULL);
+ if(AOP_TYPE(left) == AOP_LIT) {
+ DEBUGpic16_emitcode(";left lit","lit = 0x%x, sign=%d",lit,sign);
- DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ willCheckCarry = 1;
+ else willCheckCarry = 0;
/* Special cases */
if((lit == 0) && (sign == 0)){
int lp1 = (lit+1) & 0xff;
- DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
+ DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x condition = %d",__LINE__,lit, rFalseIfx.condition);
switch (lp1) {
case 0:
rFalseIfx.condition ^= 1;
genSkipz2(&rFalseIfx,1);
break;
default:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit ));
+
+ if(rFalseIfx.condition)
+ pic16_emitpcode(POC_CPFSLT, pic16_popGet(AOP(right), 0));
+ else
+ pic16_emitpcode(POC_CPFSGT, pic16_popGet(AOP(right), 0));
+
+ if(willCheckCarry) {
+ if(!rFalseIfx.condition) { emitCLRC; emitSETC; }
+ else { emitSETC; emitCLRC; }
+
+ } else {
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ }
+
+/* pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
rFalseIfx.condition ^= 1;
genSkipc(&rFalseIfx);
+*/
break;
}
} else {
}
}
+#endif
+
+
/*-----------------------------------------------------------------*/
/* genCmpGt :- greater than comparison */
} else { /* we need to get it byte by byte */
- /* set up WREG:FSR0H:FSR0L with address from left */
+ /* set up WREG:PRODL:FSR0L with address from left */
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_prodl)));
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 2));
switch( size ) {
sym = newSymbol( fgptrget, 0 );
strcpy(sym->rname, fgptrget);
checkAddSym(&externs, sym);
+
// fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget);
}
while (size--) {
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) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
- } else {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
- }
- } else {
- mov2w(AOP(right), offset);
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
- }
+ unsigned int lit;
+
+ if(!IS_FLOAT(operandType( right )))
+ lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
+ else {
+ union {
+ unsigned long lit_int;
+ float lit_float;
+ } info;
+
+ /* take care if literal is a float */
+ info.lit_float = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
+ lit = info.lit_int;
+ }
+
+ lit = lit >> (8*offset);
+ if(lit&0xff) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
+ } else {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
+ }
+ } else {
+ mov2w(AOP(right), offset);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
+ }
offset++;
resoffset++;
}
DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
- /* load value to write in TBLPTRH:TBLPTRL:PRODH:PRODL */
- mov2fp(pic16_popCopyReg(&pic16_pc_prodl), AOP(right), 0);
+
+ /* load value to write in TBLPTRH:TBLPTRL:PRODH:[stack] */
+
+ /* value of right+0 is placed on stack, which will be retrieved
+ * by the support function this restoring the stack. The important
+ * thing is that there is no need to manually restore stack pointer
+ * here */
+ mov2fp(pic16_popCopyReg(&pic16_pc_postdec1), AOP(right), 0);
if(size>1)mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), 1);
if(size>2)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(right), 2);
if(size>3)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(right), 3);
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 0),
pic16_popCopyReg(&pic16_pc_fsr0l)));
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 1),
- pic16_popCopyReg(&pic16_pc_fsr0h)));
+ pic16_popCopyReg(&pic16_pc_prodl)));
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 2));
switch (size) {
case 1: strcpy(fgptrput, "__gptrput1"); break;
case 2: strcpy(fgptrput, "__gptrput2"); break;
+ case 3: strcpy(fgptrput, "__gptrput3"); break;
case 4: strcpy(fgptrput, "__gptrput4"); break;
default:
werror(W_POSSBUG2, __FILE__, __LINE__);
sym = newSymbol( fgptrput, 0 );
strcpy(sym->rname, fgptrput);
checkAddSym(&externs, sym);
-// fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget);
}
release:
if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
return ;
- pic16_aopOp(right,ic,FALSE);
+ /* reversed order operands are aopOp'ed so that result operand
+ * is effective in case right is a stack symbol. This maneauver
+ * allows to use the _G.resDirect flag later */
pic16_aopOp(result,ic,TRUE);
+ pic16_aopOp(right,ic,FALSE);
DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
// sizeof(unsigned long int), sizeof(float));
if(AOP_TYPE(right) != AOP_LIT
- && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))) {
+ && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))
+ && !IS_FUNC(OP_SYM_TYPE(right))
+ ) {
DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__);
- fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
+// fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
// set up table pointer
if( (AOP_TYPE(right) == AOP_PCODE)
&& ((AOP(right)->aopu.pcop->type == PO_IMMEDIATE)
- || (AOP(right)->aopu.pcop->type == PO_DIR)))
+// || (AOP(right)->aopu.pcop->type == PO_DIR)
+ )
+ )
{
- fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
+// fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0));
pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1));
pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2));
pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
} else {
- fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__);
+// fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__);
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0),
pic16_popCopyReg(&pic16_pc_tblptrl)));
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1),
pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
} else {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-#if 1
- /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
- normally should work, but mind that the W register live range
- is not checked, so if the code generator assumes that the W
- is already loaded after such a pair, wrong code will be generated.
-
- Checking the live range is the next step.
- This is experimental code yet and has not been fully tested yet.
- USE WITH CARE. Revert to old code by setting 0 to the condition above.
- Vangelis Rokas 030603 (vrokas@otenet.gr) */
-
- pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
-#else
- /* This is the old code, which is assumed(?!) that works fine(!?) */
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-#endif
+ if(!_G.resDirect) /* use this aopForSym feature */
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
}
offset++;
}
-
-
+
release:
pic16_freeAsmop (right,NULL,ic,FALSE);
pic16_freeAsmop (result,NULL,ic,TRUE);
size = AOP_SIZE(right);
offset = 0 ;
while (size--) {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
-// pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
-// pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+ mov2f(AOP(result), AOP(right), offset);
offset++;
}