#endif
+#ifdef WORDS_BIGENDIAN
+ #define _ENDIAN(x) (3-x)
+#else
+ #define _ENDIAN(x) (x)
+#endif
+
+
+#define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
+
+
+/***********************************************************************
+ * Extended Instruction Set/Indexed Literal Offset Mode *
+ * Set this macro to enable code generation with the extended *
+ * instruction set and the new Indexed Literal Offset Mode *
+ ***********************************************************************/
+#define XINST 1
+
/***********************************************************************
* PIC status bits - this will move into device dependent headers
***********************************************************************/
PO_SFR_REGISTER, // A special function register (e.g. PORTA)
PO_PCL, // Program counter Low register
PO_PCLATH, // Program counter Latch high register
+ PO_PCLATU, // Program counter Latch upper register
+ PO_PRODL, // Product Register Low
+ PO_PRODH, // Product Register High
PO_LITERAL, // A constant
PO_REL_ADDR, // A relative address
PO_IMMEDIATE, // (8051 legacy)
PO_BIT, // bit operand.
PO_STR, // (8051 legacy)
PO_LABEL,
- PO_WILD // Wild card operand in peep optimizer
+ PO_WILD, // Wild card operand in peep optimizer
+ PO_TWO_OPS // combine two operands
} PIC_OPTYPE;
POC_INCFSZ,
POC_INCFSZW,
POC_INFSNZ,
+ POC_INFSNZW,
POC_IORWF,
POC_IORFW,
POC_IORLW,
POC_SUBFWB_D1,
POC_SWAPF,
POC_SWAPFW,
- POC_TRIS, // To be removed
+ POC_TBLRD,
+ POC_TBLRD_POSTINC,
+ POC_TBLRD_POSTDEC,
+ POC_TBLRD_PREINC,
+ POC_TBLWT,
+ POC_TBLWT_POSTINC,
+ POC_TBLWT_POSTDEC,
+ POC_TBLWT_PREINC,
POC_TSTFSZ,
POC_XORLW,
POC_XORWF,
- POC_XORFW
+ POC_XORFW,
+
+ POC_BANKSEL
+
+ /* pseudo-instructions */
} PIC_OPCODE;
PC_WILD, /* wildcard - an opcode place holder used
* in the pCode peep hole optimizer */
PC_CSOURCE, /* C-Source Line */
- PC_BAD /* Mark the pCode object as being bad */
+ PC_ASMDIR, /* Assembler directive */
+ PC_BAD, /* Mark the pCode object as being bad */
+ PC_INFO /* pCode information node, used primarily in optimizing */
} PC_TYPE;
+
+/***********************************************************************
+ * INFO_TYPE - information node types
+ ***********************************************************************/
+
+typedef enum
+{
+ INF_OPTIMIZATION, /* structure contains optimization information */
+ INF_LOCALREGS /* structure contains local register information */
+} INFO_TYPE;
+
+
+
+/***********************************************************************
+ * OPT_TYPE - optimization node types
+ ***********************************************************************/
+
+typedef enum
+{
+ OPT_BEGIN, /* mark beginning of optimization block */
+ OPT_END, /* mark ending of optimization block */
+ OPT_JUMPTABLE_BEGIN, /* mark beginning of a jumptable */
+ OPT_JUMPTABLE_END /* mark end of jumptable */
+} 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;
+
+
/************************************************/
/*************** Structures ********************/
/************************************************/
char *name;
} pCodeOp;
+
#if 0
typedef struct pCodeOpBit
{
just a bit of a register */
} pCodeOpBit;
#endif
+
typedef struct pCodeOpLit
{
pCodeOp pcop;
int lit;
+ pCodeOp *arg2; /* needed as pCodeOpLit and pCodeOpLit2 are not separable via their type (PO_LITERAL) */
} pCodeOpLit;
+typedef struct pCodeOpLit2
+{
+ pCodeOp pcop;
+ int lit;
+ pCodeOp *arg2;
+} pCodeOpLit2;
+
+
typedef struct pCodeOpImmd
{
pCodeOp pcop;
- int offset; /* low,med, or high byte of immediat value */
+ int offset; /* low,high or upper byte of immediate value */
int index; /* add this to the immediate value */
unsigned _const:1; /* is in code space */
struct pBlock *pb;
} pCodeOpReg;
+typedef struct pCodeOp2
+{
+ pCodeOp pcop; // describes this pCodeOp
+ pCodeOp *pcopL; // reference to left pCodeOp (src)
+ pCodeOp *pcopR; // reference to right pCodeOp (dest)
+} pCodeOp2;
+
typedef struct pCodeOpRegBit
{
pCodeOpReg pcor; // The Register containing this bit
pCodeOp *matched; /* When a wild matches, we'll store a pointer to the
* opcode we matched */
+ pCodeOp *pcop2; /* second operand if exists */
+
} pCodeOpWild;
+typedef struct pCodeOpOpt
+{
+ pCodeOp pcop;
+
+ OPT_TYPE type; /* optimization node type */
+
+ char *key; /* key by which a block is identified */
+} pCodeOpOpt;
+
+typedef struct pCodeOpLocalReg
+{
+ pCodeOp pcop;
+
+ LR_TYPE type;
+} pCodeOpLocalReg;
+
/*************************************************
pCode
} pCodeComment;
+
/*************************************************
- pCodeComment
+ pCodeCSource
**************************************************/
typedef struct pCodeCSource
} pCodeCSource;
+/*************************************************
+ pCodeAsmDir
+**************************************************/
+
/*************************************************
pCodeFlow
contiguous chunk.
**************************************************/
+struct defmap_s; // defined in pcode.c
typedef struct pCodeFlow
{
set *registers;/* Registers used in this flow */
+ struct defmap_s *defmap; /* chronologically ordered list of definitions performed
+ in this flow (most recent at the front) */
+ struct defmap_s *in_vals; /* definitions of all symbols reaching this flow
+ * symbols with multiple different definitions are stored
+ * with an assigned value of 0. */
+ struct defmap_s *out_vals; /* definitions valid AFTER thie flow */
+
} pCodeFlow;
/*************************************************
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
unsigned int isLit: 1; /* True if this instruction has an literal operand */
unsigned int isAccess: 1; /* True if this instruction has an access RAM operand */
unsigned int isFastCall: 1; /* True if this instruction has a fast call/return mode select operand */
+ unsigned int is2MemOp: 1; /* True is second operand is a memory operand VR - support for MOVFF */
+ unsigned int is2LitOp: 1; /* True if instruction takes 2 literal operands VR - support for LFSR */
PIC_OPCODE inverted_op; /* Opcode of instruction that's the opposite of this one */
unsigned int inCond; // Input conditions for this instruction
unsigned int outCond; // Output conditions for this instruction
+#define PCI_MAGIC 0x6e12
+ unsigned int pci_magic; // sanity check for pci initialization
} pCodeInstruction;
+
+/*************************************************
+ pCodeAsmDir
+**************************************************/
+
+typedef struct pCodeAsmDir
+{
+ pCodeInstruction pci;
+
+ char *directive;
+ char *arg;
+} pCodeAsmDir;
+
+
/*************************************************
pCodeLabel
**************************************************/
char *label;
int key;
+ int force; /* label cannot be optimized out */
} pCodeLabel;
int ncalled; /* Number of times function is called */
+ int absblock; /* hack to emulate a block pCodes in absolute position
+ but not inside a function */
+ int stackusage; /* stack positions used in function */
+
} pCodeFunction;
} pCodeWild;
+
+/*************************************************
+ pInfo
+
+ Here are stored generic informaton
+*************************************************/
+typedef struct pCodeInfo
+{
+ pCodeInstruction pci;
+
+ INFO_TYPE type; /* info node type */
+
+ pCodeOp *oper1; /* info node arguments */
+} pCodeInfo;
+
+
/*************************************************
pBlock
#define PCFLINK(x)((pCodeFlowLink *)(x))
#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 PCOP2(x) ((pCodeOp2 *)(x))
//#define PCOB(x) ((pCodeOpBit *)(x))
#define PCOL(x) ((pCodeOpLit *)(x))
#define PCOI(x) ((pCodeOpImmd *)(x))
#define PCOLAB(x) ((pCodeOpLabel *)(x))
#define PCOR(x) ((pCodeOpReg *)(x))
+//#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))
#define PCWB(x) ((pCodeWildBlock *)(x))
#define isPCL(x) ((PCODE(x)->type == PC_LABEL))
#define isPCW(x) ((PCODE(x)->type == PC_WILD))
#define isPCCS(x) ((PCODE(x)->type == PC_CSOURCE))
+#define isPCAD(x) ((PCODE(x)->type == PC_ASMDIR))
+#define isPCINFO(x) ((PCODE(x)->type == PC_INFO))
#define isCALL(x) ((isPCI(x)) && (PCI(x)->op == POC_CALL))
#define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS)
#define isBSR_REG(r) ((r)->pc_type == PO_BSR)
+#define isACCESS_BANK(r) (r->accessBank)
+
-#define isACCESS_LOW(r) ((pic16_finalMapping[REG_ADDR(r)].bank == \
- PIC_BANK_FIRST) && (REG_ADDR(r) < 0x80))
-#define isACCESS_HI(r) (pic16_finalMapping[REG_ADDR(r)].bank == PIC_BANK_LAST)
-#define isACCESS_BANK(r)(isACCESS_LOW(r) || isACCESS_HI(r))
#define isPCOLAB(x) ((PCOP(x)->type) == PO_LABEL)
pCode *pic16_newpCodeInlineP(char *cP); // Create a new pCode given a char *
pCode *pic16_newpCodeFunction(char *g, char *f); // Create a new function
pCode *pic16_newpCodeLabel(char *name,int key); // Create a new label given a key
+pCode *pic16_newpCodeLabelFORCE(char *name, int key); // Same as newpCodeLabel but label cannot be optimized out
pCode *pic16_newpCodeCSource(int ln, char *f, char *l); // Create a new symbol line
pBlock *pic16_newpCodeChain(memmap *cm,char c, pCode *pc); // Create a new pBlock
void pic16_printpBlock(FILE *of, pBlock *pb); // Write a pBlock to a file
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);
void pic16_pBlockConvert2ISR(pBlock *pb);
+void pic16_pBlockConvert2Absolute(pBlock *pb);
+void pic16_initDB(void);
+void pic16_emitDB(int c, char ptype, void *p); // Add DB directives to a pBlock
+void pic16_emitDS(char *s, char ptype, void *p);
+void pic16_flushDB(char ptype, void *p); // Add pending DB data to a pBlock
+
+pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
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_newpCodeOpBit(char *name, int bit,int inBitSpace);
+pCodeOp *pic16_newpCodeOpLit12(int lit);
+pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2);
+pCodeOp *pic16_newpCodeOpBit(char *name, int bit,int inBitSpace, PIC_OPTYPE subt);
+pCodeOp *pic16_newpCodeOpBit_simple (struct asmop *op, int offs, int bit);
pCodeOp *pic16_newpCodeOpRegFromStr(char *name);
+pCodeOp *pic16_newpCodeOpReg(int rIdx);
pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE p);
+pCodeOp *pic16_newpCodeOp2(pCodeOp *src, pCodeOp *dst);
+pCodeOp *pic16_newpCodeOpRegNotVect(bitVect *bv);
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);
+pCodeOp *pic16_newpCodeOpReg(int rIdx);
+
pCode * pic16_findNextInstruction(pCode *pci);
pCode * pic16_findNextpCode(pCode *pc, PC_TYPE pct);
int pic16_isPCinFlow(pCode *pc, pCode *pcflow);
struct regs * pic16_getRegFromInstruction(pCode *pc);
+struct regs * pic16_getRegFromInstruction2(pCode *pc);
+char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size);
+char *pic16_get_op2(pCodeOp *pcop,char *buffer, size_t size);
+char *dumpPicOptype(PIC_OPTYPE type);
extern void pic16_pcode_test(void);
+extern int pic16_debug_verbose;
+extern int pic16_pcode_verbose;
+
+extern char *LR_TYPE_STR[];
+
+
+#ifndef debugf
+//#define debugf(frm, rest...) _debugf(__FILE__, __LINE__, frm, rest)
+#define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest)
+#define debugf2(frm, arg1, arg2) _debugf(__FILE__, __LINE__, frm, arg1, arg2)
+#define debugf3(frm, arg1, arg2, arg3) _debugf(__FILE__, __LINE__, frm, arg1, arg2, arg3)
+
+#endif
+
+extern void _debugf(char *f, int l, char *frm, ...);
+
/*-----------------------------------------------------------------*
* pCode objects.
extern pCodeOpReg pic16_pc_status;
extern pCodeOpReg pic16_pc_intcon;
-extern pCodeOpReg pic16_pc_indf0;
-extern pCodeOpReg pic16_pc_fsr0;
extern pCodeOpReg pic16_pc_pcl;
extern pCodeOpReg pic16_pc_pclath;
+extern pCodeOpReg pic16_pc_pclatu;
extern pCodeOpReg pic16_pc_wreg;
+extern pCodeOpReg pic16_pc_tosl;
+extern pCodeOpReg pic16_pc_tosh;
+extern pCodeOpReg pic16_pc_tosu;
+extern pCodeOpReg pic16_pc_tblptrl;
+extern pCodeOpReg pic16_pc_tblptrh;
+extern pCodeOpReg pic16_pc_tblptru;
+extern pCodeOpReg pic16_pc_tablat;
+extern pCodeOpReg pic16_pc_bsr;
+extern pCodeOpReg pic16_pc_fsr0;
+extern pCodeOpReg pic16_pc_fsr0l;
+extern pCodeOpReg pic16_pc_fsr0h;
+extern pCodeOpReg pic16_pc_fsr1l;
+extern pCodeOpReg pic16_pc_fsr1h;
+extern pCodeOpReg pic16_pc_fsr2l;
+extern pCodeOpReg pic16_pc_fsr2h;
+extern pCodeOpReg pic16_pc_indf0;
+extern pCodeOpReg pic16_pc_postinc0;
+extern pCodeOpReg pic16_pc_postdec0;
+extern pCodeOpReg pic16_pc_preinc0;
+extern pCodeOpReg pic16_pc_plusw0;
+extern pCodeOpReg pic16_pc_indf1;
+extern pCodeOpReg pic16_pc_postinc1;
+extern pCodeOpReg pic16_pc_postdec1;
+extern pCodeOpReg pic16_pc_preinc1;
+extern pCodeOpReg pic16_pc_plusw1;
+extern pCodeOpReg pic16_pc_indf2;
+extern pCodeOpReg pic16_pc_postinc2;
+extern pCodeOpReg pic16_pc_postdec2;
+extern pCodeOpReg pic16_pc_preinc2;
+extern pCodeOpReg pic16_pc_plusw2;
+extern pCodeOpReg pic16_pc_prodl;
+extern pCodeOpReg pic16_pc_prodh;
+
+extern pCodeOpReg pic16_pc_eecon1;
+extern pCodeOpReg pic16_pc_eecon2;
+extern pCodeOpReg pic16_pc_eedata;
+extern pCodeOpReg pic16_pc_eeadr;
+
extern pCodeOpReg pic16_pc_kzero;
extern pCodeOpReg pic16_pc_wsave; /* wsave and ssave are used to save W and the Status */
extern pCodeOpReg pic16_pc_ssave; /* registers during an interrupt */
+extern pCodeOpReg *pic16_stackpnt_lo;
+extern pCodeOpReg *pic16_stackpnt_hi;
+extern pCodeOpReg *pic16_stack_postinc;
+extern pCodeOpReg *pic16_stack_postdec;
+extern pCodeOpReg *pic16_stack_preinc;
+extern pCodeOpReg *pic16_stack_plusw;
+
+extern pCodeOpReg *pic16_framepnt_lo;
+extern pCodeOpReg *pic16_framepnt_hi;
+extern pCodeOpReg *pic16_frame_postinc;
+extern pCodeOpReg *pic16_frame_postdec;
+extern pCodeOpReg *pic16_frame_preinc;
+extern pCodeOpReg *pic16_frame_plusw;
+
+extern pCodeOpReg pic16_pc_gpsimio;
+extern pCodeOpReg pic16_pc_gpsimio2;
#endif // __PCODE_H__