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 /***********************************************************************
69 * PIC status bits - this will move into device dependent headers
70 ***********************************************************************/
75 /***********************************************************************
77 ***********************************************************************/
83 /***********************************************************************
85 * PIC_OPTYPE - Operand types that are specific to the PIC architecture
87 * If a PIC assembly instruction has an operand then here is where we
88 * associate a type to it. For example,
92 * The movf has two operands: 'reg' and the W register. 'reg' is some
93 * arbitrary general purpose register, hence it has the type PO_GPR_REGISTER.
94 * The W register, which is the PIC's accumulator, has the type PO_W.
96 ***********************************************************************/
102 PO_NONE=0, // No operand e.g. NOP
103 PO_W, // The 'W' register
104 PO_STATUS, // The 'STATUS' register
105 PO_FSR, // The "file select register" (in 18c it's one of three)
106 PO_INDF, // The Indirect register
107 PO_GPR_REGISTER, // A general purpose register
108 PO_GPR_BIT, // A bit of a general purpose register
109 PO_GPR_TEMP, // A general purpose temporary register
110 PO_SFR_REGISTER, // A special function register (e.g. PORTA)
111 PO_PCL, // Program counter Low register
112 PO_PCLATH, // Program counter Latch high register
113 PO_LITERAL, // A constant
114 PO_IMMEDIATE, // (8051 legacy)
115 PO_DIR, // Direct memory (8051 legacy)
116 PO_CRY, // bit memory (8051 legacy)
117 PO_BIT, // bit operand.
118 PO_STR, // (8051 legacy)
120 PO_WILD // Wild card operand in peep optimizer
124 /*************************************************
127 * The "conditions" are bit-mapped flags that describe
128 * input and/or output conditions that are affected by
129 * the instructions. For example:
133 * This instruction depends upon 'SOME_REG'. Consequently
134 * it has the input condition PCC_REGISTER set to true.
136 * In addition, this instruction affects the Z bit in the
137 * status register and affects W. Thus the output conditions
138 * are the logical or:
139 * PCC_ZERO_BIT | PCC_W
141 * The conditions are intialized when the pCode for an
142 * instruction is created. They're subsequently used
143 * by the pCode optimizer determine state information
144 * in the program flow.
145 *************************************************/
148 #define PCC_REGISTER (1<<0)
151 #define PCC_DC (1<<3)
153 #define PCC_EXAMINE_PCOP (1<<5)
155 /***********************************************************************
159 * This is not a list of the PIC's opcodes per se, but instead
160 * an enumeration of all of the different types of pic opcodes.
162 ***********************************************************************/
166 POC_WILD=-1, /* Wild card - used in the pCode peep hole optimizer
167 * to represent ANY pic opcode */
218 /***********************************************************************
219 * PC_TYPE - pCode Types
220 ***********************************************************************/
224 PC_COMMENT=0, // pCode is a comment
225 PC_OPCODE, // PORT dependent opcode
226 PC_LABEL, // assembly label
227 PC_FUNCTION, // Function start or end
228 PC_WILD // wildcard - an opcode place holder
231 /************************************************/
232 /*************** Structures ********************/
233 /************************************************/
236 /*************************************************
239 The first step in optimizing pCode is determining
240 the program flow. This information is stored in
241 single-linked lists in the for of 'from' and 'to'
242 objects with in a pcode. For example, most instructions
243 don't involve any branching. So their from branch
244 points to the pCode immediately preceding them and
245 their 'to' branch points to the pcode immediately
246 following them. A skip instruction is an example of
247 a pcode that has multiple (in this case two) elements
248 in the 'to' branch. A 'label' pcode is an where there
249 may be multiple 'from' branches.
250 *************************************************/
252 typedef struct pBranch
254 struct pCode *pc; // Next pCode in a branch
255 struct pBranch *next; /* If more than one branch
256 * the next one is here */
260 /*************************************************
263 pCode Operand structure.
264 For those assembly instructions that have arguments,
265 the pCode will have a pCodeOp in which the argument
266 can be stored. For example
270 'some_register' will be stored/referenced in a pCodeOp
272 *************************************************/
274 typedef struct pCodeOp
281 typedef struct pCodeOpBit
285 unsigned int inBitSpace: 1; /* True if in bit space, else
286 just a bit of a register */
289 typedef struct pCodeOpLit
295 typedef struct pCodeOpLabel
301 typedef struct pCodeOpReg
303 pCodeOp pcop; // Can be either GPR or SFR
304 int rIdx; // Index into the register table
309 typedef struct pCodeOpRegBit
311 pCodeOpReg pcor; // The Register containing this bit
312 int bit; // 0-7 bit number.
313 PIC_OPTYPE subtype; // The type of this register.
317 /*************************************************
320 Here is the basic build block of a PIC instruction.
321 Each pic instruction will get allocated a pCode.
322 A linked list of pCodes makes a program.
324 **************************************************/
330 struct pCode *prev; // The pCode objects are linked together
331 struct pCode *next; // in doubly linked lists.
333 int seq; // sequence number
335 pBranch *from; // pCodes that execute before this one
336 pBranch *to; // pCodes that execute after
337 pBranch *label; // pCode instructions that have labels
339 struct pBlock *pb; // The pBlock that contains this pCode.
341 /* "virtual functions"
342 * The pCode structure is like a base class
343 * in C++. The subsequent structures that "inherit"
344 * the pCode structure will initialize these function
345 * pointers to something useful */
346 void (*analyze) (struct pCode *_this);
347 void (*destruct)(struct pCode *_this);
348 void (*print) (FILE *of,struct pCode *_this);
353 /*************************************************
355 **************************************************/
357 typedef struct pCodeComment
366 /*************************************************
369 Here we describe all the facets of a PIC instruction
370 (expansion for the 18cxxx is also provided).
372 **************************************************/
374 typedef struct pCodeInstruction
379 PIC_OPCODE op; // The opcode of the instruction.
381 char const * const mnemonic; // Pointer to mnemonic string
383 pCodeOp *pcop; // Operand
385 unsigned int num_ops;
386 unsigned int dest: 1; // If destination is W or F, then 1==F
387 unsigned int bit_inst: 1;
389 unsigned int inCond; // Input conditions for this instruction
390 unsigned int outCond; // Output conditions for this instruction
395 /*************************************************
397 **************************************************/
399 typedef struct pCodeLabel
409 /*************************************************
411 **************************************************/
413 typedef struct pCodeFunction
419 char *fname; /* If NULL, then this is the end of
420 a function. Otherwise, it's the
421 start and the name is contained
427 /*************************************************
429 **************************************************/
431 typedef struct pCodeWild
436 int id; /* Index into the wild card array of a peepBlock
437 * - this wild card will get expanded into that pCode
438 * that is stored at this index */
441 pCodeOp *operand; // Optional operand
442 pCodeOp *label; // Optional label
446 /*************************************************
449 Here are PIC program snippets. There's a strong
450 correlation between the eBBlocks and pBlocks.
451 SDCC subdivides a C program into managable chunks.
452 Each chunk becomes a eBBlock and ultimately in the
455 **************************************************/
457 typedef struct pBlock
459 memmap *cmemmap; /* The snippet is from this memmap */
460 char dbName; /* if cmemmap is NULL, then dbName will identify the block */
461 pCode *pcHead; /* A pointer to the first pCode in a link list of pCodes */
462 pCode *pcTail; /* A pointer to the last pCode in a link list of pCodes */
464 struct pBlock *next; /* The pBlocks will form a doubly linked list */
467 set *function_entries; /* dll of functions in this pblock */
472 unsigned visited:1; /* set true if traversed in call tree */
474 unsigned seq; /* sequence number of this pBlock */
478 /*************************************************
481 The collection of pBlock program snippets are
482 placed into a linked list that is implemented
483 in the pFile structure.
485 The pcode optimizer will parse the pFile.
487 **************************************************/
491 pBlock *pbHead; /* A pointer to the first pBlock */
492 pBlock *pbTail; /* A pointer to the last pBlock */
494 pBranch *functions; /* A SLL of functions in this pFile */
500 /*************************************************
503 The pCodePeep object mimics the peep hole optimizer
504 in the main SDCC src (e.g. SDCCpeeph.c). Essentially
505 there is a target pCode chain and a replacement
506 pCode chain. The target chain is compared to the
507 pCode that is generated by gen.c. If a match is
508 found then the pCode is replaced by the replacement
510 **************************************************/
511 typedef struct pCodePeep {
513 pBlock *target; // code we'd like to optimize
514 pBlock *replace; // and this is what we'll optimize it with.
516 int nvars; // Number of wildcard registers in target.
517 char **vars; // array of pointers to them
518 int nops; // Number of wildcard operands in target.
519 pCodeOp **wildpCodeOps; // array of pointers to the pCodeOp's.
521 int nwildpCodes; // Number of wildcard pCodes in target/replace
522 pCode **wildpCodes; // array of pointers to the pCode's.
525 /* (Note: a wildcard register is a place holder. Any register
526 * can be replaced by the wildcard when the pcode is being
527 * compared to the target. */
529 /* Post Conditions. A post condition is a condition that
530 * must be either true or false before the peep rule is
531 * accepted. For example, a certain rule may be accepted
532 * if and only if the Z-bit is not used as an input to
533 * the subsequent instructions in a pCode chain.
535 unsigned int postFalseCond;
536 unsigned int postTrueCond;
540 typedef struct pCodeOpWild
543 //PIC_OPTYPE subtype; Wild get's expanded to this by the optimizer
544 pCodePeep *pcp; // pointer to the parent peep block
545 int id; /* index into an array of char *'s that will match
546 * the wild card. The array is in *pcp. */
547 pCodeOp *subtype; /* Pointer to the Operand type into which this wild
548 * card will be expanded */
549 pCodeOp *matched; /* When a wild matches, we'll store a pointer to the
550 * opcode we matched */
554 /*************************************************
557 **************************************************/
558 #define PCODE(x) ((pCode *)(x))
559 #define PCI(x) ((pCodeInstruction *)(x))
560 #define PCL(x) ((pCodeLabel *)(x))
561 #define PCF(x) ((pCodeFunction *)(x))
562 #define PCW(x) ((pCodeWild *)(x))
564 #define PCOP(x) ((pCodeOp *)(x))
565 #define PCOB(x) ((pCodeOpBit *)(x))
566 #define PCOL(x) ((pCodeOpLit *)(x))
567 #define PCOLAB(x) ((pCodeOpLabel *)(x))
568 #define PCOR(x) ((pCodeOpReg *)(x))
569 #define PCORB(x) ((pCodeOpRegBit *)(x))
570 #define PCOW(x) ((pCodeOpWild *)(x))
572 #define PBR(x) ((pBranch *)(x))
574 /*-----------------------------------------------------------------*
576 *-----------------------------------------------------------------*/
578 pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop); // Create a new pCode given an operand
579 pCode *newpCodeCharP(char *cP); // Create a new pCode given a char *
580 pCode *newpCodeFunction(char *g, char *f); // Create a new function
581 pCode *newpCodeLabel(int key); // Create a new label given a key
582 pCode *newpCodeLabelStr(char *str); // Create a new label given a string
583 pBlock *newpCodeChain(memmap *cm,char c, pCode *pc); // Create a new pBlock
584 void printpBlock(FILE *of, pBlock *pb); // Write a pBlock to a file
585 void printpCode(FILE *of, pCode *pc); // Write a pCode to a file
586 void addpCode2pBlock(pBlock *pb, pCode *pc); // Add a pCode to a pBlock
587 void addpBlock(pBlock *pb); // Add a pBlock to a pFile
588 void copypCode(FILE *of, char dbName); // Write all pBlocks with dbName to *of
589 void movepBlock2Head(char dbName); // move pBlocks around
590 void AnalyzepCode(char dbName);
591 void OptimizepCode(char dbName);
592 void printCallTree(FILE *of);
593 void pCodePeepInit(void);
595 pCodeOp *newpCodeOpLabel(int key);
596 pCodeOp *newpCodeOpLit(int lit);
597 pCodeOp *newpCodeOpBit(char *name, int bit,int inBitSpace);
598 pCodeOp *newpCodeOp(char *name, PIC_OPTYPE p);
599 extern void pcode_test(void);
601 /*-----------------------------------------------------------------*
603 *-----------------------------------------------------------------*/
605 extern pCodeOpReg pc_status;
606 extern pCodeOpReg pc_indf;
607 extern pCodeOpReg pc_fsr;
608 extern pCodeOpReg pc_pcl;
609 extern pCodeOpReg pc_pclath;
610 extern pCodeOpReg pc_kzero;
613 //////////////////// DELETE THIS ///////////////////
614 /*-----------------------------------------------------------------*/
615 /* Allocation macros that replace those in SDCCalloc.h */
616 /* Why? I dunno. I ran across a bug with those macros that */
617 /* I couldn't fix, but I could work around... */
618 /*-----------------------------------------------------------------*/
619 # define GC_malloc(x) calloc((x), 1)
621 #define _ALLOC(x,sz) if (!(x = calloc((sz),1) )) \
623 werror(E_OUT_OF_MEM,__FILE__,(long) sz);\
627 #define _ALLOC_ATOMIC(x,y) if (!((x) = malloc(y))) \
629 werror(E_OUT_OF_MEM,__FILE__,(long) y); \
633 #endif // __PCODE_H__