Parse peephole snippets to generate pCode
[fw/sdcc] / src / pic / pcode.h
index a6eae9408f2d79749fa2b8a97ed93a463af6be03..5efd207e8095dc6067b3392b555670ca3304ecb6 100644 (file)
@@ -19,6 +19,9 @@
    
 -------------------------------------------------------------------------*/
 
+//#include "ralloc.h"
+struct regs;
+
 /*
    Post code generation
 
@@ -102,6 +105,7 @@ typedef enum
   PO_FSR,            // The "file select register" (in 18c it's one of three)
   PO_INDF,           // The Indirect register
   PO_GPR_REGISTER,   // A general purpose register
+  PO_GPR_TEMP,       // A general purpose temporary register
   PO_SFR_REGISTER,   // A special function register (e.g. PORTA)
   PO_LITERAL,        // A constant
   PO_IMMEDIATE,      //  (8051 legacy)
@@ -114,6 +118,37 @@ typedef enum
 } PIC_OPTYPE;
 
 
+/*************************************************
+ * pCode conditions:
+ *
+ * The "conditions" are bit-mapped flags that describe
+ * input and/or output conditions that are affected by
+ * the instructions. For example:
+ *
+ *    MOVF   SOME_REG,W
+ *
+ * This instruction depends upon 'SOME_REG'. Consequently
+ * it has the input condition PCC_REGISTER set to true.
+ *
+ * In addition, this instruction affects the Z bit in the
+ * status register and affects W. Thus the output conditions
+ * are the logical or:
+ *  PCC_ZERO_BIT | PCC_W
+ *
+ * The conditions are intialized when the pCode for an
+ * instruction is created. They're subsequently used
+ * by the pCode optimizer determine state information
+ * in the program flow.
+ *************************************************/
+
+#define  PCC_NONE          0
+#define  PCC_REGISTER      (1<<0)
+#define  PCC_C             (1<<1)
+#define  PCC_Z             (1<<2)
+#define  PCC_DC            (1<<3)
+#define  PCC_W             (1<<4)
+#define  PCC_EXAMINE_PCOP  (1<<5)
+
 /***********************************************************************
  *
  *  PIC_OPCODE
@@ -253,17 +288,20 @@ typedef struct pCodeOpLabel
   int key;
 } pCodeOpLabel;
 
-typedef struct pCodeOpWild
+typedef struct pCodeOpReg
 {
-  pCodeOp pcop;
-  int id;
-} pCodeOpWild;
+  pCodeOp pcop;    // Can be either GPR or SFR
+  int rIdx;        // Index into the register table
+  struct regs *r;
+  struct pBlock *pb;
+} pCodeOpReg;
+
 
 
 /*************************************************
     pCode
 
-    Here the basic build block of a PIC instruction.
+    Here is the basic build block of a PIC instruction.
     Each pic instruction will get allocated a pCode.
     A linked list of pCodes makes a program.
 
@@ -276,10 +314,14 @@ typedef struct pCode
   struct pCode *prev;  // The pCode objects are linked together
   struct pCode *next;  // in doubly linked lists.
 
+  int seq;             // sequence number
+
   pBranch *from;       // pCodes that execute before this one
   pBranch *to;         // pCodes that execute after
   pBranch *label;      // pCode instructions that have labels
 
+  struct pBlock *pb;   // The pBlock that contains this pCode.
+
   /* "virtual functions"
    *  The pCode structure is like a base class
    * in C++. The subsequent structures that "inherit"
@@ -320,7 +362,7 @@ typedef struct pCodeInstruction
 
   PIC_OPCODE op;        // The opcode of the instruction.
 
-  char *mnemonic;       // Pointer to mnemonic string
+  char const * const mnemonic;       // Pointer to mnemonic string
 
   pCodeOp *pcop;        // Operand
 
@@ -328,6 +370,9 @@ typedef struct pCodeInstruction
   unsigned int dest:     1;       // If destination is W or F, then 1==F
   unsigned int bit_inst: 1;
 
+  unsigned int inCond;   // Input conditions for this instruction
+  unsigned int outCond;  // Output conditions for this instruction
+
 } pCodeInstruction;
 
 
@@ -340,7 +385,9 @@ typedef struct pCodeLabel
 
   pCode  pc;
 
+  char *label;
   int key;
+
 } pCodeLabel;
 
 /*************************************************
@@ -361,6 +408,25 @@ typedef struct pCodeFunction
 } pCodeFunction;
 
 
+/*************************************************
+    pCodeWild
+**************************************************/
+
+typedef struct pCodeWild
+{
+
+  pCode  pc;
+
+  int    id;     /* Index into the wild card array of a peepBlock 
+                 * - this wild card will get expanded into that pCode
+                 *   that is stored at this index */
+
+
+  pCodeOp *operand;  // Optional operand
+  pCodeOp *label;    // Optional label
+
+} pCodeWild;
+
 /*************************************************
     pBlock
 
@@ -375,12 +441,22 @@ typedef struct pCodeFunction
 typedef struct pBlock
 {
   memmap *cmemmap;   /* The snippet is from this memmap */
+  char   dbName;     /* if cmemmap is NULL, then dbName will identify the block */
   pCode *pcHead;     /* A pointer to the first pCode in a link list of pCodes */
   pCode *pcTail;     /* A pointer to the last pCode in a link list of pCodes */
 
   struct pBlock *next;      /* The pBlocks will form a doubly linked list */
   struct pBlock *prev;
 
+  set *function_entries;    /* dll of functions in this pblock */
+  set *function_exits;
+  set *function_calls;
+  set *registers;
+
+  unsigned visited:1;       /* set true if traversed in call tree */
+
+  unsigned seq;             /* sequence number of this pBlock */
+
 } pBlock;
 
 /*************************************************
@@ -404,6 +480,7 @@ typedef struct pFile
 } pFile;
 
 
+
 /*************************************************
   pCodePeep
 
@@ -420,15 +497,59 @@ typedef struct pCodePeep {
   pBlock *target;    // code we'd like to optimize
   pBlock *replace;   // and this is what we'll optimize it with.
 
+  int     nvars;       // Number of wildcard registers in target.
+  char  **vars;        // array of pointers to them
+  int     nwildpCodes; // Number of wildcard pCodes in target/replace
+  pCode **wildpCodes;  // array of pointers to the pCodeOp's.
+
+
+  /* (Note: a wildcard register is a place holder. Any register
+   * can be replaced by the wildcard when the pcode is being 
+   * compared to the target. */
+
+  /* Post Conditions. A post condition is a condition that
+   * must be either true or false before the peep rule is
+   * accepted. For example, a certain rule may be accepted
+   * if and only if the Z-bit is not used as an input to 
+   * the subsequent instructions in a pCode chain.
+   */
+  unsigned int postFalseCond;  
+  unsigned int postTrueCond;
+
 } pCodePeep;
 
+typedef struct pCodeOpWild
+{
+  pCodeOp pcop;
+  //PIC_OPTYPE subtype;      Wild get's expanded to this by the optimizer
+  pCodePeep *pcp;         // pointer to the parent peep block 
+  int id;                 /* index into an array of char *'s that will match
+                          * the wild card. The array is in *pcp. */
+  pCodeOp *subtype;       /* Pointer to the Operand type into which this wild
+                          * card will be expanded */
+  pCodeOp *matched;       /* When a wild matches, we'll store a pointer to the
+                          * opcode we matched */
+
+} pCodeOpWild;
+
 /*************************************************
     pCode Macros
 
 **************************************************/
-#define PCI(x)  ((pCodeInstruction *)(x))
-#define PCL(x)  ((pCodeLabel *)(x))
-#define PCF(x)  ((pCodeFunction *)(x))
+#define PCODE(x)  ((pCode *)(x))
+#define PCI(x)    ((pCodeInstruction *)(x))
+#define PCL(x)    ((pCodeLabel *)(x))
+#define PCF(x)    ((pCodeFunction *)(x))
+#define PCW(x)    ((pCodeWild *)(x))
+
+#define PCOP(x)   ((pCodeOp *)(x))
+#define PCOB(x)   ((pCodeOpBit *)(x))
+#define PCOL(x)   ((pCodeOpLit *)(x))
+#define PCOLAB(x) ((pCodeOpLabel *)(x))
+#define PCOR(x)   ((pCodeOpReg *)(x))
+#define PCOW(x)   ((pCodeOpWild *)(x))
+
+#define PBR(x)    ((pBranch *)(x))
 
 /*-----------------------------------------------------------------*
  * pCode functions.
@@ -437,29 +558,33 @@ typedef struct pCodePeep {
 pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop); // Create a new pCode given an operand
 pCode *newpCodeCharP(char *cP);              // Create a new pCode given a char *
 pCode *newpCodeFunction(char *g, char *f);   // Create a new function
-pCode *newpCodeLabel(int key);               // Create a new label
-pBlock *newpCodeChain(memmap *cm,pCode *pc); // Create a new pBlock
+pCode *newpCodeLabel(int key);               // Create a new label given a key
+pCode *newpCodeLabelStr(char *str);          // Create a new label given a string
+pBlock *newpCodeChain(memmap *cm,char c, pCode *pc); // Create a new pBlock
 void printpBlock(FILE *of, pBlock *pb);      // Write a pBlock to a file
 void printpCode(FILE *of, pCode *pc);        // Write a pCode to a file
 void addpCode2pBlock(pBlock *pb, pCode *pc); // Add a pCode to a pBlock
 void addpBlock(pBlock *pb);                  // Add a pBlock to a pFile
 void copypCode(FILE *of, char dbName);       // Write all pBlocks with dbName to *of
+void movepBlock2Head(char dbName);           // move pBlocks around
 void AnalyzepCode(char dbName);
+void OptimizepCode(char dbName);
 void printCallTree(FILE *of);
+void pCodePeepInit(void);
 
 pCodeOp *newpCodeOpLabel(int key);
 pCodeOp *newpCodeOpLit(int lit);
 pCodeOp *newpCodeOpBit(char *name, int bit);
-pCodeOp *newpCodeOp(char *name);
+pCodeOp *newpCodeOp(char *name, PIC_OPTYPE p);
 extern void pcode_test(void);
 
 /*-----------------------------------------------------------------*
  * pCode objects.
  *-----------------------------------------------------------------*/
 
-extern pCodeOp pc_status;
-extern pCodeOp pc_indf;
-extern pCodeOp pc_fsr;
+extern pCodeOpReg pc_status;
+extern pCodeOpReg pc_indf;
+extern pCodeOpReg pc_fsr;
 
 
 ////////////////////   DELETE THIS ///////////////////