clean-intermediate:
$(RM) -f *.lst *.asm *.dump*
+
+dep .depend:
+ rm -f .depend
+ for temp in $(CFILES); do \
+ $(CPP) $(MM) $(CFLAGS) $$temp > .tmpdepend; \
+ $(SED) s/.rel/.o/g .tmpdepend >> .depend; \
+ $(RM) -f .tmpdepend; \
+ done
+
+include .depend
*/
extern stack;
+extern stack_end;
extern TBLPTRU;
{
_asm
// Initialize the stack pointer
- lfsr 1, _stack
- lfsr 2, _stack
+ lfsr 1, _stack_end
+ lfsr 2, _stack_end
clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR
// initialize the flash memory access configuration. this is harmless
*/
extern stack;
+extern stack_end;
extern TBLPTRU;
extern TBLPTRH;
{
_asm
// Initialize the stack pointer
- lfsr 1, _stack
- lfsr 2, _stack
+ lfsr 1, _stack_end
+ lfsr 2, _stack_end
clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR
// initialize the flash memory access configuration. this is harmless
*/
extern stack;
+extern stack_end;
extern TBLPTRU;
extern TBLPTRH;
{
_asm
// Initialize the stack pointer
- lfsr 1, _stack
- lfsr 2, _stack
+ lfsr 1, _stack_end
+ lfsr 2, _stack_end
clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR
// initialize the flash memory access configuration. this is harmless
SNPRINTF (buffer, sizeof(buffer),
((sOpt == 'I') ? "-%c\"%s\"": "-%c%s"), sOpt, rest);
addSet(&preArgvSet, Safe_strdup(buffer));
+ if(sOpt == 'I')addSet(&includeDirsSet, Safe_strdup(rest));
}
break;
/* initializers if not an extern */
if (SPEC_SCLS (sym->etype) == S_CODE &&
sym->ival == NULL &&
+ !sym->_isparm &&
//!sym->level &&
port->mem.code_ro &&
!IS_EXTERN (sym->etype) &&
PIC16_device *pic16=NULL;
unsigned int stackPos = 0;
+unsigned int stackLen = 0;
extern regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop);
continue;
#if 0
- fprintf(stderr, "%s:%d register %s alias:%d fix:%d ival=%i level=%i\n",
+ fprintf(stderr, "%s:%d register %s alias:%d fix:%d ival=%i level=%i code=%i\n",
__FILE__, __LINE__, reg->name, reg->alias, reg->isFixed,
(reg->regop?(OP_SYMBOL(reg->regop)->ival?1:0):-1),
- (reg->regop?(OP_SYMBOL(reg->regop)->level):-1) );
+ (reg->regop?(OP_SYMBOL(reg->regop)->level):-1),
+ (reg->regop?(IS_CODE(OP_SYM_ETYPE(reg->regop))):-1) );
#endif
docontinue=0;
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)
+ - 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
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 );
static struct {
short r0Pushed;
short r1Pushed;
+ short fsr0Pushed;
short accInUse;
short inLine;
short debugLine;
short nRegsSaved;
+ short ipushRegs;
set *sendSet;
int interruptvector;
} _G;
/*-----------------------------------------------------------------*/
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);
- (*aopp)->type = AOP_STK;
- return NULL;
+
+ fsr2iu = bitVectBitValue(ic->rUsed, IDX_FSR2);
+ fsr0iu = bitVectBitValue(ic->rUsed, IDX_FSR0);
+
+ fsr2ou = bitVectBitValue(ic->rMask, IDX_FSR2);
+ fsr0ou = bitVectBitValue(ic->rMask, IDX_FSR0);
+
+ 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 );
+
+#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
}
/*-----------------------------------------------------------------*/
* to direct memory, since pic16 does not have a specific stack */
if(sym->onStack) {
fprintf(stderr, "%s:%d symbol %s on stack\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
-#if 0
- sym->onStack = 0;
- SPEC_OCLS( sym->etype ) = data;
- space = data;
-#endif
}
-#if 0
+#if 1
/* assign depending on the storage class */
/* if it is on the stack or indirectly addressable */
/* space we need to assign either r0 or r1 to it */
DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
__FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
-// sym->aop = aop = newAsmop(0);
-// aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
-// aop->size = getSize(sym->type);
+ sym->aop = aop = newAsmop(0);
+ aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
+ aop->size = getSize(sym->type);
fprintf(stderr, "%s:%d\t%s\n", __FILE__, __LINE__, __FUNCTION__);
- sym->aop = aop = newAsmop (AOP_REG);
+#if 1
+// sym->aop = aop = newAsmop (AOP_REG);
// aop->aopu.aop_dir = sym->name; //sym->rname ;
- aop->aopu.aop_reg[0] = pic16_regWithIdx(IDX_PLUSW2); //pic16_pc_plusw2.r;
- aop->size = getSize(sym->type);
+// 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(IC_LEFT(ic))pic16_allocDirReg( IC_LEFT(ic) );
-// else if(IC_RIGHT(ic))pic16_allocDirReg(IC_RIGHT(ic));
+// 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
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)) {
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) );
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 ;
/* 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_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++;
+ }
+
+ 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));
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, op);
- //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 {
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__);
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;
/*-----------------------------------------------------------------*/
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 */
return;
}
+ /* add code for ISCRITICAL */
+
#if 0
if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
{
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)));
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++;
}
AOP_STR,
AOP_CRY,
AOP_ACC,
+ AOP_FSR0,
+ AOP_FSR1,
+ AOP_FSR2,
AOP_PCODE
};
void pic16_emitDebuggerSymbol (char *);
bool pic16_sameRegs (asmop *aop1, asmop *aop2 );
char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname);
+void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
bool pic16_genPlusIncr (iCode *ic);
const char *pic16_AopType(short type)
{
switch(type) {
- case AOP_LIT:
- return "AOP_LIT";
- break;
- case AOP_REG:
- return "AOP_REG";
- break;
- case AOP_DIR:
- return "AOP_DIR";
- break;
- case AOP_DPTR:
- return "AOP_DPTR";
- break;
- case AOP_DPTR2:
- return "AOP_DPTR2";
- break;
- case AOP_R0:
- return "AOP_R0";
- break;
- case AOP_R1:
- return "AOP_R1";
- break;
- case AOP_STK:
- return "AOP_STK";
- break;
- case AOP_IMMD:
- return "AOP_IMMD";
- break;
- case AOP_STR:
- return "AOP_STR";
- break;
- case AOP_CRY:
- return "AOP_CRY";
- break;
- case AOP_ACC:
- return "AOP_ACC";
- break;
- case AOP_PCODE:
- return "AOP_PCODE";
- break;
+ case AOP_LIT: return "AOP_LIT";
+ case AOP_REG: return "AOP_REG";
+ case AOP_DIR: return "AOP_DIR";
+ case AOP_DPTR: return "AOP_DPTR";
+ case AOP_DPTR2: return "AOP_DPTR2";
+ case AOP_FSR0: return "AOP_FSR0";
+ case AOP_FSR2: return "AOP_FSR2";
+ case AOP_R0: return "AOP_R0";
+ case AOP_R1: return "AOP_R1";
+ case AOP_STK: return "AOP_STK";
+ case AOP_IMMD: return "AOP_IMMD";
+ case AOP_STR: return "AOP_STR";
+ case AOP_CRY: return "AOP_CRY";
+ case AOP_ACC: return "AOP_ACC";
+ case AOP_PCODE: return "AOP_PCODE";
}
return "BAD TYPE";
switch(pcop->type) {
- case PO_NONE:
- return "PO_NONE";
- case PO_W:
- return "PO_W";
- case PO_WREG:
- return "PO_WREG";
- case PO_STATUS:
- return "PO_STATUS";
- case PO_BSR:
- return "PO_BSR";
- case PO_FSR0:
- return "PO_FSR0";
- case PO_INDF0:
- return "PO_INDF0";
- case PO_INTCON:
- return "PO_INTCON";
- case PO_GPR_REGISTER:
- return "PO_GPR_REGISTER";
- case PO_GPR_BIT:
- return "PO_GPR_BIT";
- case PO_GPR_TEMP:
- return "PO_GPR_TEMP";
- case PO_SFR_REGISTER:
- return "PO_SFR_REGISTER";
- case PO_PCL:
- return "PO_PCL";
- case PO_PCLATH:
- return "PO_PCLATH";
- case PO_PCLATU:
- return "PO_PCLATU";
- case PO_PRODL:
- return "PO_PRODL";
- case PO_PRODH:
- return "PO_PRODH";
- case PO_LITERAL:
- return "PO_LITERAL";
- case PO_REL_ADDR:
- return "PO_REL_ADDR";
- case PO_IMMEDIATE:
- return "PO_IMMEDIATE";
- case PO_DIR:
- return "PO_DIR";
- case PO_CRY:
- return "PO_CRY";
- case PO_BIT:
- return "PO_BIT";
- case PO_STR:
- return "PO_STR";
- case PO_LABEL:
- return "PO_LABEL";
- case PO_WILD:
- return "PO_WILD";
+ case PO_NONE: return "PO_NONE";
+ case PO_W: return "PO_W";
+ case PO_WREG: return "PO_WREG";
+ case PO_STATUS: return "PO_STATUS";
+ case PO_BSR: return "PO_BSR";
+ case PO_FSR0: return "PO_FSR0";
+ case PO_INDF0: return "PO_INDF0";
+ case PO_INTCON: return "PO_INTCON";
+ case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
+ case PO_GPR_BIT: return "PO_GPR_BIT";
+ case PO_GPR_TEMP: return "PO_GPR_TEMP";
+ case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
+ case PO_PCL: return "PO_PCL";
+ case PO_PCLATH: return "PO_PCLATH";
+ case PO_PCLATU: return "PO_PCLATU";
+ case PO_PRODL: return "PO_PRODL";
+ case PO_PRODH: return "PO_PRODH";
+ case PO_LITERAL: return "PO_LITERAL";
+ case PO_REL_ADDR: return "PO_REL_ADDR";
+ case PO_IMMEDIATE: return "PO_IMMEDIATE";
+ case PO_DIR: return "PO_DIR";
+ case PO_CRY: return "PO_CRY";
+ case PO_BIT: return "PO_BIT";
+ case PO_STR: return "PO_STR";
+ case PO_LABEL: return "PO_LABEL";
+ case PO_WILD: return "PO_WILD";
}
}
switch(PCORB(pcop)->subtype) {
- case PO_NONE:
- return "PO_NONE";
- case PO_W:
- return "PO_W";
- case PO_WREG:
- return "PO_WREG";
- case PO_STATUS:
- return "PO_STATUS";
- case PO_BSR:
- return "PO_BSR";
- case PO_FSR0:
- return "PO_FSR0";
- case PO_INDF0:
- return "PO_INDF0";
- case PO_INTCON:
- return "PO_INTCON";
- case PO_GPR_REGISTER:
- return "PO_GPR_REGISTER";
- case PO_GPR_BIT:
- return "PO_GPR_BIT";
- case PO_GPR_TEMP:
- return "PO_GPR_TEMP";
- case PO_SFR_REGISTER:
- return "PO_SFR_REGISTER";
- case PO_PCL:
- return "PO_PCL";
- case PO_PCLATH:
- return "PO_PCLATH";
- case PO_PCLATU:
- return "PO_PCLATU";
- case PO_PRODL:
- return "PO_PRODL";
- case PO_PRODH:
- return "PO_PRODH";
- case PO_LITERAL:
- return "PO_LITERAL";
- case PO_REL_ADDR:
- return "PO_REL_ADDR";
- case PO_IMMEDIATE:
- return "PO_IMMEDIATE";
- case PO_DIR:
- return "PO_DIR";
- case PO_CRY:
- return "PO_CRY";
- case PO_BIT:
- return "PO_BIT";
- case PO_STR:
- return "PO_STR";
- case PO_LABEL:
- return "PO_LABEL";
- case PO_WILD:
- return "PO_WILD";
+ case PO_NONE: return "PO_NONE";
+ case PO_W: return "PO_W";
+ case PO_WREG: return "PO_WREG";
+ case PO_STATUS: return "PO_STATUS";
+ case PO_BSR: return "PO_BSR";
+ case PO_FSR0: return "PO_FSR0";
+ case PO_INDF0: return "PO_INDF0";
+ case PO_INTCON: return "PO_INTCON";
+ case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
+ case PO_GPR_BIT: return "PO_GPR_BIT";
+ case PO_GPR_TEMP: return "PO_GPR_TEMP";
+ case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
+ case PO_PCL: return "PO_PCL";
+ case PO_PCLATH: return "PO_PCLATH";
+ case PO_PCLATU: return "PO_PCLATU";
+ case PO_PRODL: return "PO_PRODL";
+ case PO_PRODH: return "PO_PRODH";
+ case PO_LITERAL: return "PO_LITERAL";
+ case PO_REL_ADDR: return "PO_REL_ADDR";
+ case PO_IMMEDIATE: return "PO_IMMEDIATE";
+ case PO_DIR: return "PO_DIR";
+ case PO_CRY: return "PO_CRY";
+ case PO_BIT: return "PO_BIT";
+ case PO_STR: return "PO_STR";
+ case PO_LABEL: return "PO_LABEL";
+ case PO_WILD: return "PO_WILD";
}
}
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
+ DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+
if (AOP_TYPE(right) != AOP_LIT){
fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
exit(1);
return;
default:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+ if(AOP_TYPE(left) != AOP_ACC)
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
pic16_popGet(AOP(result), 0)));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
return;
default:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+ if(AOP_TYPE(left) != AOP_ACC)
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
pic16_popGet(AOP(result), 0)));
void pic16_genNot (iCode *ic)
{
int size;
+ symbol *tlbl;
/*
* result[AOP_CRY,AOP_REG] = ! left[AOP_CRY, AOP_REG]
*/
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
/* assign asmOps to operand & result */
pic16_aopOp (IC_LEFT(ic),ic,FALSE);
pic16_aopOp (IC_RESULT(ic),ic,TRUE);
}
size = AOP_SIZE(IC_LEFT(ic));
+#if 0
if(size == 1) {
pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
goto release;
}
+#endif
+
+ pic16_toBoolean( IC_LEFT(ic) );
+
+ tlbl = newiTempLabel(NULL);
+ emitCLRC;
+ pic16_emitpcode(POC_TSTFSZ, pic16_popCopyReg( &pic16_pc_wreg ));
+ emitSETC;
+ pic16_outBitC( IC_RESULT(ic) );
release:
/* release the aops */
/*
* global function definitions
*/
-void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
-
-
void pic16_DumpValue(char *prefix, value *val);
void pic16_DumpPcodeOp(char *prefix, pCodeOp *pcop);
void pic16_DumpAop(char *prefix, asmop *aop);
for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
#if 0
- fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\n",
+ fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
__FUNCTION__,
map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
- IS_AGGREGATE(sym->type));
+ IS_AGGREGATE(sym->type), SPEC_SCLS(sym->etype), IS_FUNC(sym->type));
printTypeChain( sym->type, stderr );
fprintf(stderr, "\n");
#endif
/* if extern then add to externs */
if (IS_EXTERN (sym->etype)) {
-
+
/* reduce overhead while linking by not declaring
* extern unused external functions (usually declared
* in header files) */
sectSym *ssym;
int found=0;
+ fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
+ sym->rname, reg, (reg?reg->name:"<<NULL>>"));
#if 1
for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
if(!strcmp(ssym->name, reg->name))found=1;
}
+/* set to 0 to disable debug messages */
+#define DEBUG_PRINTIVAL 1
/*-----------------------------------------------------------------*/
/* pic16_printIvalType - generates ival for int/char */
// fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
+#if DEBUG_PRINTIVAL
+ fprintf(stderr, "%s\n",__FUNCTION__);
+#endif
+
+
/* if initList is deep */
if (ilist && ilist->type == INIT_DEEP)
ilist = ilist->init.deep;
if(!p)
return 0;
+#if DEBUG_PRINTIVAL
+ fprintf(stderr, "%s\n",__FUNCTION__);
+#endif
- // fprintf(stderr, "%s\n",__FUNCTION__);
if (!s)
{
return;
+#if DEBUG_PRINTIVAL
+ fprintf(stderr, "%s\n",__FUNCTION__);
+#endif
/* take care of the special case */
/* array of characters can be init */
/* by a string */
int size =0;
+#if DEBUG_PRINTIVAL
+ fprintf(stderr, "%s\n",__FUNCTION__);
+#endif
+
+
do {
unsigned long i;
val = list2val(lilist);
symbol *sflds;
initList *iloop = NULL;
+
+#if DEBUG_PRINTIVAL
+ fprintf(stderr, "%s\n",__FUNCTION__);
+#endif
+
sflds = SPEC_STRUCT (type)->fields;
if (ilist) {
VR - Attempting to port this function to pic16 port - 8-Jun-2004
*/
-// fprintf(stderr, "%s\n",__FUNCTION__);
+
+#if DEBUG_PRINTIVAL
+ fprintf(stderr, "%s\n",__FUNCTION__);
+#endif
size = getSize (type);
// fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
// __FILE__, __LINE__, sym->name);
+
/* if it has an initial value */
if (sym->ival) {
pBlock *pb;
static void
pic16initialComments (FILE * afile)
{
- initialComments (afile);
- fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
- fprintf (afile, iComments2);
-
+ initialComments (afile);
+ fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
+ if(pic16_mplab_comp)
+ fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
+ fprintf (afile, iComments2);
}
/*-----------------------------------------------------------------*/
{
symbol *sym;
- fprintf (afile, "%s", iComments2);
+ fprintf (afile, "\n%s", iComments2);
fprintf (afile, "; public variables in this module\n");
fprintf (afile, "%s", iComments2);
{
symbol *sym;
- fprintf(afile, "%s", iComments2);
+ /* print nothing if no externs to declare */
+ if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
+ return;
+
+ fprintf(afile, "\n%s", iComments2);
fprintf(afile, "; extern variables in this module\n");
fprintf(afile, "%s", iComments2);
if(initsfpnt) {
pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
- pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack"))));
+ pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
- pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack"))));
+ pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
}
/* put in the call to main */
static void
_pic16_reset_regparm ()
{
- regParmFlg = 0;
+ regParmFlg = 0;
}
static int
_pic16_regparm (sym_link * l)
{
- /* for this processor it is simple
- can pass only the first parameter in a register */
- //if (regParmFlg)
- // return 0;
-
- regParmFlg++;// = 1;
+ /* for this processor it is simple
+ * can pass only the first parameter in a register */
+#if 0
+ if(regParmFlg)return 0;
+ regParmFlg = 1;
return 1;
+#else
+ regParmFlg++;// = 1;
+ return 1;
+#endif
}
}
}
- /* #pragma stack [stack-position] */
+ /* #pragma stack [stack-position] [stack-len] */
if(startsWith(ptr, "stack")) {
char *stackPosS = strtok((char *)NULL, WHITE);
+ char *stackLenS = strtok((char *)NULL, WHITE);
value *stackPosVal;
+ value *stackLenVal;
regs *reg;
symbol *sym;
-// fprintf(stderr, "Initializing stack pointer to 0x%x\n", (int)floatFromVal(constVal(stackPos)));
stackPosVal = constVal( stackPosS );
stackPos = (unsigned int)floatFromVal( stackPosVal );
- reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "_stack", 1, 0, NULL);
+
+ if(stackLenS) {
+ stackLenVal = constVal( stackLenS );
+ stackLen = (unsigned int)floatFromVal( stackLenVal );
+ }
+
+ if(stackLen < 1) {
+ stackLen = 64;
+ fprintf(stderr, "%s:%d setting stack to default size 0x%x\n", __FILE__, __LINE__, stackLen);
+ }
+
+// fprintf(stderr, "Initializing stack pointer at 0x%x len 0x%x\n", stackPos, stackLen);
+
+ reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "_stack", stackLen-1, 0, NULL);
+ addSet(&pic16_fix_udata, reg);
+
+ reg = newReg(REG_SFR, PO_SFR_REGISTER, stackPos + stackLen-1, "_stack_end", 1, 0, NULL);
addSet(&pic16_fix_udata, reg);
sym = newSymbol("stack", 0);
sprintf(sym->rname, "_%s", sym->name);
addSet(&publics, sym);
+
+ sym = newSymbol("stack_end", 0);
+ sprintf(sym->rname, "_%s", sym->name);
+ addSet(&publics, sym);
initsfpnt = 1; // force glue() to initialize stack/frame pointers */
#define IVT_LOC "--ivt-loc"
#define NO_DEFLIBS "--nodefaultlibs"
-
+#define MPLAB_COMPAT "--mplab-comp"
char *alt_asm=NULL;
char *alt_link=NULL;
+int pic16_mplab_comp=0;
extern int pic16_debug_verbose;
extern int pic16_ralloc_debug;
extern int pic16_pcode_verbose;
{ 0, "--denable-peeps", &pic16_enable_peeps, "explicit enable of peepholes"},
{ 0, IVT_LOC, NULL, "<nnnn> interrupt vector table location"},
{ 0, "--calltree", &pic16_options.dumpcalltree, "dump call tree in .calltree file"},
+ { 0, MPLAB_COMPAT, &pic16_mplab_comp, "enable compatibility mode for MPLAB utilities (MPASM/MPLINK)"},
{ 0, NULL, NULL, NULL}
};
/* setup pic16 library directory */
pic16libDirsSet = appendStrSet(dataDirsSet, NULL, pic16libDir);
mergeSets(&libDirsSet, pic16libDirsSet);
+ }
+
+ if(!pic16_options.nodefaultlibs) {
+ /* now add the library for the device */
+ sprintf(devlib, "%s.lib", pic16->name[2]);
+ addSet(&libFilesSet, Safe_strdup(devlib));
+ }
+}
- if(!pic16_options.nodefaultlibs) {
- /* now add the library for the device */
- sprintf(devlib, "%s.lib", pic16->name[2]);
- addSet(&libFilesSet, Safe_strdup(devlib));
- }
+extern set *linkOptionsSet;
+char *msprintf(hTab *pvals, const char *pformat, ...);
+int my_system(const char *cmd);
+
+/* custom function to link objects */
+static void _pic16_linkEdit(void)
+{
+ hTab *linkValues=NULL;
+ char lfrm[256];
+ char *lcmd;
+ char temp[128];
+ set *tSet=NULL;
+ int ret;
+
+ /*
+ * link command format:
+ * {linker} {incdirs} {lflags} -o {outfile} {spec_ofiles} {ofiles} {libs}
+ *
+ */
+
+ sprintf(lfrm, "{linker} {incdirs} {lflags} -o {outfile} {spec_ofiles} {ofiles} {libs}");
+
+ shash_add(&linkValues, "linker", "gplink");
+
+ mergeSets(&tSet, libDirsSet);
+ mergeSets(&tSet, libPathsSet);
+
+ shash_add(&linkValues, "incdirs", joinStrSet( appendStrSet(tSet, "-I\"", "\"")));
+ shash_add(&linkValues, "lflags", joinStrSet(linkOptionsSet));
+
+ shash_add(&linkValues, "outfile", dstFileName);
+
+ if(fullSrcFileName) {
+ sprintf(temp, "%s.o", dstFileName);
+// shash_add(&linkValues, "srcofile", temp);
+ addSetHead(&relFilesSet, temp);
}
+
+// shash_add(&linkValues, "spec_ofiles", "crt0i.o");
+ shash_add(&linkValues, "ofiles", joinStrSet(relFilesSet));
+ shash_add(&linkValues, "libs", joinStrSet(libFilesSet));
+
+ lcmd = msprintf(linkValues, lfrm);
+
+ ret = my_system( lcmd );
+
+ Safe_free( lcmd );
+
+ if(ret)
+ exit(1);
}
NULL /* no do_assemble function */
},
{
- pic16_linkCmd, /* linker command and arguments */
+ NULL, // pic16_linkCmd, /* linker command and arguments */
NULL, /* alternate macro based form */
- NULL, /* no do_link function */
+ _pic16_linkEdit, //NULL, /* no do_link function */
".o", /* extension for object files */
0 /* no need for linker file */
},
extern set *sectNames;
extern set *sectSyms;
+extern int pic16_mplab_comp;
#endif
pic16_pc_tosh.rIdx = IDX_TOSH;
pic16_pc_tosu.rIdx = IDX_TOSU;
- pic16_pc_tblptrl.rIdx = IDX_TBLPTRL; // patch 15
- pic16_pc_tblptrh.rIdx = IDX_TBLPTRH; // patch 15
- pic16_pc_tblptru.rIdx = IDX_TBLPTRU; // patch 15
- pic16_pc_tablat.rIdx = IDX_TABLAT; // patch 15
+ pic16_pc_tblptrl.rIdx = IDX_TBLPTRL;
+ pic16_pc_tblptrh.rIdx = IDX_TBLPTRH;
+ pic16_pc_tblptru.rIdx = IDX_TBLPTRU;
+ pic16_pc_tablat.rIdx = IDX_TABLAT;
-// pic16_pc_fsr0.rIdx = IDX_FSR0;
pic16_pc_fsr0l.rIdx = IDX_FSR0L;
pic16_pc_fsr0h.rIdx = IDX_FSR0H;
pic16_pc_fsr1l.rIdx = IDX_FSR1L;
PCORB(pcop)->subtype = subt;
/* pCodeOpBit is derived from pCodeOpReg. We need to init this too */
- PCOR(pcop)->r = pic16_dirregWithName(s); //NULL;
+ PCOR(pcop)->r = pic16_regWithName(s); //NULL;
+// fprintf(stderr, "%s:%d %s for reg: %s\treg= %p\n", __FILE__, __LINE__, __FUNCTION__, s, PCOR(pcop)->r);
// PCOR(pcop)->rIdx = 0;
return pcop;
}
if(pcop) {
switch(pcop->type) {
+ case PO_W:
+ case PO_WREG:
case PO_PRODL:
case PO_PRODH:
case PO_INDF0:
}
return buffer;
+ case PO_GPR_REGISTER:
case PO_DIR:
s = buffer;
// size = sizeof(buffer);
if(pcop) {
switch(PCOR2(pcop)->pcop2->type) {
+ case PO_W:
+ case PO_WREG:
case PO_PRODL:
case PO_PRODH:
case PO_INDF0:
// fprintf(stderr, "%s:%d reg = %p\tname= %s, accessBank= %d\n",
// __FUNCTION__, __LINE__, r, (r)?r->name:"<null>", (r)?r->accessBank:-1);
- if(r && !r->accessBank)SAFE_snprintf(&s,&size,", %s", "B");
+ if(r && !r->accessBank)SAFE_snprintf(&s,&size,", %s", (!pic16_mplab_comp?"B":"BANKED"));
}
}
}
break;
case PC_CSOURCE:
// SAFE_snprintf(&s,&size,";#CSRC\t%s %d\t%s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
- SAFE_snprintf(&s,&size,"#LINE\t%d; %s\t%s\n", PCCS(pc)->line_number, PCCS(pc)->file_name, PCCS(pc)->line);
+ SAFE_snprintf(&s,&size,"%s#LINE\t%d; %s\t%s\n", (pic16_mplab_comp?";":""),
+ PCCS(pc)->line_number, PCCS(pc)->file_name, PCCS(pc)->line);
break;
case PC_ASMDIR:
if(PCAD(pc)->directive) {
case PC_CSOURCE:
// fprintf(of,";#CSRC\t%s %d\t\t%s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
- fprintf(of,"#LINE\t%d; %s\t%s\n", PCCS(pc)->line_number, PCCS(pc)->file_name, PCCS(pc)->line);
+ fprintf(of,"%s#LINE\t%d; %s\t%s\n", (pic16_mplab_comp?";":""),
+ PCCS(pc)->line_number, PCCS(pc)->file_name, PCCS(pc)->line);
break;
case PO_GPR_BIT:
return PCOR(PCI(pc)->pcop)->r;
+ case PO_GPR_REGISTER:
case PO_DIR:
// fprintf(stderr, "pic16_getRegFromInstruction - dir\n");
return PCOR(PCI(pc)->pcop)->r;
break;
// return PCOR2(PCI(pc)->pcop)->r;
+ case PO_GPR_REGISTER:
case PO_DIR:
//fprintf(stderr, "pic16_getRegFromInstruction2 - dir\n");
return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r;
static void insertBankSwitch(int position, pCode *pc)
{
pCode *new_pc;
- regs *reg;
if(!pc)
return;
/* emit BANKSEL [symbol] */
- reg = pic16_getRegFromInstruction(pc);
- if(!reg) {
- if(!(PCI(pc)->pcop && PCI(pc)->pcop->type == PO_GPR_BIT))return;
- }
+
new_pc = pic16_newpCodeAsmDir("BANKSEL", "%s", pic16_get_op_from_instruction(PCI(pc)));
// position = 0; // position is always before (sanity check!)
}
#endif
- /* we can be 99% that within a pBlock, between two consequtive
- * refernces to the same register, the extra banksel is needless */
-
-
/* now make some tests to make sure that instruction needs bank switch */
- /* if not no register exists, and if not a bit opcode goto loop */
+ /* if no register exists, and if not a bit opcode goto loop */
if(!reg) {
if(!(PCI(pc)->pcop && PCI(pc)->pcop->type == PO_GPR_BIT))goto loop;
}
if(isPCI_SKIP(pc)) {
// fprintf(stderr, "instruction is SKIP instruction\n");
}
- if((reg && isACCESS_BANK(reg)) || !isBankInstruction(pc))goto loop;
+ if(reg && isACCESS_BANK(reg))goto loop;
+
+ if(!isBankInstruction(pc))goto loop;
if(isPCI_LIT(pc))goto loop;
{
pBlock *pb;
- if(!pic16_picIsInitialized()) {
- fprintf(stderr,"Temporary ERROR: at the moment you have to use\n");
- fprintf(stderr,"an include file create by inc2h.pl. See SDCC source:\n");
- fprintf(stderr,"support/scripts/inc2h.pl\n");
- fprintf(stderr,"this is a nuisance bug that will be fixed shortly\n");
-
- /* I think it took a long long time to fix this bug! ;-) -- VR */
-
- exit(1);
- }
-
/* Phase x - Flow Analysis - Used Banks
*
AnalyzeFlow(0);
AnalyzeFlow(1);
-// for(pb = the_pFile->pbHead; pb; pb = pb->next)
-// BanksUsedFlow(pb);
-
if(!the_pFile)return;
-
if(!pic16_options.no_banksel) {
for(pb = the_pFile->pbHead; pb; pb = pb->next) {
// fprintf(stderr, "%s:%d: Fix register banking in pb= 0x%p\n", __FILE__, __LINE__, pb);
set *pic16_dynDirectBitRegs=NULL;
set *pic16_dynInternalRegs=NULL;
-static hTab *dynDirectRegNames= NULL;
+static hTab *dynDirectRegNames=NULL;
+static hTab *dynAllocRegNames=NULL;
+static hTab *dynProcRegNames=NULL;
//static hTab *regHash = NULL; /* a hash table containing ALL registers */
extern set *sectNames;
reg->wasUsed = 0; // we do not know if they are going to be used at all
reg->accessBank = 1; // implicit add access Bank
+ hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
+
return addSet(&pic16_dynProcessorRegs, reg);
}
}
addSet(&pic16_dynAllocRegs, reg);
+ hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
reg->isFree=0;
while(reg) {
if(STRCASECMP(reg->name, name) == 0) {
+// fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
return(reg);
}
return NULL; // name wasn't found in the hash table
}
+/*-----------------------------------------------------------------*/
+/* pic16_allocregWithName - search for register by name */
+/*-----------------------------------------------------------------*/
+regs *
+pic16_allocregWithName (char *name)
+{
+ int hkey;
+ regs *reg;
+
+ if(!name)
+ return NULL;
+
+ /* hash the name to get a key */
+
+ hkey = regname2key(name);
+
+// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
+
+ reg = hTabFirstItemWK(dynAllocRegNames, hkey);
+
+ while(reg) {
+
+ if(STRCASECMP(reg->name, name) == 0) {
+ return(reg);
+ }
+
+ reg = hTabNextItemWK (dynAllocRegNames);
+
+ }
+
+ return NULL; // name wasn't found in the hash table
+
+}
+
+
+/*-----------------------------------------------------------------*/
+/* pic16_procregWithName - search for register by name */
+/*-----------------------------------------------------------------*/
+regs *
+pic16_procregWithName (char *name)
+{
+ int hkey;
+ regs *reg;
+
+ if(!name)
+ return NULL;
+
+ /* hash the name to get a key */
+
+ hkey = regname2key(name);
+
+// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
+
+ reg = hTabFirstItemWK(dynProcRegNames, hkey);
+
+ while(reg) {
+
+ if(STRCASECMP(reg->name, name) == 0) {
+ return(reg);
+ }
+
+ reg = hTabNextItemWK (dynProcRegNames);
+
+ }
+
+ return NULL; // name wasn't found in the hash table
+
+}
+
+regs *pic16_regWithName(char *name)
+{
+ regs *reg;
+
+ reg = pic16_dirregWithName( name );
+ if(reg)return reg;
+
+ reg = pic16_procregWithName( name );
+ if(reg)return reg;
+
+ reg = pic16_allocregWithName( name );
+ if(reg)return reg;
+
+ return NULL;
+}
+
/*-----------------------------------------------------------------*/
/* pic16_allocDirReg - allocates register of given type */
name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
+ if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
+ || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
+
+#if 0
+ if(pic16_debug_verbose) {
+ fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
+ IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_STACK( OP_SYM_ETYPE(op)),
+ SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
+ IS_REGPARM(OP_SYM_ETYPE(op)),
+ IS_PARM(op));
+
+ fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
+ OP_SYMBOL(op)->name);
+ }
+#endif
+
+ }
+
+
+
+ if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
+// fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
+ return NULL;
+ }
+
if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
if(pic16_debug_verbose)
{
debugAopGet(NULL, op);
}
- if (IS_CODE ( OP_SYM_ETYPE(op)) )
- return NULL;
-
- /* First, search the hash table to see if there is a register with this name */
- if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
- reg=NULL;
-// reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
-#if 0
- if(!reg)
- fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
- __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
- else
- fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
- __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
-#endif
- } else {
-// fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
-
- reg = pic16_dirregWithName(name);
- }
+ reg = pic16_dirregWithName(name);
if(!reg) {
int address = 0;
/* Register wasn't found in hash, so let's create
* a new one and put it in the hash table AND in the
* dynDirectRegNames set */
- if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
+ if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
return NULL;
}
-#ifndef USE_ONSTACK
if(OP_SYMBOL(op)->onStack) {
fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
- OP_SYMBOL(op)->onStack = 0;
- SPEC_OCLS(OP_SYM_ETYPE(op)) = data;
- regtype = REG_GPR;
- return (reg);
-#endif
}
- if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
+ if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
+ || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
+
+#if 0
if(pic16_debug_verbose)
{
fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
OP_SYMBOL(op)->name);
}
+#endif
}
reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
} else {
// fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
// addSet(&pic16_dynDirectRegs, reg);
+
checkAddReg(&pic16_dynDirectRegs, reg);
}
} else {
// debugLog (" -- %s is declared at address 0x30000x\n",name);
- return NULL;
+ return (reg); /* This was NULL before, but since we found it
+ * why not just return it?! */
}
if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
* a new one and put it in the hash table AND in the
* dynDirectRegNames set */
-// fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
+ fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
debugLog ("Found a Dynamic Register!\n");
} else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
debugLog ("Found a Stack Register!\n");
- } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
+ } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
debugLog ("Found a Processor Register!\n");
fprintf(stderr, "Found a processor register! %s\n", dReg->name);
} else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
{
packBits(pic16_dynDirectBitRegs);
+// fprintf(stderr, "%s: pic16_dynAllocRegs\n", __FUNCTION__);
pic16_groupRegistersInSection(pic16_dynAllocRegs);
+
+// fprintf(stderr, "%s: pic16_dynInternalRegs\n", __FUNCTION__);
pic16_groupRegistersInSection(pic16_dynInternalRegs);
+
+// fprintf(stderr, "%s: pic16_dynStackRegs\n", __FUNCTION__);
pic16_groupRegistersInSection(pic16_dynStackRegs);
+
+// fprintf(stderr, "%s: pic16_dynDirectRegs\n", __FUNCTION__);
pic16_groupRegistersInSection(pic16_dynDirectRegs);
+
+// fprintf(stderr, "%s: pic16_dynDirectBitsRegs\n", __FUNCTION__);
pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
+
+// fprintf(stderr, "%s: pic16_dynProcessorRegs\n", __FUNCTION__);
pic16_groupRegistersInSection(pic16_dynProcessorRegs);
if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
OP_SYMBOL (IC_RESULT (ic))->iaccess)
{
-
-#ifndef USE_ONSTACK
- /* clear the onStack flag, the port doesn't support it yet! FIXME */
- if(OP_SYMBOL(IC_RESULT(ic))->onStack) {
- OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
- return 0;
- }
-#endif
-
-
/* the operation has only one symbol
operator then we can pack */
if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
if ((ic->op == '+' || ic->op == '-') &&
OP_SYMBOL (IC_RIGHT (dic))->onStack)
{
-
-#if USE_ONSTACK
- if(OP_SYMBOL(IC_RESULT(ic))->onStack) {
- OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
- return NULL;
- }
-#endif
-
if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
#include "pcoderegs.h"
extern unsigned int stackPos;
+extern unsigned int stackLen;
enum
{
regs *pic16_regWithIdx (int);
regs *pic16_typeRegWithIdx(int, int, int);
regs *pic16_dirregWithName (char *name );
+regs *pic16_allocregWithName(char *name);
+regs *pic16_regWithName(char *name);
void pic16_freeAllRegs ();
void pic16_deallocateAllRegs ();
regs *pic16_findFreeReg(short type);
#define IDX_FSR0 0xfe9
#define IDX_FSR0L 0xfe9
#define IDX_FSR0H 0xfea
+
+#define IDX_FSR1 0xfe1
#define IDX_FSR1L 0xfe1
#define IDX_FSR1H 0xfe2
+
+#define IDX_FSR2 0xfd9
#define IDX_FSR2L 0xfd9
#define IDX_FSR2H 0xfda