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 #ifndef __PCODE_H__ 23 #define __PCODE_H__ 24 25 #include "common.h" 26 27 /* When changing these, you must also update the assembler template 28 * in device/lib/libsdcc/macros.inc */ 29 #define GPTRTAG_DATA 0x00 30 #define GPTRTAG_CODE 0x80 31 32 /* Cyclic dependency with ralloc.h: */ 33 struct reg_info; 34 35 /* 36 Post code generation 37 38 The post code generation is an assembler optimizer. The assembly code 39 produced by all of the previous steps is fully functional. This step 40 will attempt to analyze the flow of the assembly code and agressively 41 optimize it. The peep hole optimizer attempts to do the same thing. 42 As you may recall, the peep hole optimizer replaces blocks of assembly 43 with more optimal blocks (e.g. removing redundant register loads). 44 However, the peep hole optimizer has to be somewhat conservative since 45 an assembly program has implicit state information that's unavailable 46 when only a few instructions are examined. 47 Consider this example: 48 49 example1: 50 movwf t1 51 movf t1,w 52 53 The movf seems redundant since we know that the W register already 54 contains the same value of t1. So a peep hole optimizer is tempted to 55 remove the "movf". However, this is dangerous since the movf affects 56 the flags in the status register (specifically the Z flag) and subsequent 57 code may depend upon this. Look at these two examples: 58 59 example2: 60 movwf t1 61 movf t1,w ; Can't remove this movf 62 skpz 63 return 64 65 example3: 66 movwf t1 67 movf t1,w ; This movf can be removed 68 xorwf t2,w ; since xorwf will over write Z 69 skpz 70 return 71 72 */ 73 74 75 /*********************************************************************** 76 * debug stuff 77 * 78 * The DFPRINTF macro will call fprintf if PCODE_DEBUG is defined. 79 * The macro is used like: 80 * 81 * DPRINTF(("%s #%d\n","test", 1)); 82 * 83 * The double parenthesis (()) are necessary 84 * 85 ***********************************************************************/ 86 //#define PCODE_DEBUG 87 88 #ifdef PCODE_DEBUG 89 #define DFPRINTF(args) (fprintf args) 90 #else 91 #define DFPRINTF(args) ((void)0) 92 #endif 93 94 95 /*********************************************************************** 96 * PIC status bits - this will move into device dependent headers 97 ***********************************************************************/ 98 #define PIC_C_BIT 0 99 #define PIC_DC_BIT 1 100 #define PIC_Z_BIT 2 101 #define PIC_RP0_BIT 5 /* Register Bank select bits RP1:0 : */ 102 #define PIC_RP1_BIT 6 /* 00 - bank 0, 01 - bank 1, 10 - bank 2, 11 - bank 3 */ 103 #define PIC_IRP_BIT 7 /* Indirect register page select */ 104 105 /*********************************************************************** 106 * PIC INTCON bits - this will move into device dependent headers 107 ***********************************************************************/ 108 #define PIC_RBIF_BIT 0 /* Port B level has changed flag */ 109 #define PIC_INTF_BIT 1 /* Port B bit 0 interrupt on edge flag */ 110 #define PIC_T0IF_BIT 2 /* TMR0 has overflowed flag */ 111 #define PIC_RBIE_BIT 3 /* Port B level has changed - Interrupt Enable */ 112 #define PIC_INTE_BIT 4 /* Port B bit 0 interrupt on edge - Int Enable */ 113 #define PIC_T0IE_BIT 5 /* TMR0 overflow Interrupt Enable */ 114 #define PIC_PIE_BIT 6 /* Peripheral Interrupt Enable */ 115 #define PIC_GIE_BIT 7 /* Global Interrupt Enable */ 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 POC_BANKSEL, 224 POC_PAGESEL, 225 226 /* Enhanced instruction set. */ 227 228 POC_ADDFSR, 229 POC_ADDWFC, 230 POC_ADDFWC, 231 POC_ASRF, 232 POC_ASRFW, 233 POC_BRA, 234 POC_BRW, 235 POC_CALLW, 236 POC_LSLF, 237 POC_LSLFW, 238 POC_LSRF, 239 POC_LSRFW, 240 POC_MOVIW, 241 POC_MOVIW_K, 242 POC_MOVLB, 243 POC_MOVLP, 244 POC_MOVWI, 245 POC_MOVWI_K, 246 POC_RESET, 247 POC_SUBWFB, 248 POC_SUBWFBW, 249 250 MAX_PIC14MNEMONICS 251 } PIC_OPCODE; 252 253 254 /*********************************************************************** 255 * PC_TYPE - pCode Types 256 ***********************************************************************/ 257 258 typedef enum 259 { 260 PC_COMMENT=0, /* pCode is a comment */ 261 PC_INLINE, /* user's inline code */ 262 PC_OPCODE, /* PORT dependent opcode */ 263 PC_LABEL, /* assembly label */ 264 PC_FLOW, /* flow analysis */ 265 PC_FUNCTION, /* Function start or end */ 266 PC_WILD, /* wildcard - an opcode place holder used 267 * in the pCode peep hole optimizer */ 268 PC_CSOURCE, /* C-Source Line */ 269 PC_ASMDIR, /* Assembler directive */ 270 PC_BAD /* Mark the pCode object as being bad */ 271 } PC_TYPE; 272 273 /************************************************/ 274 /*************** Structures ********************/ 275 /************************************************/ 276 /* These are here as forward references - the 277 * full definition of these are below */ 278 struct pCode; 279 struct pCodeWildBlock; 280 struct pCodeRegLives; 281 282 /************************************************* 283 pBranch 284 285 The first step in optimizing pCode is determining 286 the program flow. This information is stored in 287 single-linked lists in the for of 'from' and 'to' 288 objects with in a pcode. For example, most instructions 289 don't involve any branching. So their from branch 290 points to the pCode immediately preceding them and 291 their 'to' branch points to the pcode immediately 292 following them. A skip instruction is an example of 293 a pcode that has multiple (in this case two) elements 294 in the 'to' branch. A 'label' pcode is an where there 295 may be multiple 'from' branches. 296 *************************************************/ 297 298 typedef struct pBranch 299 { 300 struct pCode *pc; // Next pCode in a branch 301 struct pBranch *next; /* If more than one branch 302 * the next one is here */ 303 304 } pBranch; 305 306 /************************************************* 307 pCodeOp 308 309 pCode Operand structure. 310 For those assembly instructions that have arguments, 311 the pCode will have a pCodeOp in which the argument 312 can be stored. For example 313 314 movf some_register,w 315 316 'some_register' will be stored/referenced in a pCodeOp 317 318 *************************************************/ 319 320 typedef struct pCodeOp 321 { 322 PIC_OPTYPE type; 323 char *name; 324 325 } pCodeOp; 326 327 typedef struct pCodeOpLit 328 { 329 pCodeOp pcop; 330 int lit; 331 } pCodeOpLit; 332 333 typedef struct pCodeOpImmd 334 { 335 pCodeOp pcop; 336 int offset; /* low,med, or high byte of immediate value */ 337 int index; /* add this to the immediate value */ 338 unsigned _const:1; /* is in code space */ 339 unsigned _function:1; /* is a (pointer to a) function */ 340 341 int rIdx; /* If this immd points to a register */ 342 struct reg_info *r; /* then this is the reg. */ 343 344 } pCodeOpImmd; 345 346 typedef struct pCodeOpLabel 347 { 348 pCodeOp pcop; 349 int key; 350 int offset; /* low or high byte of label */ 351 } pCodeOpLabel; 352 353 typedef struct pCodeOpReg 354 { 355 pCodeOp pcop; // Can be either GPR or SFR 356 int rIdx; // Index into the register table 357 struct reg_info *r; 358 int instance; // byte # of Multi-byte registers 359 struct pBlock *pb; 360 } pCodeOpReg; 361 362 typedef struct pCodeOpRegBit 363 { 364 pCodeOpReg pcor; // The Register containing this bit 365 int bit; // 0-7 bit number. 366 PIC_OPTYPE subtype; // The type of this register. 367 unsigned int inBitSpace: 1; /* True if in bit space, else 368 just a bit of a register */ 369 } pCodeOpRegBit; 370 371 typedef struct pCodeOpStr /* Only used here for the name of fn being called or jumped to */ 372 { 373 pCodeOp pcop; 374 unsigned isPublic: 1; /* True if not static ie extern */ 375 } pCodeOpStr; 376 377 typedef struct pCodeOpWild 378 { 379 pCodeOp pcop; 380 381 struct pCodeWildBlock *pcwb; 382 383 int id; /* index into an array of char *'s that will match 384 * the wild card. The array is in *pcp. */ 385 pCodeOp *subtype; /* Pointer to the Operand type into which this wild 386 * card will be expanded */ 387 pCodeOp *matched; /* When a wild matches, we'll store a pointer to the 388 * opcode we matched */ 389 390 } pCodeOpWild; 391 392 393 /************************************************* 394 pCode 395 396 Here is the basic build block of a PIC instruction. 397 Each pic instruction will get allocated a pCode. 398 A linked list of pCodes makes a program. 399 400 **************************************************/ 401 402 typedef struct pCode 403 { 404 PC_TYPE type; 405 406 struct pCode *prev; // The pCode objects are linked together 407 struct pCode *next; // in doubly linked lists. 408 409 unsigned id; // unique ID number for all pCodes to assist in debugging 410 int seq; // sequence number 411 412 struct pBlock *pb; // The pBlock that contains this pCode. 413 414 /* "virtual functions" 415 * The pCode structure is like a base class 416 * in C++. The subsequent structures that "inherit" 417 * the pCode structure will initialize these function 418 * pointers to something useful */ 419 void (*destruct)(struct pCode *_this); 420 void (*print) (FILE *of,struct pCode *_this); 421 422 } pCode; 423 424 425 /************************************************* 426 pCodeComment 427 **************************************************/ 428 429 typedef struct pCodeComment 430 { 431 pCode pc; 432 433 char *comment; 434 435 } pCodeComment; 436 437 438 /************************************************* 439 pCodeComment 440 **************************************************/ 441 442 typedef struct pCodeCSource 443 { 444 pCode pc; 445 446 int line_number; 447 char *line; 448 char *file_name; 449 450 } pCodeCSource; 451 452 453 /************************************************* 454 pCodeFlow 455 456 The Flow object is used as marker to separate 457 the assembly code into contiguous chunks. In other 458 words, everytime an instruction cause or potentially 459 causes a branch, a Flow object will be inserted into 460 the pCode chain to mark the beginning of the next 461 contiguous chunk. 462 463 **************************************************/ 464 465 typedef struct pCodeFlow 466 { 467 pCode pc; 468 469 pCode *end; /* Last pCode in this flow. Note that 470 the first pCode is pc.next */ 471 472 set *from; /* flow blocks that can send control to this flow block */ 473 set *to; /* flow blocks to which this one can send control */ 474 struct pCodeFlow *ancestor; /* The most immediate "single" pCodeFlow object that 475 * executes prior to this one. In many cases, this 476 * will be just the previous */ 477 478 int inCond; /* Input conditions - stuff assumed defined at entry */ 479 int outCond; /* Output conditions - stuff modified by flow block */ 480 481 int firstBank; /* The first and last bank flags are the first and last */ 482 int lastBank; /* register banks used within one flow object */ 483 484 int FromConflicts; 485 int ToConflicts; 486 487 set *registers;/* Registers used in this flow */ 488 489 } pCodeFlow; 490 491 492 /************************************************* 493 pCodeFlowLink 494 495 The Flow Link object is used to record information 496 about how consecutive excutive Flow objects are related. 497 The pCodeFlow objects demarcate the pCodeInstructions 498 into contiguous chunks. The FlowLink records conflicts 499 in the discontinuities. For example, if one Flow object 500 references a register in bank 0 and the next Flow object 501 references a register in bank 1, then there is a discontinuity 502 in the banking registers. 503 504 */ 505 typedef struct pCodeFlowLink 506 { 507 pCodeFlow *pcflow; /* pointer to linked pCodeFlow object */ 508 509 int bank_conflict; /* records bank conflicts */ 510 511 } pCodeFlowLink; 512 513 514 /************************************************* 515 pCodeInstruction 516 517 Here we describe all the facets of a PIC instruction 518 (expansion for the 18cxxx is also provided). 519 520 **************************************************/ 521 522 typedef struct pCodeInstruction 523 { 524 pCode pc; 525 526 PIC_OPCODE op; // The opcode of the instruction. 527 528 char const * const mnemonic; // Pointer to mnemonic string 529 530 pBranch *from; // pCodes that execute before this one 531 pBranch *to; // pCodes that execute after 532 pBranch *label; // pCode instructions that have labels 533 534 pCodeOp *pcop; /* Operand, if this instruction has one */ 535 pCodeFlow *pcflow; /* flow block to which this instruction belongs */ 536 pCodeCSource *cline; /* C Source from which this instruction was derived */ 537 538 unsigned int num_ops; /* Number of operands (0,1,2 for mid range pics) */ 539 unsigned int isModReg: 1; /* If destination is W or F, then 1==F */ 540 unsigned int isBitInst: 1; /* e.g. BCF */ 541 unsigned int isBranch: 1; /* True if this is a branching instruction */ 542 unsigned int isSkip: 1; /* True if this is a skip instruction */ 543 unsigned int isLit: 1; /* True if this instruction has an literal operand */ 544 545 PIC_OPCODE inverted_op; /* Opcode of instruction that's the opposite of this one */ 546 unsigned int inCond; // Input conditions for this instruction 547 unsigned int outCond; // Output conditions for this instruction 548 549 } pCodeInstruction; 550 551 552 /************************************************* 553 pCodeAsmDir 554 **************************************************/ 555 556 typedef struct pCodeAsmDir 557 { 558 pCodeInstruction pci; 559 560 char *directive; 561 char *arg; 562 } pCodeAsmDir; 563 564 565 /************************************************* 566 pCodeLabel 567 **************************************************/ 568 569 typedef struct pCodeLabel 570 { 571 pCode pc; 572 573 char *label; 574 int key; 575 576 } pCodeLabel; 577 578 579 /************************************************* 580 pCodeFunction 581 **************************************************/ 582 583 typedef struct pCodeFunction 584 { 585 pCode pc; 586 587 char *modname; 588 char *fname; /* If NULL, then this is the end of 589 a function. Otherwise, it's the 590 start and the name is contained 591 here. */ 592 593 pBranch *from; // pCodes that execute before this one 594 pBranch *to; // pCodes that execute after 595 pBranch *label; // pCode instructions that have labels 596 597 int ncalled; /* Number of times function is called. */ 598 unsigned isPublic:1; /* True if the fn is not static and can be called from another module (ie a another c or asm file). */ 599 unsigned isInterrupt:1; /* True if the fn is interrupt. */ 600 601 } pCodeFunction; 602 603 604 /************************************************* 605 pCodeWild 606 **************************************************/ 607 608 typedef struct pCodeWild 609 { 610 pCodeInstruction pci; 611 612 int id; /* Index into the wild card array of a peepBlock 613 * - this wild card will get expanded into that pCode 614 * that is stored at this index */ 615 616 /* Conditions on wild pcode instruction */ 617 int mustBeBitSkipInst:1; 618 int mustNotBeBitSkipInst:1; 619 int invertBitSkipInst:1; 620 621 pCodeOp *operand; // Optional operand 622 pCodeOp *label; // Optional label 623 624 } pCodeWild; 625 626 /************************************************* 627 pBlock 628 629 Here are PIC program snippets. There's a strong 630 correlation between the eBBlocks and pBlocks. 631 SDCC subdivides a C program into managable chunks. 632 Each chunk becomes a eBBlock and ultimately in the 633 PIC port a pBlock. 634 635 **************************************************/ 636 637 typedef struct pBlock 638 { 639 memmap *cmemmap; /* The snippet is from this memmap */ 640 char dbName; /* if cmemmap is NULL, then dbName will identify the block */ 641 pCode *pcHead; /* A pointer to the first pCode in a link list of pCodes */ 642 pCode *pcTail; /* A pointer to the last pCode in a link list of pCodes */ 643 644 struct pBlock *next; /* The pBlocks will form a doubly linked list */ 645 struct pBlock *prev; 646 647 set *function_entries; /* dll of functions in this pblock */ 648 set *function_exits; 649 set *function_calls; 650 set *tregisters; 651 652 set *FlowTree; 653 unsigned visited:1; /* set true if traversed in call tree */ 654 655 unsigned seq; /* sequence number of this pBlock */ 656 657 } pBlock; 658 659 /************************************************* 660 pFile 661 662 The collection of pBlock program snippets are 663 placed into a linked list that is implemented 664 in the pFile structure. 665 666 The pcode optimizer will parse the pFile. 667 668 **************************************************/ 669 670 typedef struct pFile 671 { 672 pBlock *pbHead; /* A pointer to the first pBlock */ 673 pBlock *pbTail; /* A pointer to the last pBlock */ 674 675 pBranch *functions; /* A SLL of functions in this pFile */ 676 677 } pFile; 678 679 680 681 /************************************************* 682 pCodeWildBlock 683 684 The pCodeWildBlock object keeps track of the wild 685 variables, operands, and opcodes that exist in 686 a pBlock. 687 **************************************************/ 688 typedef struct pCodeWildBlock 689 { 690 pBlock *pb; 691 struct pCodePeep *pcp; // pointer back to ... I don't like this... 692 693 int nvars; // Number of wildcard registers in target. 694 char **vars; // array of pointers to them 695 696 int nops; // Number of wildcard operands in target. 697 pCodeOp **wildpCodeOps; // array of pointers to the pCodeOp's. 698 699 int nwildpCodes; // Number of wildcard pCodes in target/replace 700 pCode **wildpCodes; // array of pointers to the pCode's. 701 702 } pCodeWildBlock; 703 704 /************************************************* 705 pCodePeep 706 707 The pCodePeep object mimics the peep hole optimizer 708 in the main SDCC src (e.g. SDCCpeeph.c). Essentially 709 there is a target pCode chain and a replacement 710 pCode chain. The target chain is compared to the 711 pCode that is generated by gen.c. If a match is 712 found then the pCode is replaced by the replacement 713 pCode chain. 714 **************************************************/ 715 typedef struct pCodePeep 716 { 717 pCodeWildBlock target; // code we'd like to optimize 718 pCodeWildBlock replace; // and this is what we'll optimize it with. 719 720 /* (Note: a wildcard register is a place holder. Any register 721 * can be replaced by the wildcard when the pcode is being 722 * compared to the target. */ 723 724 /* Post Conditions. A post condition is a condition that 725 * must be either true or false before the peep rule is 726 * accepted. For example, a certain rule may be accepted 727 * if and only if the Z-bit is not used as an input to 728 * the subsequent instructions in a pCode chain. 729 */ 730 unsigned int postFalseCond; 731 unsigned int postTrueCond; 732 733 } pCodePeep; 734 735 /************************************************* 736 737 pCode peep command definitions 738 739 Here are some special commands that control the 740 way the peep hole optimizer behaves 741 742 **************************************************/ 743 744 enum peepCommandTypes 745 { 746 NOTBITSKIP = 0, 747 BITSKIP, 748 INVERTBITSKIP, 749 _LAST_PEEP_COMMAND_ 750 }; 751 752 /************************************************* 753 peepCommand structure stores the peep commands. 754 755 **************************************************/ 756 757 typedef struct peepCommand 758 { 759 int id; 760 char *cmd; 761 } peepCommand; 762 763 /************************************************* 764 pCode Macros 765 766 **************************************************/ 767 #define PCODE(x) ((pCode *)(x)) 768 #define PCI(x) ((pCodeInstruction *)(x)) 769 #define PCL(x) ((pCodeLabel *)(x)) 770 #define PCF(x) ((pCodeFunction *)(x)) 771 #define PCFL(x) ((pCodeFlow *)(x)) 772 #define PCFLINK(x)((pCodeFlowLink *)(x)) 773 #define PCW(x) ((pCodeWild *)(x)) 774 #define PCCS(x) ((pCodeCSource *)(x)) 775 #define PCAD(x) ((pCodeAsmDir *)(x)) 776 777 #define PCOP(x) ((pCodeOp *)(x)) 778 #define PCOL(x) ((pCodeOpLit *)(x)) 779 #define PCOI(x) ((pCodeOpImmd *)(x)) 780 #define PCOLAB(x) ((pCodeOpLabel *)(x)) 781 #define PCOR(x) ((pCodeOpReg *)(x)) 782 #define PCORB(x) ((pCodeOpRegBit *)(x)) 783 #define PCOS(x) ((pCodeOpStr *)(x)) 784 #define PCOW(x) ((pCodeOpWild *)(x)) 785 786 #define PBR(x) ((pBranch *)(x)) 787 788 #define PCWB(x) ((pCodeWildBlock *)(x)) 789 790 #define isPCOLAB(x) ((PCOP(x)->type) == PO_LABEL) 791 #define isPCOS(x) ((PCOP(x)->type) == PO_STR) 792 793 794 /* 795 macros for checking pCode types 796 */ 797 #define isPCI(x) ((PCODE(x)->type == PC_OPCODE)) 798 #define isPCFL(x) ((PCODE(x)->type == PC_FLOW)) 799 #define isPCF(x) ((PCODE(x)->type == PC_FUNCTION)) 800 #define isPCL(x) ((PCODE(x)->type == PC_LABEL)) 801 #define isPCW(x) ((PCODE(x)->type == PC_WILD)) 802 #define isPCCS(x) ((PCODE(x)->type == PC_CSOURCE)) 803 #define isPCASMDIR(x) ((PCODE(x)->type == PC_ASMDIR)) 804 805 /* 806 macros for checking pCodeInstruction types 807 */ 808 #define isCALL(x) (isPCI(x) && (PCI(x)->op == POC_CALL)) 809 #define isPCI_BRANCH(x) (isPCI(x) && PCI(x)->isBranch) 810 #define isPCI_SKIP(x) (isPCI(x) && PCI(x)->isSkip) 811 #define isPCI_LIT(x) (isPCI(x) && PCI(x)->isLit) 812 #define isPCI_BITSKIP(x)(isPCI_SKIP(x) && PCI(x)->isBitInst) 813 814 815 #define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS) 816 817 /*-----------------------------------------------------------------* 818 * pCode functions. 819 *-----------------------------------------------------------------*/ 820 821 pCode *newpCode(PIC_OPCODE op, pCodeOp *pcop); // Create a new pCode given an operand 822 pCode *newpCodeCharP(const char *cP); // Create a new pCode given a char * 823 pCode *newpCodeFunction(const char *g, const char *f, int, int); // Create a new function. 824 pCode *newpCodeLabel(const char *name,int key); // Create a new label given a key 825 pCode *newpCodeCSource(int ln, const char *f, const char *l); // Create a new symbol line. 826 pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label); 827 pCode *findNextInstruction(pCode *pci); 828 pCode *findPrevInstruction(pCode *pci); 829 pCode *findNextpCode(pCode *pc, PC_TYPE pct); 830 pCode *pCodeInstructionCopy(pCodeInstruction *pci,int invert); 831 832 pBlock *newpCodeChain(memmap *cm,char c, pCode *pc); // Create a new pBlock 833 void printpBlock(FILE *of, pBlock *pb); // Write a pBlock to a file 834 void printpCode(FILE *of, pCode *pc); // Write a pCode to a file 835 void addpCode2pBlock(pBlock *pb, pCode *pc); // Add a pCode to a pBlock 836 void addpBlock(pBlock *pb); // Add a pBlock to a pFile 837 void unlinkpCode(pCode *pc); 838 void copypCode(FILE *of, char dbName); // Write all pBlocks with dbName to *of 839 void movepBlock2Head(char dbName); // move pBlocks around 840 void AnalyzeBanking(void); 841 void ReuseReg(void); 842 void AnalyzepCode(char dbName); 843 void InlinepCode(void); 844 void pCodeInitRegisters(void); 845 void pic14initpCodePeepCommands(void); 846 void pBlockConvert2ISR(pBlock *pb); 847 void pBlockMergeLabels(pBlock *pb); 848 void pCodeInsertAfter(pCode *pc1, pCode *pc2); 849 void pCodeInsertBefore(pCode *pc1, pCode *pc2); 850 void pCodeDeleteChain(pCode *f,pCode *t); 851 852 pCode *newpCodeAsmDir(const char *asdir, const char *argfmt, ...); 853 854 pCodeOp *newpCodeOpLabel(const char *name, int key); 855 pCodeOp *newpCodeOpImmd(const char *name, int offset, int index, int code_space,int is_func); 856 pCodeOp *newpCodeOpLit(int lit); 857 pCodeOp *newpCodeOpBit(const char *name, int bit,int inBitSpace); 858 pCodeOp *newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype); 859 pCodeOp *newpCodeOpRegFromStr(const char *name); 860 pCodeOp *newpCodeOp(const char *name, PIC_OPTYPE p); 861 pCodeOp *pCodeOpCopy(pCodeOp *pcop); 862 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval); 863 pCodeOp *popCopyReg(pCodeOpReg *pc); 864 865 pBranch *pBranchAppend(pBranch *h, pBranch *n); 866 867 struct reg_info * getRegFromInstruction(pCode *pc); 868 869 char *get_op(pCodeOp *pcop, char *buff, size_t buf_size); 870 char *pCode2str(char *str, size_t size, pCode *pc); 871 872 int pCodePeepMatchRule(pCode *pc); 873 874 void pcode_test(void); 875 void resetpCodeStatistics (void); 876 void dumppCodeStatistics (FILE *of); 877 878 /*-----------------------------------------------------------------* 879 * pCode objects. 880 *-----------------------------------------------------------------*/ 881 882 extern pCodeOpReg pc_status; 883 extern pCodeOpReg pc_intcon; 884 extern pCodeOpReg pc_fsr; 885 extern pCodeOpReg pc_fsr0l; 886 extern pCodeOpReg pc_fsr0h; 887 extern pCodeOpReg *pc_indf; /* pointer to either pc_indf_ or pc_indf0 */ 888 extern pCodeOpReg pc_indf_; 889 extern pCodeOpReg pc_indf0; 890 extern pCodeOpReg pc_pcl; 891 extern pCodeOpReg pc_pclath; 892 extern pCodeOpReg pc_wsave; /* wsave, ssave and psave are used to save W, the Status and PCLATH*/ 893 extern pCodeOpReg pc_ssave; /* registers during an interrupt */ 894 extern pCodeOpReg pc_psave; /* registers during an interrupt */ 895 896 extern pFile *the_pFile; 897 extern pCodeInstruction *pic14Mnemonics[MAX_PIC14MNEMONICS]; 898 899 /* 900 * From pcodepeep.h: 901 */ 902 int getpCode(const char *mnem, unsigned dest); 903 int getpCodePeepCommand(const char *cmd); 904 int pCodeSearchCondition(pCode *pc, unsigned int cond, int contIfSkip); 905 906 #endif // __PCODE_H__ 907 908