* src/pic16/pcode.h: added second memory operand to pCodeOpReg
[fw/sdcc] / src / pic16 / pcode.h
1 /*-------------------------------------------------------------------------
2
3    pcode.h - post code generation
4    Written By -  Scott Dattalo scott@dattalo.com
5    Ported to PIC16 By -  Martin Dubuc m.dubuc@rogers.com
6
7    This program is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by the
9    Free Software Foundation; either version 2, or (at your option) any
10    later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20    
21 -------------------------------------------------------------------------*/
22
23 //#include "ralloc.h"
24 struct regs;
25
26 /*
27    Post code generation
28
29    The post code generation is an assembler optimizer. The assembly code
30    produced by all of the previous steps is fully functional. This step
31    will attempt to analyze the flow of the assembly code and agressively 
32    optimize it. The peep hole optimizer attempts to do the same thing.
33    As you may recall, the peep hole optimizer replaces blocks of assembly
34    with more optimal blocks (e.g. removing redundant register loads).
35    However, the peep hole optimizer has to be somewhat conservative since
36    an assembly program has implicit state information that's unavailable 
37    when only a few instructions are examined.
38      Consider this example:
39
40    example1:
41      movwf  t1
42      movf   t1,w
43
44    The movf seems redundant since we know that the W register already
45    contains the same value of t1. So a peep hole optimizer is tempted to
46    remove the "movf". However, this is dangerous since the movf affects
47    the flags in the status register (specifically the Z flag) and subsequent
48    code may depend upon this. Look at these two examples:
49
50    example2:
51      movwf  t1
52      movf   t1,w     ; Can't remove this movf
53      skpz
54       return
55
56    example3:
57      movwf  t1
58      movf   t1,w     ; This  movf can be removed
59      xorwf  t2,w     ; since xorwf will over write Z 
60      skpz
61       return
62
63 */
64
65
66 #ifndef __PCODE_H__
67 #define __PCODE_H__
68
69 /***********************************************************************
70  * debug stuff
71  * 
72  * The DFPRINTF macro will call fprintf if PCODE_DEBUG is defined.
73  * The macro is used like:
74  *
75  * DPRINTF(("%s #%d\n","test", 1));
76  *
77  * The double parenthesis (()) are necessary
78  * 
79  ***********************************************************************/
80 //#define PCODE_DEBUG
81
82 #ifdef PCODE_DEBUG
83 #define DFPRINTF(args) (fprintf args)
84 #else
85 #define DFPRINTF(args) ;
86 #endif
87
88
89 /***********************************************************************
90  *  PIC status bits - this will move into device dependent headers
91  ***********************************************************************/
92 #define PIC_C_BIT    0
93 #define PIC_DC_BIT   1
94 #define PIC_Z_BIT    2
95 #define PIC_OV_BIT   3
96 #define PIC_N_BIT    4
97 #define PIC_IRP_BIT  7   /* Indirect register page select */
98
99 /***********************************************************************
100  *  PIC INTCON bits - this will move into device dependent headers
101  ***********************************************************************/
102 #define PIC_RBIF_BIT 0   /* Port B level has changed flag */
103 #define PIC_INTF_BIT 1   /* Port B bit 0 interrupt on edge flag */
104 #define PIC_T0IF_BIT 2   /* TMR0 has overflowed flag */
105 #define PIC_RBIE_BIT 3   /* Port B level has changed - Interrupt Enable */
106 #define PIC_INTE_BIT 4   /* Port B bit 0 interrupt on edge - Int Enable */
107 #define PIC_T0IE_BIT 5   /* TMR0 overflow Interrupt Enable */
108 #define PIC_PIE_BIT  6   /* Peripheral Interrupt Enable */
109 #define PIC_GIE_BIT  7   /* Global Interrupt Enable */
110
111 /***********************************************************************
112  *  PIC bank definitions
113  ***********************************************************************/
114 #define PIC_BANK_FIRST 0
115 #define PIC_BANK_LAST  0xf
116
117
118 /***********************************************************************
119  *  Operand types 
120  ***********************************************************************/
121 #define POT_RESULT  0
122 #define POT_LEFT    1
123 #define POT_RIGHT   2
124
125
126 /***********************************************************************
127  *
128  *  PIC_OPTYPE - Operand types that are specific to the PIC architecture
129  *
130  *  If a PIC assembly instruction has an operand then here is where we
131  *  associate a type to it. For example,
132  *
133  *     movf    reg,W
134  *
135  *  The movf has two operands: 'reg' and the W register. 'reg' is some
136  *  arbitrary general purpose register, hence it has the type PO_GPR_REGISTER.
137  *  The W register, which is the PIC's accumulator, has the type PO_W.
138  *
139  ***********************************************************************/
140
141
142
143 typedef enum 
144 {
145   PO_NONE=0,         // No operand e.g. NOP
146   PO_W,              // The working register (as a destination)
147   PO_WREG,           // The working register (as a file register)
148   PO_STATUS,         // The 'STATUS' register
149   PO_BSR,            // The 'BSR' register
150   PO_FSR0,           // The "file select register" (in PIC18 family it's one 
151                      // of three)
152   PO_INDF0,          // The Indirect register
153   PO_INTCON,         // Interrupt Control register
154   PO_GPR_REGISTER,   // A general purpose register
155   PO_GPR_BIT,        // A bit of a general purpose register
156   PO_GPR_TEMP,       // A general purpose temporary register
157   PO_SFR_REGISTER,   // A special function register (e.g. PORTA)
158   PO_PCL,            // Program counter Low register
159   PO_PCLATH,         // Program counter Latch high register
160   PO_PCLATU,         // Program counter Latch upper register
161   PO_PRODL,          // Product Register Low
162   PO_PRODH,          // Product Register High
163   PO_LITERAL,        // A constant
164   PO_REL_ADDR,       // A relative address
165   PO_IMMEDIATE,      //  (8051 legacy)
166   PO_DIR,            // Direct memory (8051 legacy)
167   PO_CRY,            // bit memory (8051 legacy)
168   PO_BIT,            // bit operand.
169   PO_STR,            //  (8051 legacy)
170   PO_LABEL,
171   PO_WILD            // Wild card operand in peep optimizer
172 } PIC_OPTYPE;
173
174
175 /***********************************************************************
176  *
177  *  PIC_OPCODE
178  *
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. 
181  *
182  ***********************************************************************/
183
184 typedef enum
185 {
186   POC_WILD=-1,   /* Wild card - used in the pCode peep hole optimizer
187                   * to represent ANY pic opcode */
188   POC_ADDLW=0,
189   POC_ADDWF,
190   POC_ADDFW,
191   POC_ADDFWC,
192   POC_ADDWFC,
193   POC_ANDLW,
194   POC_ANDWF,
195   POC_ANDFW,
196   POC_BC,
197   POC_BCF,
198   POC_BN,
199   POC_BNC,
200   POC_BNN,
201   POC_BNOV,
202   POC_BNZ,
203   POC_BOV,
204   POC_BRA,
205   POC_BSF,
206   POC_BTFSC,
207   POC_BTFSS,
208   POC_BTG,
209   POC_BZ,
210   POC_CALL,
211   POC_CLRF,
212   POC_CLRWDT,
213   POC_COMF,
214   POC_COMFW,
215   POC_CPFSEQ,
216   POC_CPFSGT,
217   POC_CPFSLT,
218   POC_DAW,
219   POC_DCFSNZ,
220   POC_DCFSNZW,
221   POC_DECF,
222   POC_DECFW,
223   POC_DECFSZ,
224   POC_DECFSZW,
225   POC_GOTO,
226   POC_INCF,
227   POC_INCFW,
228   POC_INCFSZ,
229   POC_INCFSZW,
230   POC_INFSNZ,
231   POC_INFSNZW,
232   POC_IORWF,
233   POC_IORFW,
234   POC_IORLW,
235   POC_LFSR,
236   POC_MOVF,
237   POC_MOVFW,
238   POC_MOVFF,
239   POC_MOVLB,
240   POC_MOVLW,
241   POC_MOVWF,
242   POC_MULLW,
243   POC_MULWF,
244   POC_NEGF,
245   POC_NOP,
246   POC_POP,
247   POC_PUSH,
248   POC_RCALL,
249   POC_RETFIE,
250   POC_RETLW,
251   POC_RETURN,
252   POC_RLCF,
253   POC_RLCFW,
254   POC_RLNCF,
255   POC_RLNCFW,
256   POC_RRCF,
257   POC_RRCFW,
258   POC_RRNCF,
259   POC_RRNCFW,
260   POC_SETF,
261   POC_SUBLW,
262   POC_SUBFWB,
263   POC_SUBWF,
264   POC_SUBFW,
265   POC_SUBWFB_D0,
266   POC_SUBWFB_D1,
267   POC_SUBFWB_D0,
268   POC_SUBFWB_D1,
269   POC_SWAPF,
270   POC_SWAPFW,
271   POC_TBLRD,
272   POC_TBLRD_POSTINC,
273   POC_TBLRD_POSTDEC,
274   POC_TBLRD_PREINC,
275   POC_TBLWT,
276   POC_TBLWT_POSTINC,
277   POC_TBLWT_POSTDEC,
278   POC_TBLWT_PREINC,
279   POC_TSTFSZ,
280   POC_XORLW,
281   POC_XORWF,
282   POC_XORFW,
283
284   POC_BANKSEL
285 } PIC_OPCODE;
286
287
288 /***********************************************************************
289  *  PC_TYPE  - pCode Types
290  ***********************************************************************/
291
292 typedef enum
293 {
294   PC_COMMENT=0,   /* pCode is a comment     */
295   PC_INLINE,      /* user's inline code     */
296   PC_OPCODE,      /* PORT dependent opcode  */
297   PC_LABEL,       /* assembly label         */
298   PC_FLOW,        /* flow analysis          */
299   PC_FUNCTION,    /* Function start or end  */
300   PC_WILD,        /* wildcard - an opcode place holder used 
301                    * in the pCode peep hole optimizer */
302   PC_CSOURCE,     /* C-Source Line  */
303   PC_ASMDIR,      /* Assembler directive */
304   PC_BAD,         /* Mark the pCode object as being bad */
305   PC_INFO         /* pCode informatio node, used primarily in optimizing */
306 } PC_TYPE;
307
308
309 /***********************************************************************
310  *  INFO_TYPE  - information node types
311  ***********************************************************************/
312
313 typedef enum
314 {
315   INF_OPTIMIZATION,      /* structure contains optimization information */
316   INF_LOCALREGS          /* structure contains local register information */
317 } INFO_TYPE;
318
319
320
321 /***********************************************************************
322  *  OPT_TYPE  - optimization node types
323  ***********************************************************************/
324
325 typedef enum
326 {
327   OPT_BEGIN,             /* mark beginning of optimization block */
328   OPT_END,               /* mark ending of optimization block */
329   OPT_JUMPTABLE_BEGIN,   /* mark beginning of a jumptable */
330   OPT_JUMPTABLE_END      /* mark end of jumptable */
331 } OPT_TYPE;
332
333 /***********************************************************************
334  *  LR_TYPE  - optimization node types
335  ***********************************************************************/
336
337 typedef enum
338 {
339   LR_ENTRY_BEGIN,             /* mark beginning of optimization block */
340   LR_ENTRY_END,               /* mark ending of optimization block */
341   LR_EXIT_BEGIN,
342   LR_EXIT_END
343 } LR_TYPE;
344
345
346 /************************************************/
347 /***************  Structures ********************/
348 /************************************************/
349 /* These are here as forward references - the 
350  * full definition of these are below           */
351 struct pCode;
352 struct pCodeWildBlock;
353 struct pCodeRegLives;
354
355 /*************************************************
356   pBranch
357
358   The first step in optimizing pCode is determining
359  the program flow. This information is stored in
360  single-linked lists in the for of 'from' and 'to'
361  objects with in a pcode. For example, most instructions
362  don't involve any branching. So their from branch
363  points to the pCode immediately preceding them and
364  their 'to' branch points to the pcode immediately
365  following them. A skip instruction is an example of
366  a pcode that has multiple (in this case two) elements
367  in the 'to' branch. A 'label' pcode is an where there
368  may be multiple 'from' branches.
369  *************************************************/
370
371 typedef struct pBranch
372 {
373   struct pCode   *pc;    // Next pCode in a branch
374   struct pBranch *next;  /* If more than one branch
375                           * the next one is here */
376
377 } pBranch;
378
379 /*************************************************
380   pCodeOp
381
382   pCode Operand structure.
383   For those assembly instructions that have arguments, 
384   the pCode will have a pCodeOp in which the argument
385   can be stored. For example
386
387     movf   some_register,w
388
389   'some_register' will be stored/referenced in a pCodeOp
390
391  *************************************************/
392
393 typedef struct pCodeOp
394 {
395   PIC_OPTYPE type;
396   char *name;
397   
398 } pCodeOp;
399
400 #if 0
401 typedef struct pCodeOpBit
402 {
403   pCodeOp pcop;
404   int bit;
405   unsigned int inBitSpace: 1; /* True if in bit space, else
406                                  just a bit of a register */
407 } pCodeOpBit;
408 #endif
409 typedef struct pCodeOpLit
410 {
411   pCodeOp pcop;
412   int lit;
413 } pCodeOpLit;
414
415 typedef struct pCodeOpLit2
416 {
417   pCodeOp pcop;
418   int lit;
419   pCodeOp *arg2;
420 } pCodeOpLit2;
421
422
423 typedef struct pCodeOpImmd
424 {
425   pCodeOp pcop;
426   int offset;           /* low,high or upper byte of immediate value */
427   int index;            /* add this to the immediate value */
428   unsigned _const:1;    /* is in code space    */
429
430   int rIdx;             /* If this immd points to a register */
431   struct regs *r;       /* then this is the reg. */
432
433 } pCodeOpImmd;
434
435 typedef struct pCodeOpLabel
436 {
437   pCodeOp pcop;
438   int key;
439 } pCodeOpLabel;
440
441 typedef struct pCodeOpReg
442 {
443   pCodeOp pcop;    // Can be either GPR or SFR
444   int rIdx;        // Index into the register table
445   struct regs *r;
446   int instance;    // byte # of Multi-byte registers
447   struct pBlock *pb;
448
449   pCodeOp *pcop2;       // second memory operand (NEEDED IN gen.c:pic16_popGet2p (pCodeOpReg casted into pCodeOpReg2) 
450 } pCodeOpReg;
451
452 typedef struct pCodeOpReg2
453 {
454   pCodeOp pcop;         // used by default to all references
455   int rIdx;
456   struct regs *r;
457   int instance;         // assume same instance for both operands
458   struct pBlock *pb;
459
460   pCodeOp *pcop2;       // second memory operand
461 } pCodeOpReg2;
462
463 typedef struct pCodeOpRegBit
464 {
465   pCodeOpReg  pcor;       // The Register containing this bit
466   int bit;                // 0-7 bit number.
467   PIC_OPTYPE subtype;     // The type of this register.
468   unsigned int inBitSpace: 1; /* True if in bit space, else
469                                  just a bit of a register */
470 } pCodeOpRegBit;
471
472
473 typedef struct pCodeOpWild
474 {
475   pCodeOp pcop;
476
477   struct pCodeWildBlock *pcwb;
478
479   int id;                 /* index into an array of char *'s that will match
480                            * the wild card. The array is in *pcp. */
481   pCodeOp *subtype;       /* Pointer to the Operand type into which this wild
482                            * card will be expanded */
483   pCodeOp *matched;       /* When a wild matches, we'll store a pointer to the
484                            * opcode we matched */
485
486   pCodeOp *pcop2;         /* second operand if exists */
487
488 } pCodeOpWild;
489
490
491 typedef struct pCodeOpOpt
492 {
493   pCodeOp pcop;
494   
495   OPT_TYPE type;          /* optimization node type */
496   
497   char *key;              /* key by which a block is identified */
498 } pCodeOpOpt;
499
500 typedef struct pCodeOpLocalReg
501 {
502   pCodeOp pcop;
503
504   LR_TYPE type;
505 } pCodeOpLocalReg;  
506
507 /*************************************************
508     pCode
509
510     Here is the basic build block of a PIC instruction.
511     Each pic instruction will get allocated a pCode.
512     A linked list of pCodes makes a program.
513
514 **************************************************/
515
516 typedef struct pCode
517 {
518   PC_TYPE    type;
519
520   struct pCode *prev;  // The pCode objects are linked together
521   struct pCode *next;  // in doubly linked lists.
522
523   int seq;             // sequence number
524
525   struct pBlock *pb;   // The pBlock that contains this pCode.
526
527   /* "virtual functions"
528    *  The pCode structure is like a base class
529    * in C++. The subsequent structures that "inherit"
530    * the pCode structure will initialize these function
531    * pointers to something useful */
532   //  void (*analyze) (struct pCode *_this);
533   void (*destruct)(struct pCode *_this);
534   void (*print)  (FILE *of,struct pCode *_this);
535
536 } pCode;
537
538
539 /*************************************************
540     pCodeComment
541 **************************************************/
542
543 typedef struct pCodeComment
544 {
545
546   pCode  pc;
547
548   char *comment;
549
550 } pCodeComment;
551
552
553 /*************************************************
554     pCodeCSource
555 **************************************************/
556
557 typedef struct pCodeCSource
558 {
559
560   pCode  pc;
561
562   int  line_number;
563   char *line;
564   char *file_name;
565
566 } pCodeCSource;
567
568
569 /*************************************************
570     pCodeAsmDir
571 **************************************************/
572
573 /*************************************************
574     pCodeFlow
575
576   The Flow object is used as marker to separate 
577  the assembly code into contiguous chunks. In other
578  words, everytime an instruction cause or potentially
579  causes a branch, a Flow object will be inserted into
580  the pCode chain to mark the beginning of the next
581  contiguous chunk.
582
583 **************************************************/
584
585 typedef struct pCodeFlow
586 {
587
588   pCode  pc;
589
590   pCode *end;   /* Last pCode in this flow. Note that
591                    the first pCode is pc.next */
592
593   /*  set **uses;   * map the pCode instruction inCond and outCond conditions 
594                  * in this array of set's. The reason we allocate an 
595                  * array of pointers instead of declaring each type of 
596                  * usage is because there are port dependent usage definitions */
597   //int nuses;    /* number of uses sets */
598
599   set *from;    /* flow blocks that can send control to this flow block */
600   set *to;      /* flow blocks to which this one can send control */
601   struct pCodeFlow *ancestor; /* The most immediate "single" pCodeFlow object that
602                                * executes prior to this one. In many cases, this 
603                                * will be just the previous */
604
605   int inCond;   /* Input conditions - stuff assumed defined at entry */
606   int outCond;  /* Output conditions - stuff modified by flow block */
607
608   int firstBank; /* The first and last bank flags are the first and last */
609   int lastBank;  /* register banks used within one flow object */
610
611   int FromConflicts;
612   int ToConflicts;
613
614   set *registers;/* Registers used in this flow */
615
616 } pCodeFlow;
617
618 /*************************************************
619   pCodeFlowLink
620
621   The Flow Link object is used to record information
622  about how consecutive excutive Flow objects are related.
623  The pCodeFlow objects demarcate the pCodeInstructions
624  into contiguous chunks. The FlowLink records conflicts
625  in the discontinuities. For example, if one Flow object
626  references a register in bank 0 and the next Flow object
627  references a register in bank 1, then there is a discontinuity
628  in the banking registers.
629
630 */
631 typedef struct pCodeFlowLink
632 {
633   pCodeFlow  *pcflow;   /* pointer to linked pCodeFlow object */
634
635   int bank_conflict;    /* records bank conflicts */
636
637 } pCodeFlowLink;
638
639 /*************************************************
640     pCodeInstruction
641
642     Here we describe all the facets of a PIC instruction
643     (expansion for the 18cxxx is also provided).
644
645 **************************************************/
646
647 typedef struct pCodeInstruction
648 {
649
650   pCode  pc;
651
652   PIC_OPCODE op;        // The opcode of the instruction.
653
654   char const * const mnemonic;       // Pointer to mnemonic string
655
656   char isize;          // pCode instruction size
657
658   pBranch *from;       // pCodes that execute before this one
659   pBranch *to;         // pCodes that execute after
660   pBranch *label;      // pCode instructions that have labels
661
662   pCodeOp *pcop;               /* Operand, if this instruction has one */
663   pCodeFlow *pcflow;           /* flow block to which this instruction belongs */
664   pCodeCSource *cline;         /* C Source from which this instruction was derived */
665
666   unsigned int num_ops;        /* Number of operands (0,1,2 for mid range pics) */
667   unsigned int isModReg:  1;   /* If destination is W or F, then 1==F */
668   unsigned int isBitInst: 1;   /* e.g. BCF */
669   unsigned int isBranch:  1;   /* True if this is a branching instruction */
670   unsigned int isSkip:    1;   /* True if this is a skip instruction */
671   unsigned int isLit:     1;   /* True if this instruction has an literal operand */
672   unsigned int isAccess:   1;   /* True if this instruction has an access RAM operand */
673   unsigned int isFastCall: 1;   /* True if this instruction has a fast call/return mode select operand */
674   unsigned int is2MemOp: 1;     /* True is second operand is a memory operand VR - support for MOVFF */
675   unsigned int is2LitOp: 1;     /* True if instruction takes 2 literal operands VR - support for LFSR */
676
677   PIC_OPCODE inverted_op;      /* Opcode of instruction that's the opposite of this one */
678   unsigned int inCond;   // Input conditions for this instruction
679   unsigned int outCond;  // Output conditions for this instruction
680
681 #define PCI_MAGIC       0x6e12
682   unsigned int pci_magic;       // sanity check for pci initialization
683 } pCodeInstruction;
684
685
686
687 /*************************************************
688     pCodeAsmDir
689 **************************************************/
690
691 typedef struct pCodeAsmDir
692 {
693   pCodeInstruction pci;
694   
695   char *directive;
696   char *arg;
697 } pCodeAsmDir;
698
699
700 /*************************************************
701     pCodeLabel
702 **************************************************/
703
704 typedef struct pCodeLabel
705 {
706
707   pCode  pc;
708
709   char *label;
710   int key;
711   int force;            /* label cannot be optimized out */
712
713 } pCodeLabel;
714
715 /*************************************************
716     pCodeFunction
717 **************************************************/
718
719 typedef struct pCodeFunction
720 {
721
722   pCode  pc;
723
724   char *modname;
725   char *fname;     /* If NULL, then this is the end of
726                       a function. Otherwise, it's the
727                       start and the name is contained
728                       here */
729
730   pBranch *from;       // pCodes that execute before this one
731   pBranch *to;         // pCodes that execute after
732   pBranch *label;      // pCode instructions that have labels
733
734   int  ncalled;    /* Number of times function is called */
735
736   int absblock;    /* hack to emulate a block pCodes in absolute position
737                       but not inside a function */
738   int stackusage;  /* stack positions used in function */
739   
740 } pCodeFunction;
741
742
743 /*************************************************
744     pCodeWild
745 **************************************************/
746
747 typedef struct pCodeWild
748 {
749
750   pCodeInstruction  pci;
751
752   int    id;     /* Index into the wild card array of a peepBlock 
753                   * - this wild card will get expanded into that pCode
754                   *   that is stored at this index */
755
756   /* Conditions on wild pcode instruction */
757   int    mustBeBitSkipInst:1;
758   int    mustNotBeBitSkipInst:1;
759   int    invertBitSkipInst:1;
760
761   pCodeOp *operand;  // Optional operand
762   pCodeOp *label;    // Optional label
763
764 } pCodeWild;
765
766
767 /*************************************************
768     pInfo
769     
770     Here are stored generic informaton
771 *************************************************/
772 typedef struct pCodeInfo
773 {
774   pCodeInstruction pci;
775   
776   INFO_TYPE type;       /* info node type */
777   
778   pCodeOp *oper1;       /* info node arguments */
779 } pCodeInfo;
780   
781
782 /*************************************************
783     pBlock
784
785     Here are PIC program snippets. There's a strong
786     correlation between the eBBlocks and pBlocks.
787     SDCC subdivides a C program into managable chunks.
788     Each chunk becomes a eBBlock and ultimately in the
789     PIC port a pBlock.
790
791 **************************************************/
792
793 typedef struct pBlock
794 {
795   memmap *cmemmap;   /* The snippet is from this memmap */
796   char   dbName;     /* if cmemmap is NULL, then dbName will identify the block */
797   pCode *pcHead;     /* A pointer to the first pCode in a link list of pCodes */
798   pCode *pcTail;     /* A pointer to the last pCode in a link list of pCodes */
799
800   struct pBlock *next;      /* The pBlocks will form a doubly linked list */
801   struct pBlock *prev;
802
803   set *function_entries;    /* dll of functions in this pblock */
804   set *function_exits;
805   set *function_calls;
806   set *tregisters;
807
808   set *FlowTree;
809   unsigned visited:1;       /* set true if traversed in call tree */
810
811   unsigned seq;             /* sequence number of this pBlock */
812
813 } pBlock;
814
815 /*************************************************
816     pFile
817
818     The collection of pBlock program snippets are
819     placed into a linked list that is implemented
820     in the pFile structure.
821
822     The pcode optimizer will parse the pFile.
823
824 **************************************************/
825
826 typedef struct pFile
827 {
828   pBlock *pbHead;     /* A pointer to the first pBlock */
829   pBlock *pbTail;     /* A pointer to the last pBlock */
830
831   pBranch *functions; /* A SLL of functions in this pFile */
832
833 } pFile;
834
835
836
837 /*************************************************
838   pCodeWildBlock
839
840   The pCodeWildBlock object keeps track of the wild
841   variables, operands, and opcodes that exist in
842   a pBlock.
843 **************************************************/
844 typedef struct pCodeWildBlock {
845   pBlock    *pb;
846   struct pCodePeep *pcp;    // pointer back to ... I don't like this...
847
848   int       nvars;          // Number of wildcard registers in target.
849   char    **vars;           // array of pointers to them
850
851   int       nops;           // Number of wildcard operands in target.
852   pCodeOp **wildpCodeOps;   // array of pointers to the pCodeOp's.
853
854   int       nwildpCodes;    // Number of wildcard pCodes in target/replace
855   pCode   **wildpCodes;     // array of pointers to the pCode's.
856
857 } pCodeWildBlock;
858
859 /*************************************************
860   pCodePeep
861
862   The pCodePeep object mimics the peep hole optimizer
863   in the main SDCC src (e.g. SDCCpeeph.c). Essentially
864   there is a target pCode chain and a replacement
865   pCode chain. The target chain is compared to the
866   pCode that is generated by gen.c. If a match is
867   found then the pCode is replaced by the replacement
868   pCode chain.
869 **************************************************/
870 typedef struct pCodePeep {
871   pCodeWildBlock target;     // code we'd like to optimize
872   pCodeWildBlock replace;    // and this is what we'll optimize it with.
873
874   //pBlock *target;
875   //pBlock replace;            // and this is what we'll optimize it with.
876
877
878
879   /* (Note: a wildcard register is a place holder. Any register
880    * can be replaced by the wildcard when the pcode is being 
881    * compared to the target. */
882
883   /* Post Conditions. A post condition is a condition that
884    * must be either true or false before the peep rule is
885    * accepted. For example, a certain rule may be accepted
886    * if and only if the Z-bit is not used as an input to 
887    * the subsequent instructions in a pCode chain.
888    */
889   unsigned int postFalseCond;  
890   unsigned int postTrueCond;
891
892 } pCodePeep;
893
894 /*************************************************
895
896   pCode peep command definitions 
897
898  Here are some special commands that control the
899 way the peep hole optimizer behaves
900
901 **************************************************/
902
903 enum peepCommandTypes{
904   NOTBITSKIP = 0,
905   BITSKIP,
906   INVERTBITSKIP,
907   _LAST_PEEP_COMMAND_
908 };
909
910 /*************************************************
911     peepCommand structure stores the peep commands.
912
913 **************************************************/
914
915 typedef struct peepCommand {
916   int id;
917   char *cmd;
918 } peepCommand;
919
920 /*************************************************
921     pCode Macros
922
923 **************************************************/
924 #define PCODE(x)  ((pCode *)(x))
925 #define PCI(x)    ((pCodeInstruction *)(x))
926 #define PCL(x)    ((pCodeLabel *)(x))
927 #define PCF(x)    ((pCodeFunction *)(x))
928 #define PCFL(x)   ((pCodeFlow *)(x))
929 #define PCFLINK(x)((pCodeFlowLink *)(x))
930 #define PCW(x)    ((pCodeWild *)(x))
931 #define PCCS(x)   ((pCodeCSource *)(x))
932 #define PCAD(x)   ((pCodeAsmDir *)(x))
933 #define PCINF(x)  ((pCodeInfo *)(x))
934
935 #define PCOP(x)   ((pCodeOp *)(x))
936 //#define PCOB(x)   ((pCodeOpBit *)(x))
937 #define PCOL(x)   ((pCodeOpLit *)(x))
938 #define PCOI(x)   ((pCodeOpImmd *)(x))
939 #define PCOLAB(x) ((pCodeOpLabel *)(x))
940 #define PCOR(x)   ((pCodeOpReg *)(x))
941 #define PCOR2(x)  ((pCodeOpReg2 *)(x))
942 #define PCORB(x)  ((pCodeOpRegBit *)(x))
943 #define PCOO(x)   ((pCodeOpOpt *)(x))
944 #define PCOLR(x)  ((pCodeOpLocalReg *)(x))
945 #define PCOW(x)   ((pCodeOpWild *)(x))
946 #define PCOW2(x)  (PCOW(PCOW(x)->pcop2))
947 #define PBR(x)    ((pBranch *)(x))
948
949 #define PCWB(x)   ((pCodeWildBlock *)(x))
950
951
952 /*
953   macros for checking pCode types
954 */
955 #define isPCI(x)        ((PCODE(x)->type == PC_OPCODE))
956 #define isPCI_BRANCH(x) ((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isBranch)
957 #define isPCI_SKIP(x)   ((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isSkip)
958 #define isPCI_LIT(x)    ((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isLit)
959 #define isPCI_BITSKIP(x)((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isSkip && PCI(x)->isBitInst)
960 #define isPCFL(x)       ((PCODE(x)->type == PC_FLOW))
961 #define isPCF(x)        ((PCODE(x)->type == PC_FUNCTION))
962 #define isPCL(x)        ((PCODE(x)->type == PC_LABEL))
963 #define isPCW(x)        ((PCODE(x)->type == PC_WILD))
964 #define isPCCS(x)       ((PCODE(x)->type == PC_CSOURCE))
965 #define isPCAD(x)       ((PCODE(x)->type == PC_ASMDIR))
966
967 #define isCALL(x)       ((isPCI(x)) && (PCI(x)->op == POC_CALL))
968 #define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS)
969 #define isBSR_REG(r)    ((r)->pc_type == PO_BSR)
970 #define isACCESS_BANK(r)        (r->accessBank)
971
972
973
974 #define isPCOLAB(x)     ((PCOP(x)->type) == PO_LABEL)
975
976 /*-----------------------------------------------------------------*
977  * pCode functions.
978  *-----------------------------------------------------------------*/
979
980 pCode *pic16_newpCode (PIC_OPCODE op, pCodeOp *pcop); // Create a new pCode given an operand
981 pCode *pic16_newpCodeCharP(char *cP);              // Create a new pCode given a char *
982 pCode *pic16_newpCodeInlineP(char *cP);            // Create a new pCode given a char *
983 pCode *pic16_newpCodeFunction(char *g, char *f);   // Create a new function
984 pCode *pic16_newpCodeLabel(char *name,int key);    // Create a new label given a key
985 pCode *pic16_newpCodeLabelFORCE(char *name, int key); // Same as newpCodeLabel but label cannot be optimized out
986 pCode *pic16_newpCodeCSource(int ln, char *f, char *l); // Create a new symbol line 
987 pBlock *pic16_newpCodeChain(memmap *cm,char c, pCode *pc); // Create a new pBlock
988 void pic16_printpBlock(FILE *of, pBlock *pb);      // Write a pBlock to a file
989 void pic16_addpCode2pBlock(pBlock *pb, pCode *pc); // Add a pCode to a pBlock
990 void pic16_addpBlock(pBlock *pb);                  // Add a pBlock to a pFile
991 void pic16_copypCode(FILE *of, char dbName);       // Write all pBlocks with dbName to *of
992 void pic16_movepBlock2Head(char dbName);           // move pBlocks around
993 void pic16_AnalyzepCode(char dbName);
994 void pic16_OptimizeLocalRegs(void);
995 void pic16_AssignRegBanks(void);
996 void pic16_printCallTree(FILE *of);
997 void pCodePeepInit(void);
998 void pic16_pBlockConvert2ISR(pBlock *pb);
999 void pic16_pBlockConvert2Absolute(pBlock *pb);
1000 void pic16_initDB(void);
1001 void pic16_emitDB(char c, char ptype, void *p);           // Add DB directives to a pBlock
1002 void pic16_emitDS(char *s, char ptype, void *p);
1003 void pic16_flushDB(char ptype, void *p);                          // Add pending DB data to a pBlock
1004
1005 pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...); 
1006
1007 pCodeOp *pic16_newpCodeOpLabel(char *name, int key);
1008 pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space);
1009 pCodeOp *pic16_newpCodeOpLit(int lit);
1010 pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2);
1011 pCodeOp *pic16_newpCodeOpBit(char *name, int bit,int inBitSpace, PIC_OPTYPE subt);
1012 pCodeOp *pic16_newpCodeOpRegFromStr(char *name);
1013 pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE p);
1014 pCodeOp *pic16_pCodeOpCopy(pCodeOp *pcop);
1015
1016 pCode *pic16_newpCodeInfo(INFO_TYPE type, pCodeOp *pcop);
1017 pCodeOp *pic16_newpCodeOpOpt(OPT_TYPE type, char *key);
1018 pCodeOp *pic16_newpCodeOpLocalRegs(LR_TYPE type);
1019
1020 pCode * pic16_findNextInstruction(pCode *pci);
1021 pCode * pic16_findNextpCode(pCode *pc, PC_TYPE pct);
1022 int pic16_isPCinFlow(pCode *pc, pCode *pcflow);
1023 struct regs * pic16_getRegFromInstruction(pCode *pc);
1024 struct regs * pic16_getRegFromInstruction2(pCode *pc);
1025 char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size);
1026 char *pic16_get_op2(pCodeOp *pcop,char *buffer, size_t size);
1027 char *dumpPicOptype(PIC_OPTYPE type);
1028
1029 extern void pic16_pcode_test(void);
1030 extern int pic16_debug_verbose;
1031 extern int pic16_pcode_verbose;
1032
1033 #ifndef debugf
1034 //#define debugf(frm, rest...)       _debugf(__FILE__, __LINE__, frm, rest)
1035 #define debugf(frm, rest)       _debugf(__FILE__, __LINE__, frm, rest)
1036 #define debugf2(frm, arg1, arg2)        _debugf(__FILE__, __LINE__, frm, arg1, arg2)
1037 #define debugf3(frm, arg1, arg2, arg3)  _debugf(__FILE__, __LINE__, frm, arg1, arg2, arg3)
1038
1039 #endif
1040
1041 extern void _debugf(char *f, int l, char *frm, ...);
1042
1043
1044 /*-----------------------------------------------------------------*
1045  * pCode objects.
1046  *-----------------------------------------------------------------*/
1047
1048 extern pCodeOpReg pic16_pc_status;
1049 extern pCodeOpReg pic16_pc_intcon;
1050 extern pCodeOpReg pic16_pc_pcl;
1051 extern pCodeOpReg pic16_pc_pclath;
1052 extern pCodeOpReg pic16_pc_pclatu;
1053 extern pCodeOpReg pic16_pc_wreg;
1054 extern pCodeOpReg pic16_pc_tosl;
1055 extern pCodeOpReg pic16_pc_tosh;
1056 extern pCodeOpReg pic16_pc_tosu;
1057 extern pCodeOpReg pic16_pc_tblptrl;
1058 extern pCodeOpReg pic16_pc_tblptrh;
1059 extern pCodeOpReg pic16_pc_tblptru;
1060 extern pCodeOpReg pic16_pc_tablat;
1061 extern pCodeOpReg pic16_pc_bsr;
1062 extern pCodeOpReg pic16_pc_fsr0;
1063 extern pCodeOpReg pic16_pc_fsr0l;
1064 extern pCodeOpReg pic16_pc_fsr0h;
1065 extern pCodeOpReg pic16_pc_fsr1l;
1066 extern pCodeOpReg pic16_pc_fsr1h;
1067 extern pCodeOpReg pic16_pc_fsr2l;
1068 extern pCodeOpReg pic16_pc_fsr2h;
1069 extern pCodeOpReg pic16_pc_indf0;
1070 extern pCodeOpReg pic16_pc_postinc0;
1071 extern pCodeOpReg pic16_pc_postdec0;
1072 extern pCodeOpReg pic16_pc_preinc0;
1073 extern pCodeOpReg pic16_pc_plusw0;
1074 extern pCodeOpReg pic16_pc_indf1;
1075 extern pCodeOpReg pic16_pc_postinc1;
1076 extern pCodeOpReg pic16_pc_postdec1;
1077 extern pCodeOpReg pic16_pc_preinc1;
1078 extern pCodeOpReg pic16_pc_plusw1;
1079 extern pCodeOpReg pic16_pc_indf2;
1080 extern pCodeOpReg pic16_pc_postinc2;
1081 extern pCodeOpReg pic16_pc_postdec2;
1082 extern pCodeOpReg pic16_pc_preinc2;
1083 extern pCodeOpReg pic16_pc_plusw2;
1084 extern pCodeOpReg pic16_pc_prodl;
1085 extern pCodeOpReg pic16_pc_prodh;
1086
1087 extern pCodeOpReg pic16_pc_eecon1;
1088 extern pCodeOpReg pic16_pc_eecon2;
1089 extern pCodeOpReg pic16_pc_eedata;
1090 extern pCodeOpReg pic16_pc_eeadr;
1091
1092 extern pCodeOpReg pic16_pc_kzero;
1093 extern pCodeOpReg pic16_pc_wsave;     /* wsave and ssave are used to save W and the Status */
1094 extern pCodeOpReg pic16_pc_ssave;     /* registers during an interrupt */
1095
1096 extern pCodeOpReg *pic16_stackpnt_lo;
1097 extern pCodeOpReg *pic16_stackpnt_hi;
1098 extern pCodeOpReg *pic16_stack_postinc;
1099 extern pCodeOpReg *pic16_stack_postdec;
1100 extern pCodeOpReg *pic16_stack_preinc;
1101 extern pCodeOpReg *pic16_stack_plusw;
1102
1103 extern pCodeOpReg *pic16_framepnt_lo;
1104 extern pCodeOpReg *pic16_framepnt_hi;
1105 extern pCodeOpReg *pic16_frame_postinc;
1106 extern pCodeOpReg *pic16_frame_postdec;
1107 extern pCodeOpReg *pic16_frame_preinc;
1108 extern pCodeOpReg *pic16_frame_plusw;
1109
1110 extern pCodeOpReg pic16_pc_gpsimio;
1111 extern pCodeOpReg pic16_pc_gpsimio2;
1112
1113 #endif // __PCODE_H__