1 /*-------------------------------------------------------------------------
3 pcode.h - post code generation
4 Written By - Scott Dattalo scott@dattalo.com
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 -------------------------------------------------------------------------*/
28 The post code generation is an assembler optimizer. The assembly code
29 produced by all of the previous steps is fully functional. This step
30 will attempt to analyze the flow of the assembly code and agressively
31 optimize it. The peep hole optimizer attempts to do the same thing.
32 As you may recall, the peep hole optimizer replaces blocks of assembly
33 with more optimal blocks (e.g. removing redundant register loads).
34 However, the peep hole optimizer has to be somewhat conservative since
35 an assembly program has implicit state information that's unavailable
36 when only a few instructions are examined.
37 Consider this example:
43 The movf seems redundant since we know that the W register already
44 contains the same value of t1. So a peep hole optimizer is tempted to
45 remove the "movf". However, this is dangerous since the movf affects
46 the flags in the status register (specifically the Z flag) and subsequent
47 code may depend upon this. Look at these two examples:
51 movf t1,w ; Can't remove this movf
57 movf t1,w ; This movf can be removed
58 xorwf t2,w ; since xorwf will over write Z
68 /***********************************************************************
71 * The DFPRINTF macro will call fprintf if PCODE_DEBUG is defined.
72 * The macro is used like:
74 * DPRINTF(("%s #%d\n","test", 1));
76 * The double parenthesis (()) are necessary
78 ***********************************************************************/
82 #define DFPRINTF(args) (fprintf args)
84 #define DFPRINTF(args) ;
88 /***********************************************************************
89 * PIC status bits - this will move into device dependent headers
90 ***********************************************************************/
95 /***********************************************************************
97 ***********************************************************************/
103 /***********************************************************************
105 * PIC_OPTYPE - Operand types that are specific to the PIC architecture
107 * If a PIC assembly instruction has an operand then here is where we
108 * associate a type to it. For example,
112 * The movf has two operands: 'reg' and the W register. 'reg' is some
113 * arbitrary general purpose register, hence it has the type PO_GPR_REGISTER.
114 * The W register, which is the PIC's accumulator, has the type PO_W.
116 ***********************************************************************/
122 PO_NONE=0, // No operand e.g. NOP
123 PO_W, // The 'W' register
124 PO_STATUS, // The 'STATUS' register
125 PO_FSR, // The "file select register" (in 18c it's one of three)
126 PO_INDF, // The Indirect register
127 PO_GPR_REGISTER, // A general purpose register
128 PO_GPR_BIT, // A bit of a general purpose register
129 PO_GPR_TEMP, // A general purpose temporary register
130 PO_SFR_REGISTER, // A special function register (e.g. PORTA)
131 PO_PCL, // Program counter Low register
132 PO_PCLATH, // Program counter Latch high register
133 PO_LITERAL, // A constant
134 PO_IMMEDIATE, // (8051 legacy)
135 PO_DIR, // Direct memory (8051 legacy)
136 PO_CRY, // bit memory (8051 legacy)
137 PO_BIT, // bit operand.
138 PO_STR, // (8051 legacy)
140 PO_WILD // Wild card operand in peep optimizer
144 /*************************************************
147 * The "conditions" are bit-mapped flags that describe
148 * input and/or output conditions that are affected by
149 * the instructions. For example:
153 * This instruction depends upon 'SOME_REG'. Consequently
154 * it has the input condition PCC_REGISTER set to true.
156 * In addition, this instruction affects the Z bit in the
157 * status register and affects W. Thus the output conditions
158 * are the logical or:
159 * PCC_ZERO_BIT | PCC_W
161 * The conditions are intialized when the pCode for an
162 * instruction is created. They're subsequently used
163 * by the pCode optimizer determine state information
164 * in the program flow.
165 *************************************************/
168 #define PCC_REGISTER (1<<0)
171 #define PCC_DC (1<<3)
173 #define PCC_EXAMINE_PCOP (1<<5)
175 /***********************************************************************
179 * This is not a list of the PIC's opcodes per se, but instead
180 * an enumeration of all of the different types of pic opcodes.
182 ***********************************************************************/
186 POC_WILD=-1, /* Wild card - used in the pCode peep hole optimizer
187 * to represent ANY pic opcode */
238 /***********************************************************************
239 * PC_TYPE - pCode Types
240 ***********************************************************************/
244 PC_COMMENT=0, // pCode is a comment
245 PC_OPCODE, // PORT dependent opcode
246 PC_LABEL, // assembly label
247 PC_FUNCTION, // Function start or end
248 PC_WILD // wildcard - an opcode place holder
251 /************************************************/
252 /*************** Structures ********************/
253 /************************************************/
256 /*************************************************
259 The first step in optimizing pCode is determining
260 the program flow. This information is stored in
261 single-linked lists in the for of 'from' and 'to'
262 objects with in a pcode. For example, most instructions
263 don't involve any branching. So their from branch
264 points to the pCode immediately preceding them and
265 their 'to' branch points to the pcode immediately
266 following them. A skip instruction is an example of
267 a pcode that has multiple (in this case two) elements
268 in the 'to' branch. A 'label' pcode is an where there
269 may be multiple 'from' branches.
270 *************************************************/
272 typedef struct pBranch
274 struct pCode *pc; // Next pCode in a branch
275 struct pBranch *next; /* If more than one branch
276 * the next one is here */
280 /*************************************************
283 pCode Operand structure.
284 For those assembly instructions that have arguments,
285 the pCode will have a pCodeOp in which the argument
286 can be stored. For example
290 'some_register' will be stored/referenced in a pCodeOp
292 *************************************************/
294 typedef struct pCodeOp
301 typedef struct pCodeOpBit
305 unsigned int inBitSpace: 1; /* True if in bit space, else
306 just a bit of a register */
309 typedef struct pCodeOpLit
315 typedef struct pCodeOpLabel
321 typedef struct pCodeOpReg
323 pCodeOp pcop; // Can be either GPR or SFR
324 int rIdx; // Index into the register table
329 typedef struct pCodeOpRegBit
331 pCodeOpReg pcor; // The Register containing this bit
332 int bit; // 0-7 bit number.
333 PIC_OPTYPE subtype; // The type of this register.
337 /*************************************************
340 Here is the basic build block of a PIC instruction.
341 Each pic instruction will get allocated a pCode.
342 A linked list of pCodes makes a program.
344 **************************************************/
350 struct pCode *prev; // The pCode objects are linked together
351 struct pCode *next; // in doubly linked lists.
353 int seq; // sequence number
355 pBranch *from; // pCodes that execute before this one
356 pBranch *to; // pCodes that execute after
357 pBranch *label; // pCode instructions that have labels
359 struct pBlock *pb; // The pBlock that contains this pCode.
361 /* "virtual functions"
362 * The pCode structure is like a base class
363 * in C++. The subsequent structures that "inherit"
364 * the pCode structure will initialize these function
365 * pointers to something useful */
366 void (*analyze) (struct pCode *_this);
367 void (*destruct)(struct pCode *_this);
368 void (*print) (FILE *of,struct pCode *_this);
373 /*************************************************
375 **************************************************/
377 typedef struct pCodeComment
386 /*************************************************
389 Here we describe all the facets of a PIC instruction
390 (expansion for the 18cxxx is also provided).
392 **************************************************/
394 typedef struct pCodeInstruction
399 PIC_OPCODE op; // The opcode of the instruction.
401 char const * const mnemonic; // Pointer to mnemonic string
403 pCodeOp *pcop; // Operand
405 unsigned int num_ops;
406 unsigned int dest: 1; // If destination is W or F, then 1==F
407 unsigned int bit_inst: 1;
409 unsigned int inCond; // Input conditions for this instruction
410 unsigned int outCond; // Output conditions for this instruction
415 /*************************************************
417 **************************************************/
419 typedef struct pCodeLabel
429 /*************************************************
431 **************************************************/
433 typedef struct pCodeFunction
439 char *fname; /* If NULL, then this is the end of
440 a function. Otherwise, it's the
441 start and the name is contained
447 /*************************************************
449 **************************************************/
451 typedef struct pCodeWild
456 int id; /* Index into the wild card array of a peepBlock
457 * - this wild card will get expanded into that pCode
458 * that is stored at this index */
461 pCodeOp *operand; // Optional operand
462 pCodeOp *label; // Optional label
466 /*************************************************
469 Here are PIC program snippets. There's a strong
470 correlation between the eBBlocks and pBlocks.
471 SDCC subdivides a C program into managable chunks.
472 Each chunk becomes a eBBlock and ultimately in the
475 **************************************************/
477 typedef struct pBlock
479 memmap *cmemmap; /* The snippet is from this memmap */
480 char dbName; /* if cmemmap is NULL, then dbName will identify the block */
481 pCode *pcHead; /* A pointer to the first pCode in a link list of pCodes */
482 pCode *pcTail; /* A pointer to the last pCode in a link list of pCodes */
484 struct pBlock *next; /* The pBlocks will form a doubly linked list */
487 set *function_entries; /* dll of functions in this pblock */
492 unsigned visited:1; /* set true if traversed in call tree */
494 unsigned seq; /* sequence number of this pBlock */
498 /*************************************************
501 The collection of pBlock program snippets are
502 placed into a linked list that is implemented
503 in the pFile structure.
505 The pcode optimizer will parse the pFile.
507 **************************************************/
511 pBlock *pbHead; /* A pointer to the first pBlock */
512 pBlock *pbTail; /* A pointer to the last pBlock */
514 pBranch *functions; /* A SLL of functions in this pFile */
520 /*************************************************
523 The pCodePeep object mimics the peep hole optimizer
524 in the main SDCC src (e.g. SDCCpeeph.c). Essentially
525 there is a target pCode chain and a replacement
526 pCode chain. The target chain is compared to the
527 pCode that is generated by gen.c. If a match is
528 found then the pCode is replaced by the replacement
530 **************************************************/
531 typedef struct pCodePeep {
533 pBlock *target; // code we'd like to optimize
534 pBlock *replace; // and this is what we'll optimize it with.
536 int nvars; // Number of wildcard registers in target.
537 char **vars; // array of pointers to them
538 int nops; // Number of wildcard operands in target.
539 pCodeOp **wildpCodeOps; // array of pointers to the pCodeOp's.
541 int nwildpCodes; // Number of wildcard pCodes in target/replace
542 pCode **wildpCodes; // array of pointers to the pCode's.
545 /* (Note: a wildcard register is a place holder. Any register
546 * can be replaced by the wildcard when the pcode is being
547 * compared to the target. */
549 /* Post Conditions. A post condition is a condition that
550 * must be either true or false before the peep rule is
551 * accepted. For example, a certain rule may be accepted
552 * if and only if the Z-bit is not used as an input to
553 * the subsequent instructions in a pCode chain.
555 unsigned int postFalseCond;
556 unsigned int postTrueCond;
560 typedef struct pCodeOpWild
563 //PIC_OPTYPE subtype; Wild get's expanded to this by the optimizer
564 pCodePeep *pcp; // pointer to the parent peep block
565 int id; /* index into an array of char *'s that will match
566 * the wild card. The array is in *pcp. */
567 pCodeOp *subtype; /* Pointer to the Operand type into which this wild
568 * card will be expanded */
569 pCodeOp *matched; /* When a wild matches, we'll store a pointer to the
570 * opcode we matched */
574 /*************************************************
577 **************************************************/
578 #define PCODE(x) ((pCode *)(x))
579 #define PCI(x) ((pCodeInstruction *)(x))
580 #define PCL(x) ((pCodeLabel *)(x))
581 #define PCF(x) ((pCodeFunction *)(x))
582 #define PCW(x) ((pCodeWild *)(x))
584 #define PCOP(x) ((pCodeOp *)(x))
585 #define PCOB(x) ((pCodeOpBit *)(x))
586 #define PCOL(x) ((pCodeOpLit *)(x))
587 #define PCOLAB(x) ((pCodeOpLabel *)(x))
588 #define PCOR(x) ((pCodeOpReg *)(x))
589 #define PCORB(x) ((pCodeOpRegBit *)(x))
590 #define PCOW(x) ((pCodeOpWild *)(x))
592 #define PBR(x) ((pBranch *)(x))
594 /*-----------------------------------------------------------------*
596 *-----------------------------------------------------------------*/
598 pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop); // Create a new pCode given an operand
599 pCode *newpCodeCharP(char *cP); // Create a new pCode given a char *
600 pCode *newpCodeFunction(char *g, char *f); // Create a new function
601 pCode *newpCodeLabel(int key); // Create a new label given a key
602 pCode *newpCodeLabelStr(char *str); // Create a new label given a string
603 pBlock *newpCodeChain(memmap *cm,char c, pCode *pc); // Create a new pBlock
604 void printpBlock(FILE *of, pBlock *pb); // Write a pBlock to a file
605 void printpCode(FILE *of, pCode *pc); // Write a pCode to a file
606 void addpCode2pBlock(pBlock *pb, pCode *pc); // Add a pCode to a pBlock
607 void addpBlock(pBlock *pb); // Add a pBlock to a pFile
608 void copypCode(FILE *of, char dbName); // Write all pBlocks with dbName to *of
609 void movepBlock2Head(char dbName); // move pBlocks around
610 void AnalyzepCode(char dbName);
611 void OptimizepCode(char dbName);
612 void printCallTree(FILE *of);
613 void pCodePeepInit(void);
615 pCodeOp *newpCodeOpLabel(int key);
616 pCodeOp *newpCodeOpLit(int lit);
617 pCodeOp *newpCodeOpBit(char *name, int bit,int inBitSpace);
618 pCodeOp *newpCodeOp(char *name, PIC_OPTYPE p);
619 extern void pcode_test(void);
621 /*-----------------------------------------------------------------*
623 *-----------------------------------------------------------------*/
625 extern pCodeOpReg pc_status;
626 extern pCodeOpReg pc_indf;
627 extern pCodeOpReg pc_fsr;
628 extern pCodeOpReg pc_pcl;
629 extern pCodeOpReg pc_pclath;
630 extern pCodeOpReg pc_kzero;
633 //////////////////// DELETE THIS ///////////////////
634 /*-----------------------------------------------------------------*/
635 /* Allocation macros that replace those in SDCCalloc.h */
636 /* Why? I dunno. I ran across a bug with those macros that */
637 /* I couldn't fix, but I could work around... */
638 /*-----------------------------------------------------------------*/
639 # define GC_malloc(x) calloc((x), 1)
641 #define _ALLOC(x,sz) if (!(x = calloc((sz),1) )) \
643 werror(E_OUT_OF_MEM,__FILE__,(long) sz);\
647 #define _ALLOC_ATOMIC(x,y) if (!((x) = malloc(y))) \
649 werror(E_OUT_OF_MEM,__FILE__,(long) y); \
653 #endif // __PCODE_H__