Pointers - Applied function ptr patch from Steve Tell. Fixed bugs with
[fw/sdcc] / src / pic / pcode.h
1 /*-------------------------------------------------------------------------
2
3    pcode.h - post code generation
4    Written By -  Scott Dattalo scott@dattalo.com
5
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
9    later version.
10    
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.
15    
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.
19    
20 -------------------------------------------------------------------------*/
21
22 //#include "ralloc.h"
23 struct regs;
24
25 /*
26    Post code generation
27
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:
38
39    example1:
40      movwf  t1
41      movf   t1,w
42
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:
48
49    example2:
50      movwf  t1
51      movf   t1,w     ; Can't remove this movf
52      skpz
53       return
54
55    example3:
56      movwf  t1
57      movf   t1,w     ; This  movf can be removed
58      xorwf  t2,w     ; since xorwf will over write Z 
59      skpz
60       return
61
62 */
63
64
65 #ifndef __PCODE_H__
66 #define __PCODE_H__
67
68 /***********************************************************************
69  * debug stuff
70  * 
71  * The DFPRINTF macro will call fprintf if PCODE_DEBUG is defined.
72  * The macro is used like:
73  *
74  * DPRINTF(("%s #%d\n","test", 1));
75  *
76  * The double parenthesis (()) are necessary
77  * 
78  ***********************************************************************/
79 //#define PCODE_DEBUG
80
81 #ifdef PCODE_DEBUG
82 #define DFPRINTF(args) (fprintf args)
83 #else
84 #define DFPRINTF(args) ;
85 #endif
86
87
88 /***********************************************************************
89  *  PIC status bits - this will move into device dependent headers
90  ***********************************************************************/
91 #define PIC_C_BIT    0
92 #define PIC_DC_BIT   1
93 #define PIC_Z_BIT    2
94 #define PIC_RP0_BIT  5   /* Register Bank select bits RP1:0 : */
95 #define PIC_RP1_BIT  6   /* 00 - bank 0, 01 - bank 1, 10 - bank 2, 11 - bank 3 */
96 #define PIC_IRP_BIT  7   /* Indirect register page select */
97
98 /***********************************************************************
99  *  PIC INTCON bits - this will move into device dependent headers
100  ***********************************************************************/
101 #define PIC_RBIF_BIT 0   /* Port B level has changed flag */
102 #define PIC_INTF_BIT 1   /* Port B bit 0 interrupt on edge flag */
103 #define PIC_T0IF_BIT 2   /* TMR0 has overflowed flag */
104 #define PIC_RBIE_BIT 3   /* Port B level has changed - Interrupt Enable */
105 #define PIC_INTE_BIT 4   /* Port B bit 0 interrupt on edge - Int Enable */
106 #define PIC_T0IE_BIT 5   /* TMR0 overflow Interrupt Enable */
107 #define PIC_PIE_BIT  6   /* Peripheral Interrupt Enable */
108 #define PIC_GIE_BIT  7   /* Global Interrupt Enable */
109
110 /***********************************************************************
111  *  Operand types 
112  ***********************************************************************/
113 #define POT_RESULT  0
114 #define POT_LEFT    1
115 #define POT_RIGHT   2
116
117
118 /***********************************************************************
119  *
120  *  PIC_OPTYPE - Operand types that are specific to the PIC architecture
121  *
122  *  If a PIC assembly instruction has an operand then here is where we
123  *  associate a type to it. For example,
124  *
125  *     movf    reg,W
126  *
127  *  The movf has two operands: 'reg' and the W register. 'reg' is some
128  *  arbitrary general purpose register, hence it has the type PO_GPR_REGISTER.
129  *  The W register, which is the PIC's accumulator, has the type PO_W.
130  *
131  ***********************************************************************/
132
133
134
135 typedef enum 
136 {
137   PO_NONE=0,         // No operand e.g. NOP
138   PO_W,              // The 'W' register
139   PO_STATUS,         // The 'STATUS' register
140   PO_FSR,            // The "file select register" (in 18c it's one of three)
141   PO_INDF,           // The Indirect register
142   PO_INTCON,         // Interrupt Control register
143   PO_GPR_REGISTER,   // A general purpose register
144   PO_GPR_BIT,        // A bit of a general purpose register
145   PO_GPR_TEMP,       // A general purpose temporary register
146   PO_GPR_POINTER,    // A general purpose pointer
147   PO_SFR_REGISTER,   // A special function register (e.g. PORTA)
148   PO_PCL,            // Program counter Low register
149   PO_PCLATH,         // Program counter Latch high register
150   PO_LITERAL,        // A constant
151   PO_IMMEDIATE,      //  (8051 legacy)
152   PO_DIR,            // Direct memory (8051 legacy)
153   PO_CRY,            // bit memory (8051 legacy)
154   PO_BIT,            // bit operand.
155   PO_STR,            //  (8051 legacy)
156   PO_LABEL,
157   PO_WILD            // Wild card operand in peep optimizer
158 } PIC_OPTYPE;
159
160
161 /***********************************************************************
162  *
163  *  PIC_OPCODE
164  *
165  *  This is not a list of the PIC's opcodes per se, but instead
166  *  an enumeration of all of the different types of pic opcodes. 
167  *
168  ***********************************************************************/
169
170 typedef enum
171 {
172   POC_WILD=-1,   /* Wild card - used in the pCode peep hole optimizer
173                   * to represent ANY pic opcode */
174   POC_ADDLW=0,
175   POC_ADDWF,
176   POC_ADDFW,
177   POC_ANDLW,
178   POC_ANDWF,
179   POC_ANDFW,
180   POC_BCF,
181   POC_BSF,
182   POC_BTFSC,
183   POC_BTFSS,
184   POC_CALL,
185   POC_COMF,
186   POC_COMFW,
187   POC_CLRF,
188   POC_CLRW,
189   POC_CLRWDT,
190   POC_DECF,
191   POC_DECFW,
192   POC_DECFSZ,
193   POC_DECFSZW,
194   POC_GOTO,
195   POC_INCF,
196   POC_INCFW,
197   POC_INCFSZ,
198   POC_INCFSZW,
199   POC_IORLW,
200   POC_IORWF,
201   POC_IORFW,
202   POC_MOVF,
203   POC_MOVFW,
204   POC_MOVLW,
205   POC_MOVWF,
206   POC_NOP,
207   POC_RETLW,
208   POC_RETURN,
209   POC_RETFIE,
210   POC_RLF,
211   POC_RLFW,
212   POC_RRF,
213   POC_RRFW,
214   POC_SUBLW,
215   POC_SUBWF,
216   POC_SUBFW,
217   POC_SWAPF,
218   POC_SWAPFW,
219   POC_TRIS,
220   POC_XORLW,
221   POC_XORWF,
222   POC_XORFW
223 } PIC_OPCODE;
224
225
226 /***********************************************************************
227  *  PC_TYPE  - pCode Types
228  ***********************************************************************/
229
230 typedef enum
231 {
232   PC_COMMENT=0,   /* pCode is a comment     */
233   PC_INLINE,      /* user's inline code     */
234   PC_OPCODE,      /* PORT dependent opcode  */
235   PC_LABEL,       /* assembly label         */
236   PC_FLOW,        /* flow analysis          */
237   PC_FUNCTION,    /* Function start or end  */
238   PC_WILD,        /* wildcard - an opcode place holder used 
239                    * in the pCode peep hole optimizer */
240   PC_CSOURCE,     /* C-Source Line  */
241   PC_BAD          /* Mark the pCode object as being bad */
242 } PC_TYPE;
243
244 /************************************************/
245 /***************  Structures ********************/
246 /************************************************/
247 /* These are here as forward references - the 
248  * full definition of these are below           */
249 struct pCode;
250 struct pCodeWildBlock;
251 struct pCodeRegLives;
252
253 /*************************************************
254   pBranch
255
256   The first step in optimizing pCode is determining
257  the program flow. This information is stored in
258  single-linked lists in the for of 'from' and 'to'
259  objects with in a pcode. For example, most instructions
260  don't involve any branching. So their from branch
261  points to the pCode immediately preceding them and
262  their 'to' branch points to the pcode immediately
263  following them. A skip instruction is an example of
264  a pcode that has multiple (in this case two) elements
265  in the 'to' branch. A 'label' pcode is an where there
266  may be multiple 'from' branches.
267  *************************************************/
268
269 typedef struct pBranch
270 {
271   struct pCode   *pc;    // Next pCode in a branch
272   struct pBranch *next;  /* If more than one branch
273                           * the next one is here */
274
275 } pBranch;
276
277 /*************************************************
278   pCodeOp
279
280   pCode Operand structure.
281   For those assembly instructions that have arguments, 
282   the pCode will have a pCodeOp in which the argument
283   can be stored. For example
284
285     movf   some_register,w
286
287   'some_register' will be stored/referenced in a pCodeOp
288
289  *************************************************/
290
291 typedef struct pCodeOp
292 {
293   PIC_OPTYPE type;
294   char *name;
295   
296 } pCodeOp;
297 #if 0
298 typedef struct pCodeOpBit
299 {
300   pCodeOp pcop;
301   int bit;
302   unsigned int inBitSpace: 1; /* True if in bit space, else
303                                  just a bit of a register */
304 } pCodeOpBit;
305 #endif
306 typedef struct pCodeOpLit
307 {
308   pCodeOp pcop;
309   int lit;
310 } pCodeOpLit;
311
312 typedef struct pCodeOpImmd
313 {
314   pCodeOp pcop;
315   int offset;           /* low,med, or high byte of immediat value */
316   int index;            /* add this to the immediate value */
317   unsigned _const:1;    /* is in code space    */
318
319   int rIdx;             /* If this immd points to a register */
320   struct regs *r;       /* then this is the reg. */
321
322 } pCodeOpImmd;
323
324 typedef struct pCodeOpLabel
325 {
326   pCodeOp pcop;
327   int key;
328 } pCodeOpLabel;
329
330 typedef struct pCodeOpReg
331 {
332   pCodeOp pcop;    // Can be either GPR or SFR
333   int rIdx;        // Index into the register table
334   struct regs *r;
335   int instance;    // byte # of Multi-byte registers
336   struct pBlock *pb;
337 } pCodeOpReg;
338
339 typedef struct pCodeOpRegBit
340 {
341   pCodeOpReg  pcor;       // The Register containing this bit
342   int bit;                // 0-7 bit number.
343   PIC_OPTYPE subtype;     // The type of this register.
344   unsigned int inBitSpace: 1; /* True if in bit space, else
345                                  just a bit of a register */
346 } pCodeOpRegBit;
347
348
349 typedef struct pCodeOpRegPtr
350 {
351   pCodeOpReg  pcor;       // The Register containing this bit
352
353   //  PIC_OPTYPE subtype;     // The type of this register.
354   //  unsigned int inBitSpace: 1; /* True if in bit space, else
355
356 } pCodeOpRegPtr;
357
358 typedef struct pCodeOpWild
359 {
360   pCodeOp pcop;
361
362   struct pCodeWildBlock *pcwb;
363
364   int id;                 /* index into an array of char *'s that will match
365                            * the wild card. The array is in *pcp. */
366   pCodeOp *subtype;       /* Pointer to the Operand type into which this wild
367                            * card will be expanded */
368   pCodeOp *matched;       /* When a wild matches, we'll store a pointer to the
369                            * opcode we matched */
370
371 } pCodeOpWild;
372
373
374 /*************************************************
375     pCode
376
377     Here is the basic build block of a PIC instruction.
378     Each pic instruction will get allocated a pCode.
379     A linked list of pCodes makes a program.
380
381 **************************************************/
382
383 typedef struct pCode
384 {
385   PC_TYPE    type;
386
387   struct pCode *prev;  // The pCode objects are linked together
388   struct pCode *next;  // in doubly linked lists.
389
390   int seq;             // sequence number
391
392   struct pBlock *pb;   // The pBlock that contains this pCode.
393
394   /* "virtual functions"
395    *  The pCode structure is like a base class
396    * in C++. The subsequent structures that "inherit"
397    * the pCode structure will initialize these function
398    * pointers to something useful */
399   //  void (*analyze) (struct pCode *_this);
400   void (*destruct)(struct pCode *_this);
401   void (*print)  (FILE *of,struct pCode *_this);
402
403 } pCode;
404
405
406 /*************************************************
407     pCodeComment
408 **************************************************/
409
410 typedef struct pCodeComment
411 {
412
413   pCode  pc;
414
415   char *comment;
416
417 } pCodeComment;
418
419 /*************************************************
420     pCodeComment
421 **************************************************/
422
423 typedef struct pCodeCSource
424 {
425
426   pCode  pc;
427
428   int  line_number;
429   char *line;
430   char *file_name;
431
432 } pCodeCSource;
433
434
435 /*************************************************
436     pCodeFlow
437
438   The Flow object is used as marker to separate 
439  the assembly code into contiguous chunks. In other
440  words, everytime an instruction cause or potentially
441  causes a branch, a Flow object will be inserted into
442  the pCode chain to mark the beginning of the next
443  contiguous chunk.
444
445 **************************************************/
446
447 typedef struct pCodeFlow
448 {
449
450   pCode  pc;
451
452   pCode *end;   /* Last pCode in this flow. Note that
453                    the first pCode is pc.next */
454
455   /*  set **uses;   * map the pCode instruction inCond and outCond conditions 
456                  * in this array of set's. The reason we allocate an 
457                  * array of pointers instead of declaring each type of 
458                  * usage is because there are port dependent usage definitions */
459   //int nuses;    /* number of uses sets */
460
461   set *from;    /* flow blocks that can send control to this flow block */
462   set *to;      /* flow blocks to which this one can send control */
463   struct pCodeFlow *ancestor; /* The most immediate "single" pCodeFlow object that
464                                * executes prior to this one. In many cases, this 
465                                * will be just the previous */
466
467   int inCond;   /* Input conditions - stuff assumed defined at entry */
468   int outCond;  /* Output conditions - stuff modified by flow block */
469
470   int firstBank; /* The first and last bank flags are the first and last */
471   int lastBank;  /* register banks used within one flow object */
472
473   int FromConflicts;
474   int ToConflicts;
475
476   set *registers;/* Registers used in this flow */
477
478 } pCodeFlow;
479
480 /*************************************************
481   pCodeFlowLink
482
483   The Flow Link object is used to record information
484  about how consecutive excutive Flow objects are related.
485  The pCodeFlow objects demarcate the pCodeInstructions
486  into contiguous chunks. The FlowLink records conflicts
487  in the discontinuities. For example, if one Flow object
488  references a register in bank 0 and the next Flow object
489  references a register in bank 1, then there is a discontinuity
490  in the banking registers.
491
492 */
493 typedef struct pCodeFlowLink
494 {
495   pCodeFlow  *pcflow;   /* pointer to linked pCodeFlow object */
496
497   int bank_conflict;    /* records bank conflicts */
498
499 } pCodeFlowLink;
500
501 /*************************************************
502     pCodeInstruction
503
504     Here we describe all the facets of a PIC instruction
505     (expansion for the 18cxxx is also provided).
506
507 **************************************************/
508
509 typedef struct pCodeInstruction
510 {
511
512   pCode  pc;
513
514   PIC_OPCODE op;        // The opcode of the instruction.
515
516   char const * const mnemonic;       // Pointer to mnemonic string
517
518   pBranch *from;       // pCodes that execute before this one
519   pBranch *to;         // pCodes that execute after
520   pBranch *label;      // pCode instructions that have labels
521
522   pCodeOp *pcop;               /* Operand, if this instruction has one */
523   pCodeFlow *pcflow;           /* flow block to which this instruction belongs */
524   pCodeCSource *cline;         /* C Source from which this instruction was derived */
525
526   unsigned int num_ops;        /* Number of operands (0,1,2 for mid range pics) */
527   unsigned int isModReg:  1;   /* If destination is W or F, then 1==F */
528   unsigned int isBitInst: 1;   /* e.g. BCF */
529   unsigned int isBranch:  1;   /* True if this is a branching instruction */
530   unsigned int isSkip:    1;   /* True if this is a skip instruction */
531   unsigned int isLit:     1;   /* True if this instruction has an literal operand */
532
533   PIC_OPCODE inverted_op;      /* Opcode of instruction that's the opposite of this one */
534   unsigned int inCond;   // Input conditions for this instruction
535   unsigned int outCond;  // Output conditions for this instruction
536
537 } pCodeInstruction;
538
539
540 /*************************************************
541     pCodeLabel
542 **************************************************/
543
544 typedef struct pCodeLabel
545 {
546
547   pCode  pc;
548
549   char *label;
550   int key;
551
552 } pCodeLabel;
553
554 /*************************************************
555     pCodeFunction
556 **************************************************/
557
558 typedef struct pCodeFunction
559 {
560
561   pCode  pc;
562
563   char *modname;
564   char *fname;     /* If NULL, then this is the end of
565                       a function. Otherwise, it's the
566                       start and the name is contained
567                       here */
568
569   pBranch *from;       // pCodes that execute before this one
570   pBranch *to;         // pCodes that execute after
571   pBranch *label;      // pCode instructions that have labels
572
573   int  ncalled;    /* Number of times function is called */
574
575 } pCodeFunction;
576
577
578 /*************************************************
579     pCodeWild
580 **************************************************/
581
582 typedef struct pCodeWild
583 {
584
585   pCodeInstruction  pci;
586
587   int    id;     /* Index into the wild card array of a peepBlock 
588                   * - this wild card will get expanded into that pCode
589                   *   that is stored at this index */
590
591   /* Conditions on wild pcode instruction */
592   int    mustBeBitSkipInst:1;
593   int    mustNotBeBitSkipInst:1;
594   int    invertBitSkipInst:1;
595
596   pCodeOp *operand;  // Optional operand
597   pCodeOp *label;    // Optional label
598
599 } pCodeWild;
600
601 /*************************************************
602     pBlock
603
604     Here are PIC program snippets. There's a strong
605     correlation between the eBBlocks and pBlocks.
606     SDCC subdivides a C program into managable chunks.
607     Each chunk becomes a eBBlock and ultimately in the
608     PIC port a pBlock.
609
610 **************************************************/
611
612 typedef struct pBlock
613 {
614   memmap *cmemmap;   /* The snippet is from this memmap */
615   char   dbName;     /* if cmemmap is NULL, then dbName will identify the block */
616   pCode *pcHead;     /* A pointer to the first pCode in a link list of pCodes */
617   pCode *pcTail;     /* A pointer to the last pCode in a link list of pCodes */
618
619   struct pBlock *next;      /* The pBlocks will form a doubly linked list */
620   struct pBlock *prev;
621
622   set *function_entries;    /* dll of functions in this pblock */
623   set *function_exits;
624   set *function_calls;
625   set *tregisters;
626
627   set *FlowTree;
628   unsigned visited:1;       /* set true if traversed in call tree */
629
630   unsigned seq;             /* sequence number of this pBlock */
631
632 } pBlock;
633
634 /*************************************************
635     pFile
636
637     The collection of pBlock program snippets are
638     placed into a linked list that is implemented
639     in the pFile structure.
640
641     The pcode optimizer will parse the pFile.
642
643 **************************************************/
644
645 typedef struct pFile
646 {
647   pBlock *pbHead;     /* A pointer to the first pBlock */
648   pBlock *pbTail;     /* A pointer to the last pBlock */
649
650   pBranch *functions; /* A SLL of functions in this pFile */
651
652 } pFile;
653
654
655
656 /*************************************************
657   pCodeWildBlock
658
659   The pCodeWildBlock object keeps track of the wild
660   variables, operands, and opcodes that exist in
661   a pBlock.
662 **************************************************/
663 typedef struct pCodeWildBlock {
664   pBlock    *pb;
665   struct pCodePeep *pcp;    // pointer back to ... I don't like this...
666
667   int       nvars;          // Number of wildcard registers in target.
668   char    **vars;           // array of pointers to them
669
670   int       nops;           // Number of wildcard operands in target.
671   pCodeOp **wildpCodeOps;   // array of pointers to the pCodeOp's.
672
673   int       nwildpCodes;    // Number of wildcard pCodes in target/replace
674   pCode   **wildpCodes;     // array of pointers to the pCode's.
675
676 } pCodeWildBlock;
677
678 /*************************************************
679   pCodePeep
680
681   The pCodePeep object mimics the peep hole optimizer
682   in the main SDCC src (e.g. SDCCpeeph.c). Essentially
683   there is a target pCode chain and a replacement
684   pCode chain. The target chain is compared to the
685   pCode that is generated by gen.c. If a match is
686   found then the pCode is replaced by the replacement
687   pCode chain.
688 **************************************************/
689 typedef struct pCodePeep {
690   pCodeWildBlock target;     // code we'd like to optimize
691   pCodeWildBlock replace;    // and this is what we'll optimize it with.
692
693   //pBlock *target;
694   //pBlock replace;            // and this is what we'll optimize it with.
695
696
697
698   /* (Note: a wildcard register is a place holder. Any register
699    * can be replaced by the wildcard when the pcode is being 
700    * compared to the target. */
701
702   /* Post Conditions. A post condition is a condition that
703    * must be either true or false before the peep rule is
704    * accepted. For example, a certain rule may be accepted
705    * if and only if the Z-bit is not used as an input to 
706    * the subsequent instructions in a pCode chain.
707    */
708   unsigned int postFalseCond;  
709   unsigned int postTrueCond;
710
711 } pCodePeep;
712
713 /*************************************************
714
715   pCode peep command definitions 
716
717  Here are some special commands that control the
718 way the peep hole optimizer behaves
719
720 **************************************************/
721
722 enum peepCommandTypes{
723   NOTBITSKIP = 0,
724   BITSKIP,
725   INVERTBITSKIP,
726   _LAST_PEEP_COMMAND_
727 };
728
729 /*************************************************
730     peepCommand structure stores the peep commands.
731
732 **************************************************/
733
734 typedef struct peepCommand {
735   int id;
736   char *cmd;
737 } peepCommand;
738
739 /*************************************************
740     pCode Macros
741
742 **************************************************/
743 #define PCODE(x)  ((pCode *)(x))
744 #define PCI(x)    ((pCodeInstruction *)(x))
745 #define PCL(x)    ((pCodeLabel *)(x))
746 #define PCF(x)    ((pCodeFunction *)(x))
747 #define PCFL(x)   ((pCodeFlow *)(x))
748 #define PCFLINK(x)((pCodeFlowLink *)(x))
749 #define PCW(x)    ((pCodeWild *)(x))
750 #define PCCS(x)   ((pCodeCSource *)(x))
751
752 #define PCOP(x)   ((pCodeOp *)(x))
753 //#define PCOB(x)   ((pCodeOpBit *)(x))
754 #define PCOL(x)   ((pCodeOpLit *)(x))
755 #define PCOI(x)   ((pCodeOpImmd *)(x))
756 #define PCOLAB(x) ((pCodeOpLabel *)(x))
757 #define PCOR(x)   ((pCodeOpReg *)(x))
758 #define PCORB(x)  ((pCodeOpRegBit *)(x))
759 #define PCOW(x)   ((pCodeOpWild *)(x))
760
761 #define PBR(x)    ((pBranch *)(x))
762
763 #define PCWB(x)   ((pCodeWildBlock *)(x))
764
765
766 /*
767   macros for checking pCode types
768 */
769 #define isPCI(x)        ((PCODE(x)->type == PC_OPCODE))
770 #define isPCI_BRANCH(x) ((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isBranch)
771 #define isPCI_SKIP(x)   ((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isSkip)
772 #define isPCI_LIT(x)    ((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isLit)
773 #define isPCI_BITSKIP(x)((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isSkip && PCI(x)->isBitInst)
774 #define isPCFL(x)       ((PCODE(x)->type == PC_FLOW))
775 #define isPCF(x)        ((PCODE(x)->type == PC_FUNCTION))
776 #define isPCL(x)        ((PCODE(x)->type == PC_LABEL))
777 #define isPCW(x)        ((PCODE(x)->type == PC_WILD))
778 #define isPCCS(x)       ((PCODE(x)->type == PC_CSOURCE))
779
780 #define isCALL(x)       ((isPCI(x)) && (PCI(x)->op == POC_CALL))
781 #define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS)
782
783 #define isPCOLAB(x)     ((PCOP(x)->type) == PO_LABEL)
784
785 /*-----------------------------------------------------------------*
786  * pCode functions.
787  *-----------------------------------------------------------------*/
788
789 pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop); // Create a new pCode given an operand
790 pCode *newpCodeCharP(char *cP);              // Create a new pCode given a char *
791 pCode *newpCodeInlineP(char *cP);            // Create a new pCode given a char *
792 pCode *newpCodeFunction(char *g, char *f);   // Create a new function
793 pCode *newpCodeLabel(char *name,int key);    // Create a new label given a key
794 pCode *newpCodeCSource(int ln, char *f, char *l); // Create a new symbol line 
795 pBlock *newpCodeChain(memmap *cm,char c, pCode *pc); // Create a new pBlock
796 void printpBlock(FILE *of, pBlock *pb);      // Write a pBlock to a file
797 void printpCode(FILE *of, pCode *pc);        // Write a pCode to a file
798 void addpCode2pBlock(pBlock *pb, pCode *pc); // Add a pCode to a pBlock
799 void addpBlock(pBlock *pb);                  // Add a pBlock to a pFile
800 void copypCode(FILE *of, char dbName);       // Write all pBlocks with dbName to *of
801 void movepBlock2Head(char dbName);           // move pBlocks around
802 void AnalyzepCode(char dbName);
803 int OptimizepCode(char dbName);
804 void printCallTree(FILE *of);
805 void pCodePeepInit(void);
806 void pBlockConvert2ISR(pBlock *pb);
807
808 pCodeOp *newpCodeOpLabel(char *name, int key);
809 pCodeOp *newpCodeOpImmd(char *name, int offset, int index, int code_space);
810 pCodeOp *newpCodeOpLit(int lit);
811 pCodeOp *newpCodeOpBit(char *name, int bit,int inBitSpace);
812 pCodeOp *newpCodeOpRegFromStr(char *name);
813 pCodeOp *newpCodeOp(char *name, PIC_OPTYPE p);
814 pCodeOp *pCodeOpCopy(pCodeOp *pcop);
815
816 pCode * findNextInstruction(pCode *pci);
817 pCode * findNextpCode(pCode *pc, PC_TYPE pct);
818 int isPCinFlow(pCode *pc, pCode *pcflow);
819 struct regs * getRegFromInstruction(pCode *pc);
820
821 extern void pcode_test(void);
822
823 /*-----------------------------------------------------------------*
824  * pCode objects.
825  *-----------------------------------------------------------------*/
826
827 extern pCodeOpReg pc_status;
828 extern pCodeOpReg pc_intcon;
829 extern pCodeOpReg pc_indf;
830 extern pCodeOpReg pc_fsr;
831 extern pCodeOpReg pc_pcl;
832 extern pCodeOpReg pc_pclath;
833 extern pCodeOpReg pc_kzero;
834 extern pCodeOpReg pc_wsave;     /* wsave and ssave are used to save W and the Status */
835 extern pCodeOpReg pc_ssave;     /* registers during an interrupt */
836
837
838 #endif // __PCODE_H__