+2004-01-11 Vangelis Rokas <vrokas@otenet.gr>
+
+ SDCC source changes:
+ * src/SDCCopt.c (cntToFcall, cnvToFloatCast, cnvFromFloatCast,
+ convilong): modified to inform the pic16 port that builtin functions
+ are external
+
+ PIC16 PORT specific changes:
+ * src/pic16/device.c pic16_dump_equates() added,
+ processor registers declared internally by the port are emitted in
+ the translation as equates,
+ * src/pic16/gen.c: inline code is passed unprocessed to the
+ translation,
+ * (pic16_popGetLit2): fnuction modified to take second operand as
+ pCodeOp pointer and not as literal,
+ * (popRegFromIdx): prefixed with pic16_,
+ * (pic16_popCombine2): modified to receive already allocated pCode
+ operands,
+ * (pic16_pushpCodeOpReg, pic16_poppCodeOpReg): added
+ * (genFunction): initializes local stack frame and pushes on stack
+ all the registers used by this function,
+ * (genEndFunction): restores all registers from stack and restores
+ stack frame,
+ * src/pic16/glue.c (pic16emitRegularMap): various changes and
+ improvements,
+ * (pic16glue): changed the program startup sequence,
+ * added new dbName code 'A' for functions placed in absolute section
+ * src/pic16/main.c: added function attribute _naked,
+ * added pragma 'code' to place a fnuction at an absolute address,
+ * added command line arguments --debug-ralloc and --pcode-verbose,
+ * (_pic16_finiliseOptions): options.all_callee_saves is set by default
+ * src/pic16/pcode.c (pic16_pBlockConvert2Absolute) added,
+ * (pic16_newpCodeOpLit2): modified to take the second operand as
+ pCodeOp pointer,
+ * (pic16_printpBlock): modified to emit each function in a separate
+ section,
+ * (pic16_get_op): modified to use the gpasm modifiers LOW,HIGH and
+ UPPER for immediate operands,
+ * src/pic16/pcodepeeph.c: added peephole support for the LFSR
+ instruction,
+ * src/pic16/peeph.def: all peepholes with movff are commented out,
+ because there is a problem in the pcode peep optimizer,
+ * src/pic16/ralloc.c: the register allocator can now reuse local
+ function symbols for another function. This saves register usage.
+ * src/pic16/ralloc.h: added flag isLocal in structure regs,
+
+ Added file src/pic16/NOTES with information about program writing on
+ the current port version.
+
2004-01-11 Frieder Ferlemann <Frieder.Ferlemann@web.de>
* src/mcs51/peephole.def: added peepholes 177.c,d (redundant moves)
IC_RESULT (newic) = IC_RESULT (ic);
newic->lineno = lineno;
newic->parmBytes+=bytesPushed;
+
+ if(TARGET_IS_PIC16) {
+ /* normally these functions aren't marked external, so we can use their
+ * _extern field to marked as already added to symbol table */
+
+ if(!SPEC_EXTR(func->etype)) {
+ memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+
+ SPEC_EXTR(func->etype) = 1;
+ seg = SPEC_OCLS( func->etype );
+ addSet(&seg->syms, func);
+ }
+ }
+
addiCodeToeBBlock (ebp, newic, ip);
}
newic = newiCode (CALL, operandFromSymbol (func), NULL);
IC_RESULT (newic) = IC_RESULT (ic);
newic->parmBytes+=bytesPushed;
+
+ if(TARGET_IS_PIC16) {
+ /* normally these functions aren't marked external, so we can use their
+ * _extern field to marked as already added to symbol table */
+
+ if(!SPEC_EXTR(func->etype)) {
+ memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+
+ SPEC_EXTR(func->etype) = 1;
+ seg = SPEC_OCLS( func->etype );
+ addSet(&seg->syms, func);
+ }
+ }
+
addiCodeToeBBlock (ebp, newic, ip);
newic->lineno = linenno;
-
}
/*-----------------------------------------------------------------*/
newic = newiCode (CALL, operandFromSymbol (func), NULL);
IC_RESULT (newic) = IC_RESULT (ic);
newic->parmBytes+=bytesPushed;
+
+ if(TARGET_IS_PIC16) {
+ /* normally these functions aren't marked external, so we can use their
+ * _extern field to marked as already added to symbol table */
+
+ if(!SPEC_EXTR(func->etype)) {
+ memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+
+ SPEC_EXTR(func->etype) = 1;
+ seg = SPEC_OCLS( func->etype );
+ addSet(&seg->syms, func);
+ }
+ }
+
addiCodeToeBBlock (ebp, newic, ip);
newic->lineno = lineno;
-
}
extern operand *geniCodeRValue (operand *, bool);
IC_RESULT (newic) = IC_RESULT (ic);
newic->lineno = lineno;
newic->parmBytes+=bytesPushed; // to clear the stack after the call
+
+ if(TARGET_IS_PIC16) {
+ /* normally these functions aren't marked external, so we can use their
+ * _extern field to marked as already added to symbol table */
+
+ if(!SPEC_EXTR(func->etype)) {
+ memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+
+ SPEC_EXTR(func->etype) = 1;
+ seg = SPEC_OCLS( func->etype );
+ addSet(&seg->syms, func);
+ }
+ }
+
addiCodeToeBBlock (ebp, newic, ip);
}
--- /dev/null
+NOTES file for SDCC pic16 port
+$Id$
+
+Current pic16 port status is: Development
+
+Some things may change without notification between port updates. The latest
+CVS snapshot is guarenteed to compile without problems, but does not
+guarantee backwards compatibility.
+
+For any questions please ask the current port
+developers.
+
+Current developer:
+Vangelis Rokas <vrokas@otenet.gr>
+
+Other people to contact:
+Scott Dattalo <scott@dattalo.com>
+
+
+
+2004-Jan-11 Vangelis Rokas
+
+1. Compiling
+The current release of the port can produce object code which is not
+completely bug free. To use the new features the user should enable them via
+command line arguments. A sane set of command arguments that I use to test
+programs is:
+
+- debug options
+ --debug enable sdcc debug information
+ --debug-xtra enable pic16 port debug information (most useful)
+ --debug-ralloc enable register allocator debug messages
+ --pcode-verbose enable verbose pcode generator messages
+
+- port options
+ --pgen-banksel enable banksel directives for the assembler
+ This will be turned on by default later, but left as
+ is for now
+ --pomit-config-words does not emit configuration instruction in
+ the translation This is useful when copmiling
+ multiple sources, when you do not want multiple
+ config instructions in the end file
+ --pomit-ivt disables the dumping of the interrupt vector tables
+ in the translation for the same reasons as above
+ --penable-stack enables stack support. This option uses stack to
+ pass function arguments, and reuses registers between
+ functions by saving the registers used in the function
+ on the stack
+
+- compiler options
+ --all-callee-saves you may omit this options as the port
+ enables it by default, all functions are currently
+ compiled as reentrant and they are marked as
+ callee-saves
+ --no-peep peephole optimizer is better to be switched off,
+ because it behaves strangely in some cases
+ --fommit-frame-pointer this omits frame pointer in functions that
+ don't use registers (maybe changed later, not
+ important)
+
+
+2. Functions
+The current implementation puts every function in its own code section in
+PIC's program memory. This may not be the standard, but I think its more
+flexible.
+
+3. Pragmas
+Since SDCC is goind for a release, its better to document pragmas available.
+
+3.1. code
+The 'code' pragma emits a function's code at a specific address in program
+memory. Currently it is only used for functions.
+Syntax:
+#pragma code [function_name] [address]
+
+3.2. stack
+The 'stack' pragma initializes the stack/frame pointer at an address of the
+data ram other than the default (which is the end of the available data ram)
+Synatx:
+#pragma stack [address]
+
+3.3. maxram
+The 'maxram' pragma sets maximum data ram of the device. Currently is not
+used at all, but it may be useful in the future when devices with external
+memory will be supported.
+Syntax:
+#pragma maxram [max_address]
+
+
+4. Internal compiler functions
+Internal SDCC functions like, __fsmul, etc... are currently supported by the
+port, but the libraries for the pic16 port are not yet ready. So one cannot
+use long and float variables.
+
+
+5. Special Function Registers (SFRs)
+The processor SFRs are not anymore declared in any header file. The user can
+define by himself all the needed SFR's. The code to that is:
+
+sfr at [sfr_address] [sfr_name];
+
+Where sfr_address is the SFR address in the data ram, and sfr_name is the
+name of the SFR. i.e.:
+
+sfr at 0xf80 PORTA;
}
#endif
+extern char *iComments2;
-void pic16_dump_section(FILE *of, char *sname, set *section, int fix)
+void pic16_dump_equates(FILE *of, set *equs)
+{
+ regs *r;
+
+ r = setFirstItem(equs);
+ if(!r)return;
+
+ fprintf(of, "%s", iComments2);
+ fprintf(of, ";\tEquates to used internal registers\n");
+ fprintf(of, "%s", iComments2);
+
+ for(; r; r = setNextItem(equs)) {
+ fprintf(of, "%s\tequ\t0x%02x\n", r->name, r->address);
+ }
+}
+
+
+void pic16_dump_section(FILE *of, set *section, int fix)
{
static int abs_section_no=0;
regs *r, *rprev;
for(reg=setFirstItem(regset); reg; reg = setNextItem(regset)) {
if(reg->wasUsed
&& !(reg->regop && SPEC_EXTR(OP_SYM_ETYPE(reg->regop)))) {
- if(reg->isFixed)
+
+ if(reg->alias) {
+ checkAddReg(&pic16_equ_data, reg);
+ } else
+ if(reg->isFixed) {
checkAddReg(&pic16_fix_udata, reg);
-
- if(!reg->isFixed)
+ } else
+ if(!reg->isFixed) {
+// fprintf(stderr, "%s:%d adding symbol %s in relocatable udata section\n",
+// __FILE__, __LINE__, reg->name);
checkAddReg(&pic16_rel_udata, reg);
+ }
}
}
}
#include "gen.h"
#include "genutils.h"
#include "device.h"
+#include "main.h"
extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
void pic16_genMult8X8_8 (operand *, operand *,operand *);
-pCode *pic16_AssembleLine(char *line);
+pCode *pic16_AssembleLine(char *line, int peeps);
extern void pic16_printpBlock(FILE *of, pBlock *pb);
static asmop *newAsmop (short type);
static pCodeOp *pic16_popRegFromString(char *str, int size, int offset);
+extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
static void mov2w (asmop *aop, int offset);
static int aopIdx (asmop *aop, int offset);
}
+void pic16_emitcomment (char *fmt, ...)
+{
+ va_list ap;
+ char lb[INITIAL_INLINEASM];
+ char *lbp = lb;
+
+ if(!pic16_debug_verbose)
+ return;
+
+ va_start(ap,fmt);
+
+ lb[0] = ';';
+ vsprintf(lb+1,fmt,ap);
+
+ while (isspace(*lbp)) lbp++;
+
+ if (lbp && *lbp)
+ lineCurr = (lineCurr ?
+ connectLine(lineCurr,newLineNode(lb)) :
+ (lineHead = newLineNode(lb)));
+ lineCurr->isInline = _G.inLine;
+ lineCurr->isDebug = _G.debugLine;
+
+ pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
+ va_end(ap);
+
+// fprintf(stderr, "%s\n", lb);
+}
+
void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
{
va_list ap;
// fprintf(stderr, "%s\n", lb);
}
-
void pic16_emitpLabel(int key)
{
pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
/*-----------------------------------------------------------------*/
/* pic16_popGetLit2 - asm operator to pcode operator conversion */
/*-----------------------------------------------------------------*/
-pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2)
+pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2)
{
- return pic16_newpCodeOpLit2(lit, lit2);
+ return pic16_newpCodeOpLit2(lit, arg2);
}
return pcop;
}
-static pCodeOp *popRegFromIdx(int rIdx)
+static pCodeOp *pic16_popRegFromIdx(int rIdx)
{
pCodeOp *pcop;
- DEBUGpic16_emitcode ("; ***","%s,%d , rIdx=0x%x",
- __FUNCTION__,__LINE__,rIdx);
-
- pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+// DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
- PCOR(pcop)->rIdx = rIdx;
- PCOR(pcop)->r = pic16_regWithIdx(rIdx);
- PCOR(pcop)->r->isFree = 0;
- PCOR(pcop)->r->wasUsed = 1;
-
- pcop->type = PCOR(pcop)->r->pc_type;
+ pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+ PCOR(pcop)->rIdx = rIdx;
+ PCOR(pcop)->r = pic16_regWithIdx(rIdx);
+ PCOR(pcop)->r->isFree = 0;
+ PCOR(pcop)->r->wasUsed = 1;
+ pcop->type = PCOR(pcop)->r->pc_type;
return pcop;
}
pCodeOp *temp;
pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
+
+ /* comment the following check, so errors to throw up */
+// if(!pcop2)return NULL;
+
temp = pic16_popGet(aop_dst, offset);
pcop2->pcop2 = temp;
return PCOP(pcop2);
}
-pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst)
+/*---------------------------------------------------------------------------------*/
+/* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
+/* movff instruction */
+/*---------------------------------------------------------------------------------*/
+pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
{
pCodeOpReg2 *pcop2;
- pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
- pcop2->pcop2 = pic16_popCopyReg(dst);
+ if(!noalloc) {
+ pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
+ pcop2->pcop2 = pic16_popCopyReg(dst);
+ } else {
+ /* the pCodeOp may be already allocated */
+ pcop2 = (pCodeOpReg2 *)(src);
+ pcop2->pcop2 = (pCodeOp *)(dst);
+ }
return PCOP(pcop2);
}
+
/*-----------------------------------------------------------------*/
/* pic16_popGet - asm operator to pcode operator conversion */
/*-----------------------------------------------------------------*/
case AOP_DPTR2:
case AOP_ACC:
DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
+ fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
return NULL;
case AOP_IMMD:
}
+void pic16_pushpCodeOpReg(pCodeOpReg *pcop)
+{
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2(pcop, &pic16_pc_postdec1, 0));
+}
+
+void pic16_poppCodeOpReg(pCodeOpReg *pcop)
+{
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, pcop, 0));
+}
+
+
/*-----------------------------------------------------------------*/
/* pushw - pushes wreg to stack */
/*-----------------------------------------------------------------*/
void pushaop(asmop *aop, int offset)
{
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1));
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
}
-#if 0
/*-----------------------------------------------------------------*/
/* popaop - pops aop from stack */
/*-----------------------------------------------------------------*/
void popaop(asmop *aop, int offset)
{
- DEBUG
+ DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
}
-#endif
void popaopidx(asmop *aop, int offset, int index)
{
if(STACK_MODEL_LARGE)ofs++;
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
- pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset))));
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
}
/*-----------------------------------------------------------------*/
if(USE_STACK) {
popaopidx(AOP(oper), size, GpsuedoStkPtr);
} else {
- pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
}
#else
- pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
#endif /* STACK_SUPPORT */
GpsuedoStkPtr++;
pushw();
--psuedoStkPtr; // sanity check
} else {
- pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
}
#else
- pic16_emitpcode(POC_MOVWF, popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
#endif /* STACK_SUPPORT */
}
}
#if STACK_SUPPORT
- if(USE_STACK) {
+ if(USE_STACK && stackParms>0) {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
if(STACK_MODEL_LARGE) {
#endif
/* adjust the stack for parameters if required */
- fprintf(stderr, "%s:%d: ic->parmBytes= %d\n", __FILE__, __LINE__, ic->parmBytes);
+// fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
if (ic->parmBytes) {
int i;
/*-----------------------------------------------------------------*/
static void genFunction (iCode *ic)
{
- symbol *sym;
- sym_link *ftype;
+ symbol *sym;
+ sym_link *ftype;
- DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
+ DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
- labelOffset += (max_key+4);
- max_key=0;
- GpsuedoStkPtr=0;
- _G.nRegsSaved = 0;
- /* create the function header */
- pic16_emitcode(";","-----------------------------------------");
- pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
- pic16_emitcode(";","-----------------------------------------");
+ labelOffset += (max_key+4);
+ max_key=0;
+ GpsuedoStkPtr=0;
+ _G.nRegsSaved = 0;
+ /* create the function header */
+ pic16_emitcode(";","-----------------------------------------");
+ pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
+ pic16_emitcode(";","-----------------------------------------");
- pic16_emitcode("","%s:",sym->rname);
- pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
+ pic16_emitcode("","%s:",sym->rname);
+ pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
- ftype = operandType(IC_LEFT(ic));
+ {
+ absSym *ab;
- /* if critical function then turn interrupts off */
- if (IFFUNC_ISCRITICAL(ftype))
- pic16_emitcode("clr","ea");
+ for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
+ if(strcmp(ab->name, sym->name)) {
+ pic16_pBlockConvert2Absolute(pb);
+ break;
+ }
+
+ }
- /* here we need to generate the equates for the
- register bank if required */
-#if 0
- if (FUNC_REGBANK(ftype) != rbank) {
- int i ;
-
- rbank = FUNC_REGBANK(ftype);
- for ( i = 0 ; i < pic16_nRegs ; i++ ) {
- if (strcmp(regspic16[i].base,"0") == 0)
- pic16_emitcode("","%s = 0x%02x",
- regspic16[i].dname,
- 8*rbank+regspic16[i].offset);
- else
- pic16_emitcode ("","%s = %s + 0x%02x",
- regspic16[i].dname,
- regspic16[i].base,
- 8*rbank+regspic16[i].offset);
- }
- }
-#endif
+ ftype = operandType(IC_LEFT(ic));
- /* if this is an interrupt service routine then
- save acc, b, dpl, dph */
- if (IFFUNC_ISISR(sym->type)) {
+ if(IFFUNC_ISNAKED(ftype)) {
+ DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
+ return;
+ }
+
+
+ /* if critical function then turn interrupts off */
+ if (IFFUNC_ISCRITICAL(ftype))
+ pic16_emitcode("clr","ea");
+ /* here we need to generate the equates for the
+ * register bank if required */
#if 0
- pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
-
- /* what is the reason of having these 3 NOPS? VR - 030701 */
- pic16_emitpcodeNULLop(POC_NOP);
- pic16_emitpcodeNULLop(POC_NOP);
- pic16_emitpcodeNULLop(POC_NOP);
+ if (FUNC_REGBANK(ftype) != rbank) {
+ int i ;
+
+ rbank = FUNC_REGBANK(ftype);
+ for ( i = 0 ; i < pic16_nRegs ; i++ ) {
+ if (strcmp(regspic16[i].base,"0") == 0)
+ pic16_emitcode("","%s = 0x%02x",
+ regspic16[i].dname,
+ 8*rbank+regspic16[i].offset);
+ else
+ pic16_emitcode ("","%s = %s + 0x%02x",
+ regspic16[i].dname,
+ regspic16[i].base,
+ *rbank+regspic16[i].offset);
+ }
+ }
#endif
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
- pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
- pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
+ /* if this is an interrupt service routine then
+ * save acc, b, dpl, dph */
+ if (IFFUNC_ISISR(sym->type)) {
+ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
+ pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
+ pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
+ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
- pic16_pBlockConvert2ISR(pb);
+ pic16_pBlockConvert2ISR(pb);
#if 0
- if (!inExcludeList("acc"))
- pic16_emitcode ("push","acc");
- if (!inExcludeList("b"))
- pic16_emitcode ("push","b");
- if (!inExcludeList("dpl"))
- pic16_emitcode ("push","dpl");
- if (!inExcludeList("dph"))
- pic16_emitcode ("push","dph");
- if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
- {
- pic16_emitcode ("push", "dpx");
- /* Make sure we're using standard DPTR */
- pic16_emitcode ("push", "dps");
- pic16_emitcode ("mov", "dps, #0x00");
- if (options.stack10bit)
- {
- /* This ISR could conceivably use DPTR2. Better save it. */
- pic16_emitcode ("push", "dpl1");
- pic16_emitcode ("push", "dph1");
- pic16_emitcode ("push", "dpx1");
- }
- }
- /* if this isr has no bank i.e. is going to
- run with bank 0 , then we need to save more
- registers :-) */
- if (!FUNC_REGBANK(sym->type)) {
+ if (!inExcludeList("acc"))
+ pic16_emitcode ("push","acc");
+ if (!inExcludeList("b"))
+ pic16_emitcode ("push","b");
+ if (!inExcludeList("dpl"))
+ pic16_emitcode ("push","dpl");
+ if (!inExcludeList("dph"))
+ pic16_emitcode ("push","dph");
+
+ if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) {
+ pic16_emitcode ("push", "dpx");
+
+ /* Make sure we're using standard DPTR */
+ pic16_emitcode ("push", "dps");
+ pic16_emitcode ("mov", "dps, #0x00");
+ if (options.stack10bit) {
+ /* This ISR could conceivably use DPTR2. Better save it. */
+ pic16_emitcode ("push", "dpl1");
+ pic16_emitcode ("push", "dph1");
+ pic16_emitcode ("push", "dpx1");
+ }
+ }
- /* if this function does not call any other
- function then we can be economical and
- save only those registers that are used */
- if (! IFFUNC_HASFCALL(sym->type)) {
- int i;
+ /* if this isr has no bank i.e. is going to
+ * run with bank 0 , then we need to save more
+ * registers :-) */
+ if (!FUNC_REGBANK(sym->type)) {
+
+ /* if this function does not call any other
+ * function then we can be economical and
+ * save only those registers that are used */
+ if (! IFFUNC_HASFCALL(sym->type)) {
+ int i;
+
+ /* if any registers used */
+ if (sym->regsUsed) {
+ /* save the registers used */
+ for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+ if (bitVectBitValue(sym->regsUsed,i) ||
+ (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
+ pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
+ }
+ }
- /* if any registers used */
- if (sym->regsUsed) {
- /* save the registers used */
- for ( i = 0 ; i < sym->regsUsed->size ; i++) {
- if (bitVectBitValue(sym->regsUsed,i) ||
- (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
- pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
- }
+ } else {
+ /* this function has a function call cannot
+ * determines register usage so we will have the
+ * entire bank */
+ saverbank(0,ic,FALSE);
+ }
}
-
- } else {
- /* this function has a function call cannot
- determines register usage so we will have the
- entire bank */
- saverbank(0,ic,FALSE);
- }
- }
#endif
- } else {
- /* if callee-save to be used for this function
- then save the registers being used in this function */
- if (IFFUNC_CALLEESAVES(sym->type)) {
- int i;
-
- /* if any registers used */
- if (sym->regsUsed) {
- /* save the registers used */
- for ( i = 0 ; i < sym->regsUsed->size ; i++) {
- if (bitVectBitValue(sym->regsUsed,i) ||
- (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
- //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
- _G.nRegsSaved++;
- }
- }
- }
- }
-
+ } else {
#if STACK_SUPPORT
- /* emit code to setup stack frame if user enabled,
- * and function is not main() */
+ /* emit code to setup stack frame if user enabled,
+ * and function is not main() */
- fprintf(stderr, "function name: %s\n", sym->name);
- if(USE_STACK && strcmp(sym->name, "main")) {
- /* setup the stack frame */
- pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1));
- pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l));
- if(STACK_MODEL_LARGE)
- pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h));
- }
+// fprintf(stderr, "function name: %s\n", sym->name);
+ if(USE_STACK && strcmp(sym->name, "main")) {
+ if(!options.ommitFramePtr || sym->regsUsed) {
+ /* setup the stack frame */
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
+ if(STACK_MODEL_LARGE)
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
+ }
+ }
#endif
- }
+ /* if callee-save to be used for this function
+ * then save the registers being used in this function */
+ if (IFFUNC_CALLEESAVES(sym->type)) {
+ int i;
+
+// fprintf(stderr, "%s:%d function sym->regsUsed= %p\n", __FILE__, __LINE__, sym->regsUsed);
+
+ /* if any registers used */
+ if (sym->regsUsed
+#if STACK_SUPPORT
+ && USE_STACK
+#endif
+ ) {
+ /* save the registers used */
+ DEBUGpic16_emitcode("; **", "Saving used registers in stack");
+ for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+ if (bitVectBitValue(sym->regsUsed,i)) {
+// fprintf(stderr, "%s:%d function %s uses register %s\n",
+// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
+// pic16_regWithIdx(i)->name);
+
+ pic16_pushpCodeOpReg( PCOR(pic16_popRegFromIdx(i) ));
+// pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
+// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
+// &pic16_pc_postdec1, 0));
+ _G.nRegsSaved++;
+ }
+ }
+ }
+ }
+ }
- /* set the register bank to the desired value */
- if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
- pic16_emitcode("push","psw");
- pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
- }
- if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
+
+#if 0
+ if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
- if (options.useXstack) {
- pic16_emitcode("mov","r0,%s",spname);
- pic16_emitcode("mov","a,_bp");
- pic16_emitcode("movx","@r0,a");
- pic16_emitcode("inc","%s",spname);
- }
- else
- {
- /* set up the stack */
- pic16_emitcode ("push","_bp"); /* save the callers stack */
+ if (options.useXstack) {
+ pic16_emitcode("mov","r0,%s",spname);
+ pic16_emitcode("mov","a,_bp");
+ pic16_emitcode("movx","@r0,a");
+ pic16_emitcode("inc","%s",spname);
+ } else {
+ /* set up the stack */
+ pic16_emitcode ("push","_bp"); /* save the callers stack */
+ }
+ pic16_emitcode ("mov","_bp,%s",spname);
}
- pic16_emitcode ("mov","_bp,%s",spname);
- }
-
+#endif
DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
- /* adjust the stack for the function */
- if (sym->stack) {
+ /* adjust the stack for the function */
+ if (sym->stack) {
+ int i = sym->stack;
- int i = sym->stack;
- if (i > 256 )
- werror(W_STACK_OVERFLOW,sym->name);
+ if (i > 127 )
+ werror(W_STACK_OVERFLOW,sym->name);
- if (i > 3 && sym->recvSize < 4) {
- pic16_emitcode ("mov","a,sp");
- pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
- pic16_emitcode ("mov","sp,a");
-
+ if (i > 3 && sym->recvSize < 4) {
+ pic16_emitcode ("mov","a,sp");
+ pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
+ pic16_emitcode ("mov","sp,a");
+ } else
+ while(i--)
+ pic16_emitcode("inc","sp");
}
- else
- while(i--)
- pic16_emitcode("inc","sp");
- }
- if (sym->xstack) {
+ if (sym->xstack) {
DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
- pic16_emitcode ("mov","a,_spx");
- pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
- pic16_emitcode ("mov","_spx,a");
- }
+ pic16_emitcode ("mov","a,_spx");
+ pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
+ pic16_emitcode ("mov","_spx,a");
+ }
+
}
/*-----------------------------------------------------------------*/
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if(IFFUNC_ISNAKED(sym->type)) {
+ DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
+ return;
+ }
+
+#if 0
if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
{
pic16_emitcode ("mov","%s,_bp",spname);
}
+#endif
/* if use external stack but some variables were
added to the local stack then decrement the
}
+#if 0
if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
if (options.useXstack) {
pic16_emitcode("mov","r0,%s",spname);
pic16_emitcode ("pop","_bp");
}
}
+#endif
/* restore the register bank */
if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
if (IFFUNC_ISCRITICAL(sym->type))
pic16_emitcode("setb","ea");
- if (IFFUNC_CALLEESAVES(sym->type)) {
- int i;
-
- /* if any registers used */
- if (sym->regsUsed) {
+ /* if any registers used */
+ if (sym->regsUsed
+#if STACK_SUPPORT
+ && USE_STACK
+#endif
+ ) {
+ int i;
/* save the registers used */
- for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
- if (bitVectBitValue(sym->regsUsed,i) ||
- (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
- pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
+ DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
+ for ( i = sym->regsUsed->size; i >= 0; i--) {
+ if (bitVectBitValue(sym->regsUsed,i)) {
+// fprintf(stderr, "%s:%d function %s uses register %s\n",
+// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
+// pic16_regWithIdx(i)->name);
+
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
+ &pic16_pc_preinc1,
+ PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+ }
}
- }
-
}
+
/* if debug then send end of function */
if (currFunc) {
* and function is not main() */
if(USE_STACK && strcmp(sym->name, "main")) {
- /* restore stack frame */
- if(STACK_MODEL_LARGE)
+ if(!options.ommitFramePtr || sym->regsUsed) {
+ /* restore stack frame */
+ if(STACK_MODEL_LARGE)
+ pic16_emitpcode(POC_MOVFF,
+ pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2h, 0));
pic16_emitpcode(POC_MOVFF,
- pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2h ));
- pic16_emitpcode(POC_MOVFF,
- pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2l ));
-
-/*
- * I added this because of a mistake in the stack pointers design
- * They should be removed though
-
- pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc2, &pic16_pc_fsr2h));
- pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc2, &pic16_pc_fsr2l));
-*/
+ pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2l, 0));
+ }
}
#endif
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
}
if(size) {
- pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
}
offset++;
}
/* Sigh. thus sucks... */
if(size) {
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
- pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
- pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
} else {
/* Signed char comparison */
/* Special thanks to Nikolai Golovchenko for this snippet */
*bp++ = '\0';
if(*bp1)
- pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
+ pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0));
+ // inline directly, no process
bp1 = bp;
} else {
if (*bp == ':') {
}
}
if ((bp1 != bp) && *bp1)
- pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
+ pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0));
Safe_free(buffer);
poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
+ /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
while (size--) {
if (offset) {
sprintf(buffer,"(%s + %d)",l,offset);
- fprintf(stderr,"oops %s\n",buffer);
+ fprintf(stderr,"%s:%d: oops %s\n",__FILE__, __LINE__, buffer);
} else
sprintf(buffer,"%s",l);
operand *result, *left;
int size;
symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
- pCodeOp *pcop0, *pcop1;
+ pCodeOp *pcop0, *pcop1, *pcop2;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
size = AOP_SIZE(IC_RESULT(ic));
- /* Assume that what we want the address of is in direct addressing space
+ 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)));
+ }
+
+ /* Assume that what we want the address of is in data space
* since there is no stack on the PIC, yet! -- VR */
+ /* low */
+ pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
- pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, 0));
- pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, 0));
-#if 0
- pcop0 = pic16_newpCodeOp(sym->rname, PO_IMMEDIATE);
- PCOI(pcop0)->offset = 0;
- PCOI(pcop0)->index = 0;
- pcop1 = pic16_newpCodeOp(sym->rname, PO_IMMEDIATE);
- PCOI(pcop1)->offset = 1;
- PCOI(pcop1)->index = 0;
-#endif
+ /* high */
+ pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
+
+ /* upper */
+ pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
+
+ if (size == 3) {
+ pic16_emitpcode(POC_MOVLW, pcop0);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+ pic16_emitpcode(POC_MOVLW, pcop1);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+ pic16_emitpcode(POC_MOVLW, pcop2);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
+ } else
if (size == 2) {
pic16_emitpcode(POC_MOVLW, pcop0);
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
/*-----------------------------------------------------------------*/
static void genCast (iCode *ic)
{
- operand *result = IC_RESULT(ic);
- sym_link *ctype = operandType(IC_LEFT(ic));
- sym_link *rtype = operandType(IC_RIGHT(ic));
- operand *right = IC_RIGHT(ic);
- int size, offset ;
-
- DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
- /* if they are equivalent then do nothing */
- if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
- return ;
-
- pic16_aopOp(right,ic,FALSE) ;
- pic16_aopOp(result,ic,FALSE);
-
- DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
-
- /* if the result is a bit */
- if (AOP_TYPE(result) == AOP_CRY) {
- /* if the right size is a literal then
- we know what the value is */
- DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
- if (AOP_TYPE(right) == AOP_LIT) {
-
- pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
- pic16_popGet(AOP(result),0));
+ operand *result = IC_RESULT(ic);
+ sym_link *ctype = operandType(IC_LEFT(ic));
+ sym_link *rtype = operandType(IC_RIGHT(ic));
+ operand *right = IC_RIGHT(ic);
+ int size, offset ;
- if (((int) operandLitValue(right)))
- pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- else
- pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
+ DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* if they are equivalent then do nothing */
+ if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
+ return ;
- goto release;
- }
+ pic16_aopOp(right,ic,FALSE) ;
+ pic16_aopOp(result,ic,FALSE);
- /* the right is also a bit variable */
- if (AOP_TYPE(right) == AOP_CRY) {
+ DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
- emitCLRC;
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
+ /* if the result is a bit */
+ if (AOP_TYPE(result) == AOP_CRY) {
+
+ /* if the right size is a literal then
+ * we know what the value is */
+ DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if (AOP_TYPE(right) == AOP_LIT) {
+ pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
+ pic16_popGet(AOP(result),0));
+
+ if (((int) operandLitValue(right)))
+ pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ else
+ pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ goto release;
+ }
- pic16_emitcode("clrc","");
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_aopPut(AOP(result),"c",0);
- goto release ;
- }
+ /* the right is also a bit variable */
+ if (AOP_TYPE(right) == AOP_CRY) {
+ emitCLRC;
+ pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
+
+ pic16_emitcode("clrc","");
+ pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(right)->aopu.aop_dir,
+ AOP(right)->aopu.aop_dir);
+ pic16_aopPut(AOP(result),"c",0);
+ goto release ;
+ }
- /* we need to or */
- if (AOP_TYPE(right) == AOP_REG) {
- pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
- pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
+ /* we need to or */
+ if (AOP_TYPE(right) == AOP_REG) {
+ pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
+ pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
+ }
+ pic16_toBoolean(right);
+ pic16_aopPut(AOP(result),"a",0);
+ goto release ;
}
- pic16_toBoolean(right);
- pic16_aopPut(AOP(result),"a",0);
- goto release ;
- }
- if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
- int offset = 1;
- size = AOP_SIZE(result);
+ if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
+ int offset = 1;
- DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+ size = AOP_SIZE(result);
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
+ DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
- while (size--)
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
- goto release;
- }
+ while (size--)
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
- /* if they are the same size : or less */
- if (AOP_SIZE(result) <= AOP_SIZE(right)) {
+ goto release;
+ }
- /* if they are in the same place */
- if (pic16_sameRegs(AOP(right),AOP(result)))
- goto release;
+ /* if they are the same size : or less */
+ if (AOP_SIZE(result) <= AOP_SIZE(right)) {
+
+ /* if they are in the same place */
+ if (pic16_sameRegs(AOP(right),AOP(result)))
+ goto release;
- DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+ DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
#if 0
- if (IS_PTR_CONST(rtype))
+ if (IS_PTR_CONST(rtype))
#else
- if (IS_CODEPTR(rtype))
+ if (IS_CODEPTR(rtype))
#endif
- DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
+ DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
+
#if 0
- if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
+ if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
#else
- if (IS_CODEPTR(operandType(IC_RESULT(ic))))
+ if (IS_CODEPTR(operandType(IC_RESULT(ic))))
#endif
- DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
-
- if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
- if(AOP_SIZE(result) <2)
- fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
-
- } else {
-
- /* if they in different places then copy */
- size = AOP_SIZE(result);
- offset = 0 ;
- while (size--) {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-
- //pic16_aopPut(AOP(result),
- // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
- // offset);
-
- offset++;
- }
- }
- goto release;
- }
+ DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
+#if 0
+ if(AOP_TYPE(right) == AOP_IMMD) {
+ pCodeOp *pcop0, *pcop1, *pcop2;
+ symbol *sym = OP_SYMBOL( right );
+
+ size = AOP_SIZE(result);
+ /* low */
+ pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
+ /* high */
+ pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
+ /* upper */
+ pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
+
+ if (size == 3) {
+ pic16_emitpcode(POC_MOVLW, pcop0);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+ pic16_emitpcode(POC_MOVLW, pcop1);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+ pic16_emitpcode(POC_MOVLW, pcop2);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
+ } else
+ if (size == 2) {
+ pic16_emitpcode(POC_MOVLW, pcop0);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_MOVLW, pcop1);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
+ } else {
+ pic16_emitpcode(POC_MOVLW, pcop0);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+ }
+ } else
+#endif
+ if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
+ if(AOP_SIZE(result) <2)
+ fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
+ } else {
+ /* if they in different places then copy */
+ size = AOP_SIZE(result);
+ offset = 0 ;
+ while (size--) {
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+ offset++;
+ }
+ }
+ goto release;
+ }
- /* if the result is of type pointer */
- if (IS_PTR(ctype)) {
+ /* if the result is of type pointer */
+ if (IS_PTR(ctype)) {
+ int p_type;
+ sym_link *type = operandType(right);
+ sym_link *etype = getSpec(type);
- int p_type;
- sym_link *type = operandType(right);
- sym_link *etype = getSpec(type);
- DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
+ DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
- /* pointer to generic pointer */
- if (IS_GENPTR(ctype)) {
- char *l = zero;
+ /* pointer to generic pointer */
+ if (IS_GENPTR(ctype)) {
+ char *l = zero;
- if (IS_PTR(type))
- p_type = DCL_TYPE(type);
- else {
+ if (IS_PTR(type))
+ p_type = DCL_TYPE(type);
+ else {
/* we have to go by the storage class */
p_type = PTR_TYPE(SPEC_OCLS(etype));
while (size--)
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
} else {
- /* we need to extend the sign :{ */
+ /* we need to extend the sign :( */
if(size == 1) {
/* Save one instruction of casting char to int */
ic->level,ic->block);
_G.debugLine = 0;
}
- pic16_addpCode2pBlock(pb,
- pic16_newpCodeCSource(ic->lineno,
- ic->filename,
- printCLine(ic->filename, ic->lineno)));
+
+ if(!options.noCcodeInAsm) {
+ pic16_addpCode2pBlock(pb,
+ pic16_newpCodeCSource(ic->lineno, ic->filename,
+ printCLine(ic->filename, ic->lineno)));
+ }
cln = ic->lineno ;
}
+
+ if(options.iCodeInAsm) {
+ /* insert here code to print iCode as comment */
+ }
+
/* if the result is marked as
spilt and rematerializable or code for
this has already been generated then
pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval);
pCodeOp *pic16_popGetLit(unsigned int lit);
-pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2);
+pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2);
pCodeOp *popGetWithString(char *str);
pCodeOp *pic16_popGet (asmop *aop, int offset);//, bool bit16, bool dname);
pCodeOp *pic16_popGetTempReg(void);
void pic16_popReleaseTempReg(pCodeOp *pcop);
+pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc);
void pic16_aopPut (asmop *aop, char *s, int offset);
void pic16_outAcc(operand *result);
extern void printChar (FILE * ofile, char *s, int plen);
void pic16_pCodeInitRegisters(void);
pCodeOp *pic16_popGetLit(unsigned int lit);
-pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2);
+pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2);
pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst);
// fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
- if (addPublics)
-
- fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
-
- /* print the area name */
- for (sym = setFirstItem (map->syms); sym;
- sym = setNextItem (map->syms))
- {
+ if(addPublics)
+ fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
+ /* print the area name */
+ for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
#if 0
- fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
- printTypeChain( sym->type, stderr );
- printf("\n");
+ fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
+ printTypeChain( sym->type, stderr );
+ printf("\n");
#endif
-
- /* if extern then add to externs */
- if (IS_EXTERN (sym->etype)) {
- addSetHead(&externs, sym);
- continue;
- }
-
- /* if allocation required check is needed
- then check if the symbol really requires
- allocation only for local variables */
- if (arFlag && !IS_AGGREGATE (sym->type) &&
- !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
- !sym->allocreq && sym->level)
- continue;
-
- /* if global variable & not static or extern
- and addPublics allowed then add it to the public set */
- if ((sym->used) && (sym->level == 0 ||
- (sym->_isparm && !IS_REGPARM (sym->etype))) &&
- addPublics &&
- !IS_STATIC (sym->etype))
- addSetHead (&publics, sym);
-
- /* if extern then do nothing or is a function
- then do nothing */
- if (IS_FUNC (sym->type))
- continue;
+ /* if extern then add to externs */
+ if (IS_EXTERN (sym->etype)) {
+// if(sym->used) // fixme
+ addSetHead(&externs, sym);
+ continue;
+ }
+ /* if allocation required check is needed
+ * then check if the symbol really requires
+ * allocation only for local variables */
+ if (arFlag && !IS_AGGREGATE (sym->type) &&
+ !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
+ !sym->allocreq && sym->level)
+
+ continue;
+
+ /* if global variable & not static or extern
+ * and addPublics allowed then add it to the public set */
+ if ((sym->used) && (sym->level == 0 ||
+ (sym->_isparm && !IS_REGPARM (sym->etype))) &&
+ addPublics &&
+ !IS_STATIC (sym->etype) && !IS_FUNC(sym->type))
+
+ addSetHead (&publics, sym);
+
+ /* if extern then do nothing or is a function
+ * then do nothing */
+ if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
+ if(SPEC_OCLS(sym->etype) == code) {
+// fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
+ addSetHead(&publics, sym);
+ }
+ continue;
+ }
#if 0
- /* print extra debug info if required */
- if (options.debug || sym->level == 0)
- {
-
- cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
-
- if (!sym->level) /* global */
- if (IS_STATIC (sym->etype))
- fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
- else
- fprintf (map->oFile, "G_"); /* scope is global */
- else
- /* symbol is local */
- fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
- fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
- }
+ /* print extra debug info if required */
+ if (options.debug || sym->level == 0) {
+ cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
+
+ if (!sym->level) /* global */
+ if (IS_STATIC (sym->etype))
+ fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
+ else
+ fprintf (map->oFile, "G_"); /* scope is global */
+ else
+ /* symbol is local */
+ fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
+ fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
+ }
#endif
- /* FIXME -- VR
- * The equates are nice, but do not allow relocatable objects to
- * be created in the form that I (VR) want to make SDCC to work */
+ /* FIXME -- VR
+ * The equates are nice, but do not allow relocatable objects to
+ * be created in the form that I (VR) want to make SDCC to work */
- /* if is has an absolute address then generate
- an equate for this no need to allocate space */
- if (SPEC_ABSA (sym->etype))
- {
- //if (options.debug || sym->level == 0)
-// fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
-// sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
-
- fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
- sym->rname,
- SPEC_ADDR (sym->etype));
+ /* if is has an absolute address then generate
+ an equate for this no need to allocate space */
+ if (SPEC_ABSA (sym->etype)) {
+// if (options.debug || sym->level == 0)
+// fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
+// sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
+ fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
+ sym->rname,
+ SPEC_ADDR (sym->etype));
#if 1
- /* emit only if it is global */
- if(sym->level == 0) {
- regs *reg;
- operand *op;
-
-// fprintf(stderr, "%s: implicit add of symbol = %s\n", __FUNCTION__, sym->name);
- op = operandFromSymbol( sym );
- reg = pic16_allocDirReg( op );
- if(reg) {
- //continue;
-
- checkAddReg(&pic16_fix_udata, reg);
- /* and add to globals list */
- addSetHead(&publics, sym);
- }
- }
+ /* emit only if it is global */
+ if(sym->level == 0) {
+ regs *reg;
+ operand *op;
+// fprintf(stderr, "%s: implicit add of symbol = %s\n", __FUNCTION__, sym->name);
+ op = operandFromSymbol( sym );
+ reg = pic16_allocDirReg( op );
+ if(reg) {
+ //continue;
+ checkAddReg(&pic16_fix_udata, reg);
+ /* and add to globals list */
+ addSetHead(&publics, sym);
+ }
+ }
#endif
- }
- else
- {
- /* allocate space */
-
- /* If this is a bit variable, then allocate storage after 8 bits have been declared */
- /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
- /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
- if (IS_BITVAR (sym->etype))
- {
- bitvars++;
- }
- else
- {
- fprintf (map->oFile, "\t%s\n", sym->rname);
- if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
- {
- for (i = 1; i < size; i++)
- fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
+ } else {
+ /* allocate space */
+ /* If this is a bit variable, then allocate storage after 8 bits have been declared */
+ /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
+ /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
+ if (IS_BITVAR (sym->etype)) {
+ bitvars++;
+ } else {
+ fprintf (map->oFile, "\t%s\n", sym->rname);
+ if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
+ for (i = 1; i < size; i++)
+ fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
+ }
+ }
+// fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
}
- }
- //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
- }
+ /* FIXME -- VR Fix the following, so that syms to be placed
+ * in the idata section and let linker decide about their fate */
- /* FIXME -- VR Fix the following, so that syms to be placed
- * in the idata section and let linker decide about their fate */
-
- /* if it has an initial value then do it only if
- it is a global variable */
-// if(sym->ival && sym->level == 0)
-
+ /* if it has an initial value then do it only if
+ it is a global variable */
#if 1
- if (sym->ival && sym->level == 0) {
- ast *ival = NULL;
-
-// if(SPEC_OCLS(sym->etype)==data) {
-// fprintf(stderr, "%s: sym %s placed in data\n", map->sname, sym->name);
-// }
-
-// fprintf(stderr, "'%s': sym '%s' has initial value\n", map->sname, sym->name);
-
- if (IS_AGGREGATE (sym->type))
- ival = initAggregates (sym, sym->ival, NULL);
- else
- ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
- decorateType (resolveSymbols (list2expr (sym->ival))));
- codeOutFile = statsg->oFile;
- GcurMemmap = statsg;
- eBBlockFromiCode (iCodeFromAst (ival));
- sym->ival = NULL;
- }
+ if (sym->ival && sym->level == 0) {
+ ast *ival = NULL;
+
+// if(SPEC_OCLS(sym->etype)==data) {
+// fprintf(stderr, "%s: sym %s placed in data\n", map->sname, sym->name);
+// }
+
+// fprintf(stderr, "'%s': sym '%s' has initial value\n", map->sname, sym->name);
+
+ if (IS_AGGREGATE (sym->type))
+ ival = initAggregates (sym, sym->ival, NULL);
+ else
+ ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
+ decorateType (resolveSymbols (list2expr (sym->ival))));
+ codeOutFile = statsg->oFile;
+ GcurMemmap = statsg;
+ eBBlockFromiCode (iCodeFromAst (ival));
+ sym->ival = NULL;
+ }
#endif
- }
+ }
}
static void
pic16createInterruptVect (FILE * vFile)
{
- mainf = newSymbol ("main", 0);
- mainf->block = 0;
-
- /* only if the main function exists */
- if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
- {
- if (!options.cc_only)
- werror (E_NO_MAIN);
- return;
- }
-
- /* if the main is only a prototype ie. no body then do nothing */
- if (!IFFUNC_HASBODY(mainf->type))
- {
- /* if ! compile only then main function should be present */
- if (!options.cc_only)
- werror (E_NO_MAIN);
- return;
- }
+ /* if the main is only a prototype ie. no body then do nothing */
+#if 0
+ if (!IFFUNC_HASBODY(mainf->type)) {
+ /* if ! compile only then main function should be present */
+ if (!options.cc_only)
+ werror (E_NO_MAIN);
+ return;
+ }
+#endif
if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
/* printPublics - generates global declarations for publics */
/*-----------------------------------------------------------------*/
static void
-pic16printPublics (FILE * afile)
+pic16printPublics (FILE *afile)
{
symbol *sym;
fprintf (afile, "%s", iComments2);
- fprintf (afile, "; publics variables in this module\n");
+ fprintf (afile, "; public variables in this module\n");
fprintf (afile, "%s", iComments2);
- for (sym = setFirstItem (publics); sym; sym = setNextItem (publics))
+ for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
fprintf(afile, "\tglobal %s\n", sym->rname);
}
symbol *sym;
fprintf(afile, "%s", iComments2);
- fprintf(afile, "; extern variables to this module\n");
+ fprintf(afile, "; extern variables in this module\n");
fprintf(afile, "%s", iComments2);
for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
fprintf(afile, "\textern %s\n", sym->rname);
+
+ for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
+ fprintf(afile, "\textern _%s\n", sym->name);
}
/*-----------------------------------------------------------------*/
FILE *asmFile;
FILE *ovrFile = tempfile();
- addSetHead(&tmpfileSet,ovrFile);
- pic16_pCodeInitRegisters();
-
- if (mainf && IFFUNC_HASBODY(mainf->type)) {
-
- pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
- pic16_addpBlock(pb);
-
- /* entry point @ start of CSEG */
- pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
- /* put in the call to main */
- pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
- if (options.mainreturn) {
+ mainf = newSymbol ("main", 0);
+ mainf->block = 0;
- pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
- pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
+ mainf = findSymWithLevel(SymbolTab, mainf);
+#if 0
+ /* only if the main function exists */
+ if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
+ if (!options.cc_only)
+ werror (E_NO_MAIN);
+ return;
+ }
+#endif
- } else {
+// fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
- pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
- pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
+ addSetHead(&tmpfileSet,ovrFile);
+ pic16_pCodeInitRegisters();
- }
- }
-
-#if STACK_SUPPORT
- if(USE_STACK) {
- pBlock *pb = pic16_newpCodeChain(NULL, 'X', pic16_newpCodeCharP("; Setup stack & frame register"));
+ if (mainf && IFFUNC_HASBODY(mainf->type)) {
+ pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
pic16_addpBlock(pb);
- pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, pic16_popGetLit2(1, stackPos)));
- pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, pic16_popGetLit2(2, stackPos)));
- }
-#endif
+ /* entry point @ start of CSEG */
+ pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup\t;VR1",-1));
+ if(USE_STACK) {
+ pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
+ pic16_popGetLit2(1, pic16_popGetLit(stackPos))));
+ pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
+ pic16_popGetLit2(2, pic16_popGetLit(stackPos))));
+ }
- /* At this point we've got all the code in the form of pCode structures */
- /* Now it needs to be rearranged into the order it should be placed in the */
- /* code space */
+ /* put in the call to main */
+ pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
- pic16_movepBlock2Head('P'); // Last
- pic16_movepBlock2Head(code->dbName);
- pic16_movepBlock2Head('X');
- pic16_movepBlock2Head(statsg->dbName); // First
+ if (options.mainreturn) {
+ pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
+ pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
+ } else {
+ pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
+ pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
+ }
+ }
+ /* At this point we've got all the code in the form of pCode structures */
+ /* Now it needs to be rearranged into the order it should be placed in the */
+ /* code space */
- /* print the global struct definitions */
- if (options.debug)
- cdbStructBlock (0); //,cdbFile);
+ pic16_movepBlock2Head('P'); // Last
+ pic16_movepBlock2Head(code->dbName);
+ pic16_movepBlock2Head('X');
+ pic16_movepBlock2Head(statsg->dbName); // First
- vFile = tempfile();
- /* PENDING: this isnt the best place but it will do */
- if (port->general.glue_up_main) {
- /* create the interrupt vector table */
+ /* print the global struct definitions */
+// if (options.debug)
+// cdbStructBlock (0); //,cdbFile);
- pic16createInterruptVect (vFile);
- }
+ vFile = tempfile();
+ /* PENDING: this isnt the best place but it will do */
+ if (port->general.glue_up_main) {
+ /* create the interrupt vector table */
+ pic16createInterruptVect (vFile);
+ }
- addSetHead(&tmpfileSet,vFile);
+ addSetHead(&tmpfileSet,vFile);
- /* emit code for the all the variables declared */
- pic16emitMaps ();
- /* do the overlay segments */
- pic16emitOverlay(ovrFile);
-
-
+ /* emit code for the all the variables declared */
+ pic16emitMaps ();
+ /* do the overlay segments */
+ pic16emitOverlay(ovrFile);
pic16_AnalyzepCode('*');
#if 0
}
#endif
- pic16_InlinepCode();
- pic16_AnalyzepCode('*');
- pic16_pcode_test();
+ pic16_InlinepCode();
+ pic16_AnalyzepCode('*');
- /* now put it all together into the assembler file */
- /* create the assembler file name */
-
- if ((noAssemble || options.c1mode) && fullDstFileName)
- {
- sprintf (buffer, fullDstFileName);
- }
- else
- {
- sprintf (buffer, dstFileName);
- strcat (buffer, ".asm");
- }
+ if(pic16_debug_verbose)
+ pic16_pcode_test();
- if (!(asmFile = fopen (buffer, "w"))) {
- werror (E_FILE_OPEN_ERR, buffer);
- exit (1);
- }
+ /* now put it all together into the assembler file */
+ /* create the assembler file name */
+ if ((noAssemble || options.c1mode) && fullDstFileName) {
+ sprintf (buffer, fullDstFileName);
+ } else {
+ sprintf (buffer, dstFileName);
+ strcat (buffer, ".asm");
+ }
+
+ if (!(asmFile = fopen (buffer, "w"))) {
+ werror (E_FILE_OPEN_ERR, buffer);
+ exit (1);
+ }
- /* initial comments */
- pic16initialComments (asmFile);
+ /* initial comments */
+ pic16initialComments (asmFile);
- /* print module name */
- fprintf (asmFile, ";\t.module %s\n", moduleName);
+ /* print module name */
+ fprintf (asmFile, ";\t.module %s\n", moduleName);
- /* Let the port generate any global directives, etc. */
- if (port->genAssemblerPreamble)
- {
- port->genAssemblerPreamble(asmFile);
- }
+ /* Let the port generate any global directives, etc. */
+ if (port->genAssemblerPreamble) {
+ port->genAssemblerPreamble(asmFile);
+ }
- /* print the extern variables to this module */
- pic16_printExterns(asmFile);
+ /* print the extern variables to this module */
+ pic16_printExterns(asmFile);
- /* print the global variables in this module */
- pic16printPublics (asmFile);
+ /* print the global variables in this module */
+ pic16printPublics (asmFile);
#if 0
- /* copy the sfr segment */
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; special function registers\n");
- fprintf (asmFile, "%s", iComments2);
- copyFile (asmFile, sfr->oFile);
+ /* copy the sfr segment */
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; special function registers\n");
+ fprintf (asmFile, "%s", iComments2);
+ copyFile (asmFile, sfr->oFile);
#endif
- /* Put all variables into a cblock */
- pic16_AnalyzeBanking();
- pic16_writeUsedRegs(asmFile);
-
- /* create the overlay segments */
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; overlayable items in internal ram \n");
- fprintf (asmFile, "%s", iComments2);
- copyFile (asmFile, ovrFile);
-
- /* create the stack segment MOF */
- if (mainf && IFFUNC_HASBODY(mainf->type)) {
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; Stack segment in internal ram \n");
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
- ";__start__stack:\n;\t.ds\t1\n\n");
- }
+ /* Put all variables into a cblock */
+ pic16_AnalyzeBanking();
+ pic16_writeUsedRegs(asmFile);
+
+ /* create the overlay segments */
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; overlayable items in internal ram \n");
+ fprintf (asmFile, "%s", iComments2);
+ copyFile (asmFile, ovrFile);
+
+ /* create the stack segment MOF */
+ if (mainf && IFFUNC_HASBODY(mainf->type)) {
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; Stack segment in internal ram \n");
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
+ ";__start__stack:\n;\t.ds\t1\n\n");
+ }
#if 0
/* no indirect data in pic */
- /* create the idata segment */
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; indirectly addressable internal ram data\n");
- fprintf (asmFile, "%s", iComments2);
- copyFile (asmFile, idata->oFile);
+ /* create the idata segment */
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; indirectly addressable internal ram data\n");
+ fprintf (asmFile, "%s", iComments2);
+ copyFile (asmFile, idata->oFile);
#endif
#if 0
/* no xdata in pic */
- /* if external stack then reserve space of it */
- if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; external stack \n");
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
- fprintf (asmFile,";\t.ds 256\n");
- }
+ /* if external stack then reserve space of it */
+ if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; external stack \n");
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
+ fprintf (asmFile,";\t.ds 256\n");
+ }
#endif
#if 0
/* no xdata in pic */
- /* copy xtern ram data */
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; external ram data\n");
- fprintf (asmFile, "%s", iComments2);
- copyFile (asmFile, xdata->oFile);
+ /* copy xtern ram data */
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; external ram data\n");
+ fprintf (asmFile, "%s", iComments2);
+ copyFile (asmFile, xdata->oFile);
#endif
- /* copy the bit segment */
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; bit data\n");
- fprintf (asmFile, "%s", iComments2);
- copyFile (asmFile, bit->oFile);
-
+ /* copy the bit segment */
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; bit data\n");
+ fprintf (asmFile, "%s", iComments2);
+ copyFile (asmFile, bit->oFile);
-/* the following is commented out. the CODE directive will be
- used instead before code */
-// fprintf (asmFile, "\tORG 0\n");
- /* copy the interrupt vector table */
- if (mainf && IFFUNC_HASBODY(mainf->type)) {
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; interrupt vector \n");
- fprintf (asmFile, "%s", iComments2);
- copyFile (asmFile, vFile);
- }
+ /* copy the interrupt vector table */
+ if(mainf && IFFUNC_HASBODY(mainf->type)) {
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; interrupt vector \n");
+ fprintf (asmFile, "%s", iComments2);
+ copyFile (asmFile, vFile);
+ }
- /* copy global & static initialisations */
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; global & static initialisations\n");
- fprintf (asmFile, "%s", iComments2);
+ /* copy global & static initialisations */
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; global & static initialisations\n");
+ fprintf (asmFile, "%s", iComments2);
#if 0
- /* FIXME 8051 Legacy -- VR */
- /* Everywhere we generate a reference to the static_name area,
- * (which is currently only here), we immediately follow it with a
- * definition of the post_static_name area. This guarantees that
- * the post_static_name area will immediately follow the static_name
- * area.
- */
- fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
- fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
- fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
+ /* FIXME 8051 Legacy -- VR */
+ /* Everywhere we generate a reference to the static_name area,
+ * (which is currently only here), we immediately follow it with a
+ * definition of the post_static_name area. This guarantees that
+ * the post_static_name area will immediately follow the static_name
+ * area.
+ */
+ fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
+ fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
+ fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
#endif
+ /* copy over code */
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "\tcode\n");
+ fprintf (asmFile, "%s", iComments2);
+
- if (mainf && IFFUNC_HASBODY(mainf->type)) {
- fprintf (asmFile,"__sdcc_gsinit_startup:\n");
+ if(mainf && IFFUNC_HASBODY(mainf->type)) {
+ fprintf (asmFile,"__sdcc_gsinit_startup:\t\t;VRokas\n");
#if 0
- /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
- /* if external stack is specified then the
- higher order byte of the xdatalocation is
- going into P2 and the lower order going into
- spx */
- if (options.useXstack) {
- fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
- (((unsigned int)options.xdata_loc) >> 8) & 0xff);
- fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
- (unsigned int)options.xdata_loc & 0xff);
- }
+ /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
+ /* if external stack is specified then the
+ * higher order byte of the xdatalocation is
+ * going into P2 and the lower order going into */
+
+ if (options.useXstack) {
+ fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
+ (((unsigned int)options.xdata_loc) >> 8) & 0xff);
+ fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
+ (unsigned int)options.xdata_loc & 0xff);
+ }
#endif
+ }
- }
+// copyFile (stderr, code->oFile);
- /* copy over code */
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "\tcode\n");
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
- if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
- {
- /* This code is generated in the post-static area.
- * This area is guaranteed to follow the static area
- * by the ugly shucking and jiving about 20 lines ago.
- */
-// fprintf(asmFile, ";\t.area %s\n", port->mem.post_static_name);
- fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
- }
-
+ if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
+ fprintf (asmFile,"\tgoto\t__sdcc_program_startup\t;VR2\n");
+ }
- //copyFile (stderr, code->oFile);
- fprintf(asmFile, "; I code from now on!\n");
+ fprintf(asmFile, "; I code from now on!\n");
pic16_copypCode(asmFile, 'I');
+ fprintf(asmFile, "; A code from now on!\n");
+ pic16_copypCode(asmFile, 'A');
+
-// fprintf(asmFile, "; dbName from now on!\n");
- fprintf(asmFile, "__sdcc_program_startup:\n");
+ if(pic16_debug_verbose)
+ fprintf(asmFile, "; dbName from now on!\n");
pic16_copypCode(asmFile, statsg->dbName);
+ if(pic16_debug_verbose)
fprintf(asmFile, "; X code from now on!\n");
pic16_copypCode(asmFile, 'X');
+ if(pic16_debug_verbose)
fprintf(asmFile, "; M code from now on!\n");
pic16_copypCode(asmFile, 'M');
+
pic16_copypCode(asmFile, code->dbName);
pic16_copypCode(asmFile, 'P');
fprintf (asmFile,"\tend\n");
-
fclose (asmFile);
rm_tmpfiles();
"_xdata",
"_pdata",
"_idata",
+ "_naked",
NULL
};
}
+set *absSymSet;
+
static int
_process_pragma(const char *sz)
{
static const char *WHITE = " \t";
+
char *ptr = strtok((char *)sz, WHITE);
if (startsWith (ptr, "maxram")) {
// fprintf(stderr, "Initializing stack pointer to 0x%x\n", (int)floatFromVal(constVal(stackPos)));
stackPosVal = constVal( stackPosS );
stackPos = (unsigned int)floatFromVal( stackPosVal );
+
+ return 0;
}
+
+ if(startsWith(ptr, "code")) {
+ char *symname = strtok((char *)NULL, WHITE);
+ char *location = strtok((char *)NULL, WHITE);
+ absSym *absS;
+ value *addr;
- return 0;
+ absS = Safe_calloc(1, sizeof(absSym));
+ absS->name = Safe_strdup( symname );
+ addr = constVal( location );
+ absS->address = (unsigned int)floatFromVal( addr );
+
+ addSet(&absSymSet, absS);
+ fprintf(stderr, "%s:%d symbol %s will be placed in location 0x%06x in code memory\n",
+ __FILE__, __LINE__, symname, absS->address);
+
+ return 0;
+ }
+
+ return 1;
}
#define REP_UDATA "--preplace-udata-with="
extern int pic16_debug_verbose;
+extern int pic16_ralloc_debug;
+extern int pic16_pcode_verbose;
OPTION pic16_optionsTable[]= {
{ 0, "--pgen-banksel", &pic16_options.gen_banksel, "generate BANKSEL assembler directives"},
{ 0, STACK_MODEL, NULL, "use stack model 'small' (default) or 'large'"},
{ 0, "--debug-xtra", &pic16_debug_verbose, "show more debug info in assembly output"},
+ { 0, "--debug-ralloc", &pic16_ralloc_debug, "dump register allocator debug file *.d"},
+ { 0, "--pcode-verbose", &pic16_pcode_verbose, "dump pcode related info"},
+
{ 0, REP_UDATA, NULL, "Place udata variables at another section: udata_acs, udata_ovr, udata_shr"},
#if 0
port->mem.default_local_map = data;
port->mem.default_globl_map = data;
+ options.all_callee_saves = 1; // always callee saves
+
setMainValue("mcu", pic16_processor_base_name() );
addSet(&preArgvSet, Safe_strdup("-DMCU={mcu}"));
}
}
-#if 0
+#if 1
static char *_pic16_mangleFunctionName(char *sz)
{
- fprintf(stderr, "mangled function name: %s\n", sz);
+// fprintf(stderr, "mangled function name: %s\n", sz);
return sz;
}
_pic16_reset_regparm,
_pic16_regparm,
_process_pragma, /* process a pragma */
- NULL, //_pic16_mangleFunctionName, /* mangles function name */
+ _pic16_mangleFunctionName, /* mangles function name */
_hasNativeMulFor,
hasExtBitOp, /* hasExtBitOp */
oclsExpense, /* oclsExpense */
unsigned int addr_udatashr;
} pic16_sectioninfo_t;
+typedef struct absSym {
+ char *name;
+ unsigned int address;
+} absSym;
+
+extern set *absSymSet;
+
+
#endif
#include "newalloc.h"
+#include "main.h"
#include "pcode.h"
#include "pcodeflow.h"
#include "ralloc.h"
// Eventually this will go into device dependent files:
-pCodeOpReg pic16_pc_status = {{PO_STATUS, "_STATUS"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_status = {{PO_STATUS, "STATUS"}, -1, NULL,0,NULL};
pCodeOpReg pic16_pc_indf0 = {{PO_INDF0, "INDF0"}, -1, NULL,0,NULL};
pCodeOpReg pic16_pc_fsr0 = {{PO_FSR0, "FSR0"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_intcon = {{PO_INTCON, "_INTCON"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_intcon = {{PO_INTCON, "INTCON"}, -1, NULL,0,NULL};
pCodeOpReg pic16_pc_pcl = {{PO_PCL, "PCL"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_pclath = {{PO_PCLATH, "_PCLATH"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_pclath = {{PO_PCLATH, "PCLATH"}, -1, NULL,0,NULL};
pCodeOpReg pic16_pc_wreg = {{PO_WREG, "WREG"}, -1, NULL,0,NULL};
pCodeOpReg pic16_pc_bsr = {{PO_BSR, "BSR"}, -1, NULL,0,NULL};
pCodeOpReg pic16_pc_fsr2l = {{PO_FSR0, "FSR2L"}, -1, NULL, 0, NULL};
pCodeOpReg pic16_pc_fsr2h = {{PO_FSR0, "FSR2H"}, -1, NULL, 0, NULL};
pCodeOpReg pic16_pc_postinc1 = {{PO_FSR0, "POSTINC1"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_preinc1 = {{PO_FSR0, "PREINC1"}, -1, NULL, 0, NULL};
pCodeOpReg pic16_pc_plusw2 = {{PO_FSR0, "PLUSW2"}, -1, NULL, 0, NULL};
pCodeOpReg pic16_pc_preinc2 = {{PO_FSR0, "PREINC1"}, -1, NULL, 0, NULL};
static int functionInlining = 1; /* inline functions if nonzero */
int pic16_debug_verbose = 0; /* Set true to inundate .asm file */
+int pic16_pcode_verbose = 0;
+
//static int GpCodeSequenceNumber = 1;
static int GpcFlowSeq = 1;
pic16_initStack(0xfff, 8);
pic16_init_pic(port->processor);
- pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"_STATUS", PO_STATUS, 0x00);
- pic16_pc_pcl.r = pic16_allocProcessorRegister(IDX_PCL,"_PCL", PO_PCL, 0x80);
- pic16_pc_pclath.r = pic16_allocProcessorRegister(IDX_PCLATH,"_PCLATH", PO_PCLATH, 0x80);
- pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"_FSR0", PO_FSR0, 0x80);
- pic16_pc_indf0.r = pic16_allocProcessorRegister(IDX_INDF0,"_INDF0", PO_INDF0, 0x80);
- pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"_INTCON", PO_INTCON, 0x80);
- pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"_WREG", PO_WREG, 0x80);
-
- pic16_pc_fsr1l.r = pic16_allocProcessorRegister(IDX_FSR1L, "_FSR1L", PO_FSR0, 0x80);
- pic16_pc_fsr1h.r = pic16_allocProcessorRegister(IDX_FSR1H, "_FSR1H", PO_FSR0, 0x80);
- pic16_pc_fsr2l.r = pic16_allocProcessorRegister(IDX_FSR2L, "_FSR2L", PO_FSR0, 0x80);
- pic16_pc_fsr2h.r = pic16_allocProcessorRegister(IDX_FSR2H, "_FSR2H", PO_FSR0, 0x80);
- pic16_pc_postinc1.r = pic16_allocProcessorRegister(IDX_POSTINC1, "_POSTINC1", PO_FSR0, 0x80);
- pic16_pc_postdec1.r = pic16_allocProcessorRegister(IDX_POSTDEC1, "_POSTDEC1", PO_FSR0, 0x80);
- pic16_pc_preinc2.r = pic16_allocProcessorRegister(IDX_PREINC2, "_PREINC2", PO_FSR0, 0x80);
- pic16_pc_plusw2.r = pic16_allocProcessorRegister(IDX_PLUSW2, "_PLUSW2", PO_FSR0, 0x80);
+ pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80);
+ pic16_pc_pcl.r = pic16_allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80);
+ pic16_pc_pclath.r = pic16_allocProcessorRegister(IDX_PCLATH,"PCLATH", PO_PCLATH, 0x80);
+ pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"FSR0", PO_FSR0, 0x80);
+ pic16_pc_indf0.r = pic16_allocProcessorRegister(IDX_INDF0,"INDF0", PO_INDF0, 0x80);
+ pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"INTCON", PO_INTCON, 0x80);
+ pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"WREG", PO_WREG, 0x80);
+
+ pic16_pc_fsr1l.r = pic16_allocProcessorRegister(IDX_FSR1L, "FSR1L", PO_FSR0, 0x80);
+ pic16_pc_fsr1h.r = pic16_allocProcessorRegister(IDX_FSR1H, "FSR1H", PO_FSR0, 0x80);
+ pic16_pc_fsr2l.r = pic16_allocProcessorRegister(IDX_FSR2L, "FSR2L", PO_FSR0, 0x80);
+ pic16_pc_fsr2h.r = pic16_allocProcessorRegister(IDX_FSR2H, "FSR2H", PO_FSR0, 0x80);
+ pic16_pc_postinc1.r = pic16_allocProcessorRegister(IDX_POSTINC1, "POSTINC1", PO_FSR0, 0x80);
+ pic16_pc_postdec1.r = pic16_allocProcessorRegister(IDX_POSTDEC1, "POSTDEC1", PO_FSR0, 0x80);
+ pic16_pc_preinc1.r = pic16_allocProcessorRegister(IDX_PREINC1, "PREINC1", PO_FSR0, 0x80);
+
+ pic16_pc_preinc2.r = pic16_allocProcessorRegister(IDX_PREINC2, "PREINC2", PO_FSR0, 0x80);
+ pic16_pc_plusw2.r = pic16_allocProcessorRegister(IDX_PLUSW2, "PLUSW2", PO_FSR0, 0x80);
pic16_pc_status.rIdx = IDX_STATUS;
pic16_pc_fsr0.rIdx = IDX_FSR0;
pic16_pc_fsr2h.rIdx = IDX_FSR2H;
pic16_pc_postinc1.rIdx = IDX_POSTINC1;
pic16_pc_postdec1.rIdx = IDX_POSTDEC1;
+ pic16_pc_preinc1.rIdx = IDX_PREINC1;
pic16_pc_preinc2.rIdx = IDX_PREINC2;
pic16_pc_plusw2.rIdx = IDX_PLUSW2;
while(pci) {
if(STRCASECMP(pci->mnemonic, mnem) == 0) {
- if((pci->num_ops <= 1) || (pci->isModReg == dest) || (pci->isBitInst) ||
- (pci->num_ops <= 2 && pci->isAccess) ||
- (pci->num_ops <= 2 && pci->isFastCall))
+ if((pci->num_ops <= 1)
+ || (pci->isModReg == dest)
+ || (pci->isBitInst)
+ || (pci->num_ops <= 2 && pci->isAccess)
+ || (pci->num_ops <= 2 && pci->isFastCall)
+ || (pci->num_ops <= 2 && pci->is2MemOp)
+ || (pci->num_ops <= 2 && pci->is2LitOp) )
return(pci->op);
}
pb->dbName = 'I';
}
+void pic16_pBlockConvert2Absolute(pBlock *pb)
+{
+ if(!pb)return;
+ if(pb->cmemmap)pb->cmemmap = NULL;
+
+ pb->dbName = 'A';
+}
+
/*-----------------------------------------------------------------*/
/* pic16_movepBlock2Head - given the dbname of a pBlock, move all */
/* instances to the front of the doubly linked */
pCodeFunction *pcf;
pcf = Safe_calloc(1,sizeof(pCodeFunction));
- //_ALLOC(pcf,sizeof(pCodeFunction));
pcf->pc.type = PC_FUNCTION;
pcf->pc.prev = pcf->pc.next = NULL;
pcf->ncalled = 0;
if(mod) {
- //_ALLOC_ATOMIC(pcf->modname,strlen(mod)+1);
pcf->modname = Safe_calloc(1,strlen(mod)+1);
strcpy(pcf->modname,mod);
} else
pcf->modname = NULL;
if(f) {
- //_ALLOC_ATOMIC(pcf->fname,strlen(f)+1);
pcf->fname = Safe_calloc(1,strlen(f)+1);
strcpy(pcf->fname,f);
} else
{
pCodeAsmDir *pcad;
va_list ap;
- char buffer[256]; // how long can a directive be?!
+ char buffer[512];
char *lbp=buffer;
- pcad = Safe_alloc(/*1, */sizeof(pCodeAsmDir));
+ pcad = Safe_calloc(1, sizeof(pCodeAsmDir));
pcad->pc.type = PC_ASMDIR;
pcad->pc.prev = pcad->pc.next = NULL;
pcad->pc.pb = NULL;
pcad->pc.print = genericPrint;
if(asdir && *asdir) {
+
+ while(isspace(*asdir))asdir++; // strip any white space from the beginning
+
pcad->directive = Safe_strdup( asdir );
}
va_start(ap, argfmt);
+ memset(buffer, 0, sizeof(buffer));
if(argfmt && *argfmt)
vsprintf(buffer, argfmt, ap);
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
-pCodeOp *pic16_newpCodeOpLit2(int lit, int lit2)
+pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2)
{
- char *s = buffer;
+ char *s = buffer, tbuf[256], *tb=tbuf;
pCodeOp *pcop;
+ tb = pic16_get_op(arg2, NULL, 0);
pcop = Safe_calloc(1,sizeof(pCodeOpLit2) );
pcop->type = PO_LITERAL;
pcop->name = NULL;
- if(lit>=0 && lit2>=0) {
- sprintf(s,"0x%02x,0x%02x",lit, lit2);
+ if(lit>=0) {
+ sprintf(s,"0x%02x, %s",lit, tb);
if(s)
pcop->name = Safe_strdup(s);
}
((pCodeOpLit2 *)pcop)->lit = lit;
- ((pCodeOpLit2 *)pcop)->lit2 = lit2;
+ ((pCodeOpLit2 *)pcop)->arg2 = arg2;
return pcop;
}
PCOI(pcop)->r = r;
if(r) {
-// fprintf(stderr, " pic16_newpCodeOpImmd reg %s exists\n",name);
+ fprintf(stderr, "%s:%d %s reg %s exists\n",__FILE__, __LINE__, __FUNCTION__, name);
PCOI(pcop)->rIdx = r->rIdx;
} else {
- fprintf(stderr, " pic16_newpCodeOpImmd reg %s doesn't exist\n",name);
+ fprintf(stderr, "%s:%d %s reg %s doesn't exist\n",
+ __FILE__, __LINE__, __FUNCTION__, name);
PCOI(pcop)->rIdx = -1;
}
// fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset);
pCodeOp *pic16_newpCodeOpRegFromStr(char *name)
{
pCodeOp *pcop;
+ regs *r;
pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
- PCOR(pcop)->r = pic16_allocRegByName(name, 1);
+ PCOR(pcop)->r = r = pic16_allocRegByName(name, 1);
PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
pcop->type = PCOR(pcop)->r->pc_type;
pcop->name = PCOR(pcop)->r->name;
+ fprintf(stderr, "%s:%d %s allocates register %s rIdx:0x%02x\n",
+ __FILE__, __LINE__, __FUNCTION__, r->name, r->rIdx);
+
return pcop;
}
{
pCode *pc;
- if(!pb)
- return;
+ if(!pb)return;
- if(!of)
- of = stderr;
+ if(!of)of=stderr;
- for(pc = pb->pcHead; pc; pc = pc->next)
- printpCode(of,pc);
+#if 0
+ if(pb->dbName == 'A') {
+ absSym *ab;
+
+ PCF(pb->pcHead)->
+ for(ab=setFirstItem(absSymSet); ab; ab=setNextItem(absSymSet))
+ if(strcmp(ab->name,
+// fprintf(of, "%s\tcode\t%d"
+ }
+#endif
+ for(pc = pb->pcHead; pc; pc = pc->next) {
+ if(isPCF(pc) && PCF(pc)->fname) {
+ fprintf(of, "S_%s_%s\tcode", PCF(pc)->modname, PCF(pc)->fname);
+ if(pb->dbName == 'A') {
+ absSym *ab;
+ for(ab=setFirstItem(absSymSet); ab; ab=setNextItem(absSymSet))
+ if(strcmp(ab->name, PCF(pc)->fname)) {
+ fprintf(of, "\t0X%06X", ab->address);
+ break;
+ }
+ }
+ fprintf(of, "\n");
+ }
+ printpCode(of,pc);
+ }
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
+/* modifiers for constant immediate */
+const char *immdmod[3]={"LOW", "HIGH", "UPPER"};
+
char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size)
{
regs *r;
case PO_IMMEDIATE:
- s = buffer;
-
- if(PCOI(pcop)->_const) {
+ s = buffer;
+
+ if(PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
+ if(PCOI(pcop)->index) {
+ SAFE_snprintf(&s,&size, "%s(%s + %d)",
+ immdmod[ PCOI(pcop)->offset ],
+ pcop->name,
+ PCOI(pcop)->index);
+ } else {
+ SAFE_snprintf(&s,&size,"%s(%s)",
+ immdmod[ PCOI(pcop)->offset ],
+ pcop->name);
+ }
+ } else {
+ if(PCOI(pcop)->index) {
+ SAFE_snprintf(&s,&size, "%s(%s + %d)",
+ immdmod[ 0 ],
+ pcop->name,
+ PCOI(pcop)->index);
+ } else {
+ SAFE_snprintf(&s,&size, "%s(%s)",
+ immdmod[ 0 ],
+ pcop->name);
+ }
+ }
+
+#if 0
+ if(PCOI(pcop)->_const) {
+ if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
+ if(PCOI(pcop)->index) {
+ SAFE_snprintf(&s,&size,"%s(%s + %d)",
+ immdmod[ PCOI(pcop)->offset ],
+ pcop->name,
+ PCOI(pcop)->index);
+ } else {
+ SAFE_snprintf(&s,&size,"%s(%s)",
+ immdmod[ PCOI(pcop)->offset ],
+ pcop->name);
+ }
- if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
- SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)",
- pcop->name,
- PCOI(pcop)->index,
- 8 * PCOI(pcop)->offset );
- } else
- SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index);
- } else {
-
- if( PCOI(pcop)->index) { // && PCOI(pcc->pcop)->offset<4) {
- SAFE_snprintf(&s,&size,"(%s + %d)",
- pcop->name,
- PCOI(pcop)->index );
+ } else {
+ if(PCOI(pcop)->index)
+ SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index);
+ else
+ SAFE_snprintf(&s,&size,"LOW(%s)",pcop->name);
+ }
} else {
- if(PCOI(pcop)->offset)
- SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset);
- else
- SAFE_snprintf(&s,&size,"%s",pcop->name);
+ if( PCOI(pcop)->index) { // && PCOI(pcc->pcop)->offset<4)
+ SAFE_snprintf(&s,&size,"(%s + %d)",
+ pcop->name,
+ PCOI(pcop)->index );
+ } else {
+ if(PCOI(pcop)->offset)
+ SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset);
+ else
+ SAFE_snprintf(&s,&size,"(%s)",pcop->name);
+ }
}
- }
+#endif
- return buffer;
+ return buffer;
case PO_DIR:
s = buffer;
char *s = str;
regs *r;
- if(PCI(pc)->pci_magic != PCI_MAGIC) {
- fprintf(stderr, "%s:%d: pCodeInstruction initialization error in instruction %s\n",
- __FILE__, __LINE__, PCI(pc)->mnemonic);
+#if 0
+ if(isPCI(pc) && (PCI(pc)->pci_magic != PCI_MAGIC)) {
+ fprintf(stderr, "%s:%d: pCodeInstruction initialization error in instruction %s, magic is %x (defaut: %x)\n",
+ __FILE__, __LINE__, PCI(pc)->mnemonic, PCI(pc)->pci_magic, PCI_MAGIC);
exit(-1);
}
+#endif
switch(pc->type) {
if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) {
if(PCI(pc)->is2MemOp) {
- SAFE_snprintf(&s,&size, "%s,%s",
+ SAFE_snprintf(&s,&size, "%s, %s",
pic16_get_op(PCOP(PCI(pc)->pcop), NULL, 0),
pic16_get_op2(PCOP(PCI(pc)->pcop), NULL, 0));
break;
SAFE_snprintf(&s,&size,";\t--FLOW change\n");
break;
case PC_CSOURCE:
- SAFE_snprintf(&s,&size,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
+ SAFE_snprintf(&s,&size,";#CSRC\t%s %d\t%s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
break;
case PC_ASMDIR:
SAFE_snprintf(&s,&size,"\t%s\t%s\n", PCAD(pc)->directive, PCAD(pc)->arg?PCAD(pc)->arg:"");
break;
case PC_CSOURCE:
- fprintf(of,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
+ fprintf(of,";#CSRC\t%s %d\t\t%s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
break;
case PC_ASMDIR:
{
if(!pc || !of)
return;
+#if 0
if( ((pCodeFunction *)pc)->modname)
fprintf(of,"F_%s",((pCodeFunction *)pc)->modname);
+#endif
if(PCF(pc)->fname) {
pBranch *exits = PCF(pc)->to;
int i=0;
- fprintf(of,"%s\t;Function start\n",PCF(pc)->fname);
+ fprintf(of,"%s", PCF(pc)->fname);
+
+// if(pic16_pcode_verbose)
+ fprintf(of, "\t;Function start");
+
+ fprintf(of, "\n");
+
while(exits) {
i++;
exits = exits->next;
}
//if(i) i--;
- fprintf(of,"; %d exit point%c\n",i, ((i==1) ? ' ':'s'));
+
+ if(pic16_pcode_verbose)
+ fprintf(of,"; %d exit point%c\n",i, ((i==1) ? ' ':'s'));
- }else {
- if((PCF(pc)->from &&
- PCF(pc)->from->pc->type == PC_FUNCTION &&
- PCF(PCF(pc)->from->pc)->fname) )
- fprintf(of,"; exit point of %s\n",PCF(PCF(pc)->from->pc)->fname);
- else
- fprintf(of,"; exit point [can't find entry point]\n");
+ } else {
+ if((PCF(pc)->from &&
+ PCF(pc)->from->pc->type == PC_FUNCTION &&
+ PCF(PCF(pc)->from->pc)->fname) ) {
+
+ if(pic16_pcode_verbose)
+ fprintf(of,"; exit point of %s\n",PCF(PCF(pc)->from->pc)->fname);
+ } else {
+ if(pic16_pcode_verbose)
+ fprintf(of,"; exit point [can't find entry point]\n");
+ }
+ fprintf(of, "\n");
}
}
/*-----------------------------------------------------------------*/
//pc->print(stderr,pc);
if(!(pcol && isPCOLAB(pcol))) {
- if((PCI(pc)->op != POC_RETLW) && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL) && (PCI(pc)->op != POC_RETFIE) ) {
- pc->print(stderr,pc);
- fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__);
+ if((PCI(pc)->op != POC_RETLW)
+ && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL) && (PCI(pc)->op != POC_RETFIE) ) {
+
+ /* continue if label is '$' which assembler knows how to parse */
+ if(((PCI(pc)->pcop->type == PO_STR) && !strcmp(PCI(pc)->pcop->name, "$")))continue;
+
+ pc->print(stderr,pc);
+ fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__);
}
continue;
}
pCode *pc;
regs *r;
+ if(!pic16_pcode_verbose)return;
+
fprintf(of,";***\n; pBlock Stats: dbName = %c\n;***\n",getpBlock_dbName(pb));
// for now just print the first element of each set
{
pCodeOp pcop;
int lit;
- int lit2;
+ pCodeOp *arg2;
} pCodeOpLit2;
void pic16_printCallTree(FILE *of);
void pCodePeepInit(void);
void pic16_pBlockConvert2ISR(pBlock *pb);
+void pic16_pBlockConvert2Absolute(pBlock *pb);
pCodeOp *pic16_newpCodeOpLabel(char *name, int key);
pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space);
pCodeOp *pic16_newpCodeOpLit(int lit);
-pCodeOp *pic16_newpCodeOpLit2(int lit, int lit2);
+pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2);
pCodeOp *pic16_newpCodeOpBit(char *name, int bit,int inBitSpace);
pCodeOp *pic16_newpCodeOpRegFromStr(char *name);
pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE p);
struct regs * pic16_getRegFromInstruction2(pCode *pc);
extern void pic16_pcode_test(void);
-
+extern int pic16_debug_verbose;
/*-----------------------------------------------------------------*
* pCode objects.
*-----------------------------------------------------------------*/
extern pCodeOpReg pic16_pc_fsr2h;
extern pCodeOpReg pic16_pc_postinc1;
extern pCodeOpReg pic16_pc_postdec1;
+extern pCodeOpReg pic16_pc_preinc1;
extern pCodeOpReg pic16_pc_preinc2;
extern pCodeOpReg pic16_pc_plusw2;
void pic16_pBlockMergeLabels(pBlock *pb);
char *pCode2str(char *str, int size, pCode *pc);
char *pic16_get_op( pCodeOp *pcop,char *buf,int buf_size);
+pCodeOp *pic16_popCombine2(pCodeOp *, pCodeOp *, int);
extern pCodeInstruction *pic16Mnemonics[];
-
+static int parsing_peeps=1;
#define IS_PCCOMMENT(x) ( x && (x->type==PC_COMMENT))
ALT_MNEM1B,
ALT_MNEM2,
ALT_MNEM2A,
- ALT_MNEM3
+ ALT_MNEM2B,
+ ALT_MNEM3,
+ ALT_MNEM4,
+ ALT_MNEM4a
} altPatterns;
static char alt_comment[] = { PCP_COMMENT, 0};
static char alt_mnem1b[] = { PCP_STR, PCP_NUMBER, 0};
static char alt_mnem2[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_STR, 0};
static char alt_mnem2a[] = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_STR, 0};
+//static char alt_mnem2b[] = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_WILDVAR, 0};
static char alt_mnem3[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_NUMBER, 0};
+static char alt_mnem4[] = { PCP_STR, PCP_NUMBER, PCP_COMMA, PCP_STR, 0}; // for lfsr 0 , name
+static char alt_mnem4a[] = { PCP_STR, PCP_NUMBER, PCP_COMMA, PCP_NUMBER, 0}; // for lfsr 0 , value
static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb);
static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb);
static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb);
static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb);
static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb);
+//static void * cvt_altpat_mnem2b(void *pp, pCodeWildBlock *pcwb);
static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem4(void *pp, pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem4a(void *pp, pCodeWildBlock *pcwb);
+/* NOTE: Order is important in the following table */
static pcPattern altArr[] = {
{ALT_LABEL, alt_label, cvt_altpat_label},
{ALT_COMMENT, alt_comment,cvt_altpat_comment},
+ {ALT_MNEM4a, alt_mnem4a, cvt_altpat_mnem4a},
+ {ALT_MNEM4, alt_mnem4, cvt_altpat_mnem4},
{ALT_MNEM3, alt_mnem3, cvt_altpat_mnem3},
+// {ALT_MNEM2B, alt_mnem2b, cvt_altpat_mnem2b},
{ALT_MNEM2A, alt_mnem2a, cvt_altpat_mnem2a},
{ALT_MNEM2, alt_mnem2, cvt_altpat_mnem2},
{ALT_MNEM1B, alt_mnem1b, cvt_altpat_mnem1b},
if(pic16Mnemonics[opcode]->isBitInst)
pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_BIT);
- else
- pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
+ else {
+// fprintf(stderr, "%s:%d tok.s= %s\n", __FILE__, __LINE__, p[1].pct[0].tok.s);
+ pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_STR); //GPR_REGISTER);
+ }
pci = PCI(pic16_newpCode(opcode, pcosubtype));
p[3].pct[0].tok.s,
dest));
-
opcode = pic16_getpCode(p->pct[0].tok.s,dest);
if(opcode < 0) {
fprintf(stderr, "Bad mnemonic\n");
return NULL;
}
+ } else
+ if(pic16Mnemonics[opcode]->is2MemOp) {
+ /* support for movff instruction */
+ pcosubtype = pic16_popCombine2(
+ pic16_newpCodeOp(p[1].pct[0].tok.s, PO_GPR_REGISTER),
+ pic16_newpCodeOp(p[3].pct[0].tok.s, PO_GPR_REGISTER), 0);
} else
pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
+
pci = PCI(pic16_newpCode(opcode,pcosubtype));
if(pic16Mnemonics[opcode]->isBitInst)
pcosubtype = pic16_newpCodeOp(NULL,PO_BIT);
else
+ if(pic16Mnemonics[opcode]->is2MemOp) {
+ return NULL;
+ /* support for movff instruction */
+ pcosubtype = pic16_popCombine2(
+ pic16_newpCodeOp(p[1].pct[0].tok.s, PO_GPR_REGISTER),
+ pic16_newpCodeOp(p[3].pct[0].tok.s, PO_GPR_REGISTER), 0);
+ } else
pcosubtype = pic16_newpCodeOp(NULL,PO_GPR_REGISTER);
}
+#if 0
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem2b - convert assembly line type to a pCode */
+/* instruction with 2 wild operands */
+/* */
+/* pp[0] - mnem */
+/* pp[1] - wild var */
+/* pp[2] - comma */
+/* pp[3] - wild var */
+/* */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem2b(void *pp,pCodeWildBlock *pcwb)
+{
+ parsedPattern *p = pp;
+ int opcode;
+ int dest;
+
+ pCodeInstruction *pci=NULL;
+ pCodeOp *pcosubtype;
+
+ if(!pcwb) {
+ fprintf(stderr,"ERROR %s:%d - can't assemble line\n",__FILE__,__LINE__);
+ return NULL;
+ }
+
+ dest = cvt_extract_destination(&p[3]);
+
+ DFPRINTF((stderr,"altpat_mnem2b %s src %d dst (%d)\n",
+ p->pct[0].tok.s,
+ p[1].pct[1].tok.n,
+ p[3].pct[1].tok.n));
+
+
+ opcode = pic16_getpCode(p->pct[0].tok.s,dest);
+ if(opcode < 0) {
+ fprintf(stderr, "Bad mnemonic\n");
+ return NULL;
+ }
+
+ if(pic16Mnemonics[opcode]->is2MemOp) {
+ /* support for movff instruction */
+ pcosubtype = pic16_popCombine2(
+ pic16_newpCodeOp(NULL, PO_GPR_REGISTER),
+ pic16_newpCodeOp(NULL, PO_GPR_REGISTER), 0);
+ } else pcosubtype = NULL;
+
+ pci = PCI(pic16_newpCode(opcode,
+ pic16_newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
+
+ /* Save the index of the maximum wildcard variable */
+ //if(p[1].pct[1].tok.n > sMaxWildVar)
+ // sMaxWildVar = p[1].pct[1].tok.n;
+
+ if(p[1].pct[1].tok.n > pcwb->nvars)
+ pcwb->nvars = p[1].pct[1].tok.n;
+
+ if(!pci)
+ fprintf(stderr,"couldn't find mnemonic\n");
+
+ return pci;
+
+}
+#endif
+
/*-----------------------------------------------------------------*/
/* cvt_altpat_mem3 - convert assembly line type to a pCode */
}
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem4 - convert assembly line type to a pCode */
+/* This rule is for lfsr instruction */
+/* */
+/* */
+/* pp[0] - mnem */
+/* pp[1] - number */
+/* pp[2] - comma */
+/* pp[3] - source */
+/* */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem4(void *pp, pCodeWildBlock *pcwb)
+{
+ parsedPattern *p = pp;
+ int opcode;
+ int dest; // or could be bit position in the register
+
+ pCodeInstruction *pci=NULL;
+ pCodeOp *pcosubtype=NULL;
+
+ dest = cvt_extract_destination(&p[3]);
+
+ DFPRINTF((stderr,"altpat_mnem4 %s fsr %d source %s\n",
+ p->pct[0].tok.s,
+ p[1].pct[0].tok.n,
+ p[3].pct[0].tok.s));
+
+ opcode = pic16_getpCode(p->pct[0].tok.s,0);
+ if(opcode < 0) {
+ fprintf(stderr, "Bad mnemonic\n");
+ return NULL;
+ }
+ DFPRINTF((stderr, "Found mnemonic opcode= %d\n", opcode));
+
+ if(pic16Mnemonics[opcode]->is2LitOp) {
+ pcosubtype = pic16_newpCodeOpLit2(p[1].pct[0].tok.n, pic16_newpCodeOp(p[3].pct[0].tok.s, PO_STR));
+ }
+
+ if(pcosubtype == NULL) {
+ fprintf(stderr, "Bad operand\n");
+ return NULL;
+ }
+
+ pci = PCI(pic16_newpCode(opcode, pcosubtype));
+
+ if(!pci)
+ fprintf(stderr,"couldn't find mnemonic\n");
+
+ return pci;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem4a - convert assembly line type to a pCode */
+/* This rule is for lfsr instruction */
+/* */
+/* */
+/* pp[0] - mnem */
+/* pp[1] - number */
+/* pp[2] - comma */
+/* pp[3] - value */
+/* */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem4a(void *pp, pCodeWildBlock *pcwb)
+{
+ parsedPattern *p = pp;
+ int opcode;
+ int dest; // or could be bit position in the register
+
+ pCodeInstruction *pci=NULL;
+ pCodeOp *pcosubtype=NULL;
+
+ dest = cvt_extract_destination(&p[3]);
+
+ DFPRINTF((stderr,"altpat_mnem4a %s fsr %d value 0x%02x\n",
+ p->pct[0].tok.s,
+ p[1].pct[0].tok.n,
+ p[3].pct[0].tok.n));
+
+ opcode = pic16_getpCode(p->pct[0].tok.s,0);
+ if(opcode < 0) {
+ fprintf(stderr, "Bad mnemonic\n");
+ return NULL;
+ }
+ DFPRINTF((stderr, "Found mnemonic opcode= %d\n", opcode));
+
+ if(pic16Mnemonics[opcode]->is2LitOp) {
+ pcosubtype = pic16_newpCodeOpLit2(p[1].pct[0].tok.n, pic16_newpCodeOpLit(p[3].pct[0].tok.n));
+ }
+
+ if(pcosubtype == NULL) {
+ fprintf(stderr, "Bad operand\n");
+ return NULL;
+ }
+
+ pci = PCI(pic16_newpCode(opcode, pcosubtype));
+
+ if(!pci)
+ fprintf(stderr,"couldn't find mnemonic\n");
+
+ return pci;
+
+}
+
/*-----------------------------------------------------------------*/
/* tokenizeLineNode - Convert a string (of char's) that was parsed */
/* by SDCCpeeph.c into a string of tokens. */
break;
- default:
- if(isalpha(*ln) || (*ln == '_') ) {
+ default: // hack to allow : goto $
+ if(isalpha(*ln) || (*ln == '_') || (!parsing_peeps && (*ln == '$'))) {
char buffer[50];
int i=0;
- while( (isalpha(*ln) || isdigit(*ln) || (*ln == '_')) && i<49)
+ while( (isalpha(*ln) || isdigit(*ln) || (*ln == '_') || (*ln == '$')) && i<49)
buffer[i++] = *ln++;
ln--;
tokArr[tokIdx++].tt = PCT_STRING;
} else {
- fprintf(stderr, "Error while parsing peep rules (check peeph.def)\n");
- fprintf(stderr, "Line: %s\n",lnstart);
- fprintf(stderr, "Token: '%c'\n",*ln);
- exit(1);
+ if(parsing_peeps) {
+ fprintf(stderr, "Error while parsing peep rules (check peeph.def)\n");
+ fprintf(stderr, "Line: %s\n",lnstart);
+ fprintf(stderr, "Token: '%c'\n",*ln);
+ exit(1);
+ }
}
}
while(i < max_tokens) {
if(*pct == 0) {
- //DFPRINTF((stderr,"matched\n"));
+ DFPRINTF((stderr,"matched\n"));
return i;
}
- //dump1Token(*pat); DFPRINTF((stderr,"\n"));
+// dump1Token(*pat); DFPRINTF((stderr,"\n"));
if( !pat || !pat->pcp )
return 0;
if (pat->pcp->pt != *pct)
return 0;
- //DFPRINTF((stderr," pct=%d\n",*pct));
+ DFPRINTF((stderr," pct=%d\n",*pct));
pct++;
pat++;
i++;
parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
lparsedPatIdx++;
- //dump1Token(tokArr[ltokIdx].tt);
+// dump1Token(tokArr[ltokIdx].tt);
if(advTokIdx(<okIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
DFPRINTF((stderr," reached end \n"));
}
/*-----------------------------------------------------------------*/
-/* */
+/* pic16_AssembleLine - parse line and return the pCode equivalent */
+/* peeps=1 if parsing peep rules, 0 otherwise */
/*-----------------------------------------------------------------*/
-pCode *pic16_AssembleLine(char *line)
+pCode *pic16_AssembleLine(char *line, int peeps)
{
pCode *pc=NULL;
return NULL;
}
+ parsing_peeps = peeps;
+
tokenizeLineNode(line);
if(parseTokens(NULL,&pc))
fprintf(stderr, "WARNING: unable to assemble line:\n%s\n",line);
+ else {
+ DFPRINTF((stderr, "pc= %p\n", pc));
+// if(pc)pc->print(stderr, pc);
+ }
+ parsing_peeps = 1;
return pc;
}
return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]);
}
- {
+ if(PCI(pcs)->pcop) {
char *n;
switch(PCI(pcs)->pcop->type) {
case PO_GPR_TEMP:
case PO_FSR0:
//case PO_INDF0:
- n = PCOR(PCI(pcs)->pcop)->r->name;
+ n = PCOR(PCI(pcs)->pcop)->r->name;
+
+ break;
+ default:
+ n = PCI(pcs)->pcop->name;
+ }
+
+ if(peepBlock->target.vars[index])
+ return (strcmp(peepBlock->target.vars[index],n) == 0);
+ else {
+ DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
+ peepBlock->target.vars[index] = n;
+ return 1;
+ }
+ }
+
+ if(PCI(pcs)->is2MemOp) {
+ char *n;
+
+ switch(PCOP(PCOR2(PCI(pcs))->pcop2)->type) {
+ case PO_GPR_TEMP:
+ case PO_FSR0:
+ //case PO_INDF0:
+ n = PCOR(PCOR2(PCI(pcs))->pcop2)->r->name;
break;
default:
inefficient code with the optimized version */
#ifdef PCODE_DEBUG
DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n"));
- printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
+// printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
DFPRINTF((stderr,"first thing matched\n"));
pc->print(stderr,pc);
if(pcin) {
} while( passes && ((total_registers_saved != saved) || (passes==OPT_PASSES-1)) );
if(total_registers_saved == t)
+
+ if(pic16_debug_verbose)
fprintf(stderr, "No registers saved on this pass\n");
// From: Vangelis Rokas (vrokas@otenet.gr)
+// movff peeps are disabled for the moment
+// until support is added in the pcodepeeph.c
//replace {
// movf %1,w
// movwf %3
//}
-replace {
- movff %1,%2
-} by {
- ; peep xxx - test peep to see if peep rules can handle movff
- movf %1,w
- movwf %2
-}
+//replace {
+// movff %1,%2
+//} by {
+// ; peep xxx - test peep to see if peep rules can handle movff
+// movf %1,w
+// movwf %2
+//}
#include "ralloc.h"
#include "pcode.h"
#include "gen.h"
+#include "device.h"
#if defined(__BORLANDC__) || defined(_MSC_VER)
#define STRCASECMP stricmp
set *pic16_rel_udata=NULL;
set *pic16_fix_udata=NULL;
+set *pic16_equ_data=NULL;
+set *pic16_builtin_functions=NULL;
-static int dynrIdx=0x20;
+static int dynrIdx=0x10; //0x20; // starting temporary register rIdx
static int rDirectIdx=0;
int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
static void spillThis (symbol *);
-static int debug = 1;
+int pic16_ralloc_debug = 0;
static FILE *debugF = NULL;
/*-----------------------------------------------------------------*/
/* debugLog - open a file for debugging information */
//char *bufferP=buffer;
va_list ap;
- if (!debug || !dstFileName)
+ if (!pic16_ralloc_debug || !dstFileName)
return;
static void
debugNewLine (void)
{
- if (debugF)
- fputc ('\n', debugF);
+ if(!pic16_ralloc_debug)return;
+
+ if (debugF)
+ fputc ('\n', debugF);
}
/*-----------------------------------------------------------------*/
/* debugLogClose - closes the debug log file (if opened) */
static void
debugLogClose (void)
{
- if (debugF)
- {
- fclose (debugF);
- debugF = NULL;
- }
+ if (debugF) {
+ fclose (debugF);
+ debugF = NULL;
+ }
}
+
#define AOP(op) op->aop
static char *
debugAopGet (char *str, operand * op)
{
- if (str)
- debugLog (str);
+ if(!pic16_ralloc_debug)return NULL;
- printOperand (op, debugF);
- debugNewLine ();
+ if (str)
+ debugLog (str);
- return NULL;
+ printOperand (op, debugF);
+ debugNewLine ();
+ return NULL;
}
static char *
decodeOp (unsigned int op)
{
+ if (op < 128 && op > ' ') {
+ buffer[0] = (op & 0xff);
+ buffer[1] = 0;
+ return buffer;
+ }
- if (op < 128 && op > ' ')
- {
- buffer[0] = (op & 0xff);
- buffer[1] = 0;
- return buffer;
- }
+ switch (op) {
+ case IDENTIFIER: return "IDENTIFIER";
+ case TYPE_NAME: return "TYPE_NAME";
+ case CONSTANT: return "CONSTANT";
+ case STRING_LITERAL: return "STRING_LITERAL";
+ case SIZEOF: return "SIZEOF";
+ case PTR_OP: return "PTR_OP";
+ case INC_OP: return "INC_OP";
+ case DEC_OP: return "DEC_OP";
+ case LEFT_OP: return "LEFT_OP";
+ case RIGHT_OP: return "RIGHT_OP";
+ case LE_OP: return "LE_OP";
+ case GE_OP: return "GE_OP";
+ case EQ_OP: return "EQ_OP";
+ case NE_OP: return "NE_OP";
+ case AND_OP: return "AND_OP";
+ case OR_OP: return "OR_OP";
+ case MUL_ASSIGN: return "MUL_ASSIGN";
+ case DIV_ASSIGN: return "DIV_ASSIGN";
+ case MOD_ASSIGN: return "MOD_ASSIGN";
+ case ADD_ASSIGN: return "ADD_ASSIGN";
+ case SUB_ASSIGN: return "SUB_ASSIGN";
+ case LEFT_ASSIGN: return "LEFT_ASSIGN";
+ case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
+ case AND_ASSIGN: return "AND_ASSIGN";
+ case XOR_ASSIGN: return "XOR_ASSIGN";
+ case OR_ASSIGN: return "OR_ASSIGN";
+ case TYPEDEF: return "TYPEDEF";
+ case EXTERN: return "EXTERN";
+ case STATIC: return "STATIC";
+ case AUTO: return "AUTO";
+ case REGISTER: return "REGISTER";
+ case CODE: return "CODE";
+ case EEPROM: return "EEPROM";
+ case INTERRUPT: return "INTERRUPT";
+ case SFR: return "SFR";
+ case AT: return "AT";
+ case SBIT: return "SBIT";
+ case REENTRANT: return "REENTRANT";
+ case USING: return "USING";
+ case XDATA: return "XDATA";
+ case DATA: return "DATA";
+ case IDATA: return "IDATA";
+ case PDATA: return "PDATA";
+ case VAR_ARGS: return "VAR_ARGS";
+ case CRITICAL: return "CRITICAL";
+ case NONBANKED: return "NONBANKED";
+ case BANKED: return "BANKED";
+ case CHAR: return "CHAR";
+ case SHORT: return "SHORT";
+ case INT: return "INT";
+ case LONG: return "LONG";
+ case SIGNED: return "SIGNED";
+ case UNSIGNED: return "UNSIGNED";
+ case FLOAT: return "FLOAT";
+ case DOUBLE: return "DOUBLE";
+ case CONST: return "CONST";
+ case VOLATILE: return "VOLATILE";
+ case VOID: return "VOID";
+ case BIT: return "BIT";
+ case STRUCT: return "STRUCT";
+ case UNION: return "UNION";
+ case ENUM: return "ENUM";
+ case ELIPSIS: return "ELIPSIS";
+ case RANGE: return "RANGE";
+ case FAR: return "FAR";
+ case CASE: return "CASE";
+ case DEFAULT: return "DEFAULT";
+ case IF: return "IF";
+ case ELSE: return "ELSE";
+ case SWITCH: return "SWITCH";
+ case WHILE: return "WHILE";
+ case DO: return "DO";
+ case FOR: return "FOR";
+ case GOTO: return "GOTO";
+ case CONTINUE: return "CONTINUE";
+ case BREAK: return "BREAK";
+ case RETURN: return "RETURN";
+ case INLINEASM: return "INLINEASM";
+ case IFX: return "IFX";
+ case ADDRESS_OF: return "ADDRESS_OF";
+ case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
+ case SPIL: return "SPIL";
+ case UNSPIL: return "UNSPIL";
+ case GETHBIT: return "GETHBIT";
+ case BITWISEAND: return "BITWISEAND";
+ case UNARYMINUS: return "UNARYMINUS";
+ case IPUSH: return "IPUSH";
+ case IPOP: return "IPOP";
+ case PCALL: return "PCALL";
+ case ENDFUNCTION: return "ENDFUNCTION";
+ case JUMPTABLE: return "JUMPTABLE";
+ case RRC: return "RRC";
+ case RLC: return "RLC";
+ case CAST: return "CAST";
+ case CALL: return "CALL";
+ case PARAM: return "PARAM ";
+ case NULLOP: return "NULLOP";
+ case BLOCK: return "BLOCK";
+ case LABEL: return "LABEL";
+ case RECEIVE: return "RECEIVE";
+ case SEND: return "SEND";
+ }
+ sprintf (buffer, "unkown op %d %c", op, op & 0xff);
- switch (op)
- {
- case IDENTIFIER:
- return "IDENTIFIER";
- case TYPE_NAME:
- return "TYPE_NAME";
- case CONSTANT:
- return "CONSTANT";
- case STRING_LITERAL:
- return "STRING_LITERAL";
- case SIZEOF:
- return "SIZEOF";
- case PTR_OP:
- return "PTR_OP";
- case INC_OP:
- return "INC_OP";
- case DEC_OP:
- return "DEC_OP";
- case LEFT_OP:
- return "LEFT_OP";
- case RIGHT_OP:
- return "RIGHT_OP";
- case LE_OP:
- return "LE_OP";
- case GE_OP:
- return "GE_OP";
- case EQ_OP:
- return "EQ_OP";
- case NE_OP:
- return "NE_OP";
- case AND_OP:
- return "AND_OP";
- case OR_OP:
- return "OR_OP";
- case MUL_ASSIGN:
- return "MUL_ASSIGN";
- case DIV_ASSIGN:
- return "DIV_ASSIGN";
- case MOD_ASSIGN:
- return "MOD_ASSIGN";
- case ADD_ASSIGN:
- return "ADD_ASSIGN";
- case SUB_ASSIGN:
- return "SUB_ASSIGN";
- case LEFT_ASSIGN:
- return "LEFT_ASSIGN";
- case RIGHT_ASSIGN:
- return "RIGHT_ASSIGN";
- case AND_ASSIGN:
- return "AND_ASSIGN";
- case XOR_ASSIGN:
- return "XOR_ASSIGN";
- case OR_ASSIGN:
- return "OR_ASSIGN";
- case TYPEDEF:
- return "TYPEDEF";
- case EXTERN:
- return "EXTERN";
- case STATIC:
- return "STATIC";
- case AUTO:
- return "AUTO";
- case REGISTER:
- return "REGISTER";
- case CODE:
- return "CODE";
- case EEPROM:
- return "EEPROM";
- case INTERRUPT:
- return "INTERRUPT";
- case SFR:
- return "SFR";
- case AT:
- return "AT";
- case SBIT:
- return "SBIT";
- case REENTRANT:
- return "REENTRANT";
- case USING:
- return "USING";
- case XDATA:
- return "XDATA";
- case DATA:
- return "DATA";
- case IDATA:
- return "IDATA";
- case PDATA:
- return "PDATA";
- case VAR_ARGS:
- return "VAR_ARGS";
- case CRITICAL:
- return "CRITICAL";
- case NONBANKED:
- return "NONBANKED";
- case BANKED:
- return "BANKED";
- case CHAR:
- return "CHAR";
- case SHORT:
- return "SHORT";
- case INT:
- return "INT";
- case LONG:
- return "LONG";
- case SIGNED:
- return "SIGNED";
- case UNSIGNED:
- return "UNSIGNED";
- case FLOAT:
- return "FLOAT";
- case DOUBLE:
- return "DOUBLE";
- case CONST:
- return "CONST";
- case VOLATILE:
- return "VOLATILE";
- case VOID:
- return "VOID";
- case BIT:
- return "BIT";
- case STRUCT:
- return "STRUCT";
- case UNION:
- return "UNION";
- case ENUM:
- return "ENUM";
- case ELIPSIS:
- return "ELIPSIS";
- case RANGE:
- return "RANGE";
- case FAR:
- return "FAR";
- case CASE:
- return "CASE";
- case DEFAULT:
- return "DEFAULT";
- case IF:
- return "IF";
- case ELSE:
- return "ELSE";
- case SWITCH:
- return "SWITCH";
- case WHILE:
- return "WHILE";
- case DO:
- return "DO";
- case FOR:
- return "FOR";
- case GOTO:
- return "GOTO";
- case CONTINUE:
- return "CONTINUE";
- case BREAK:
- return "BREAK";
- case RETURN:
- return "RETURN";
- case INLINEASM:
- return "INLINEASM";
- case IFX:
- return "IFX";
- case ADDRESS_OF:
- return "ADDRESS_OF";
- case GET_VALUE_AT_ADDRESS:
- return "GET_VALUE_AT_ADDRESS";
- case SPIL:
- return "SPIL";
- case UNSPIL:
- return "UNSPIL";
- case GETHBIT:
- return "GETHBIT";
- case BITWISEAND:
- return "BITWISEAND";
- case UNARYMINUS:
- return "UNARYMINUS";
- case IPUSH:
- return "IPUSH";
- case IPOP:
- return "IPOP";
- case PCALL:
- return "PCALL";
- case ENDFUNCTION:
- return "ENDFUNCTION";
- case JUMPTABLE:
- return "JUMPTABLE";
- case RRC:
- return "RRC";
- case RLC:
- return "RLC";
- case CAST:
- return "CAST";
- case CALL:
- return "CALL";
- case PARAM:
- return "PARAM ";
- case NULLOP:
- return "NULLOP";
- case BLOCK:
- return "BLOCK";
- case LABEL:
- return "LABEL";
- case RECEIVE:
- return "RECEIVE";
- case SEND:
- return "SEND";
- }
- sprintf (buffer, "unkown op %d %c", op, op & 0xff);
return buffer;
}
/*-----------------------------------------------------------------*/
static char *
debugLogRegType (short type)
{
+ if(!pic16_ralloc_debug)return NULL;
+ switch (type) {
+ case REG_GPR: return "REG_GPR";
+ case REG_PTR: return "REG_PTR";
+ case REG_CND: return "REG_CND";
+ }
+ sprintf (buffer, "unknown reg type %d", type);
- switch (type)
- {
- case REG_GPR:
- return "REG_GPR";
- case REG_PTR:
- return "REG_PTR";
- case REG_CND:
- return "REG_CND";
- }
-
- sprintf (buffer, "unknown reg type %d", type);
return buffer;
}
}
// fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
+
dReg->isFree = 0;
dReg->wasUsed = 1;
for (dReg = setFirstItem(dRegs) ; dReg ;
dReg = setNextItem(dRegs)) {
- if(dReg->isFree)
+// fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
+// __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
+
+ if(dReg->isFree) {
return dReg;
+ }
}
return NULL;
{
regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
-// fprintf(stderr,"pic16_allocInternalRegister %s addr =0x%x\n",name,rIdx);
+// fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
if(reg) {
reg->wasUsed = 0;
static regs *
allocReg (short type)
{
+ regs * reg=NULL;
+
+#if 0
+ if(dynrIdx > pic16_nRegs)
+ return NULL;
+#endif
+
+#if STACK_SUPPORT
+ if(USE_STACK) {
+ /* try to reuse some unused registers */
+ reg = regFindFree( pic16_dynAllocRegs );
+ }
+#endif
- debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
- //fprintf(stderr,"allocReg\n");
+ if(!reg) {
+ reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
+ addSet(&pic16_dynAllocRegs, reg);
+ }
+ reg->isFree=0;
+ debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
- return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
+// fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
+// __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
+
+ if(reg) {
+ reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
+ reg->isLocal = 1; /* this is a local frame register */
+ }
+
+#if STACK_SUPPORT
+ if (currFunc)
+ currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
+#endif
+
+ return (reg); // addSet(&pic16_dynAllocRegs,reg);
}
/* 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(pic16_debug_verbose)
+ fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__,
+ OP_SYMBOL(op)->name);
+ return NULL;
+ }
if(!IS_CONFIG_ADDRESS(address)) {
//fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
debugLog (" -- %s is declared at address 0x30000x\n",name);
fprintf(stderr, " -- %s is declared at address 0x30000x\n",name);
-/*
- fprintf(stderr, " setting config word to %x\n",
- (int) floatFromVal (op->operand.valOperand)); //IC_RIGHT(ic)->operand.valOperand));
-
- pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
- (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
-*/
-
-
return NULL;
}
}
case REG_GPR:
if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
return dReg;
- return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
+ return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
case REG_STK:
freeReg (regs * reg)
{
debugLog ("%s\n", __FUNCTION__);
+// fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
reg->isFree = 1;
}
static int
nFreeRegs (int type)
{
+ regs *reg;
+ int nfr=0;
+
+
+ /* although I fixed the register allocation/freeing scheme
+ * the for loop below doesn't give valid results. I do not
+ * know why yet. -- VR 10-Jan-2003 */
+
+ return 100;
+
+
/* dynamically allocate as many as we need and worry about
* fitting them into a PIC later */
- return 100;
-#if 0
- int i;
- int nfr = 0;
-
debugLog ("%s\n", __FUNCTION__);
- for (i = 0; i < pic16_nRegs; i++)
- if (regspic16[i].isFree && regspic16[i].type == type)
- nfr++;
+
+ for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
+ if((reg->type == type) && reg->isFree)nfr++;
+
+ fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
return nfr;
-#endif
}
/*-----------------------------------------------------------------*/
extern void pic16_groupRegistersInSection(set *regset);
-extern void pic16_dump_map(void);
-extern void pic16_dump_section(FILE *of, char *sname, set *section, int fix);
+extern void pic16_dump_equates(FILE *of, set *equs);
+//extern void pic16_dump_map(void);
+extern void pic16_dump_section(FILE *of, set *section, int fix);
static void packBits(set *bregs)
// pic16_dump_map();
// pic16_dump_cblock(of);
- pic16_dump_section(of, "ud1", pic16_rel_udata, 0);
- pic16_dump_section(of, "ud2", pic16_fix_udata, 1);
-
+ pic16_dump_equates(of, pic16_equ_data);
+
+ pic16_dump_section(of, pic16_rel_udata, 0);
+ pic16_dump_section(of, pic16_fix_udata, 1);
+
#if 0
bitEQUs(of,pic16_dynDirectBitRegs);
aliasEQUs(of,pic16_dynAllocRegs,0);
void
pic16_freeAllRegs ()
{
- // int i;
-
debugLog ("%s\n", __FUNCTION__);
applyToSet(pic16_dynAllocRegs,markRegFree);
applyToSet(pic16_dynStackRegs,markRegFree);
-
-/*
- for (i = 0; i < pic16_nRegs; i++)
- regspic16[i].isFree = 1;
-*/
}
/*-----------------------------------------------------------------*/
void
pic16_deallocateAllRegs ()
{
- // int i;
-
debugLog ("%s\n", __FUNCTION__);
applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
-
-/*
- for (i = 0; i < pic16_nRegs; i++) {
- if(regspic16[i].pc_type == PO_GPR_TEMP) {
- regspic16[i].isFree = 1;
- regspic16[i].wasUsed = 0;
- }
- }
-*/
}
return 0;
}
+
+#if 0
+ if(ic->op == CALL || ic->op == PCALL) {
+ addSet(&pic16_builtin_functions, OP_SYMBOL( IC_LEFT(ic)));
+ debugLog ("%d This is a call, function: %s\n", __LINE__, OP_SYMBOL(IC_LEFT(ic))->name);
+ return 0;
+ }
+#endif
+
/* find the definition of iTempNN scanning backwards if we find a
a use of the true symbol before we find the definition then
we cannot pack */
break;
}
+
if (SKIP_IC2 (dic))
continue;
static void printSymType(char * str, sym_link *sl)
{
- debugLog (" %s Symbol type: ",str);
- printTypeChain( sl, debugF);
- debugLog ("\n");
-
+ if(!pic16_ralloc_debug)return;
+
+ debugLog (" %s Symbol type: ",str);
+ printTypeChain( sl, debugF);
+ debugLog ("\n");
}
/*-----------------------------------------------------------------*/
{
FILE *of = stderr;
- if(!sl)
- return;
-
- if(debugF)
- of = debugF;
-
- for ( ; sl; sl=sl->next) {
- if(!IS_DECL(sl) ) {
- switch (SPEC_SCLS(sl)) {
+ if(!pic16_ralloc_debug)return;
- case S_DATA: fprintf (of, "data "); break;
- case S_XDATA: fprintf (of, "xdata "); break;
- case S_SFR: fprintf (of, "sfr "); break;
- case S_SBIT: fprintf (of, "sbit "); break;
- case S_CODE: fprintf (of, "code "); break;
- case S_IDATA: fprintf (of, "idata "); break;
- case S_PDATA: fprintf (of, "pdata "); break;
- case S_LITERAL: fprintf (of, "literal "); break;
- case S_STACK: fprintf (of, "stack "); break;
- case S_XSTACK: fprintf (of, "xstack "); break;
- case S_BIT: fprintf (of, "bit "); break;
- case S_EEPROM: fprintf (of, "eeprom "); break;
- default: break;
- }
-
- }
+ if(!sl)return;
+
+ if(debugF)
+ of = debugF;
+
+ for ( ; sl; sl=sl->next) {
+ if(!IS_DECL(sl) ) {
+ switch (SPEC_SCLS(sl)) {
+ case S_DATA: fprintf (of, "data "); break;
+ case S_XDATA: fprintf (of, "xdata "); break;
+ case S_SFR: fprintf (of, "sfr "); break;
+ case S_SBIT: fprintf (of, "sbit "); break;
+ case S_CODE: fprintf (of, "code "); break;
+ case S_IDATA: fprintf (of, "idata "); break;
+ case S_PDATA: fprintf (of, "pdata "); break;
+ case S_LITERAL: fprintf (of, "literal "); break;
+ case S_STACK: fprintf (of, "stack "); break;
+ case S_XSTACK: fprintf (of, "xstack "); break;
+ case S_BIT: fprintf (of, "bit "); break;
+ case S_EEPROM: fprintf (of, "eeprom "); break;
+ default: break;
+ }
- }
-
+ }
+ }
}
/*--------------------------------------------------------------------*/
sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
debugAopGet ("x left:", IC_LEFT (ic));
-#if 1
+#if 0
if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
#else
if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
{
int i;
- if (!debug || !debugF)
+ if (!pic16_ralloc_debug || !debugF)
return;
for (i = 0; i < count; i++)
/* and serially allocate registers */
serialRegAssign (ebbs, count);
+ //pic16_freeAllRegs();
+
/* if stack was extended then tell the user */
if (_G.stackExtend)
{
setToNull ((void *) &_G.stackSpil);
setToNull ((void *) &_G.spiltSet);
/* mark all registers as free */
- //pic16_freeAllRegs ();
+ pic16_freeAllRegs ();
debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
debugLogClose ();
unsigned isBitField:1; /* True if reg is type bit OR is holder for several bits */
unsigned isEmitted:1; /* True if the reg has been written to a .asm file */
unsigned accessBank:1; /* True if the reg is explicit placed in access bank */
+ unsigned isLocal:1; /* True if the reg is allocated in function's local frame */
unsigned address; /* reg's address if isFixed | isMapped is true */
unsigned size; /* 0 for byte, 1 for int, 4 for long */
unsigned alias; /* Alias mask if register appears in multiple banks */
extern set *pic16_dynDirectBitRegs;
extern set *pic16_dynInternalRegs;
+extern set *pic16_builtin_functions;
+
extern set *pic16_rel_udata;
extern set *pic16_fix_udata;
+extern set *pic16_equ_data;
regs *pic16_regWithIdx (int);
regs *pic16_dirregWithName (char *name );
#define IDX_FSR2H 0xfda
#define IDX_POSTINC1 0xfe6
#define IDX_POSTDEC1 0xfe5
+#define IDX_PREINC1 0xfe4
#define IDX_PREINC2 0xfdc
#define IDX_PLUSW2 0xfdb