From: vrokas Date: Sat, 24 Jul 2004 11:25:56 +0000 (+0000) Subject: * src/SDCCmain.c (parseCmdLine): when sOpt is 'I' add rest in X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=1b41c07c9632988c16a3bd08b09fd7d5430a35ac;p=fw%2Fsdcc * src/SDCCmain.c (parseCmdLine): when sOpt is 'I' add rest in includeDirsSet, too, * src/SDCCsymt.c (checkSClass): don't emit error when a variable, const char [] is found in function prototype... * src/pic16/genarith.c (pic16_genUMult8XLit_8): optimization to omit moving to WREG with source is already in WREG, * src/pic16/gen.h: added AOP_FSR0 and AOP_FSR2 in enum, * src/pic16/gen.c (getFreePtr): updated to look for FSR0 and FSR2, * (aopForSym): stack'ed symbols are partially supported, added if-clause to support symbols in FARSPACE, * (sameRegs): added test for AOP_ACC to see if registers are same, * (pic16_freeAsmop): added case for AOP_FSR0 and AOP_FSR2, * (pic16_aopGet): added case for AOP_FSR0 and AOP_FSR2, * (pic16_popRegFromString): will not allocate a new register if it doesn't find one by name, bug may have introduced... * (pic16_popGet): added case for AOP_FSR0 and AOP_FSR2, * (genIpush): revived to use pic16 port's stack, * (genAddrOf): added incomplete case for stack'ed operand, * (genCast): optimized a pair of MOVFW,MOVWF to MOVFF * src/pic16/genutils.c (pic16_genNot): almot new vesrion for NOT, can handle multibyte operands, * src/pic16/glue.c (pic16_printIval*): some debug info added, * (pic16initialComments): added message for MPLAB compatibility mode enabled, * src/pic16/main.h: prototype for pic16_mplab_comp, * src/pic16/main.c (pic16_optionsTable): new option --mplab-comp, which enabled MPLAB compatibility mode (i.e. no #LINE/#FILE, BANKED) * (_pic16_linkEdit): NEW, handles link stage, transferred here because of increased complexity of procedure, * src/pic16/pcode.c (pic16_newpCodeOpBit): using pic16_regWithName to search for register, * (pic16_get_op, pic16_get_op2): added case for PO_W, PO_WREG and PO_GPR_REGISTER, * (pic16_pCode2str): when in MPLAB compatibility mode, comment out #LINE directives and replace 'B' with 'BANKED' in instruction opcodes * (pic16_getRegFromInstruction, pic16_getRegFromInstruction2): added case for PO_GPR_REGISTER, * (pic16_AnalyzeBanking): removed the old message for inc2h.pl, past dies, the new era is ahead !... * src/pic16/ralloc.c: added hash reposits pic16_dynAllocRegNames and pic16_dynInternalRegs, * (pic16_allocregWithName, pic16_procregWithName, pic16_regWithname): NEW, * (pic16_allocDirReg): minor optimizations and bug fixes, * (pic16_allocWithIdx): when searching pic16_dynProcessorRegs use fixed, git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3391 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/device/lib/pic16/startup/Makefile b/device/lib/pic16/startup/Makefile index ba2b341b..f13ee80d 100644 --- a/device/lib/pic16/startup/Makefile +++ b/device/lib/pic16/startup/Makefile @@ -47,3 +47,13 @@ clean: 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 diff --git a/device/lib/pic16/startup/crt0.c b/device/lib/pic16/startup/crt0.c index a6d134de..34692f1f 100644 --- a/device/lib/pic16/startup/crt0.c +++ b/device/lib/pic16/startup/crt0.c @@ -10,6 +10,7 @@ */ extern stack; +extern stack_end; extern TBLPTRU; @@ -35,8 +36,8 @@ void _startup (void) { _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 diff --git a/device/lib/pic16/startup/crt0i.c b/device/lib/pic16/startup/crt0i.c index 487403f6..45e3af77 100644 --- a/device/lib/pic16/startup/crt0i.c +++ b/device/lib/pic16/startup/crt0i.c @@ -11,6 +11,7 @@ */ extern stack; +extern stack_end; extern TBLPTRU; extern TBLPTRH; @@ -45,8 +46,8 @@ void _startup (void) { _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 diff --git a/device/lib/pic16/startup/crt0iz.c b/device/lib/pic16/startup/crt0iz.c index a557301a..f9105a76 100644 --- a/device/lib/pic16/startup/crt0iz.c +++ b/device/lib/pic16/startup/crt0iz.c @@ -11,6 +11,7 @@ */ extern stack; +extern stack_end; extern TBLPTRU; extern TBLPTRH; @@ -46,8 +47,8 @@ void _startup (void) { _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 diff --git a/src/SDCCmain.c b/src/SDCCmain.c index 9aa914aa..4fef51b9 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -1179,6 +1179,7 @@ parseCmdLine (int argc, char **argv) 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; diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index e9b76c7d..b621774b 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -1475,6 +1475,7 @@ checkSClass (symbol * sym, int isProto) /* 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) && diff --git a/src/pic16/device.c b/src/pic16/device.c index 1126b69b..bbc23023 100644 --- a/src/pic16/device.c +++ b/src/pic16/device.c @@ -465,6 +465,7 @@ static int num_of_supported_PICS = sizeof(Pics16)/sizeof(PIC16_device); 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); @@ -962,10 +963,11 @@ void pic16_groupRegistersInSection(set *regset) 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; diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 464bab94..49dbd235 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -6,7 +6,7 @@ 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 @@ -76,6 +76,8 @@ static int max_key=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 ); @@ -122,10 +124,12 @@ static char *accUse[] = {"WREG"}; static struct { short r0Pushed; short r1Pushed; + short fsr0Pushed; short accInUse; short inLine; short debugLine; short nRegsSaved; + short ipushRegs; set *sendSet; int interruptvector; } _G; @@ -357,13 +361,60 @@ pic16_emitDebuggerSymbol (char * debugSym) /*-----------------------------------------------------------------*/ 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 */ @@ -437,6 +488,7 @@ endOfWorld : werror(E_INTERNAL_ERROR,__FILE__,__LINE__, "getFreePtr should never reach here"); exit(0); +#endif } /*-----------------------------------------------------------------*/ @@ -543,15 +595,10 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) * 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 */ @@ -560,27 +607,41 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) 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) { @@ -607,6 +668,8 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) } else aop->aopu.aop_stk = sym->stack; return aop; +#endif + } #endif @@ -661,6 +724,15 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) 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)) { @@ -700,7 +772,7 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) 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) ); @@ -901,6 +973,11 @@ bool pic16_sameRegs (asmop *aop1, asmop *aop2 ) 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 ; @@ -1095,8 +1172,24 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) /* 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) { @@ -1194,6 +1287,39 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) /* 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) @@ -1234,10 +1360,12 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) 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)); @@ -1429,9 +1557,10 @@ static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand 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 { @@ -1549,6 +1678,17 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) 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__); @@ -1594,7 +1734,7 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) 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; @@ -2532,8 +2672,22 @@ static void assignResultValue(operand * oper, int rescall) /*-----------------------------------------------------------------*/ 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; @@ -2736,6 +2890,11 @@ static void genCall (iCode *ic) 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; @@ -2814,6 +2973,10 @@ static void genCall (iCode *ic) 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 )); @@ -2825,7 +2988,7 @@ static void genCall (iCode *ic) /* 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; @@ -2837,6 +3000,7 @@ static void genCall (iCode *ic) for ( i = 0 ; i < ic->parmBytes ;i++) pic16_emitcode("dec","%s",spname); } +#endif #if 0 /* if register bank was saved then pop them */ @@ -3464,6 +3628,8 @@ static void genEndFunction (iCode *ic) return; } + /* add code for ISCRITICAL */ + #if 0 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) { @@ -10485,6 +10651,13 @@ static void genAddrOf (iCode *ic) 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))); @@ -11205,8 +11378,9 @@ static void genCast (iCode *ic) 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++; } diff --git a/src/pic16/gen.h b/src/pic16/gen.h index 9c8c7e05..33c0fa87 100644 --- a/src/pic16/gen.h +++ b/src/pic16/gen.h @@ -43,6 +43,9 @@ enum AOP_STR, AOP_CRY, AOP_ACC, + AOP_FSR0, + AOP_FSR1, + AOP_FSR2, AOP_PCODE }; @@ -154,6 +157,7 @@ void DEBUGpic16_emitcode (char *inst,char *fmt, ...); 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); diff --git a/src/pic16/genarith.c b/src/pic16/genarith.c index 83212de5..7af1e3f7 100644 --- a/src/pic16/genarith.c +++ b/src/pic16/genarith.c @@ -59,45 +59,21 @@ pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst); 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"; @@ -110,58 +86,32 @@ const char *pic16_pCodeOpType(pCodeOp *pcop) 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"; } } @@ -175,58 +125,32 @@ const char *pic16_pCodeOpSubType(pCodeOp *pcop) 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"; } } @@ -1720,7 +1644,8 @@ void pic16_genUMult8XLit_8 (operand *left, 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); @@ -1744,7 +1669,8 @@ void pic16_genUMult8XLit_8 (operand *left, 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))); @@ -1762,7 +1688,8 @@ void pic16_genUMult8XLit_8 (operand *left, 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))); diff --git a/src/pic16/genutils.c b/src/pic16/genutils.c index 25d645cf..1b188c59 100644 --- a/src/pic16/genutils.c +++ b/src/pic16/genutils.c @@ -69,12 +69,14 @@ 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); @@ -94,12 +96,22 @@ void pic16_genNot (iCode *ic) } 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 */ diff --git a/src/pic16/genutils.h b/src/pic16/genutils.h index 358c4ed2..6c94e8ba 100644 --- a/src/pic16/genutils.h +++ b/src/pic16/genutils.h @@ -27,9 +27,6 @@ void pic16_genCpl(iCode *ic); /* * 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); diff --git a/src/pic16/glue.c b/src/pic16/glue.c index 3921c2cb..2dfe5e4b 100644 --- a/src/pic16/glue.c +++ b/src/pic16/glue.c @@ -132,17 +132,17 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag) 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) */ @@ -297,6 +297,8 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag) 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:"<>")); #if 1 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) { if(!strcmp(ssym->name, reg->name))found=1; @@ -570,6 +572,8 @@ void pic16_printGPointerType (const char *iname, const char *oname, const unsign } +/* set to 0 to disable debug messages */ +#define DEBUG_PRINTIVAL 1 /*-----------------------------------------------------------------*/ /* pic16_printIvalType - generates ival for int/char */ @@ -582,6 +586,11 @@ pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, // 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; @@ -635,8 +644,10 @@ pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, voi if(!p) return 0; +#if DEBUG_PRINTIVAL + fprintf(stderr, "%s\n",__FUNCTION__); +#endif - // fprintf(stderr, "%s\n",__FUNCTION__); if (!s) { @@ -682,6 +693,9 @@ pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist, 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 */ @@ -748,6 +762,11 @@ void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void * int size =0; +#if DEBUG_PRINTIVAL + fprintf(stderr, "%s\n",__FUNCTION__); +#endif + + do { unsigned long i; val = list2val(lilist); @@ -804,6 +823,11 @@ void pic16_printIvalStruct (symbol * sym, sym_link * type, symbol *sflds; initList *iloop = NULL; + +#if DEBUG_PRINTIVAL + fprintf(stderr, "%s\n",__FUNCTION__); +#endif + sflds = SPEC_STRUCT (type)->fields; if (ilist) { @@ -843,7 +867,10 @@ int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char pty 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); @@ -1259,6 +1286,7 @@ CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__, // 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; @@ -1380,10 +1408,11 @@ pic16createInterruptVect (FILE * vFile) 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); } /*-----------------------------------------------------------------*/ @@ -1394,7 +1423,7 @@ pic16printPublics (FILE *afile) { symbol *sym; - fprintf (afile, "%s", iComments2); + fprintf (afile, "\n%s", iComments2); fprintf (afile, "; public variables in this module\n"); fprintf (afile, "%s", iComments2); @@ -1410,7 +1439,11 @@ pic16_printExterns(FILE *afile) { 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); @@ -1569,9 +1602,9 @@ pic16glue () 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 */ diff --git a/src/pic16/main.c b/src/pic16/main.c index 2cdd52ba..8598b4f1 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -118,19 +118,22 @@ _pic16_init (void) 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 } @@ -163,23 +166,44 @@ _process_pragma(const char *sz) } } - /* #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 */ @@ -259,11 +283,12 @@ _process_pragma(const char *sz) #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; @@ -291,6 +316,7 @@ OPTION pic16_optionsTable[]= { { 0, "--denable-peeps", &pic16_enable_peeps, "explicit enable of peepholes"}, { 0, IVT_LOC, NULL, " 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} }; @@ -382,13 +408,65 @@ static void _pic16_initPaths(void) /* 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); } @@ -711,9 +789,9 @@ PORT pic16_port = 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 */ }, diff --git a/src/pic16/main.h b/src/pic16/main.h index 6bda4099..5870c9ea 100644 --- a/src/pic16/main.h +++ b/src/pic16/main.h @@ -32,5 +32,6 @@ extern set *absSymSet; extern set *sectNames; extern set *sectSyms; +extern int pic16_mplab_comp; #endif diff --git a/src/pic16/pcode.c b/src/pic16/pcode.c index f2744b3b..f4ec7207 100644 --- a/src/pic16/pcode.c +++ b/src/pic16/pcode.c @@ -2871,12 +2871,11 @@ void pic16_pCodeInitRegisters(void) 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; @@ -3989,7 +3988,8 @@ pCodeOp *pic16_newpCodeOpBit(char *s, int bit, int inBitSpace, PIC_OPTYPE subt) 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; } @@ -4447,6 +4447,8 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size) if(pcop) { switch(pcop->type) { + case PO_W: + case PO_WREG: case PO_PRODL: case PO_PRODH: case PO_INDF0: @@ -4492,6 +4494,7 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size) } return buffer; + case PO_GPR_REGISTER: case PO_DIR: s = buffer; // size = sizeof(buffer); @@ -4543,6 +4546,8 @@ char *pic16_get_op2(pCodeOp *pcop,char *buffer, size_t size) if(pcop) { switch(PCOR2(pcop)->pcop2->type) { + case PO_W: + case PO_WREG: case PO_PRODL: case PO_PRODH: case PO_INDF0: @@ -4706,7 +4711,7 @@ char *pic16_pCode2str(char *str, size_t size, pCode *pc) // fprintf(stderr, "%s:%d reg = %p\tname= %s, accessBank= %d\n", // __FUNCTION__, __LINE__, r, (r)?r->name:"", (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")); } } } @@ -4738,7 +4743,8 @@ char *pic16_pCode2str(char *str, size_t size, pCode *pc) 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) { @@ -4829,7 +4835,8 @@ static void genericPrint(FILE *of, pCode *pc) 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; @@ -5396,6 +5403,7 @@ regs * pic16_getRegFromInstruction(pCode *pc) 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; @@ -5475,6 +5483,7 @@ regs * pic16_getRegFromInstruction2(pCode *pc) 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; @@ -5987,17 +5996,13 @@ extern int pic16_labelOffset; 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!) @@ -6535,13 +6540,9 @@ static void pic16_FixRegisterBanking(pBlock *pb) } #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; } @@ -6549,7 +6550,9 @@ static void pic16_FixRegisterBanking(pBlock *pb) 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; @@ -6779,17 +6782,6 @@ void pic16_AnalyzeBanking(void) { 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 * @@ -6800,12 +6792,8 @@ void pic16_AnalyzeBanking(void) 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); diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index 991d78f1..27df5684 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -77,7 +77,9 @@ set *pic16_dynDirectRegs=NULL; 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; @@ -459,6 +461,8 @@ pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias) 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); } @@ -505,6 +509,7 @@ allocReg (short type) } addSet(&pic16_dynAllocRegs, reg); + hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg); reg->isFree=0; @@ -552,6 +557,7 @@ pic16_dirregWithName (char *name) 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); } @@ -562,6 +568,91 @@ pic16_dirregWithName (char *name) 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 */ @@ -580,6 +671,35 @@ pic16_allocDirReg (operand *op ) 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) { @@ -617,27 +737,8 @@ pic16_allocDirReg (operand *op ) 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; @@ -652,24 +753,21 @@ pic16_allocDirReg (operand *op ) /* 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", @@ -683,6 +781,7 @@ pic16_allocDirReg (operand *op ) 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); @@ -701,12 +800,14 @@ pic16_allocDirReg (operand *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)) ) { @@ -747,7 +848,7 @@ pic16_allocRegByName (char *name, int size, operand *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); @@ -847,7 +948,7 @@ pic16_allocWithIdx (int idx) 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 ) { @@ -1047,11 +1148,22 @@ void pic16_writeUsedRegs(FILE *of) { 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); @@ -2851,16 +2963,6 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) 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))) || @@ -2957,14 +3059,6 @@ findAssignToSym (operand * op, iCode * ic) 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) diff --git a/src/pic16/ralloc.h b/src/pic16/ralloc.h index e2ab7d37..71124bbb 100644 --- a/src/pic16/ralloc.h +++ b/src/pic16/ralloc.h @@ -32,6 +32,7 @@ #include "pcoderegs.h" extern unsigned int stackPos; +extern unsigned int stackLen; enum { @@ -111,6 +112,8 @@ extern set *pic16_int_regs; 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); @@ -143,8 +146,12 @@ regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alia #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