+2004-10-30 Vangelis Rokas <vrokas AT otenet.gr>
+
+ * doc/sdccman.lyx: updated SDCC version,
+ * (PIC16 port): update list of command line options,
+ * src/pic16/device.h (structure pic16_options_t): added field gstack
+ to enable stack overflow tracing on push/pops,
+ * src/pic16/device.c (statistics structure): added statistics
+ structure,
+ * (pic16_dump_access, pic16_dump_usection, pic16_dump_gsection,
+ pic16_dump_int_registers): increase statistics counters for each
+ * variable which is encountered
+ * (pic16_dump_usection): emit each .udata variable to its own udata
+ section,
+ * src/pic16/gen.c (assignResultValue, genCall, genPcall, genFunction):
+ when macro USE_WREG_IN_FUNC_PARAMS is set to 0 pass all function
+ parameters via stack, otherwise use old scheme,
+ * src/pic16/glue.c (pic16_emitStatistics): dump statistics in
+ assembler output file,
+ * src/pic16/main.c: added command line options --gstack to enable
+ push/pop tracing for stack overflow,
+ * src/pic16/pcode.c (all pCodeInstruction records for PIC18F
+ instructions): added size of each instruction,
+ * (pic16_countInstruction): estimate size of instructions in
+ the_pFile list, inline assembly blocks are not counted,
+ * (pic16_FixRegisterBanking): trace previous register usage, when
+ banksel optimizations is greater than 0, don't emit a redudant
+ banksel directive,
+
2004-10-26 Slade Rich <slade_rich AT users.sourceforge.net>
* src/pic/ralloc.c : fixed inefficient code produced when compiling a complimented bit operation.
\size normal
-SDCC 2.4.5
+SDCC 2.4.6
\size footnotesize
\newline
/
\end_inset
--stack-auto Auto variables that are function parameters, will be saved on
- stack by default.
-
-\emph on
-There is no need to specify this in the command line.
-\layout List
-\labelwidthstring 00.00.0000
-
--
-\begin_inset ERT
-status Collapsed
-
-\layout Standard
-
-\backslash
-/
-\end_inset
-
--float-reent All floating point functions are reentrant by default.
-
-\emph on
-There is no need to specifiy this in the command line.
-\layout List
-\labelwidthstring 00.00.0000
-
--
-\begin_inset ERT
-status Collapsed
-
-\layout Standard
-
-\backslash
-/
-\end_inset
-
-callee-saves See -
\begin_inset ERT
status Collapsed
/
\end_inset
--pgen-bank Instructs the port to insert BANKSEL directives before instructions
- that use the Bank Select Register (BSR).
+-nodefaultlibs do not link default libraries when linking.
+\layout List
+\labelwidthstring 00.00.0000
+
+-
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash
+/
+\end_inset
+
+-obanksel=# Set optimization level for inserting BANKSELs.
+\begin_deeper
+\layout List
+\labelwidthstring 00.00.0000
+
+0 is no optimization
+\layout List
+\labelwidthstring 00.00.0000
+
+1 checkes previous used register and if it is the same then doesn't emit
+ BANKSEL, accounts only for labels.
+\end_deeper
\layout List
\labelwidthstring 00.00.0000
/
\end_inset
--pomit-config-words Instructs the port to omit the generation of the configurati
-on words.
+-pomit-config-words Omit the generation of the configuration words.
\layout List
\labelwidthstring 00.00.0000
/
\end_inset
--pomit-ivt Instructs the port to omit the generation of the interrupt vectors
+-pomit-ivt Omit the generation of the interrupt vectors.
\layout List
\labelwidthstring 00.00.0000
/
\end_inset
--pleave-reset-vector Used in conjuction with the previous command, instructs
- the port NOT to omit the reset vector.
+-pleave-reset-vector Used in conjuction with -
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash
+/
+\end_inset
+
+-pomit-ivt, instructs the port NOT to omit the reset vector.
\layout List
\labelwidthstring 00.00.0000
\end_inset
-link= sets the full path and name of an external linker to call.
+\layout List
+\labelwidthstring 00.00.0000
+
+-
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash
+/
+\end_inset
+
+-call-tree dump call tree in .calltree file
+\layout List
+\labelwidthstring 00.00.0000
+
+-
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash
+/
+\end_inset
+
+-mplab-comp MPLAB compatibility option.
+ Currently only suppresses special gpasm directives.
+\layout List
+\labelwidthstring 00.00.0000
+
+-
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash
+/
+\end_inset
+
+-use-crt= Use a custom run-time module instead of the defaults.
+\layout List
+\labelwidthstring 00.00.0000
+
+-
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash
+/
+\end_inset
+
+-no-crt Don't link the default run-time modules
+\layout List
+\labelwidthstring 00.00.0000
+
+-
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash
+/
+\end_inset
+
+-flr-support When entering/leaving a function, call support functions to
+ store/restore used registers
\layout Subsubsection
Debugging Options
\end_inset
-pcode-verbose Enable pcode debugging information in translation.
+\layout List
+\labelwidthstring 00.00.0000
+
+-
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash
+/
+\end_inset
+
+-denable-peeps Force the usage of peepholes.
+ Use with care.
+\layout List
+\labelwidthstring 00.00.0000
+
+-
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+\backslash
+/
+\end_inset
+
+-gstack Trace push/pops for stack pointer overflow
\layout Subsection
Preprocessor Macros
\layout List
\labelwidthstring 00.00.0000
+code place a function symbol at static FLASH address
+\layout LyX-Code
+
+Example:
+\layout LyX-Code
+
+\layout LyX-Code
+
+/* place function test_func at 0x4000 */
+\layout LyX-Code
+
+#pragma code test_func 0x4000
+\layout List
+\labelwidthstring 00.00.0000
+
udata pragma udata instructs the compiler to emit code so that linker will
place a variable at a specific memory bank
\layout LyX-Code
======================================================================
======================================================================
+2004-Oct-29 Vangelis Rokas
+1. Function parameters are passed now all via stack. This might
+lower performance, but some issues are solved this way. Later
+we can enable passing through WREG,PRODL,PRODH,FSR0L by implementing
+specific pragmas
+
+
2004-Sep-27 Vangelis Rokas
1. Function parameters have been extended to cover functions with
variable arguments. Now function parameters follow the rules below:
static int num_of_supported_PICS = sizeof(Pics16)/sizeof(PIC16_device);
+stats_t statistics = { 0, 0, 0, 0 };
+
#define DEFAULT_PIC "452"
PIC16_device *pic16=NULL;
fprintf(of, "\tudata_acs\n");
for(; r; r = setNextItem(section)) {
fprintf(of, "%s\tres\t%d\n", r->name, r->size);
+ statistics.adsize += r->size;
}
}
qsort(rlist, i /*elementsInSet(section)*/, sizeof(regs *), regCompare);
if(!fix) {
+
+#define EMIT_SINGLE_UDATA_SECTION 0
+#if EMIT_SINGLE_UDATA_SECTION
fprintf(of, "\n\n\tudata\n");
for(r = setFirstItem(section); r; r = setNextItem(section)) {
fprintf(of, "%s\tres\t%d\n", r->name, r->size);
+ statistics.udsize += r->size;
+ }
+#else
+ for(r = setFirstItem(section); r; r = setNextItem(section)) {
+ fprintf(of, "\nudata_%s_%s\tudata\n", moduleName, r->name);
+ fprintf(of, "%s\tres\t%d\n", r->name, r->size);
+ statistics.udsize += r->size;
}
+#endif
} else {
unsigned int j=0;
int deb_addr=0;
} else {
fprintf(of, "%s\tres\t%d\n", r->name, r->size);
deb_addr += r->size;
+ statistics.udsize += r->size;
}
rprev = r;
r->name, sname->name, sname);
#endif
fprintf(of, "%s\tres\t%d\n", r->name, r->size);
+ statistics.udsize += r->size;
}
}
}
fprintf(of, "\n\n; Internal registers\n");
fprintf(of, "%s\tudata_ovr\t0x0000\n", ".registers");
- for(r = setFirstItem(section); r; r = setNextItem(section))
+ for(r = setFirstItem(section); r; r = setNextItem(section)) {
fprintf(of, "%s\tres\t%d\n", r->name, r->size);
+ statistics.intsize += r->size;
+ }
free(rlist);
}
int no_crt;
int ip_stack;
unsigned long opt_flags;
+ int gstack;
} pic16_options_t;
#define STACK_MODEL_SMALL (pic16_options.stack_model == 0)
extern set *fix_idataSymSet;
extern set *rel_idataSymSet;
+typedef struct {
+ unsigned long isize;
+ unsigned long adsize;
+ unsigned long udsize;
+ unsigned long idsize;
+ unsigned long intsize;
+} stats_t;
+
+extern stats_t statistics;
+
extern pic16_options_t pic16_options;
extern PIC16_device *pic16;
#define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
+/* set the following macro to 1 to enable passing the
+ * first byte of functions parameters via WREG */
+#define USE_WREG_IN_FUNC_PARAMS 0
+
+
/* this is the down and dirty file with all kinds of
kludgy & hacky stuff. This is what it is all about
CODE GENERATION for a specific MCU . some of the
/*-----------------------------------------------------------------*/
/* assignResultValue - assign results to oper, rescall==1 is */
-/* called from genCall() or genPCall() */
+/* called from genCall() or genPcall() */
/*-----------------------------------------------------------------*/
static void assignResultValue(operand * oper, int rescall)
{
} else {
int areg = 0; /* matching argument register */
+ debugf("_G.useWreg = %d\n", _G.useWreg);
areg = SPEC_ARGREG( OP_SYM_ETYPE( oper ) ) - 1;
if (_G.sendSet) {
iCode *sic;
int psuedoStkPtr=-1;
+#if USE_WREG_IN_FUNC_PARAMS
int firstTimeThruLoop = 1;
-
+#endif
#if 1
/* reverse sendSet if function is not reentrant */
use_wreg = 0;
for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
- int size, offset = 0;
-
+ int size;
+#if USE_WREG_IN_FUNC_PARAMS
+ int offset = 0;
+#endif
pic16_aopOp(IC_LEFT(sic),sic,FALSE);
size = AOP_SIZE(IC_LEFT(sic));
stackParms += size;
+ /* set the following to 1 to enable passing arguments via WREG */
+#if USE_WREG_IN_FUNC_PARAMS
while (size--) {
DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
pushw();
// --psuedoStkPtr; // sanity check
+ use_wreg = 1;
}
firstTimeThruLoop=0;
offset++;
}
+#else
+ /* all arguments are passed via stack */
+ while (size--) {
+ DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
+ pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
+ DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
+
+ mov2w (AOP(IC_LEFT(sic)), size);
+ pushw();
+ }
+#endif
+
pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
}
+#if USE_WREG_IN_FUNC_PARAMS
/* save last parameter to stack if functions has varargs */
if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw();
else use_wreg = 1; /* last parameter in WREG */
-
+#endif
+
_G.stackRegSet = _G.sendSet;
_G.sendSet = NULL;
}
}
stackParms -= use_wreg;
-
+
if(stackParms>0) {
if(stackParms == 1) {
pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1l));
{
sym_link *ftype;
int stackParms=0;
+ int use_wreg=0;
symbol *retlbl = newiTempLabel(NULL);
pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
- int use_wreg=0;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (_G.sendSet) {
iCode *sic;
int psuedoStkPtr=-1;
+#if USE_WREG_IN_FUNC_PARAMS
int firstTimeThruLoop = 1;
+#endif
/* For the Pic port, there is no data stack.
* So parameters passed to functions are stored
stackParms = 0;
for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
- int size, offset = 0;
+ int size;
+#if USE_WREG_IN_FUNC_PARAMS
+ int offset = 0;
+#endif
pic16_aopOp(IC_LEFT(sic),sic,FALSE);
size = AOP_SIZE(IC_LEFT(sic));
stackParms += size;
+#if USE_WREG_IN_FUNC_PARAMS
while (size--) {
DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
firstTimeThruLoop=0;
mov2w (AOP(IC_LEFT(sic)), size);
+ use_wreg = 1;
offset++;
}
+#else
+ while (size--) {
+ DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
+ pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
+ DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
+ mov2w (AOP(IC_LEFT(sic)), size);
+ pushw();
+ }
+#endif
pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
}
+#if USE_WREG_IN_FUNC_PARAMS
if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw();
else use_wreg = 1; /* last parameter in WREG */
+#endif
_G.stackRegSet = _G.sendSet;
_G.sendSet = NULL;
pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_fsr1h));
}
+#if USE_WREG_IN_FUNC_PARAMS
if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type))
_G.useWreg = 0;
else _G.useWreg = 1;
+#else
+ _G.useWreg = 0;
+#endif
/* if callee-save to be used for this function
* then save the registers being used in this function */
} else if (AOP_TYPE(right) == AOP_CRY) {
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
if(offset == 0) {
+ debugf("%s: BTFSS offset == 0\n", __FUNCTION__);
pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
}
extern char *iComments2;
extern int initsfpnt;
+extern unsigned long pFile_isize;
+extern unsigned long pic16_countInstructions();
set *rel_idataSymSet=NULL;
set *fix_idataSymSet=NULL;
}
}
+void emitStatistics(FILE *asmFile)
+{
+ statistics.isize = pic16_countInstructions();
+
+ fprintf (asmFile, "\n\n; Statistics:\n");
+ fprintf (asmFile, "; code size:\t%ld (0x%lx) bytes\n;\t\t%ld (0x%lx) words\n",
+ statistics.isize, statistics.isize,
+ statistics.isize>>1, statistics.isize>>1);
+ fprintf (asmFile, "; udata size:\t%ld (0x%lx) bytes\n",
+ statistics.udsize, statistics.udsize);
+ fprintf (asmFile, "; access size:\t%ld (0x%lx) bytes\n",
+ statistics.intsize, statistics.intsize);
+
+ fprintf (asmFile, "\n\n");
+}
+
+
/*-----------------------------------------------------------------*/
/* glue - the final glue that hold the whole thing together */
pic16_copypCode(asmFile, 'P');
+ emitStatistics(asmFile);
+
fprintf (asmFile,"\tend\n");
fclose (asmFile);
#define OFMSG_LRSUPPORT "--flr-support"
-
char *alt_asm=NULL;
char *alt_link=NULL;
{ 0, NL_OPT, NULL, "new line, \"lf\" or \"crlf\""},
{ 0, USE_CRT, NULL, "use <crt-o> run-time initialization module"},
{ 0, "--no-crt", &pic16_options.no_crt, "do not link any default run-time initialization module"},
+ { 0, "--gstack", &pic16_options.gstack, "trace stack pointer push/pop to overflow"},
{ 0, OFMSG_LRSUPPORT, NULL, "use support functions for local register store/restore"},
{ 0, NULL, NULL, NULL}
};
pic16_options.crt_name = "crt0i.o"; /* the default crt to link */
pic16_options.no_crt = 0; /* use crt by default */
pic16_options.ip_stack = 1; /* set to 1 to enable ipop/ipush for stack */
+ pic16_options.gstack = 0;
}
static const char *
genericPrint},
POC_ADDWF,
"ADDWF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_ADDFW,
"ADDWF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_ADDWFC,
"ADDWFC",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_ADDFWC,
"ADDWFC",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_ADDLW,
"ADDLW",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_ANDLW,
"ANDLW",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_ANDWF,
"ANDWF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_ANDFW,
"ANDWF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BC,
"BC",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BCF,
"BCF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BN,
"BN",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BNC,
"BNC",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BNN,
"BNN",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BNOV,
"BNOV",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BNZ,
"BNZ",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BOV,
"BOV",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BRA,
"BRA",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BSF,
"BSF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BTFSC,
"BTFSC",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BTFSS,
"BTFSS",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BTG,
"BTG",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BZ,
"BZ",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_CALL,
"CALL",
+ 4,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_COMF,
"COMF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_COMFW,
"COMF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_CLRF,
"CLRF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_CLRWDT,
"CLRWDT",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_CPFSEQ,
"CPFSEQ",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_CPFSGT,
"CPFSGT",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_CPFSLT,
"CPFSLT",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_DAW,
"DAW",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_DCFSNZ,
"DCFSNZ",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_DCFSNZW,
"DCFSNZ",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_DECF,
"DECF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_DECFW,
"DECF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_DECFSZ,
"DECFSZ",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_DECFSZW,
"DECFSZ",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_GOTO,
"GOTO",
+ 4,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_INCF,
"INCF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_INCFW,
"INCF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_INCFSZ,
"INCFSZ",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_INCFSZW,
"INCFSZ",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_INFSNZ,
"INFSNZ",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_INFSNZW,
"INFSNZ",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_IORWF,
"IORWF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_IORFW,
"IORWF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_IORLW,
"IORLW",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_LFSR,
"LFSR",
+ 4,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_MOVF,
"MOVF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_MOVFW,
"MOVF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_MOVFF,
"MOVFF",
+ 4,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_MOVLB,
"MOVLB",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_MOVLW,
"MOVLW",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_MOVWF,
"MOVWF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_MULLW,
"MULLW",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_MULWF,
"MULWF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_NEGF,
"NEGF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_NOP,
"NOP",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_POP,
"POP",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_PUSH,
"PUSH",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_RCALL,
"RCALL",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_RETFIE,
"RETFIE",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_RETLW,
"RETLW",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_RETURN,
"RETURN",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_RLCF,
"RLCF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_RLCFW,
"RLCF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_RLNCF,
"RLNCF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_RLNCFW,
"RLNCF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_RRCF,
"RRCF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_RRCFW,
"RRCF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_RRNCF,
"RRNCF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_RRNCFW,
"RRNCF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_SETF,
"SETF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_SUBLW,
"SUBLW",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_SUBFWB,
"SUBFWB",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_SUBWF,
"SUBWF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_SUBFW,
"SUBWF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_SUBFWB_D1,
"SUBFWB",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_SUBFWB_D0,
"SUBFWB",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_SUBWFB_D1,
"SUBWFB",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_SUBWFB_D0,
"SUBWFB",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_SWAPF,
"SWAPF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_SWAPFW,
"SWAPF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_TBLRD,
"TBLRD*",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_TBLRD_POSTINC,
"TBLRD*+",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_TBLRD_POSTDEC,
"TBLRD*-",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_TBLRD_PREINC,
"TBLRD+*",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_TBLWT,
"TBLWT*",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_TBLWT_POSTINC,
"TBLWT*+",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_TBLWT_POSTDEC,
"TBLWT*-",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_TBLWT_PREINC,
"TBLWT+*",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_TSTFSZ,
"TSTFSZ",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_XORWF,
"XORWF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_XORFW,
"XORWF",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_XORLW,
"XORLW",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
genericPrint},
POC_BANKSEL,
"BANKSEL",
+ 2,
NULL, // from branch
NULL, // to branch
NULL, // label
}
}
}
+
+
+unsigned long pic16_countInstructions(void)
+{
+ pBlock *pb;
+ pCode *pc;
+ unsigned long isize=0;
+
+ if(!the_pFile)return -1;
+
+ for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+ for(pc = pb->pcHead; pc; pc = pc->next) {
+ if(isPCI(pc) || isASMDIR(pc))isize += PCI(pc)->isize;
+ }
+ }
+ return (isize);
+}
+
+
/*-----------------------------------------------------------------*/
/* int RegCond(pCodeOp *pcop) - if pcop points to the STATUS reg- */
/* ister, RegCond will return the bit being referenced. */
pcad->pci.pc.type = PC_ASMDIR;
pcad->pci.pc.prev = pcad->pci.pc.next = NULL;
pcad->pci.pc.pb = NULL;
-
+ pcad->pci.isize = 2;
pcad->pci.pc.destruct = genericDestruct;
pcad->pci.pc.print = genericPrint;
/* for each flow block, determine the register banking
* requirements */
+
+ /* if label, then might come from other point, force banksel */
+ if(isPCL(pc))prevreg = NULL;
+
if(!isPCI(pc))goto loop;
+ if(PCI(pc)->label)prevreg = NULL;
+
if(PCI(pc)->is2MemOp)goto loop;
+
+ /* if goto, then force banksel */
+// if(PCI(pc)->op == POC_GOTO)prevreg = NULL;
reg = pic16_getRegFromInstruction(pc);
if(isPCI_SKIP(pc)) {
// fprintf(stderr, "instruction is SKIP instruction\n");
+// prevreg = NULL;
}
if(reg && isACCESS_BANK(reg))goto loop;
/* if previous instruction is a skip one, then set flag
* to 2 and call insertBankSwitch */
- if(pcprev && isPCI_SKIP(pcprev))flag=2; //goto loop;
+ if(pcprev && isPCI_SKIP(pcprev)) {
+ flag=2; //goto loop
+// prevreg = NULL;
+ }
+ if(pic16_options.opt_banksel>0) {
+ char op1[128], op2[128];
+
+ if(prevreg) {
+ strcpy(op1, pic16_get_op_from_instruction(PCI(pc)));
+ strcpy(op2, pic16_get_op_from_instruction(PCI(pcprev)));
+ if(!strcmp(op1, op2))goto loop;
+ }
+ }
prevreg = reg;
insertBankSwitch(flag, pc);
- pcprev = pc;
// fprintf(stderr, "BANK SWITCH inserted\n");
loop:
+ pcprev = pc;
pc = pc->next;
} while (pc);
}
char const * const mnemonic; // Pointer to mnemonic string
+ char isize; // pCode instruction size
+
pBranch *from; // pCodes that execute before this one
pBranch *to; // pCodes that execute after
pBranch *label; // pCode instructions that have labels