From 476f65e63356c85584ef8e42481ddecf5c09e488 Mon Sep 17 00:00:00 2001 From: vrokas Date: Sun, 11 Jan 2004 15:26:54 +0000 Subject: [PATCH] 2004-01-11 Vangelis Rokas 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. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3112 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 49 +++ src/SDCCopt.c | 58 ++- src/pic16/NOTES | 105 ++++++ src/pic16/device.c | 33 +- src/pic16/gen.c | 845 ++++++++++++++++++++++++------------------ src/pic16/gen.h | 3 +- src/pic16/glue.c | 664 ++++++++++++++++----------------- src/pic16/main.c | 39 +- src/pic16/main.h | 8 + src/pic16/pcode.c | 271 ++++++++++---- src/pic16/pcode.h | 8 +- src/pic16/pcodepeep.c | 272 ++++++++++++-- src/pic16/pcoderegs.c | 2 + src/pic16/peeph.def | 16 +- src/pic16/ralloc.c | 573 +++++++++++++--------------- src/pic16/ralloc.h | 5 + 16 files changed, 1804 insertions(+), 1147 deletions(-) create mode 100644 src/pic16/NOTES diff --git a/ChangeLog b/ChangeLog index e66dbb32..df1568f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,52 @@ +2004-01-11 Vangelis Rokas + + 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 * src/mcs51/peephole.def: added peepholes 177.c,d (redundant moves) diff --git a/src/SDCCopt.c b/src/SDCCopt.c index a4c7de22..05eab6f5 100644 --- a/src/SDCCopt.c +++ b/src/SDCCopt.c @@ -176,6 +176,20 @@ cnvToFcall (iCode * ic, eBBlock * ebp) 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); } @@ -250,9 +264,22 @@ found: 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; - } /*-----------------------------------------------------------------*/ @@ -327,9 +354,22 @@ found: 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); @@ -477,6 +517,20 @@ found: 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); } diff --git a/src/pic16/NOTES b/src/pic16/NOTES new file mode 100644 index 00000000..d49eb7e5 --- /dev/null +++ b/src/pic16/NOTES @@ -0,0 +1,105 @@ +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 + +Other people to contact: +Scott Dattalo + + + +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; diff --git a/src/pic16/device.c b/src/pic16/device.c index b7eb7865..9aeaeb38 100644 --- a/src/pic16/device.c +++ b/src/pic16/device.c @@ -339,8 +339,26 @@ void pic16_dump_map(void) } #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; @@ -552,11 +570,18 @@ void pic16_groupRegistersInSection(set *regset) 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); + } } } } diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 7775b12c..9bd719d2 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -44,14 +44,16 @@ #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); @@ -184,6 +186,35 @@ void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, op } +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; @@ -219,7 +250,6 @@ void DEBUGpic16_emitcode (char *inst,char *fmt, ...) // fprintf(stderr, "%s\n", lb); } - void pic16_emitpLabel(int key) { pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset)); @@ -1239,9 +1269,9 @@ pCodeOp *pic16_popGetLit(unsigned int lit) /*-----------------------------------------------------------------*/ /* 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); } @@ -1310,22 +1340,19 @@ static pCodeOp *pic16_popRegFromString(char *str, int size, int offset) 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; } @@ -1340,22 +1367,37 @@ pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset) 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 */ /*-----------------------------------------------------------------*/ @@ -1383,6 +1425,7 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) 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: @@ -1702,6 +1745,17 @@ static void mov2w (asmop *aop, int offset) } +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 */ /*-----------------------------------------------------------------*/ @@ -1718,18 +1772,17 @@ void pushw(void) 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) { @@ -1740,7 +1793,7 @@ 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)); } /*-----------------------------------------------------------------*/ @@ -2228,10 +2281,10 @@ static void assignResultValue(operand * oper) 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++; @@ -2501,10 +2554,10 @@ static void genCall (iCode *ic) 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 */ } @@ -2543,7 +2596,7 @@ static void genCall (iCode *ic) } #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) { @@ -2554,7 +2607,7 @@ static void genCall (iCode *ic) #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; @@ -2740,205 +2793,221 @@ static bool inExcludeList(char *s) /*-----------------------------------------------------------------*/ 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"); + } + } /*-----------------------------------------------------------------*/ @@ -2950,10 +3019,17 @@ static void genEndFunction (iCode *ic) 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 @@ -2965,6 +3041,7 @@ static void genEndFunction (iCode *ic) } +#if 0 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) { if (options.useXstack) { pic16_emitcode("mov","r0,%s",spname); @@ -2977,6 +3054,7 @@ static void genEndFunction (iCode *ic) pic16_emitcode ("pop","_bp"); } } +#endif /* restore the register bank */ if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) @@ -3071,20 +3149,28 @@ static void genEndFunction (iCode *ic) 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) { @@ -3104,20 +3190,14 @@ static void genEndFunction (iCode *ic) * 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 @@ -3169,7 +3249,7 @@ static void genRet (iCode *ic) 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++; } @@ -4469,11 +4549,11 @@ static void genCmp (operand *left,operand *right, /* 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 */ @@ -6231,7 +6311,8 @@ static void genInline (iCode *ic) *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 == ':') { @@ -6245,7 +6326,7 @@ static void genInline (iCode *ic) } } if ((bp1 != bp) && *bp1) - pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1)); + pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0)); Safe_free(buffer); @@ -8512,6 +8593,7 @@ static void genConstPointerGet (operand *left, 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)); @@ -8800,7 +8882,7 @@ static void genDataPointerSet(operand *right, 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); @@ -9355,7 +9437,7 @@ static void genAddrOf (iCode *ic) 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__); @@ -9366,20 +9448,31 @@ static void genAddrOf (iCode *ic) 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)); @@ -9748,149 +9841,174 @@ release: /*-----------------------------------------------------------------*/ 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)); @@ -9998,7 +10116,7 @@ static void genCast (iCode *ic) 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 */ @@ -10196,13 +10314,20 @@ void genpic16Code (iCode *lic) 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 diff --git a/src/pic16/gen.h b/src/pic16/gen.h index c37eebd6..54ed8d20 100644 --- a/src/pic16/gen.h +++ b/src/pic16/gen.h @@ -163,12 +163,13 @@ pCodeOp *pic16_popGetLabel(unsigned int key); 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); diff --git a/src/pic16/glue.c b/src/pic16/glue.c index 0d0407d0..88f49291 100644 --- a/src/pic16/glue.c +++ b/src/pic16/glue.c @@ -69,7 +69,7 @@ extern void printPublics (FILE * afile); 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); @@ -112,156 +112,142 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag) // 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 - } + } } @@ -610,25 +596,15 @@ pic16emitMaps () 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); @@ -661,15 +637,15 @@ pic16initialComments (FILE * afile) /* 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); } @@ -682,11 +658,14 @@ pic16_printExterns(FILE *afile) 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); } /*-----------------------------------------------------------------*/ @@ -805,74 +784,78 @@ pic16glue () 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 @@ -886,200 +869,191 @@ pic16glue () } #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(); diff --git a/src/pic16/main.c b/src/pic16/main.c index 0eed2092..c3ce60ac 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -63,6 +63,7 @@ static char *_pic16_keywords[] = "_xdata", "_pdata", "_idata", + "_naked", NULL }; @@ -117,10 +118,13 @@ _pic16_regparm (sym_link * l) } +set *absSymSet; + static int _process_pragma(const char *sz) { static const char *WHITE = " \t"; + char *ptr = strtok((char *)sz, WHITE); if (startsWith (ptr, "maxram")) { @@ -143,9 +147,29 @@ _process_pragma(const char *sz) // 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=" @@ -172,6 +196,8 @@ _process_pragma(const char *sz) 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"}, @@ -183,6 +209,9 @@ OPTION pic16_optionsTable[]= { { 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 @@ -375,6 +404,8 @@ _pic16_finaliseOptions (void) 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}")); } @@ -473,10 +504,10 @@ _pic16_getRegName (struct regs *reg) } -#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; } @@ -736,7 +767,7 @@ PORT pic16_port = _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 */ diff --git a/src/pic16/main.h b/src/pic16/main.h index b5861727..087476d0 100644 --- a/src/pic16/main.h +++ b/src/pic16/main.h @@ -27,4 +27,12 @@ typedef struct { unsigned int addr_udatashr; } pic16_sectioninfo_t; +typedef struct absSym { + char *name; + unsigned int address; +} absSym; + +extern set *absSymSet; + + #endif diff --git a/src/pic16/pcode.c b/src/pic16/pcode.c index 1623b998..d6d80458 100644 --- a/src/pic16/pcode.c +++ b/src/pic16/pcode.c @@ -26,6 +26,7 @@ #include "newalloc.h" +#include "main.h" #include "pcode.h" #include "pcodeflow.h" #include "ralloc.h" @@ -52,12 +53,12 @@ static peepCommand peepCommands[] = { // 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}; @@ -66,6 +67,7 @@ pCodeOpReg pic16_pc_fsr1h = {{PO_FSR0, "FSR1H"}, -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}; @@ -89,6 +91,8 @@ static int peepOptimizing = 1; /* run the peephole optimizer if nonzero * 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; @@ -2539,22 +2543,24 @@ void pic16_pCodeInitRegisters(void) 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; @@ -2569,6 +2575,7 @@ void pic16_pCodeInitRegisters(void) 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; @@ -2741,9 +2748,13 @@ int pic16_getpCode(char *mnem,unsigned dest) 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); } @@ -2828,6 +2839,14 @@ void pic16_pBlockConvert2ISR(pBlock *pb) 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 */ @@ -3121,7 +3140,6 @@ pCode *pic16_newpCodeFunction(char *mod,char *f) pCodeFunction *pcf; pcf = Safe_calloc(1,sizeof(pCodeFunction)); - //_ALLOC(pcf,sizeof(pCodeFunction)); pcf->pc.type = PC_FUNCTION; pcf->pc.prev = pcf->pc.next = NULL; @@ -3135,14 +3153,12 @@ pCode *pic16_newpCodeFunction(char *mod,char *f) 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 @@ -3266,10 +3282,10 @@ pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...) { 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; @@ -3278,11 +3294,15 @@ pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...) 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); @@ -3444,24 +3464,25 @@ pCodeOp *pic16_newpCodeOpLit(int lit) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -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; } @@ -3480,10 +3501,11 @@ pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space) 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); @@ -3585,13 +3607,17 @@ pCodeOp *pic16_newpCodeOpReg(int rIdx) 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; } @@ -3799,15 +3825,36 @@ void pic16_printpBlock(FILE *of, pBlock *pb) { 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); + } } /*-----------------------------------------------------------------*/ @@ -3876,6 +3923,9 @@ static void genericDestruct(pCode *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; @@ -3911,32 +3961,67 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size) 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; @@ -4104,11 +4189,13 @@ static char *pic16_pCode2str(char *str, size_t size, pCode *pc) 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) { @@ -4118,7 +4205,7 @@ static char *pic16_pCode2str(char *str, size_t size, pCode *pc) 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; @@ -4193,7 +4280,7 @@ static char *pic16_pCode2str(char *str, size_t size, pCode *pc) 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:""); @@ -4278,7 +4365,7 @@ static void genericPrint(FILE *of, pCode *pc) 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: { @@ -4309,27 +4396,42 @@ static void pCodePrintFunction(FILE *of, pCode *pc) 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"); } } /*-----------------------------------------------------------------*/ @@ -5279,9 +5381,14 @@ static void LinkFlow(pBlock *pb) //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; } @@ -6360,6 +6467,8 @@ static void pBlockStats(FILE *of, pBlock *pb) 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 diff --git a/src/pic16/pcode.h b/src/pic16/pcode.h index 2b57ef5d..e2391114 100644 --- a/src/pic16/pcode.h +++ b/src/pic16/pcode.h @@ -364,7 +364,7 @@ typedef struct pCodeOpLit2 { pCodeOp pcop; int lit; - int lit2; + pCodeOp *arg2; } pCodeOpLit2; @@ -910,11 +910,12 @@ void pic16_AssignRegBanks(void); 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); @@ -927,7 +928,7 @@ struct regs * pic16_getRegFromInstruction(pCode *pc); struct regs * pic16_getRegFromInstruction2(pCode *pc); extern void pic16_pcode_test(void); - +extern int pic16_debug_verbose; /*-----------------------------------------------------------------* * pCode objects. *-----------------------------------------------------------------*/ @@ -945,6 +946,7 @@ extern pCodeOpReg pic16_pc_fsr2l; 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; diff --git a/src/pic16/pcodepeep.c b/src/pic16/pcodepeep.c index 69ce8a42..4b6c1a96 100644 --- a/src/pic16/pcodepeep.c +++ b/src/pic16/pcodepeep.c @@ -46,9 +46,10 @@ int pic16_getpCodePeepCommand(char *cmd); 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)) @@ -203,7 +204,10 @@ typedef enum { ALT_MNEM1B, ALT_MNEM2, ALT_MNEM2A, - ALT_MNEM3 + ALT_MNEM2B, + ALT_MNEM3, + ALT_MNEM4, + ALT_MNEM4a } altPatterns; static char alt_comment[] = { PCP_COMMENT, 0}; @@ -215,7 +219,10 @@ static char alt_mnem1a[] = { PCP_STR, PCP_WILDVAR, 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); @@ -226,12 +233,19 @@ static void * cvt_altpat_mnem1a(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}, @@ -434,8 +448,10 @@ static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb) 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)); @@ -567,7 +583,6 @@ static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb) p[3].pct[0].tok.s, dest)); - opcode = pic16_getpCode(p->pct[0].tok.s,dest); if(opcode < 0) { fprintf(stderr, "Bad mnemonic\n"); @@ -581,8 +596,15 @@ static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb) 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)); @@ -637,6 +659,13 @@ static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb) 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); @@ -657,6 +686,70 @@ static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb) } +#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 */ @@ -716,6 +809,110 @@ static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb) } +/*-----------------------------------------------------------------*/ +/* 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. */ @@ -785,12 +982,12 @@ static void tokenizeLineNode(char *ln) 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--; @@ -800,10 +997,12 @@ static void tokenizeLineNode(char *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); + } } } @@ -915,11 +1114,11 @@ static int altComparePattern( char *pct, parsedPattern *pat, int max_tokens) 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; @@ -927,7 +1126,7 @@ static int altComparePattern( char *pct, parsedPattern *pat, int max_tokens) if (pat->pcp->pt != *pct) return 0; - //DFPRINTF((stderr," pct=%d\n",*pct)); + DFPRINTF((stderr," pct=%d\n",*pct)); pct++; pat++; i++; @@ -1122,7 +1321,7 @@ static int parseTokens(pCodeWildBlock *pcwb, pCode **pcret) 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")); @@ -1216,9 +1415,10 @@ static void peepRuleBlock2pCodeBlock( lineNode *ln, pCodeWildBlock *pcwb) } /*-----------------------------------------------------------------*/ -/* */ +/* 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; @@ -1227,11 +1427,18 @@ pCode *pic16_AssembleLine(char *line) 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; } @@ -1708,14 +1915,37 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) 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: @@ -2110,7 +2340,7 @@ int pic16_pCodePeepMatchRule(pCode *pc) 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) { diff --git a/src/pic16/pcoderegs.c b/src/pic16/pcoderegs.c index 8ea1e52c..0a772a8d 100644 --- a/src/pic16/pcoderegs.c +++ b/src/pic16/pcoderegs.c @@ -819,6 +819,8 @@ void pic16_pCodeRegOptimizeRegUsage(int level) } 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"); diff --git a/src/pic16/peeph.def b/src/pic16/peeph.def index 2eb4dcbf..15987cef 100644 --- a/src/pic16/peeph.def +++ b/src/pic16/peeph.def @@ -287,6 +287,8 @@ replace restart { // 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 @@ -323,10 +325,10 @@ replace restart { // 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 +//} diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index cb96f41e..848702fe 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -29,6 +29,7 @@ #include "ralloc.h" #include "pcode.h" #include "gen.h" +#include "device.h" #if defined(__BORLANDC__) || defined(_MSC_VER) #define STRCASECMP stricmp @@ -79,9 +80,11 @@ static hTab *dynDirectRegNames= NULL; 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); @@ -93,7 +96,7 @@ int pic16_Gstack_base_addr=0; /* The starting address of registers that static void spillThis (symbol *); -static int debug = 1; +int pic16_ralloc_debug = 0; static FILE *debugF = NULL; /*-----------------------------------------------------------------*/ /* debugLog - open a file for debugging information */ @@ -108,7 +111,7 @@ debugLog (char *fmt,...) //char *bufferP=buffer; va_list ap; - if (!debug || !dstFileName) + if (!pic16_ralloc_debug || !dstFileName) return; @@ -149,8 +152,10 @@ debugLog (char *fmt,...) 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) */ @@ -158,244 +163,142 @@ debugNewLine (void) 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; } /*-----------------------------------------------------------------*/ @@ -403,18 +306,14 @@ decodeOp (unsigned int op) 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; } @@ -459,6 +358,7 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i } // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx); + dReg->isFree = 0; dReg->wasUsed = 1; @@ -516,8 +416,12 @@ regFindFree (set *dRegs) 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; @@ -560,7 +464,7 @@ pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias) { 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; @@ -575,12 +479,42 @@ pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias) 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); } @@ -707,6 +641,12 @@ pic16_allocDirReg (operand *op ) /* Register wasn't found in hash, so let's create * a new one and put it in the hash table AND in the * dynDirectRegNames set */ + if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) { + if(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); @@ -731,15 +671,6 @@ pic16_allocDirReg (operand *op ) 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; } } @@ -905,7 +836,7 @@ pic16_findFreeReg(short type) 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: @@ -928,6 +859,7 @@ static void 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; } @@ -938,20 +870,27 @@ freeReg (regs * reg) 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 } /*-----------------------------------------------------------------*/ @@ -988,8 +927,9 @@ static void writeSetUsedRegs(FILE *of, set *dRegs) 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) @@ -1142,9 +1082,11 @@ void pic16_writeUsedRegs(FILE *of) // 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); @@ -2607,17 +2549,10 @@ DEFSETFUNC (pic16_deallocReg) 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; -*/ } /*-----------------------------------------------------------------*/ @@ -2625,20 +2560,9 @@ pic16_freeAllRegs () 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; - } - } -*/ } @@ -2804,6 +2728,15 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) 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 */ @@ -2821,6 +2754,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) break; } + if (SKIP_IC2 (dic)) continue; @@ -3510,10 +3444,11 @@ packForPush (iCode * ic, eBBlock * ebp) 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"); } /*-----------------------------------------------------------------*/ @@ -3525,35 +3460,33 @@ static void isData(sym_link *sl) { 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; + } - } - + } + } } /*--------------------------------------------------------------------*/ @@ -3606,7 +3539,7 @@ pic16_packRegisters (eBBlock * ebp) 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)) @@ -3892,7 +3825,7 @@ dumpEbbsToDebug (eBBlock ** ebbs, int count) { int i; - if (!debug || !debugF) + if (!pic16_ralloc_debug || !debugF) return; for (i = 0; i < count; i++) @@ -3982,6 +3915,8 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) /* and serially allocate registers */ serialRegAssign (ebbs, count); + //pic16_freeAllRegs(); + /* if stack was extended then tell the user */ if (_G.stackExtend) { @@ -4022,7 +3957,7 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) setToNull ((void *) &_G.stackSpil); setToNull ((void *) &_G.spiltSet); /* mark all registers as free */ - //pic16_freeAllRegs (); + pic16_freeAllRegs (); debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n"); debugLogClose (); diff --git a/src/pic16/ralloc.h b/src/pic16/ralloc.h index 547ce930..de67f9bd 100644 --- a/src/pic16/ralloc.h +++ b/src/pic16/ralloc.h @@ -77,6 +77,7 @@ typedef struct regs 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 */ @@ -102,8 +103,11 @@ extern set *pic16_dynDirectRegs; 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 ); @@ -133,6 +137,7 @@ regs *pic16_allocRegByName (char *name, int size ); #define IDX_FSR2H 0xfda #define IDX_POSTINC1 0xfe6 #define IDX_POSTDEC1 0xfe5 +#define IDX_PREINC1 0xfe4 #define IDX_PREINC2 0xfdc #define IDX_PLUSW2 0xfdb -- 2.30.2