From: vrokas Date: Wed, 20 Oct 2004 14:02:16 +0000 (+0000) Subject: * device/lib/pic16/libsdcc/Makefile: added lregs directory in X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=b69c2ce731d39b467f0bac5f532ef5e94a1eff5e;p=fw%2Fsdcc * device/lib/pic16/libsdcc/Makefile: added lregs directory in makefile targets, * device/lib/pic16/libsdcc/lregs/{Makefile,lrst.c,lrrest.c}: NEW support functions to replace long sequences of MOVFF's from access bank registers to stack and vice versa, * src/pic16/device.h: added new field opt_flags, where optimization flags can be set to enable certain features, * src/pic16/gen.c (pic16_emitpinfo): NEW to add PC_INFO pCode in * pBlock, (genFunction, genEndFunction): surroung loop for saving/loading used registers in stack with PC_INFO pCodes, INF_LREGS. Code in between can then be optimized by pCode optimizer to support function calls, * (genDataPointerSet): fixed bug which loaded float fields in structures with corrupt data, * src/pic16/genutils.c (debugf, _debugf): macro/function which emits in a standard way debug info on stderr. Feature used for developing and debugging only, * src/pic16/glue.c (pic16glue): reformatted, deleted some old and obsolete chunks of code, * if optimization flag OF_LR_SUPPORT was set, call pic16_OptimizeLocalRegs, * src/pic16/main.c (_pic16_parseOptions): added handler for --flr-support, * pic16/src/pcode.c (pic16_newpCodeInfo, * (pic16_newpCodeOpLocalRegs), * (pic16_convertLocalRegs2Support): NEW, to support new optimization feature, * (pic16_pCodeConstString): printing of the initial value of a symbol as a comment is inhibited since parsing was already done by copyStr and output is corrupt, * (pic16_pCode2str, genericPrint): handle PC_INFO pCode, git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3546 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index e7cac1e7..4f71c922 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2004-10-20 Vangelis Rokas + + * device/lib/pic16/libsdcc/Makefile: added lregs directory in + makefile targets, + * device/lib/pic16/libsdcc/lregs/{Makefile,lrst.c,lrrest.c}: NEW + support functions to replace long sequences of MOVFF's from access + bank registers to stack and vice versa, + * src/pic16/device.h: added new field opt_flags, where optimization + flags can be set to enable certain features, + * src/pic16/gen.c (pic16_emitpinfo): NEW to add PC_INFO pCode in + * pBlock, (genFunction, genEndFunction): surroung loop for + saving/loading used registers in stack with PC_INFO pCodes, + INF_LREGS. Code in between can then be optimized by pCode optimizer + to support function calls, + * (genDataPointerSet): fixed bug which loaded float fields in + structures with corrupt data, + * src/pic16/genutils.c (debugf, _debugf): macro/function which emits + in a standard way debug info on stderr. Feature used for developing + and debugging only, + * src/pic16/glue.c (pic16glue): reformatted, deleted some old and + obsolete chunks of code, + * if optimization flag OF_LR_SUPPORT was set, call pic16_OptimizeLocalRegs, + * src/pic16/main.c (_pic16_parseOptions): added handler for --flr-support, + * pic16/src/pcode.c (pic16_newpCodeInfo, + * (pic16_newpCodeOpLocalRegs), + * (pic16_convertLocalRegs2Support): NEW, to support new optimization + feature, + * (pic16_pCodeConstString): printing of the initial value of a + symbol as a comment is inhibited since parsing was already done by + copyStr and output is corrupt, + * (pic16_pCode2str, genericPrint): handle PC_INFO pCode, + 2004-10-20 Erik Petrich * src/mcs51/ralloc.c (packRegisters): fixed bug #1044601 diff --git a/device/lib/pic16/libsdcc/Makefile b/device/lib/pic16/libsdcc/Makefile index bd6b60d3..391342be 100644 --- a/device/lib/pic16/libsdcc/Makefile +++ b/device/lib/pic16/libsdcc/Makefile @@ -16,7 +16,8 @@ DIRS = char \ int \ long \ float \ - gptr + gptr \ + lregs LIB = libsdcc.lib diff --git a/device/lib/pic16/libsdcc/float/Makefile b/device/lib/pic16/libsdcc/float/Makefile index cc1dd1f8..841273e5 100644 --- a/device/lib/pic16/libsdcc/float/Makefile +++ b/device/lib/pic16/libsdcc/float/Makefile @@ -38,9 +38,6 @@ SRCS = fs2schar \ include ../Makefile.rules -CFLAGS += -I$(LIBC_INC_DIR) - - all: build-library build-library: $(LIB) diff --git a/device/lib/pic16/libsdcc/lregs/Makefile b/device/lib/pic16/libsdcc/lregs/Makefile new file mode 100644 index 00000000..0677a42a --- /dev/null +++ b/device/lib/pic16/libsdcc/lregs/Makefile @@ -0,0 +1,25 @@ +# +# Makefile - Makefile to build pic16 local register store/restore +# support library +# +# This file is part of the GNU PIC Library. +# +# January, 2004 +# The GNU PIC Library is maintained by, +# Vangelis Rokas +# +# $Id$ +# +# + + +SRCS = lrst \ + lrrest + + +include ../Makefile.rules + + +all: build-library + +build-library: $(OFILES) diff --git a/device/lib/pic16/libsdcc/lregs/lrrest.c b/device/lib/pic16/libsdcc/lregs/lrrest.c new file mode 100644 index 00000000..f3c21cdd --- /dev/null +++ b/device/lib/pic16/libsdcc/lregs/lrrest.c @@ -0,0 +1,46 @@ +/*------------------------------------------------------------------------- + + lrrest.c :- restore local registers in stack upon function exit + + Written for pic16 port by Vangelis Rokas, 2004 (vrokas@otenet.gr) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ +/* +** $Id$ +*/ + +/* FSR0 points to last register to store, WREG holds the register count + */ + +extern PREINC1; +extern POSTDEC0; +extern WREG; + +void _lr_restore(void) _naked +{ + _asm +loop: + movff _PREINC1, _POSTDEC0 + decfsz _WREG, f + bra loop + + return + _endasm; +} diff --git a/device/lib/pic16/libsdcc/lregs/lrst.c b/device/lib/pic16/libsdcc/lregs/lrst.c new file mode 100644 index 00000000..72528055 --- /dev/null +++ b/device/lib/pic16/libsdcc/lregs/lrst.c @@ -0,0 +1,46 @@ +/*------------------------------------------------------------------------- + + lrst.c :- store local registers in stack upon function entry + + Written for pic16 port by Vangelis Rokas, 2004 (vrokas@otenet.gr) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ +/* +** $Id$ +*/ + +/* FSR0 points to first register to store, WREG holds the register count + */ + +extern POSTDEC1; +extern POSTINC0; +extern WREG; + +void _lr_store(void) _naked +{ + _asm +loop: + movff _POSTINC0, _POSTDEC1 + decfsz _WREG, f + bra loop + + return + _endasm; +} diff --git a/src/pic16/device.h b/src/pic16/device.h index f2516333..f6033055 100644 --- a/src/pic16/device.h +++ b/src/pic16/device.h @@ -86,6 +86,8 @@ typedef struct PIC16_device { /* Given a pointer to a register, this macro returns the bank that it is in */ #define REG_ADDR(r) ((r)->isBitField ? (((r)->address)>>3) : (r)->address) +#define OF_LR_SUPPORT 0x00000001 + typedef struct { int no_banksel; @@ -100,6 +102,7 @@ typedef struct { char *crt_name; int no_crt; int ip_stack; + unsigned long opt_flags; } pic16_options_t; #define STACK_MODEL_SMALL (pic16_options.stack_model == 0) diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 1424a756..159eeb8b 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -297,10 +297,16 @@ void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop) pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop)); else DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__); - -// fprintf(stderr, "%s\n", pcop->name); } +void pic16_emitpinfo(INFO_TYPE itype, pCodeOp *pcop) +{ + if(pcop) + pic16_addpCode2pBlock(pb, pic16_newpCodeInfo(itype, pcop)); + else + DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__); +} + void pic16_emitpcodeNULLop(PIC_OPCODE poc) { @@ -3547,6 +3553,7 @@ static void genFunction (iCode *ic) if (sym->regsUsed) { /* save the registers used */ DEBUGpic16_emitcode("; **", "Saving used registers in stack"); + pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN)); for ( i = 0 ; i < sym->regsUsed->size ; i++) { if (bitVectBitValue(sym->regsUsed,i)) { pic16_pushpCodeOp( pic16_popRegFromIdx(i) ); @@ -3559,6 +3566,7 @@ static void genFunction (iCode *ic) } } } + pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_END)); } } @@ -3602,6 +3610,7 @@ static void genEndFunction (iCode *ic) if (sym->regsUsed) { int i; + pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_BEGIN)); /* restore registers used */ DEBUGpic16_emitcode("; **", "Restoring used registers from stack"); for ( i = sym->regsUsed->size; i >= 0; i--) { @@ -3610,6 +3619,8 @@ static void genEndFunction (iCode *ic) _G.nRegsSaved--; } } + pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END)); + } if(strcmp(sym->name, "main")) { @@ -10826,19 +10837,32 @@ static void genDataPointerSet(operand *right, while (size--) { if (AOP_TYPE(right) == AOP_LIT) { - unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); - - lit = lit >> (8*offset); - if(lit&0xff) { - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8 - } else { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8 - } - } else { - mov2w(AOP(right), offset); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8 - } + unsigned int lit; + + if(!IS_FLOAT(operandType( right ))) + lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); + else { + union { + unsigned long lit_int; + float lit_float; + } info; + + /* take care if literal is a float */ + info.lit_float = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); + lit = info.lit_int; + } + + lit = lit >> (8*offset); + if(lit&0xff) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8 + } else { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8 + } + } else { + mov2w(AOP(right), offset); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8 + } offset++; resoffset++; } diff --git a/src/pic16/genutils.c b/src/pic16/genutils.c index 284d60ce..ace571cf 100644 --- a/src/pic16/genutils.c +++ b/src/pic16/genutils.c @@ -418,6 +418,19 @@ void pic16_DumpOp(char *prefix, operand *op) } +//#define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest) + +void _debugf(char *f, int l, char *frm, ...) +{ + va_list ap; + + va_start(ap, frm); + fprintf(stderr, "%s:%d ", f, l); + vfprintf(stderr, frm, ap); + va_end(ap); +} + + void gpsimio2_pcop(pCodeOp *pcop) { diff --git a/src/pic16/genutils.h b/src/pic16/genutils.h index 07914e33..2f181801 100644 --- a/src/pic16/genutils.h +++ b/src/pic16/genutils.h @@ -38,4 +38,7 @@ void gpsimio2_lit(unsigned char lit); void gpsimDebug_StackDump(char *fname, int line, char *info); +#define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest) +void _debugf(char *f, int l, char *frm, ...); + #endif /* __GENUTILS_H__ */ diff --git a/src/pic16/glue.c b/src/pic16/glue.c index 73b13398..56e458b0 100644 --- a/src/pic16/glue.c +++ b/src/pic16/glue.c @@ -78,6 +78,9 @@ void pic16_pCodeInitRegisters(void); pCodeOp *pic16_popCopyReg(pCodeOpReg *pc); extern void pic16_pCodeConstString(char *name, char *value); +#define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest) +extern void _debugf(char *f, int l, char *frm, ...); + /*-----------------------------------------------------------------*/ /* aopLiteral - string from a literal value */ /*-----------------------------------------------------------------*/ @@ -659,30 +662,24 @@ pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, voi fprintf(stderr, "%s\n",__FUNCTION__); #endif - if (!s) - { - - val = list2val (ilist); - /* if the value is a character string */ - if (IS_ARRAY (val->type) && IS_CHAR (val->etype)) - { - if (!DCL_ELEM (type)) - DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1; - - for(remain=0; remainetype).v_char[ remain ], ptype, p); - - if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) { - while (remain--) { - pic16_emitDB(0x00, ptype, p); - } - } - return 1; - } - else - return 0; - } - else { + if(!s) { + val = list2val (ilist); + /* if the value is a character string */ + if(IS_ARRAY (val->type) && IS_CHAR (val->etype)) { + if(!DCL_ELEM (type)) + DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1; + + for(remain=0; remainetype).v_char)+1; remain++) + pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p); + + if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) { + while(remain--) { + pic16_emitDB(0x00, ptype, p); + } + } + return 1; + } else return 0; + } else { for(remain=0; remaintype) && IS_CHAR (sym->type->next) && SPEC_CVAL (sym->etype).v_char) { -// fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname); +// fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname); pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char); } else { @@ -1610,233 +1607,218 @@ pic16emitOverlay (FILE * afile) void pic16glue () { - FILE *vFile; FILE *asmFile; FILE *ovrFile = tempfile(); + mainf = newSymbol ("main", 0); + mainf->block = 0; - mainf = newSymbol ("main", 0); - mainf->block = 0; + mainf = findSymWithLevel(SymbolTab, mainf); - 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 - -// fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1); - - addSetHead(&tmpfileSet,ovrFile); - pic16_pCodeInitRegisters(); + addSetHead(&tmpfileSet,ovrFile); + pic16_pCodeInitRegisters(); + if(pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) { + pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block")); - if (pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) { - pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block")); + pic16_addpBlock(pb); - pic16_addpBlock(pb); + /* entry point @ start of CSEG */ + pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1)); - /* entry point @ start of CSEG */ - pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1)); - - if(initsfpnt) { - pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, - pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end")))); - pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, - pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end")))); - } + if(initsfpnt) { + pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, + pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end")))); + pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, + pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end")))); + } - /* put in the call to main */ - pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR))); + /* put in the call to main */ + pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR))); - 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))); - } - } + 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 */ + /* 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 */ - pic16_movepBlock2Head('P'); // Last - pic16_movepBlock2Head(code->dbName); - pic16_movepBlock2Head('X'); - pic16_movepBlock2Head(statsg->dbName); // First + pic16_movepBlock2Head('P'); // Last + pic16_movepBlock2Head(code->dbName); + pic16_movepBlock2Head('X'); + pic16_movepBlock2Head(statsg->dbName); // First - /* print the global struct definitions */ -// if (options.debug) -// cdbStructBlock (0); //,cdbFile); + /* print the global struct definitions */ - 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); - } + 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); - pic16_AnalyzepCode('*'); + /* emit code for the all the variables declared */ + pic16emitMaps (); + + /* do the overlay segments */ + pic16emitOverlay(ovrFile); + pic16_AnalyzepCode('*'); #if 1 - if(pic16_options.dumpcalltree) { - FILE *cFile; - sprintf(buffer, dstFileName); - strcat(buffer, ".calltree"); - cFile = fopen(buffer, "w"); - pic16_printCallTree( cFile ); - fclose(cFile); - } + if(pic16_options.dumpcalltree) { + FILE *cFile; + + sprintf(buffer, dstFileName); + strcat(buffer, ".calltree"); + cFile = fopen(buffer, "w"); + pic16_printCallTree( cFile ); + fclose(cFile); + } #endif - pic16_InlinepCode(); - pic16_AnalyzepCode('*'); + pic16_InlinepCode(); + pic16_AnalyzepCode('*'); - if(pic16_debug_verbose) - pic16_pcode_test(); - /* 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 */ - if(options.debug) - fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName); + /* print module name */ + if(options.debug) + fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName); - /* Let the port generate any global directives, etc. */ - if (port->genAssemblerPreamble) { - port->genAssemblerPreamble(asmFile); - } - - /* print the extern variables to this module */ - pic16_printExterns(asmFile); + /* Let the port generate any global directives, etc. */ + if(port->genAssemblerPreamble) { + port->genAssemblerPreamble(asmFile); + } - /* print the global variables in this module */ - pic16printPublics (asmFile); + /* Put all variables into a cblock */ + pic16_AnalyzeBanking(); -#if 0 - /* copy the sfr segment */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; special function registers\n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, sfr->oFile); -#endif + if(pic16_options.opt_flags & OF_LR_SUPPORT) { + pic16_OptimizeLocalRegs(); + } - /* Put all variables into a cblock */ - pic16_AnalyzeBanking(); - pic16_writeUsedRegs(asmFile); + /* print the extern variables to this module */ + pic16_printExterns(asmFile); + + /* print the global variables in this module */ + pic16printPublics (asmFile); + + pic16_writeUsedRegs(asmFile); #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"); - } + /* 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"); + } #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); + /* 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); #endif #if 0 - /* 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); #endif - /* copy the interrupt vector table */ - if(mainf && IFFUNC_HASBODY(mainf->type)) { - fprintf (asmFile, "\n%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, "\n%s", iComments2); + fprintf (asmFile, "; interrupt vector \n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, vFile); + } - /* copy global & static initialisations */ - fprintf (asmFile, "\n%s", iComments2); - fprintf (asmFile, "; global & static initialisations\n"); - fprintf (asmFile, "%s", iComments2); + /* copy global & static initialisations */ + fprintf (asmFile, "\n%s", iComments2); + fprintf (asmFile, "; global & static initialisations\n"); + fprintf (asmFile, "%s", iComments2); - if(pic16_debug_verbose) - fprintf(asmFile, "; A code from now on!\n"); - pic16_copypCode(asmFile, 'A'); - - - if(pic16_options.no_crt) { - if(mainf && IFFUNC_HASBODY(mainf->type)) { - fprintf(asmFile, "\tcode\n"); - fprintf(asmFile,"__sdcc_gsinit_startup:\n"); - } - } + if(pic16_debug_verbose) + fprintf(asmFile, "; A code from now on!\n"); + + pic16_copypCode(asmFile, 'A'); -// copyFile (stderr, code->oFile); + if(pic16_options.no_crt) { + if(mainf && IFFUNC_HASBODY(mainf->type)) { + fprintf(asmFile, "\tcode\n"); + fprintf(asmFile,"__sdcc_gsinit_startup:\n"); + } + } - fprintf(asmFile, "; I code from now on!\n"); - pic16_copypCode(asmFile, 'I'); +// copyFile (stderr, code->oFile); - if(pic16_debug_verbose) - fprintf(asmFile, "; dbName from now on!\n"); - pic16_copypCode(asmFile, statsg->dbName); + fprintf(asmFile, "; I code from now on!\n"); + pic16_copypCode(asmFile, 'I'); + if(pic16_debug_verbose) + fprintf(asmFile, "; dbName from now on!\n"); + + pic16_copypCode(asmFile, statsg->dbName); - if(pic16_options.no_crt) { - if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) { - fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n"); - } - } + if(pic16_options.no_crt) { + if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) { + fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n"); + } + } + if(pic16_debug_verbose) + fprintf(asmFile, "; X code from now on!\n"); - if(pic16_debug_verbose) - fprintf(asmFile, "; X code from now on!\n"); - pic16_copypCode(asmFile, 'X'); + pic16_copypCode(asmFile, 'X'); - if(pic16_debug_verbose) - fprintf(asmFile, "; M code from now on!\n"); - pic16_copypCode(asmFile, 'M'); + 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); + pic16_copypCode(asmFile, code->dbName); + + pic16_copypCode(asmFile, 'P'); - rm_tmpfiles(); + fprintf (asmFile,"\tend\n"); + fclose (asmFile); + + rm_tmpfiles(); } diff --git a/src/pic16/main.c b/src/pic16/main.c index f298a0ea..c24466af 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -296,6 +296,9 @@ _process_pragma(const char *sz) #define NL_OPT "--nl=" #define USE_CRT "--use-crt=" +#define OFMSG_LRSUPPORT "--flr-support" + + char *alt_asm=NULL; char *alt_link=NULL; @@ -334,6 +337,7 @@ OPTION pic16_optionsTable[]= { { 0, NL_OPT, NULL, "new line, \"lf\" or \"crlf\""}, { 0, USE_CRT, NULL, "use run-time initialization module"}, { 0, "--no-crt", &pic16_options.no_crt, "do not link any default run-time initialization module"}, + { 0, OFMSG_LRSUPPORT, NULL, "use support functions for local register store/restore"}, { 0, NULL, NULL, NULL} }; @@ -352,71 +356,76 @@ _pic16_parseOptions (int *pargc, char **argv, int *i) /* TODO: allow port-specific command line options to specify * segment names here. */ - /* check for arguments that have associated an integer variable */ - while(pic16_optionsTable[j].pparameter) { - if(ISOPT( pic16_optionsTable[j].longOpt )) { - (*pic16_optionsTable[j].pparameter)++; - return TRUE; - } - j++; - } - + + /* check for arguments that have associated an integer variable */ + while(pic16_optionsTable[j].pparameter) { + if(ISOPT( pic16_optionsTable[j].longOpt )) { + (*pic16_optionsTable[j].pparameter)++; + return TRUE; + } + j++; + } - if(ISOPT(STACK_MODEL)) { - stkmodel = getStringArg(STACK_MODEL, argv, i, *pargc); - if(!STRCASECMP(stkmodel, "small"))pic16_options.stack_model = 0; - else if(!STRCASECMP(stkmodel, "large"))pic16_options.stack_model = 1; - else { - fprintf(stderr, "Unknown stack model: %s", stkmodel); - exit(-1); - } - return TRUE; - } + if(ISOPT(STACK_MODEL)) { + stkmodel = getStringArg(STACK_MODEL, argv, i, *pargc); + if(!STRCASECMP(stkmodel, "small"))pic16_options.stack_model = 0; + else if(!STRCASECMP(stkmodel, "large"))pic16_options.stack_model = 1; + else { + fprintf(stderr, "Unknown stack model: %s", stkmodel); + exit(-1); + } + return TRUE; + } - if(ISOPT(OPT_BANKSEL)) { - pic16_options.opt_banksel = getIntArg(OPT_BANKSEL, argv, i, *pargc); - return TRUE; - } + if(ISOPT(OPT_BANKSEL)) { + pic16_options.opt_banksel = getIntArg(OPT_BANKSEL, argv, i, *pargc); + return TRUE; + } - if(ISOPT(REP_UDATA)) { - pic16_sectioninfo.at_udata = Safe_strdup(getStringArg(REP_UDATA, argv, i, *pargc)); - return TRUE; - } + if(ISOPT(REP_UDATA)) { + pic16_sectioninfo.at_udata = Safe_strdup(getStringArg(REP_UDATA, argv, i, *pargc)); + return TRUE; + } - if(ISOPT(ALT_ASM)) { - alt_asm = Safe_strdup(getStringArg(ALT_ASM, argv, i, *pargc)); - return TRUE; - } + if(ISOPT(ALT_ASM)) { + alt_asm = Safe_strdup(getStringArg(ALT_ASM, argv, i, *pargc)); + return TRUE; + } - if(ISOPT(ALT_LINK)) { - alt_link = Safe_strdup(getStringArg(ALT_LINK, argv, i, *pargc)); - return TRUE; - } + if(ISOPT(ALT_LINK)) { + alt_link = Safe_strdup(getStringArg(ALT_LINK, argv, i, *pargc)); + return TRUE; + } - if(ISOPT(IVT_LOC)) { - pic16_options.ivt_loc = getIntArg(IVT_LOC, argv, i, *pargc); - return TRUE; - } + if(ISOPT(IVT_LOC)) { + pic16_options.ivt_loc = getIntArg(IVT_LOC, argv, i, *pargc); + return TRUE; + } - if(ISOPT(NL_OPT)) { - char *tmp; + if(ISOPT(NL_OPT)) { + char *tmp; - tmp = Safe_strdup( getStringArg(NL_OPT, argv, i, *pargc) ); - if(!STRCASECMP(tmp, "lf"))pic16_nl = 0; - else if(!STRCASECMP(tmp, "crlf"))pic16_nl = 1; - else { - fprintf(stderr, "invalid termination character id\n"); - exit(-1); - } - return TRUE; + tmp = Safe_strdup( getStringArg(NL_OPT, argv, i, *pargc) ); + if(!STRCASECMP(tmp, "lf"))pic16_nl = 0; + else if(!STRCASECMP(tmp, "crlf"))pic16_nl = 1; + else { + fprintf(stderr, "invalid termination character id\n"); + exit(-1); } + return TRUE; + } - if(ISOPT(USE_CRT)) { - pic16_options.no_crt = 0; - pic16_options.crt_name = Safe_strdup( getStringArg(USE_CRT, argv, i, *pargc) ); + if(ISOPT(USE_CRT)) { + pic16_options.no_crt = 0; + pic16_options.crt_name = Safe_strdup( getStringArg(USE_CRT, argv, i, *pargc) ); - return TRUE; - } + return TRUE; + } + + if(ISOPT(OFMSG_LRSUPPORT)) { + pic16_options.opt_flags |= OF_LR_SUPPORT; + return TRUE; + } return FALSE; } diff --git a/src/pic16/pcode.c b/src/pic16/pcode.c index 14b8863d..38abb360 100644 --- a/src/pic16/pcode.c +++ b/src/pic16/pcode.c @@ -115,6 +115,9 @@ pCodeOpReg pic16_pc_ssave = {{PO_GPR_REGISTER, "SSAVE"}, -1, NULL,0,NULL}; pCodeOpReg pic16_pc_gpsimio = {{PO_GPR_REGISTER, "GPSIMIO"}, -1, NULL, 0, NULL}; pCodeOpReg pic16_pc_gpsimio2 = {{PO_GPR_REGISTER, "GPSIMIO2"}, -1, NULL, 0, NULL}; +char *OPT_TYPE_STR[] = { "begin", "end" }; +char *LR_TYPE_STR[] = { "entry begin", "entry end", "exit begin", "exit end" }; + static int mnemonics_initialized = 0; @@ -171,9 +174,15 @@ extern void pic16_pCodeInsertAfter(pCode *pc1, pCode *pc2); extern pCodeOp *pic16_popCopyReg(pCodeOpReg *pc); pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval); void pic16_pCodeRegMapLiveRanges(pBlock *pb); +void OptimizeLocalRegs(void); char *dumpPicOptype(PIC_OPTYPE type); +pCodeOp *pic16_popGetLit2(int, pCodeOp *); +pCodeOp *pic16_popGetLit(int); +pCodeOp *pic16_popGetWithString(char *); + + /****************************************************************/ /* PIC Instructions */ /****************************************************************/ @@ -3778,12 +3787,24 @@ pCode *pic16_newpCodeLabelFORCE(char *name, int key) return ( (pCode *)pcl ); } -#if 0 pCode *pic16_newpCodeInfo(INFO_TYPE type, pCodeOp *pcop) { + pCodeInfo *pci; + pci = Safe_calloc(1, sizeof(pCodeInfo)); + pci->pci.pc.type = PC_INFO; + pci->pci.pc.prev = pci->pci.pc.next = NULL; + pci->pci.pc.pb = NULL; + pci->pci.label = NULL; + + pci->pci.pc.destruct = genericDestruct; + pci->pci.pc.print = genericPrint; + + pci->type = type; + pci->oper1 = pcop; + + return ((pCode *)pci); } -#endif /*-----------------------------------------------------------------*/ @@ -4114,6 +4135,19 @@ pCodeOp *pic16_newpCodeOpOpt(OPT_TYPE type, char *key) return (PCOP(pcop)); } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +pCodeOp *pic16_newpCodeOpLocalRegs(LR_TYPE type) +{ + pCodeOpLocalReg *pcop; + + pcop = Safe_calloc(1, sizeof(pCodeOpLocalReg)); + + pcop->type = type; + + return (PCOP(pcop)); +} + /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ @@ -4263,9 +4297,11 @@ void pic16_pCodeConstString(char *name, char *value) pic16_addpBlock(pb); - sprintf(buffer,"; %s = %s",name,value); - - pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(buffer)); +// sprintf(buffer,"; %s = ", name); +// strcat(buffer, value); +// fputs(buffer, stderr); + +// pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(buffer)); pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(name,-1)); do { @@ -4791,6 +4827,17 @@ char *pic16_pCode2str(char *str, size_t size, pCode *pc) SAFE_snprintf(&s,&size,";%s", ((pCodeComment *)pc)->comment); break; + case PC_INFO: + SAFE_snprintf(&s,&size,"; info ==>"); + switch(((pCodeInfo *)pc)->type) { + case INF_OPTIMIZATION: + SAFE_snprintf(&s,&size, " [optimization] %s\n", OPT_TYPE_STR[ PCOO(PCINF(pc)->oper1)->type ]); + break; + case INF_LOCALREGS: + SAFE_snprintf(&s,&size, " [localregs] %s\n", LR_TYPE_STR[ PCOLR(PCINF(pc)->oper1)->type ]); + break; + }; break; + case PC_INLINE: /* assuming that inline code ends with a \n */ SAFE_snprintf(&s,&size,"%s", ((pCodeComment *)pc)->comment); @@ -4826,10 +4873,6 @@ char *pic16_pCode2str(char *str, size_t size, pCode *pc) case PC_BAD: SAFE_snprintf(&s,&size,";A bad pCode is being used\n"); break; - - case PC_INFO: - SAFE_snprintf(&s,&size,"; PC INFO pcode\n"); - break; } return str; @@ -4847,9 +4890,30 @@ static void genericPrint(FILE *of, pCode *pc) switch(pc->type) { case PC_COMMENT: - fprintf(of,";%s\n", ((pCodeComment *)pc)->comment); +// fputs(((pCodeComment *)pc)->comment, of); + fprintf(of,"; %s\n", ((pCodeComment *)pc)->comment); break; + case PC_INFO: + { + pBranch *pbl = PCI(pc)->label; + while(pbl && pbl->pc) { + if(pbl->pc->type == PC_LABEL) + pCodePrintLabel(of, pbl->pc); + pbl = pbl->next; + } + } + + fprintf(of, "; info ==>"); + switch(((pCodeInfo *)pc)->type) { + case INF_OPTIMIZATION: + fprintf(of, " [optimization] %s\n", OPT_TYPE_STR[ PCOO(PCINF(pc)->oper1)->type ]); + break; + case INF_LOCALREGS: + fprintf(of, " [localregs] %s\n", LR_TYPE_STR[ PCOLR(PCINF(pc)->oper1)->type ]); + break; + }; break; + case PC_INLINE: fprintf(of,"%s\n", ((pCodeComment *)pc)->comment); break; @@ -7043,9 +7107,162 @@ void pic16_AnalyzepCode(char dbName) } while(changes && (i++ < MAX_PASSES)); + buildCallTree(); } + +/* convert a series of movff's of local regs to stack, with a single call to + * a support functions which does the same thing via loop */ +static void pic16_convertLocalRegs2Support(pCode *pcstart, pCode *pcend, int count, regs *r, int entry) +{ + pBranch *pbr; + pCode *pc, *pct; + char *fname[]={"__lr_store", "__lr_restore"}; + +// pc = pic16_newpCode(POC_CALL, pic16_popGetFromString( (entry?fname[0]:fname[1]) )); + + pct = pic16_findNextInstruction(pcstart->next); + do { + pc = pct; + pct = pc->next; //pic16_findNextInstruction(pc->next); +// pc->print(stderr, pc); + if(isPCI(pc) && PCI(pc)->label) { + pbr = PCI(pc)->label; + while(pbr && pbr->pc) { + PCI(pcstart)->label = pic16_pBranchAppend(PCI(pcstart)->label, pbr); + pbr = pbr->next; + } + +// pc->print(stderr, pc); + /* unlink pCode */ + pc->prev->next = pct; + pct->prev = pc->prev; +// pc->next = NULL; +// pc->prev = NULL; + } + } while ((pc) && (pc != pcend)); + + /* unlink movff instructions */ + pcstart->next = pcend; + pcend->prev = pcstart; + + pic16_pCodeInsertAfter(pcstart, (pct=pic16_newpCode(POC_LFSR, pic16_popGetLit2(0, pic16_popGetWithString(r->name))))); pc = pct; + pic16_pCodeInsertAfter(pc, pct=pic16_newpCode(POC_MOVLW, pic16_popGetLit( count ))); pc = pct; + pic16_pCodeInsertAfter(pc, pct=pic16_newpCode(POC_CALL, pic16_popGetWithString( fname[ (entry==1?0:1) ] ))); + + { + symbol *sym; + + sym = newSymbol( fname[ entry?0:1 ], 0 ); + strcpy(sym->rname, fname[ entry?0:1 ]); + checkAddSym(&externs, sym); + +// fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fname[ entry?0:1 ]); + } + +} + + +/*-----------------------------------------------------------------*/ +/* OptimizeLocalRegs - turn sequence of MOVFF instructions for */ +/* local registers to a support function call */ +/*-----------------------------------------------------------------*/ +void pic16_OptimizeLocalRegs(void) +{ + pBlock *pb; + pCode *pc; + pCodeInfo *pci; + pCodeOpLocalReg *pclr; + int regCount=0; + int inRegCount=0; + regs *r, *lastr=NULL, *firstr=NULL; + pCode *pcstart=NULL, *pcend=NULL; + int inEntry=0; + + /* Overview: + * local_regs begin mark + * MOVFF r0x01, POSTDEC1 + * MOVFF r0x02, POSTDEC1 + * ... + * ... + * MOVFF r0x0n, POSTDEC1 + * local_regs end mark + * + * convert the above to the below: + * MOVLW starting_register_index + * MOVWF PRODL + * MOVLW register_count + * call __save_registers_in_stack + */ + + if(!the_pFile) + return; + + for(pb = the_pFile->pbHead; pb; pb = pb->next) { + inRegCount = regCount = 0; + firstr = lastr = NULL; + for(pc = pb->pcHead; pc; pc = pc->next) { + if(pc && (pc->type == PC_INFO)) { + pci = PCINF(pc); + + if(pci->type == INF_LOCALREGS) { + pclr = PCOLR(pci->oper1); + + if((pclr->type == LR_ENTRY_BEGIN) + || (pclr->type == LR_ENTRY_END))inEntry = 1; + else inEntry = 0; + + switch(pclr->type) { + case LR_ENTRY_BEGIN: + case LR_EXIT_BEGIN: + inRegCount = 1; regCount = 0; + pcstart = pc; //pic16_findNextInstruction(pc->next); + firstr = lastr = NULL; + break; + + case LR_ENTRY_END: + case LR_EXIT_END: + inRegCount = -1; + pcend = pc; //pic16_findPrevInstruction(pc->prev); + +#if 1 + if(regCount>2) { + pic16_convertLocalRegs2Support(pcstart, pcend, regCount, + firstr, inEntry); + } +#endif + firstr = lastr = NULL; + break; + } + + if(inRegCount == -1) { +// fprintf(stderr, "%s:%d registers used [%s] %d\n", __FILE__, __LINE__, inEntry?"entry":"exit", regCount); + regCount = 0; + inRegCount = 0; + } + } + } else { + if(isPCI(pc) && (PCI(pc)->op == POC_MOVFF) && (inRegCount == 1)) { + if(inEntry) + r = pic16_getRegFromInstruction(pc); + else + r = pic16_getRegFromInstruction2(pc); + if(r && (r->type == REG_GPR) && (r->pc_type == PO_GPR_TEMP)) { + if(!firstr)firstr = r; + regCount++; +// fprintf(stderr, "%s:%d\t%s\t%i\t%d/%d\n", __FILE__, __LINE__, r->name, r->rIdx); + } + } + } + } + } +} + + + + + /*-----------------------------------------------------------------*/ /* ispCodeFunction - returns true if *pc is the pCode of a */ /* function */ diff --git a/src/pic16/pcode.h b/src/pic16/pcode.h index 55ae2e9e..c3d17fd9 100644 --- a/src/pic16/pcode.h +++ b/src/pic16/pcode.h @@ -313,6 +313,7 @@ typedef enum typedef enum { INF_OPTIMIZATION, /* structure contains optimization information */ + INF_LOCALREGS /* structure contains local register information */ } INFO_TYPE; @@ -327,6 +328,17 @@ typedef enum OPT_END, /* mark ending of optimization block */ } OPT_TYPE; +/*********************************************************************** + * LR_TYPE - optimization node types + ***********************************************************************/ + +typedef enum +{ + LR_ENTRY_BEGIN, /* mark beginning of optimization block */ + LR_ENTRY_END, /* mark ending of optimization block */ + LR_EXIT_BEGIN, + LR_EXIT_END +} LR_TYPE; /************************************************/ @@ -481,7 +493,12 @@ typedef struct pCodeOpOpt char *key; /* key by which a block is identified */ } pCodeOpOpt; - +typedef struct pCodeOpLocalReg +{ + pCodeOp pcop; + + LR_TYPE type; +} pCodeOpLocalReg; /************************************************* pCode @@ -746,14 +763,14 @@ typedef struct pCodeWild Here are stored generic informaton *************************************************/ -typedef struct pInfo +typedef struct pCodeInfo { - pCode pc; + pCodeInstruction pci; INFO_TYPE type; /* info node type */ pCodeOp *oper1; /* info node arguments */ -} pInfo; +} pCodeInfo; /************************************************* @@ -907,6 +924,7 @@ typedef struct peepCommand { #define PCW(x) ((pCodeWild *)(x)) #define PCCS(x) ((pCodeCSource *)(x)) #define PCAD(x) ((pCodeAsmDir *)(x)) +#define PCINF(x) ((pCodeInfo *)(x)) #define PCOP(x) ((pCodeOp *)(x)) //#define PCOB(x) ((pCodeOpBit *)(x)) @@ -917,6 +935,7 @@ typedef struct peepCommand { #define PCOR2(x) ((pCodeOpReg2 *)(x)) #define PCORB(x) ((pCodeOpRegBit *)(x)) #define PCOO(x) ((pCodeOpOpt *)(x)) +#define PCOLR(x) ((pCodeOpLocalReg *)(x)) #define PCOW(x) ((pCodeOpWild *)(x)) #define PCOW2(x) (PCOW(PCOW(x)->pcop2)) #define PBR(x) ((pBranch *)(x)) @@ -966,6 +985,7 @@ void pic16_addpBlock(pBlock *pb); // Add a pBlock to a pFile void pic16_copypCode(FILE *of, char dbName); // Write all pBlocks with dbName to *of void pic16_movepBlock2Head(char dbName); // move pBlocks around void pic16_AnalyzepCode(char dbName); +void pic16_OptimizeLocalRegs(void); void pic16_AssignRegBanks(void); void pic16_printCallTree(FILE *of); void pCodePeepInit(void); @@ -987,6 +1007,10 @@ pCodeOp *pic16_newpCodeOpRegFromStr(char *name); pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE p); pCodeOp *pic16_pCodeOpCopy(pCodeOp *pcop); +pCode *pic16_newpCodeInfo(INFO_TYPE type, pCodeOp *pcop); +pCodeOp *pic16_newpCodeOpOpt(OPT_TYPE type, char *key); +pCodeOp *pic16_newpCodeOpLocalRegs(LR_TYPE type); + pCode * pic16_findNextInstruction(pCode *pci); pCode * pic16_findNextpCode(pCode *pc, PC_TYPE pct); int pic16_isPCinFlow(pCode *pc, pCode *pcflow);