make RAM big enough for tinibios
[fw/sdcc] / src / pic / pcode.h
index f3c05fd57ffc3537eaef729e28eadf88a49f443a..86c245081b4f4b41219eb0ce67273108d52fd1bf 100644 (file)
@@ -185,6 +185,7 @@ typedef enum
   POC_COMFW,
   POC_CLRF,
   POC_CLRW,
+  POC_CLRWDT,
   POC_DECF,
   POC_DECFW,
   POC_DECFSZ,
@@ -235,14 +236,18 @@ typedef enum
   PC_FUNCTION,    /* Function start or end  */
   PC_WILD,        /* wildcard - an opcode place holder used 
                   * in the pCode peep hole optimizer */
-  PC_CSOURCE      /* C-Source Line  */
+  PC_CSOURCE,     /* C-Source Line  */
+  PC_BAD          /* Mark the pCode object as being bad */
 } PC_TYPE;
 
 /************************************************/
 /***************  Structures ********************/
 /************************************************/
+/* These are here as forward references - the 
+ * full definition of these are below           */
 struct pCode;
 struct pCodeWildBlock;
+struct pCodeRegLives;
 
 /*************************************************
   pBranch
@@ -306,9 +311,12 @@ typedef struct pCodeOpLit
 typedef struct pCodeOpImmd
 {
   pCodeOp pcop;
-  int offset;                   /* low,med, or high byte of immediat value */
-  int index;                    /* add this to the immediate value */
-  unsigned _const:1;           /* is in code space    */
+  int offset;           /* low,med, or high byte of immediat value */
+  int index;            /* add this to the immediate value */
+  unsigned _const:1;    /* is in code space    */
+
+  int rIdx;             /* If this immd points to a register */
+  struct regs *r;       /* then this is the reg. */
 
 } pCodeOpImmd;
 
@@ -423,6 +431,7 @@ typedef struct pCodeCSource
  causes a branch, a Flow object will be inserted into
  the pCode chain to mark the beginning of the next
  contiguous chunk.
+
 **************************************************/
 
 typedef struct pCodeFlow
@@ -433,20 +442,52 @@ typedef struct pCodeFlow
   pCode *end;   /* Last pCode in this flow. Note that
                   the first pCode is pc.next */
 
-  set **uses;   /* map the pCode instruction inCond and outCond conditions 
+  /*  set **uses;   * map the pCode instruction inCond and outCond conditions 
                 * in this array of set's. The reason we allocate an 
                 * array of pointers instead of declaring each type of 
                 * usage is because there are port dependent usage definitions */
-  int nuses;    /* number of uses sets */
+  //int nuses;    /* number of uses sets */
 
   set *from;    /* flow blocks that can send control to this flow block */
   set *to;      /* flow blocks to which this one can send control */
+  struct pCodeFlow *ancestor; /* The most immediate "single" pCodeFlow object that
+                              * executes prior to this one. In many cases, this 
+                              * will be just the previous */
 
   int inCond;   /* Input conditions - stuff assumed defined at entry */
   int outCond;  /* Output conditions - stuff modified by flow block */
 
+  int firstBank; /* The first and last bank flags are the first and last */
+  int lastBank;  /* register banks used within one flow object */
+
+  int FromConflicts;
+  int ToConflicts;
+
+  set *registers;/* Registers used in this flow */
+
 } pCodeFlow;
 
+/*************************************************
+  pCodeFlowLink
+
+  The Flow Link object is used to record information
+ about how consecutive excutive Flow objects are related.
+ The pCodeFlow objects demarcate the pCodeInstructions
+ into contiguous chunks. The FlowLink records conflicts
+ in the discontinuities. For example, if one Flow object
+ references a register in bank 0 and the next Flow object
+ references a register in bank 1, then there is a discontinuity
+ in the banking registers.
+
+*/
+typedef struct pCodeFlowLink
+{
+  pCodeFlow  *pcflow;   /* pointer to linked pCodeFlow object */
+
+  int bank_conflict;    /* records bank conflicts */
+
+} pCodeFlowLink;
+
 /*************************************************
     pCodeInstruction
 
@@ -477,6 +518,7 @@ typedef struct pCodeInstruction
   unsigned int isBitInst: 1;   /* e.g. BCF */
   unsigned int isBranch:  1;   /* True if this is a branching instruction */
   unsigned int isSkip:    1;   /* True if this is a skip instruction */
+  unsigned int isLit:     1;   /* True if this instruction has an literal operand */
 
   PIC_OPCODE inverted_op;      /* Opcode of instruction that's the opposite of this one */
   unsigned int inCond;   // Input conditions for this instruction
@@ -572,6 +614,7 @@ typedef struct pBlock
   set *function_calls;
   set *tregisters;
 
+  set *FlowTree;
   unsigned visited:1;       /* set true if traversed in call tree */
 
   unsigned seq;             /* sequence number of this pBlock */
@@ -683,7 +726,6 @@ typedef struct peepCommand {
   char *cmd;
 } peepCommand;
 
-
 /*************************************************
     pCode Macros
 
@@ -693,6 +735,7 @@ typedef struct peepCommand {
 #define PCL(x)    ((pCodeLabel *)(x))
 #define PCF(x)    ((pCodeFunction *)(x))
 #define PCFL(x)   ((pCodeFlow *)(x))
+#define PCFLINK(x)((pCodeFlowLink *)(x))
 #define PCW(x)    ((pCodeWild *)(x))
 #define PCCS(x)   ((pCodeCSource *)(x))
 
@@ -709,6 +752,26 @@ typedef struct peepCommand {
 
 #define PCWB(x)   ((pCodeWildBlock *)(x))
 
+
+/*
+  macros for checking pCode types
+*/
+#define isPCI(x)        ((PCODE(x)->type == PC_OPCODE))
+#define isPCI_BRANCH(x) ((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isBranch)
+#define isPCI_SKIP(x)   ((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isSkip)
+#define isPCI_LIT(x)    ((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isLit)
+#define isPCI_BITSKIP(x)((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isSkip && PCI(x)->isBitInst)
+#define isPCFL(x)       ((PCODE(x)->type == PC_FLOW))
+#define isPCF(x)        ((PCODE(x)->type == PC_FUNCTION))
+#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 isCALL(x)       ((isPCI(x)) && (PCI(x)->op == POC_CALL))
+#define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS)
+
+#define isPCOLAB(x)     ((PCOP(x)->type) == PO_LABEL)
+
 /*-----------------------------------------------------------------*
  * pCode functions.
  *-----------------------------------------------------------------*/
@@ -740,6 +803,11 @@ pCodeOp *newpCodeOpRegFromStr(char *name);
 pCodeOp *newpCodeOp(char *name, PIC_OPTYPE p);
 pCodeOp *pCodeOpCopy(pCodeOp *pcop);
 
+pCode * findNextInstruction(pCode *pci);
+pCode * findNextpCode(pCode *pc, PC_TYPE pct);
+int isPCinFlow(pCode *pc, pCode *pcflow);
+struct regs * getRegFromInstruction(pCode *pc);
+
 extern void pcode_test(void);
 
 /*-----------------------------------------------------------------*