Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
PIC port - Scott Dattalo scott@dattalo.com (2000)
PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
+ - Vangelis Rokas vrokas@otenet.gr (2003,2004)
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
pCode *pic16_AssembleLine(char *line, int peeps);
extern void pic16_printpBlock(FILE *of, pBlock *pb);
static asmop *newAsmop (short type);
-static pCodeOp *pic16_popRegFromString(char *str, int size, int offset);
+static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op);
extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
static void mov2w (asmop *aop, int offset);
static int aopIdx (asmop *aop, int offset);
-static int labelOffset=0;
+int pic16_labelOffset=0;
extern int pic16_debug_verbose;
static int optimized_for_speed = 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);
static iCode *ifxForOp ( operand *op, iCode *ic );
void pic16_poppCodeOp(pCodeOp *pcop);
static bool is_LitOp(operand *op);
+static bool is_LitAOp(asmop *aop);
#define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
static struct {
short r0Pushed;
short r1Pushed;
+ short fsr0Pushed;
short accInUse;
short inLine;
short debugLine;
short nRegsSaved;
+ short ipushRegs;
set *sendSet;
int interruptvector;
+ int usefastretfie;
} _G;
/* Resolved ifx structure. This structure stores information
void pic16_emitpLabel(int key)
{
- pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
+ pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+pic16_labelOffset));
+}
+
+void pic16_emitpLabelFORCE(int key)
+{
+ pic16_addpCode2pBlock(pb,pic16_newpCodeLabelFORCE(NULL,key+100+pic16_labelOffset));
}
void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
/*-----------------------------------------------------------------*/
static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
{
- bool r0iu = FALSE , r1iu = FALSE;
- bool r0ou = FALSE , r1ou = FALSE;
+// bool r0iu = FALSE , r1iu = FALSE;
+// bool r0ou = FALSE , r1ou = FALSE;
+ bool fsr0iu = FALSE, fsr0ou;
+ bool fsr2iu = FALSE, fsr2ou;
+
+ fprintf(stderr, "%s:%d: getting free ptr from ic = %c result: %d\n", __FUNCTION__, __LINE__, ic->op, result);
+
+
+ fsr2iu = bitVectBitValue(ic->rUsed, IDX_FSR2);
+ fsr0iu = bitVectBitValue(ic->rUsed, IDX_FSR0);
+
+ fsr2ou = bitVectBitValue(ic->rMask, IDX_FSR2);
+ fsr0ou = bitVectBitValue(ic->rMask, IDX_FSR0);
- //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
+ if(bitVectBitValue(ic->rUsed, IDX_WREG)) {
+ fprintf(stderr, "%s:%d WREG is used by this ic\n", __FILE__, __LINE__);
+ DEBUGpic16_emitcode("%s:%d WREG is used by this ic", __FILE__, __LINE__);
+ }
+
+ /* no usage of FSR2 */
+ if(!fsr2iu && !fsr2ou) {
+ ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR2);
+ (*aopp)->type = AOP_FSR2;
+
+ return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR2);
+ }
+
+ if(!fsr0iu && !fsr0ou) {
+ ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR0);
+ (*aopp)->type = AOP_FSR0;
+
+ return ((*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR0));
+ }
+ /* now we know they both have usage */
+ /* if fsr0 not used in this instruction */
+ if (!fsr0iu) {
+ if (!_G.fsr0Pushed) {
+ pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
+ pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
+ _G.fsr0Pushed++;
+ }
+
+ ic->rUsed = bitVectSetBit (ic->rUsed, IDX_FSR0);
+ (*aopp)->type = AOP_FSR0;
+
+ return (*aopp)->aopu.aop_ptr = pic16_regWithIdx (IDX_FSR0);
+ }
+
+
+ fprintf(stderr, "%s:%d could not allocate a free pointer\n", __FILE__, __LINE__);
+ assert( 0 );
+
+ return NULL;
+#if 0
/* the logic: if r0 & r1 used in the instruction
then we are in trouble otherwise */
werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
"getFreePtr should never reach here");
exit(0);
+#endif
}
/*-----------------------------------------------------------------*/
#endif
}
- DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
+ DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,pic16_labelOffset);
}
#if 0
}
#endif
+
/*-----------------------------------------------------------------*/
/* aopForSym - for a true symbol */
/*-----------------------------------------------------------------*/
-static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
+static asmop *aopForSym (iCode *ic, operand *op, bool result)
{
+ symbol *sym=OP_SYMBOL(op);
asmop *aop;
memmap *space= SPEC_OCLS(sym->etype);
DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
+// sym = OP_SYMBOL(op);
+
/* if already has one */
if (sym->aop) {
DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
/* if symbol was initially placed onStack then we must re-place it
* to direct memory, since pic16 does not have a specific stack */
if(sym->onStack) {
- sym->onStack = 0;
- SPEC_OCLS( sym->etype ) = data;
- space = data;
+ fprintf(stderr, "%s:%d symbol %s on stack\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
}
-
+
#if 1
/* assign depending on the storage class */
aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
aop->size = getSize(sym->type);
+ fprintf(stderr, "%s:%d\t%s\n", __FILE__, __LINE__, __FUNCTION__);
+
+#if 1
+// sym->aop = aop = newAsmop (AOP_REG);
+// aop->aopu.aop_dir = sym->name; //sym->rname ;
+// aop->aopu.aop_reg[0] = pic16_regWithIdx(IDX_PLUSW0); //pic16_pc_plusw2.r;
+// aop->size = getSize(sym->type);
+ DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
+
+// if(_G.accInUse) {
+// pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
+// }
+
+// pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_fsr2l), pic16_popCopyReg(&pic16_pc_fsr0l)));
+// pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_fsr2h), pic16_popCopyReg(&pic16_pc_fsr0h)));
+
+
+ /* initialise for stack access via frame pointer */
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
+
+// pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+// pic16_popCopyReg(&pic16_pc_plusw2), pic16_popCopyReg(&pic16_pc_kzero)));
+
+// if(_G.accInUse) {
+// pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
+// }
+
+ return (aop);
+#endif
+
+#if 0
/* now assign the address of the variable to
the pointer register */
if (aop->type != AOP_STK) {
} else
aop->aopu.aop_stk = sym->stack;
return aop;
+#endif
+
}
#endif
+#if 0
if (sym->onStack && options.stack10bit)
{
/* It's on the 10 bit stack, which is located in
aop->size = getSize(sym->type);
return aop;
}
-
+#endif
//DEBUGpic16_emitcode(";","%d",__LINE__);
/* if in bit space */
if (IN_BITSPACE(space)) {
return aop;
}
+ if (IN_FARSPACE(space)) {
+ sym->aop = aop = newAsmop (AOP_DIR);
+ aop->aopu.aop_dir = sym->rname ;
+ aop->size = getSize(sym->type);
+ DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
+ pic16_allocDirReg( IC_LEFT(ic) );
+ return aop;
+ }
+
#if 0 // patch 14
/* special case for a function */
if (IS_FUNC(sym->type)) {
PCOI(aop->aopu.pcop)->index = 0;
} else {
/* try to allocate via direct register */
- aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset); // Patch 8
+ aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset, op); // Patch 8
// aop->size = getSize( sym->type );
}
if(IN_DIRSPACE( space ))
aop->size = PTRSIZE;
- else if(IN_CODESPACE( space ))
+ else if(IN_CODESPACE( space ) || IN_FARSPACE( space ))
aop->size = FPTRSIZE;
else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) );
else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) );
} else {
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);
+ aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname,
+ getSize( OP_SYMBOL( IC_LEFT(ic))->type), val, op);
// aop->size = AOP_SIZE( IC_LEFT(ic) );
}
if (sym1 == sym2)
return TRUE ;
- if (strcmp(sym1->rname,sym2->rname) == 0)
+ if (sym1->rname[0] && sym2->rname[0]
+ && strcmp (sym1->rname, sym2->rname) == 0)
return TRUE;
if (aop1 == aop2)
return TRUE ;
+ DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s\n", __FUNCTION__,
+ pic16_AopType(aop1->type), pic16_AopType(aop2->type));
+
+ if(aop1->type == AOP_ACC && aop2->type == AOP_ACC)return TRUE;
+
if (aop1->type != AOP_REG ||
aop2->type != AOP_REG )
return FALSE ;
/* if this is a true symbol */
if (IS_TRUE_SYMOP(op)) {
DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
- op->aop = aopForSym(ic,OP_SYMBOL(op),result);
+ op->aop = aopForSym(ic, op, result);
return ;
}
//aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
getSize(sym->type),
- sym->usl.spillLoc->offset);
+ sym->usl.spillLoc->offset, op);
aop->size = getSize(sym->type);
return;
/* depending on the asmop type only three cases need work AOP_RO
, AOP_R1 && AOP_STK */
-#if 0
+#if 1
switch (aop->type) {
+ case AOP_FSR0 :
+ if (_G.fsr0Pushed ) {
+ if (pop) {
+ pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
+ pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
+// pic16_emitcode ("pop","ar0");
+ _G.fsr0Pushed--;
+ }
+ }
+ bitVectUnSetBit(ic->rUsed,IDX_FSR0);
+ break;
+
+ case AOP_FSR2 :
+ bitVectUnSetBit(ic->rUsed,IDX_FSR2);
+ break;
+
case AOP_R0 :
if (_G.r0Pushed ) {
if (pop) {
/* depending on type */
switch (aop->type) {
-
- case AOP_R0:
- case AOP_R1:
- DEBUGpic16_emitcode(";","%d",__LINE__);
- /* if we need to increment it */
- while (offset > aop->coff) {
- pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
- aop->coff++;
- }
-
- while (offset < aop->coff) {
- pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
- aop->coff--;
- }
-
- aop->coff = offset ;
- if (aop->paged) {
- pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
- return (dname ? "acc" : "a");
- }
- sprintf(s,"@%s",aop->aopu.aop_ptr->name);
- rs = Safe_calloc(1,strlen(s)+1);
- strcpy(rs,s);
- return rs;
-
- case AOP_DPTR:
- case AOP_DPTR2:
- DEBUGpic16_emitcode(";","%d",__LINE__);
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR(1);
- }
-
- while (offset > aop->coff) {
- pic16_emitcode ("inc","dptr");
- aop->coff++;
- }
-
- while (offset < aop->coff) {
- pic16_emitcode("lcall","__decdptr");
- aop->coff--;
- }
-
- aop->coff = offset;
- if (aop->code) {
- pic16_emitcode("clr","a");
- pic16_emitcode("movc","a,@a+dptr");
+
+ case AOP_FSR0:
+ case AOP_FSR2:
+ sprintf(s, "%s", aop->aopu.aop_ptr->name);
+ rs = Safe_calloc(1, strlen(s)+1);
+ strcpy(rs, s);
+ return (rs);
+
+#if 0
+ /* if we need to increment it */
+ while (offset > aop->coff)
+ {
+ emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
+ aop->coff++;
}
- else {
- pic16_emitcode("movx","a,@dptr");
- }
-
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR(0);
- }
-
- return (dname ? "acc" : "a");
-
+
+ while (offset < aop->coff)
+ {
+ emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
+ aop->coff--;
+ }
+ aop->coff = offset;
+ if (aop->paged)
+ {
+ emitcode ("movx", "a,@%s", aop->aopu.aop_ptr->name);
+ return (dname ? "acc" : "a");
+ }
+ sprintf (s, "@%s", aop->aopu.aop_ptr->name);
+ rs = Safe_calloc (1, strlen (s) + 1);
+ strcpy (rs, s);
+ return rs;
+#endif
+
case AOP_IMMD:
if (bit16)
return aop->aopu.aop_dir;
case AOP_ACC:
- DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
+ DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d\toffset: %d",__LINE__, offset);
// fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
// assert( 0 );
- return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
+// return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
+ rs = Safe_strdup("WREG");
+ return (rs);
case AOP_LIT:
sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
strcpy(rs,s);
return rs;
+ case AOP_STK:
+// pCodeOp *pcop = aop->aop
+ break;
+
}
+ fprintf(stderr, "%s:%d unsupported aop->type: %s\n", __FILE__, __LINE__, pic16_AopType(aop->type));
werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
"aopget got unsupported aop->type");
exit(0);
}
/*-----------------------------------------------------------------*/
-/* pic16_popGetTempReg - create a new temporary pCodeOp */
+/* pic16_popReleaseTempReg - create a new temporary pCodeOp */
/*-----------------------------------------------------------------*/
void pic16_popReleaseTempReg(pCodeOp *pcop)
{
pCodeOp *pic16_popGetLabel(unsigned int key)
{
- DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
+ DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, pic16_labelOffset);
if(key>max_key)
max_key = key;
- return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
+ return pic16_newpCodeOpLabel(NULL,key+100+pic16_labelOffset);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
/* pic16_popRegFromString - */
/*-----------------------------------------------------------------*/
-static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
+static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op)
{
pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
if(PCOR(pcop)->r == NULL) {
// fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
// __FUNCTION__, __LINE__, str, size, offset);
- PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
- //fprintf(stderr, "allocating new register -> %s\n", str);
+
+// PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size, op);
+ fprintf(stderr, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str);
// DEBUGpic16_emitcode(";","%d %s size= %d offset=%d - had to alloc by reg name",__LINE__,pcop->name,size,offset);
} else {
pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
PCOR(pcop)->rIdx = rIdx;
PCOR(pcop)->r = pic16_regWithIdx(rIdx);
+
PCOR(pcop)->r->isFree = 0;
PCOR(pcop)->r->wasUsed = 1;
return NULL;
+ case AOP_FSR0:
+ case AOP_FSR2:
+ pcop = Safe_calloc(1, sizeof(pCodeOpReg));
+ PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */
+ PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx );
+ PCOR(pcop)->r->wasUsed = 1;
+ PCOR(pcop)->r->isFree = 0;
+
+ PCOR(pcop)->instance = offset;
+ pcop->type = PCOR(pcop)->r->pc_type;
+ return (pcop);
case AOP_IMMD:
DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
case AOP_DIR:
DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
- return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
+ return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL);
case AOP_REG:
{
DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+// pcop->type = PO_GPR_REGISTER;
PCOR(pcop)->rIdx = rIdx;
- PCOR(pcop)->r = pic16_regWithIdx(rIdx);
+ PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx);
PCOR(pcop)->r->wasUsed=1;
PCOR(pcop)->r->isFree=0;
case AOP_CRY:
DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
- pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
+ pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1, PO_GPR_REGISTER);
PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
//if(PCOR(pcop)->r == NULL)
//fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
static void mov2w (asmop *aop, int offset)
{
- if(!aop)
- return;
+// if(!aop)
+// return;
- DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
+ DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
- if ( aop->type == AOP_PCODE ||
- aop->type == AOP_LIT )
- pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
- else
- pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
+ if(is_LitAOp(aop))
+ pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
+ else
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
}
} else {
/* >32-bits, result on stack, and FSR0 points to beginning.
* Fix stack when done */
-
+ /* FIXME FIXME */
while (size--) {
// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
/*-----------------------------------------------------------------*/
static void genIpush (iCode *ic)
{
+ int size, offset=0;
DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
+
+
+ pic16_aopOp(IC_LEFT(ic), ic, FALSE);
+
+
+ size = AOP_SIZE( IC_LEFT(ic) );
+
+ while(size--) {
+ mov2w( AOP(IC_LEFT(ic)), offset );
+ pushw();
+ offset++;
+ }
+
#if 0
int size, offset = 0 ;
char *l;
saverbank(FUNC_REGBANK(dtype),ic,TRUE);
+
+ /* initialise stackParms for IPUSH pushes */
+// stackParms = psuedoStkPtr;
+// fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes);
+
/* if send set is not empty the assign */
if (_G.sendSet) {
iCode *sic;
pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
}
+ if(!stackParms && ic->parmBytes) {
+ stackParms = ic->parmBytes;
+ }
+
if(stackParms>0) {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
/* 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 (ic->parmBytes) {
int i;
for ( i = 0 ; i < ic->parmBytes ;i++)
pic16_emitcode("dec","%s",spname);
}
+#endif
#if 0
/* if register bank was saved then pop them */
// push return address
// push $ on return stack, then replace with retlbl
- // Note: retlbl is supplied as dummy operand to PUSH
- // This has the nice side effect of keeping the label from being optimized out :o)
- pic16_emitpcode(POC_PUSH, pic16_popGetLabel(retlbl->key));
+ pic16_emitpcodeNULLop(POC_PUSH);
pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0));
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosl));
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
/* make the call by writing the pointer into pc */
-// FIXME Disabled writes to PCLATU because of gpsim problems
-#if 0
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
-#else
- fprintf(stderr,
-"WARNING: (%s:%d) PCLATU is not written because of gpsim problems\n\
-Correct this as soon as gpsim bug is fixed\n", __FILE__, __LINE__);
-#endif
-
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
+
// note: MOVFF to PCL not allowed
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
+
+// pic16_emitpcode(POC_GOTO, pic16_popGetLabel(retlbl->key));
+// pic16_emitpcodeNULLop(POC_NOP);
+// pic16_emitpcodeNULLop(POC_NOP);
+
/* return address is here: (X) */
- pic16_emitpLabel(retlbl->key);
+ pic16_emitpLabelFORCE(retlbl->key);
+
+// pic16_emitpcodeNULLop(POC_NOP);
pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
symbol *sym;
sym_link *ftype;
- DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
+ DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key);
- labelOffset += (max_key+4);
+ pic16_labelOffset += (max_key+4);
max_key=0;
GpsuedoStkPtr=0;
_G.nRegsSaved = 0;
case 2: abSym->address = 0x000018; break;
}
+ /* relocate interrupt vectors if needed */
+ abSym->address += pic16_options.ivt_loc;
+
addSet(&absSymSet, abSym);
}
}
* 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 ));
}
+
+ /* 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 ));
DEBUGpic16_emitcode("; **", "Saving used registers in stack");
for ( i = 0 ; i < sym->regsUsed->size ; i++) {
if (bitVectBitValue(sym->regsUsed,i)) {
-// fprintf(stderr, "%s:%d function %s uses register %s\n",
-// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
-// pic16_regWithIdx(i)->name);
+#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;
+ }
}
}
}
for ( i = 0 ; i < sym->regsUsed->size ; i++) {
if (bitVectBitValue(sym->regsUsed,i)) {
-// fprintf(stderr, "%s:%d function %s uses register %s\n",
-// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
-// pic16_regWithIdx(i)->name);
+#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_pc_postdec1, 0));
_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;
+ }
+
}
}
}
return;
}
+ /* add code for ISCRITICAL */
+
#if 0
if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
{
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");
}
}
- pic16_emitpcomment("%s: _G.nRegsSaved upon exit from function: %d\n", __FUNCTION__, _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);
}
}
- pic16_emitcode ("return","");
pic16_emitpcodeNULLop(POC_RETURN);
/* Mark the end of a function */
void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
{
- if(is_LitOp(op))
-// if((AOP(op)->aopu.pcop->type == PO_IMMEDIATE)
-// || (AOP(op)->aopu.pcop->type == PO_LITERAL))
- {
+ 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));
}
&& IC_LABEL(ic->next) == returnLabel)) {
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
- pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
+ pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + pic16_labelOffset);
}
}
return ;
pic16_emitpLabel(IC_LABEL(ic)->key);
- pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
+ pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + pic16_labelOffset));
}
/*-----------------------------------------------------------------*/
static void genGoto (iCode *ic)
{
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
- pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
+ pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+pic16_labelOffset);
}
emitSKPC;
else {
DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
}
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
- pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
+ pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + pic16_labelOffset);
}
else {
emitSKPNC;
else {
DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
- pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
+ pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
}
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
- pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
+ pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset);
}
}
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
- // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
+ // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
} else {
break;
}
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
- // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
+ // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
}
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
if ( IC_TRUE(ifx) )
- pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
+ pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
else
- pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
+ pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
}
#endif
return;
if(rifx->condition)
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
else
- pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
+ pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
#if 0
fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
- __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+labelOffset, lbl->key+100+labelOffset);
+ __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+pic16_labelOffset, lbl->key+100+pic16_labelOffset);
#endif
#ifndef _swapp
//genSkipCond(&rFalseIfx,left,size,7);
//rFalseIfx.condition ^= 1;
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
+ 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
//genSkipCond(&rFalseIfx,left,size,7);
- pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
+ 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 {
/* 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));
+ 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
}
if(ifx) ifx->generated = 1;
- goto check_carry;
-// return;
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ goto check_carry;
+ return;
} else {
int s = size;
if(rFalseIfx.condition) {
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
+ 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));
}
//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));
+ 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_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));
+ 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
if(sign) {
/* Sigh. thus sucks... */
if(size) {
+ pCodeOp *pctemp;
+
+ pctemp = pic16_popGetTempReg();
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
- pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
- pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_popReleaseTempReg(pctemp);
} else {
/* Signed char comparison */
/* Special thanks to Nikolai Golovchenko for this snippet */
if ((AOP_TYPE(result) != AOP_CRY)
&& AOP_SIZE(result)) {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-// pic16_emitpLabel( rFalseIfx.lbl->key );
+
+ if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
pic16_outBitC(result);
} else {
|| (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) ));
}
+/*-----------------------------------------------------------------*/
+/* is_LitAOp - check if operand has to be treated as literal */
+/*-----------------------------------------------------------------*/
+static bool is_LitAOp(asmop *aop)
+{
+ return (aop->type == AOP_LIT)
+ || ( (aop->type == AOP_PCODE)
+ && ( (aop->aopu.pcop->type == PO_LITERAL)
+ || (aop->aopu.pcop->type == PO_IMMEDIATE) ));
+}
+
+
/*-----------------------------------------------------------------*/
/* genCmpEq - generates code for equal to */
pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
}
- pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
+ pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
{
/* left and right are both bit variables, result is carry */
if ( IC_TRUE(ifx) ) {
emitSKPNZ;
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
- // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
+ // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
} else {
emitSKPZ;
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
- // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
+ // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
}
} else {
DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
- pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
+ pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+pic16_labelOffset);
} else {
emitSKPNZ;
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
- pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
+ pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
}
} else {
emitSKPZ;
DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
- pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
+ pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
}
offset++;
}
if(s>1 && IC_TRUE(ifx)) {
pic16_emitpLabel(tlbl->key);
- pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
+ pic16_emitcode("","_%05d_DS_:",tlbl->key+100+pic16_labelOffset);
}
}
}
tlbl = newiTempLabel(NULL);
pic16_toBoolean(left);
emitSKPZ;
- pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
+ pic16_emitcode("goto","%05d_DS_",tlbl->key+100+pic16_labelOffset);
pic16_toBoolean(right);
- pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
+ pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
pic16_outBitAcc(result);
}
}
pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
- pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0));
+ pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER));
}
/*
if(p>=0) {
/* only one bit is set in the literal, so use a bcf instruction */
// pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
- pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
+ pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
} else {
pic16_emitcode("movlw","0x%x", (lit & 0xff));
if(p>=0) {
/* only one bit is set in the literal, so use a bsf instruction */
pic16_emitpcode(POC_BSF,
- pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
+ pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
} else {
if(know_W != (lit & 0xff))
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
case 4:
pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
break;
}
pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
break;
case 6:
if(same) {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
} else {
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
- pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
- pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
+ pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
}
break;
case 7:
if(same) {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
} else {
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
}
if(sign) {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
pic16_emitpcode(POC_BTFSC,
- pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
+ pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
}
pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
if(sign) {
pic16_emitpcode(POC_BTFSC,
- pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
+ pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
}
pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
if(sign) {
pic16_emitpcode(POC_BTFSC,
- pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
+ pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
}
pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
if(optimized_for_speed) {
pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
- pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
+ pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
+ pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
} else {
pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
if(sign) {
- pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
+ pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
}
}
if(res_size == 1) {
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
if(sign) {
- pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
+ pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
}
} else {
if(sign) {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
while(res_size--)
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
}
#endif
+#if 1
+ if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE),
+ pic16_aopGet(AOP(left), 0, TRUE, FALSE))) {
+ DEBUGpic16_emitcode("; ***", "left and result names are same, skipping moving");
+ goto release;
+ }
+#endif
+
+
#if 0
if ( AOP_TYPE(left) == AOP_PCODE) {
fprintf(stderr,"genDataPointerGet %s, %d\n",
leoffset++;
}
-//release:
+release:
pic16_freeAsmop(result,NULL,ic,TRUE);
}
pic16_aopOp(left,ic,FALSE);
- pic16_DumpOp("(left)",left);
- pic16_DumpOp("(result)",result);
+// pic16_DumpOp("(left)",left);
+// pic16_DumpOp("(result)",result);
/* if left is rematerialisable and
* result is not bit variable type and
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
offset++;
}
- // .... patch 15
+
pic16_freeAsmop(left,NULL,ic,TRUE);
pic16_freeAsmop(result,NULL,ic,TRUE);
}
+
+
/*-----------------------------------------------------------------*/
/* genPointerGet - generate code for pointer get */
/*-----------------------------------------------------------------*/
#endif
genGenPointerGet (left,result,ic);
break;
+
+ default:
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "genPointerGet: illegal pointer type");
+
}
}
size = AOP_SIZE(IC_RESULT(ic));
+
+ if(sym->onStack) {
+ DEBUGpic16_emitcode("; ", "%s symbol %s on stack", __FUNCTION__, sym->name);
+
+ return;
+ }
+
// if(pic16_debug_verbose) {
// fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
// __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
// fprintf(stderr, "%s:%d: assigning value 0x%04lx (%d:%d)\n", __FUNCTION__, __LINE__, lit,
// sizeof(unsigned long int), sizeof(float));
+ if(AOP_TYPE(right) != AOP_LIT
+ && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))) {
+ DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__);
+
+ // set up table pointer
+ if( (AOP_TYPE(right) == AOP_PCODE)
+ && ((AOP(right)->aopu.pcop->type == PO_IMMEDIATE)
+ || (AOP(right)->aopu.pcop->type == PO_DIR)))
+ {
+ 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_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
+ pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2));
+ pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
+ } else {
+ 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_popCopyReg(&pic16_pc_tblptrh)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2),
+ pic16_popCopyReg(&pic16_pc_tblptru)));
+ }
+
+ size = min(AOP_SIZE(right), AOP_SIZE(result));
+ while(size--) {
+ pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat),
+ pic16_popGet(AOP(result),offset)));
+ offset++;
+ }
+
+ if(AOP_SIZE(result) > AOP_SIZE(right)) {
+ size = AOP_SIZE(result) - AOP_SIZE(right);
+ while(size--) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset));
+ offset++;
+ }
+ }
+ goto release;
+ }
+
+
+
/* VR - What is this?! */
if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(aopIdx(AOP(result),0) == 4) {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ assert(0);
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
goto release;
} else
+// assert(0);
DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
}
/* we need to or */
if (AOP_TYPE(right) == AOP_REG) {
pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
}
pic16_toBoolean(right);
size = AOP_SIZE(right);
offset = 0 ;
while (size--) {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+ 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));
offset++;
}
if(size == 1) {
/* Save one instruction of casting char to int */
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
} else {
pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
if(offset)
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
else
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
+ pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + pic16_labelOffset);
}
/* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
{
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+#if 0
+ fprintf(stderr, "%s:%d %s for symbol %s\tonStack: %d\n", __FILE__, __LINE__, __FUNCTION__,
+ OP_SYMBOL( IC_RESULT(ic) )->rname, OP_SYMBOL( IC_RESULT(ic) )->onStack);
+#endif
+// pic16_DumpOp(__FUNCTION__, IC_RESULT(ic));
+
if (isOperandInFarSpace(IC_RESULT(ic)) &&
( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
int size = getSize(operandType(IC_RESULT(ic)));
int offset = pic16_fReturnSizePic - size;
+ assert( 0 );
while (size--) {
pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));