1 /*************************************************************************** 2 * Copyright (C) 2004-2005 by Daniel Clarke <daniel.jc@gmail.com> * 3 * 2005 by David Saxton <david@bluehaze.org> * 4 * * 5 * 24-04-2007 * 6 * Modified to add pic 16f877,16f627 and 16f628 * 7 * by george john george@space-kerala.org * 8 * supported by SPACE www.space-kerala.org * 9 * * 10 * This program is free software; you can redistribute it and/or modify * 11 * it under the terms of the GNU General Public License as published by * 12 * the Free Software Foundation; either version 2 of the License, or * 13 * (at your option) any later version. * 14 * * 15 * This program is distributed in the hope that it will be useful, * 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 * GNU General Public License for more details. * 19 * * 20 * You should have received a copy of the GNU General Public License * 21 * along with this program; if not, write to the * 22 * Free Software Foundation, Inc., * 23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 24 ***************************************************************************/ 25 26 #ifndef INSTRUCTION_H 27 #define INSTRUCTION_H 28 29 #include <QMap> 30 #include <QString> 31 #include <QStringList> 32 #include <QList> 33 34 class Code; 35 class CodeIterator; 36 class CodeConstIterator; 37 class Instruction; 38 class PIC14; 39 40 typedef QList<Instruction*> InstructionList; 41 42 43 /** 44 Abstraction for a Register - should be used instead of a register name. Contains 45 info like whether or not the adressing of the register depends on the bank 46 selection. 47 48 @author David Saxton 49 */ 50 class Register 51 { 52 public: 53 enum Type 54 { 55 TMR0, 56 OPTION_REG, 57 PCL, 58 STATUS, 59 FSR, 60 PORTA, 61 TRISA, 62 PORTB, 63 TRISB, 64 EEDATA, 65 EECON1, 66 EEADR, 67 EECON2, 68 PCLATH, 69 INTCON, 70 //modification start 71 PORTC, 72 PORTD, 73 PORTE, 74 TRISC, 75 TRISD, 76 TRISE, 77 ADCON0, 78 ADCON1, 79 //modification end 80 // The following three are "special" 81 WORKING, // Not a register that is addressable by an address 82 GPR, // Refers to the collection of General Purpose Registers 83 //modification start 84 PIR1, 85 PIR2, 86 TMR1L, 87 TMR1H, 88 T1CON, 89 TMR2, 90 T2CON, 91 RCSTA, 92 TXREG, 93 RCREG, 94 ADRESH, 95 PIE1, 96 TXSTA, 97 ADRESL, 98 EEDATH, 99 EEADRH, 100 SSPBUF, 101 SSPCON, 102 CCPR1L, 103 CCPR1H, 104 CCP1CON, 105 CCPR2L, 106 CCPR2H, 107 CCP2CON, 108 PIE2, 109 PCON, 110 SSPCON2, 111 PR2, 112 SSPADD, 113 SSPSTAT, 114 SPBRG, 115 VRCON, 116 CMCON, 117 118 //modification end 119 none // used in default constructor 120 //TODO 121 //SSPBUF:SSPCON:CCPR1L:CCPR1H:CCP1CON:CCPR2L:CCPR2H:CCP2CON:--FOR BANK0 122 //PIE2:PCON:SSPCON2:PR2:SSPADD:SSPSTAT:SPBRG:--------FOR BANK1 123 }; 124 125 // These banks are used for ORing together in the banks() function 126 enum Banks 127 { 128 Bank0 = 1 << 0, 129 Bank1 = 1 << 1 130 }; 131 132 /** 133 * Creates a register of the given type, giving it the appropriate name. 134 * Note that this constructor should not be used for GPR. 135 */ 136 Register( Type type = none ); 137 /** 138 * Construct a Register with the given name. If the name is not 139 * recognized, then it is assumed to be a GPR register. 140 */ 141 Register( const QString & name ); 142 /** 143 * Construct a Register with the given name. If the name is not 144 * recognized, then it is assumed to be a GPR register. 145 */ 146 Register( const char * name ); 147 /** 148 * @return less-than-equality between registers; name is only compared 149 * if both registers have type GPR. 150 */ 151 bool operator < ( const Register & reg ) const; 152 /** 153 * @return equality between registers; name is only compared if both 154 * registers have type GPR. 155 */ 156 bool operator == ( const Register & reg ) const; 157 /** 158 * @return 0x1 and 0x2 for being addressable from banks 0 and 1 159 * respectively, OR'ed together. 160 */ 161 uchar banks() const; 162 /** 163 * Convenience function. 164 * @see banks 165 */ 166 bool bankDependent() const; 167 /** 168 * Returns the name of the register, or the alias for the GPR. 169 */ name()170 QString name() const { return m_name; } 171 /** 172 * @return the type of register. 173 */ type()174 Type type() const { return m_type; } 175 /** 176 * From the Optimizer's perspective, it is OK to remove, change or add 177 * any instruction so long as there are no visible external changes that 178 * go against the original intention of the microbe source (a general 179 * guiding principle). Therefore, this function returns true for PORT 180 * and TRIS registers, false for everything else. 181 */ 182 bool affectsExternal() const; 183 184 protected: 185 QString m_name; 186 Type m_type; 187 }; 188 189 190 191 class RegisterBit 192 { 193 public: 194 enum STATUS_bits 195 { 196 C = 0, // Carry 197 DC = 1, // Digit carry 198 Z = 2, // Zero 199 NOT_PD = 3, // Power-down 200 NOT_TO = 4, // Time-out 201 RP0 = 5, // Bank Select 202 RP1 = 6, 203 IRP = 7 204 }; 205 206 enum INTCON_bits 207 { 208 RBIF = 0, 209 INTF = 1, 210 T0IF = 2, 211 RBIE = 3, 212 INTE = 4, 213 T0IE = 5, 214 EEIE = 6, 215 GIE = 7 216 }; 217 218 enum OPTION_bits 219 { 220 PS0 = 0, 221 PS1 = 1, 222 PS2 = 2, 223 PSA = 3, 224 T0SE = 4, 225 T0CS = 5, 226 INTEDG = 6, 227 NOT_RBPU = 7 228 }; 229 230 enum EECON1_bits 231 { 232 RD = 0, 233 WR = 1, 234 WREN = 2, 235 WRERR = 3, 236 EEIF = 4, 237 EEPGD = 7 238 }; 239 /** 240 * Constructs a bit of the given register type at the given position. 241 */ 242 RegisterBit( uchar bitPos = 0, Register::Type reg = Register::none ); 243 /** 244 * Construct a register bit with the given name. 245 */ 246 RegisterBit( const QString & name ); 247 /** 248 * Construct a register bit with the given name. 249 */ 250 RegisterBit( const char * name ); 251 /** 252 * @warning do not trust this value! actually, this function should be 253 * removed, or the constructors fixed so that this value can be trusted. 254 * @return the register type that the bit belongs to. 255 */ registerType()256 Register::Type registerType() const { return m_registerType; } 257 /** 258 * @return the position of the bit, e.g. "5" for RP0. 259 */ bitPos()260 uchar bitPos() const { return m_bitPos; } 261 /** 262 * @return the bit, e.g. "0x20" for Z. 263 */ bit()264 uchar bit() const { return (1 << m_bitPos); } 265 /** 266 * @return the name of the bit, e.g. "Z" for Z. 267 */ name()268 QString name() const { return m_name; } 269 270 271 protected: 272 /** 273 * Determines the register type and bit pos from the bit name (m_name). 274 */ 275 void initFromName(); 276 277 Register::Type m_registerType; 278 uchar m_bitPos:3; 279 QString m_name; 280 }; 281 282 283 284 285 /** 286 Contains information on the state of a register before an instruction is 287 executed. 288 289 Note that all the "uchar" values in this class should be considered as the 8 290 bits of a register. So for example, if known=0x2, then only the second bit of 291 the register is known, and its value is given in the second bit of value. 292 293 @author David Saxton 294 */ 295 class RegisterState 296 { 297 public: 298 RegisterState(); 299 300 /** 301 * Merges the known and values together, (possibly) reducing what is 302 * known. 303 */ 304 void merge( const RegisterState & state ); 305 /** 306 * Sets known to unknown and value to zero. 307 */ 308 void reset(); 309 /** 310 * Returns the bits that are definitely zero. 311 */ definiteZeros()312 uchar definiteZeros() const { return (~value) & known; } 313 /** 314 * Returns the bits that are definitely one. 315 */ definiteOnes()316 uchar definiteOnes() const { return value & known; } 317 /** 318 * Returns the bits that are unknown. 319 */ unknown()320 uchar unknown() const { return ~known; } 321 /** 322 * @return the largest possible value that this register might be 323 * storing, based on which bits are known and the value of those bits. 324 */ maxValue()325 uchar maxValue() const { return (value & known) | (~known); } 326 /** 327 * @return the smallest possible value that this register might be 328 * storing, based on which bits are known and the value of those bits. 329 */ minValue()330 uchar minValue() const { return (value & known); } 331 /** 332 * @return whether the known and value uchars are equal 333 */ 334 bool operator == ( const RegisterState & state ) const; 335 /** 336 * @return whether either of the known and value uchars are not equal. 337 */ 338 bool operator != ( const RegisterState & state ) const { return !( *this == state ); } 339 /** 340 * Prints known and value. 341 */ 342 void print(); 343 344 /// Whether or not the value is known (for each bit). 345 uchar known; 346 347 /// The value of the register. 348 uchar value; 349 }; 350 351 352 /** 353 Setting and dependency information for register bits. See the respective member 354 descriptions for more information. 355 356 @author David Saxton 357 */ 358 class RegisterBehaviour 359 { 360 public: 361 RegisterBehaviour(); 362 /** 363 * Sets "depends", "indep" and "changes" to 0x0. 364 */ 365 void reset(); 366 367 /** 368 * The bits whose value before the instruction is executed will affect 369 * the processor state after execution. So for example, 370 * in MOVLW this will be 0x0; 371 * in ANDLW this will be the bits that are non-zero in the literal; 372 * in BTFSC this will be the bit being tested (if this is the register 373 * being tested). 374 */ 375 uchar depends; 376 377 /** 378 * The bits whose value after the instruction is executed is independent 379 * of the value before execution. So for example, 380 * in MOVLW, this will be 0xff; 381 * in ANDLW this will be the bits that are zero in the literal; 382 * in BTFSC this will be 0x0. 383 */ 384 uchar indep; 385 }; 386 387 388 389 /** 390 Contains information on the state of a processor; e.g. register values 391 392 @author David Saxton 393 */ 394 class ProcessorState 395 { 396 public: 397 ProcessorState(); 398 /** 399 * Calls merge for each RegisterState. 400 */ 401 void merge( const ProcessorState & state ); 402 /** 403 * Calls reset() for each RegisterState. 404 */ 405 void reset(); 406 /** 407 * @return state for the given register. 408 */ 409 RegisterState & reg( const Register & reg ); 410 /** 411 * @return state for the given register. 412 */ 413 RegisterState reg( const Register & reg ) const; 414 /** 415 * @return whether all the RegisterStates are identical 416 */ 417 bool operator == ( const ProcessorState & state ) const; 418 /** 419 * @return whether any of the RegisterStates are not equal. 420 */ 421 bool operator != ( const ProcessorState & state ) const { return !( *this == state ); } 422 /** 423 * Displays each register's name and calls RegisterState::print in turn. 424 */ 425 void print(); 426 427 /// The working register 428 RegisterState working; 429 430 /// The status register 431 RegisterState status; 432 433 protected: 434 typedef QMap< Register, RegisterState > RegisterMap; 435 /** 436 * All registers other than working and status. Entries are created on 437 * calls to reg with a new Register. 438 */ 439 RegisterMap m_registers; 440 }; 441 442 443 /** 444 Contains behavioural information for each register. 445 446 @author David Saxton 447 */ 448 class ProcessorBehaviour 449 { 450 public: 451 ProcessorBehaviour(); 452 /** 453 * Calls reset() for each RegisterBehaviour. 454 */ 455 void reset(); 456 /** 457 * @return behaviour for the given register. 458 */ 459 RegisterBehaviour & reg( const Register & reg ); 460 461 /// The working register 462 RegisterBehaviour working; 463 464 /// The status register 465 RegisterBehaviour status; 466 467 protected: 468 typedef QMap< Register, RegisterBehaviour > RegisterMap; 469 /** 470 * All registers other than working and status. Entries are created on 471 * calls to reg with a new Register. 472 */ 473 RegisterMap m_registers; 474 }; 475 476 477 /** 478 Contains information on whether a register is overwritten before its value is 479 used. Each uchar respresents the 8 bits of the register; if the bit is 1, then 480 the corresponding bit of the register is used by the Instruction or one 481 of its outputs before it is overwritten. 482 483 @author David Saxton 484 */ 485 class RegisterDepends 486 { 487 public: 488 RegisterDepends(); 489 /** 490 * Sets all the depends values to 0x0. 491 */ 492 void reset(); 493 /** 494 * @return behaviour for the given register. 495 */ 496 uchar & reg( const Register & reg ); 497 498 /// The working register 499 uchar working; 500 501 /// The status register 502 uchar status; 503 504 protected: 505 typedef QMap< Register, uchar > RegisterMap; 506 /** 507 * All registers other than working and status. Entries are created on 508 * calls to reg with a new Register. 509 */ 510 RegisterMap m_registers; 511 }; 512 513 514 515 /** 516 Holds a program structure; an (ordered) list of blocks of code, each of which 517 contains a list of instructions. The structure is such as to provide easy 518 manipulation of the program, as well as aiding the optimizer. 519 520 @author David Saxton 521 */ 522 class Code 523 { 524 public: 525 Code(); 526 527 typedef CodeIterator iterator; 528 typedef CodeConstIterator const_iterator; 529 530 enum InstructionPosition 531 { 532 InterruptHandler = 0, 533 LookupTable = 1, 534 Middle = 2, ///< Used for main code 535 Subroutine = 3, ///< Used for subroutines 536 537 PositionCount = 4 ///< This must remain the last item and be the number of valid positions 538 }; 539 540 CodeIterator begin(); 541 CodeIterator end(); 542 CodeConstIterator begin() const; 543 CodeConstIterator end() const; 544 545 /** 546 * Queues a label to be given to the next instruction to be added in the 547 * given position 548 */ 549 void queueLabel( const QString & label, InstructionPosition position = Middle ); 550 /** 551 * Returns the list of queued labels for the given position. This is 552 * used in merging code, as we also need to merge any queued labels. 553 */ queuedLabels(InstructionPosition position)554 QStringList queuedLabels( InstructionPosition position ) const { return m_queuedLabels[position]; } 555 /** 556 * Adds the Instruction at the given position. 557 */ 558 void append( Instruction * instruction, InstructionPosition position = Middle ); 559 /** 560 * @returns the Instruction with the given label (or null if no such 561 * Instruction). 562 */ 563 Instruction * instruction( const QString & label ) const; 564 /** 565 * Look for an Assembly instruction (other types are ignored). 566 * @return an iterator to the current instruction, or end if it wasn't 567 * found. 568 */ 569 iterator find( Instruction * instruction ); 570 /** 571 * Removes the Instruction (regardless of position). 572 * @warning You should always use only this function to remove an 573 * instruction as this function handles stuff such as pushing labels 574 * from this instruction onto the next before deletion. 575 */ 576 void removeInstruction( Instruction * instruction ); 577 /** 578 * Merges all the blocks output together with other magic such as adding 579 * variables, gpasm directives, etc. 580 */ 581 QString generateCode( PIC14 * pic ) const; 582 /** 583 * Appends the InstructionLists to the end of the ones in this instance. 584 * @param middleInsertionPosition is the position where the middle code 585 * blocks of the given code will be merged at. 586 */ 587 void merge( Code * code, InstructionPosition middleInsertionPosition = Middle ); 588 /** 589 * @returns the InstructionList for the given insertion position. 590 */ instructionList(InstructionPosition position)591 InstructionList * instructionList( InstructionPosition position ) { return & m_instructionLists[position]; } 592 /** 593 * @returns the InstructionList for the given insertion position. 594 */ instructionList(InstructionPosition position)595 const InstructionList * instructionList( InstructionPosition position ) const { return & m_instructionLists[position]; } 596 /** 597 * Calls generateOutputLinks for each Instruction 598 */ 599 void generateLinksAndStates(); 600 /** 601 * Calls setUsed(false) for all instructions. 602 */ 603 void setAllUnused(); 604 /** 605 * Does any work that is needed to the code before it can be passed to 606 * the optimizer (such as flushing out queued labels). This is called 607 * after all the instructions have been added to the code. 608 */ 609 void postCompileConstruct(); 610 611 protected: 612 /** 613 * Used when generating the code. Finds the list of general purpose 614 * registers that are referenced and returns their aliases. 615 */ 616 QStringList findVariables() const; 617 618 InstructionList m_instructionLists[ PositionCount ]; ///< @see InstructionPosition 619 QStringList m_queuedLabels[ PositionCount ]; ///< @see InstructionPosition 620 621 private: // Disable copy constructor and operator= 622 Code( const Code & ); 623 Code &operator=( const Code & ); 624 }; 625 626 627 /** 628 Iterates over all the instructions, going seamlessly between the different lists 629 and avoiding the non-assembly instructions. 630 631 @author David Saxton 632 */ 633 class CodeIterator 634 { 635 public: 636 bool operator != ( const CodeIterator & i ) const { return it != i.it; } 637 bool operator == ( const CodeIterator & i ) const { return it == i.it; } 638 CodeIterator & operator ++ (); 639 Instruction * & operator * () { return *it; } 640 /** 641 * Deletes the instruction that this iterator is currently pointing at 642 * (removing it from any lists), and increments the iterator to the next 643 * instruction. 644 */ 645 CodeIterator & removeAndIncrement(); 646 /** 647 * Inserts the given instruction before the instruction pointed at by 648 * this iterator. 649 */ 650 void insertBefore( Instruction * ins ); 651 652 InstructionList::iterator it; 653 InstructionList::iterator listEnd; 654 Code::InstructionPosition pos; 655 Code * code; 656 InstructionList * list; 657 }; 658 659 660 /** 661 A const version of CodeIterator (cannot change instructions). 662 663 @author David Saxton 664 */ 665 class CodeConstIterator 666 { 667 public: 668 bool operator != ( const CodeConstIterator & i ) const { return it != i.it; } 669 bool operator == ( const CodeConstIterator & i ) const { return it == i.it; } 670 CodeConstIterator & operator ++ (); 671 const Instruction * operator * () const { return *it; } 672 673 InstructionList::const_iterator it; 674 InstructionList::const_iterator listEnd; 675 Code::InstructionPosition pos; 676 const Code * code; 677 const InstructionList * list; 678 }; 679 680 681 /** 682 @author Daniel Clarke 683 @author David Saxton 684 */ 685 class Instruction 686 { 687 public: 688 enum InstructionType 689 { 690 Assembly, 691 Raw, // User-inserted assembly 692 Comment 693 }; 694 /** 695 * Used in optimization. Note that this follows roughly, but not 696 * exactly, the Microchip classifications of similar categories. 697 */ 698 enum AssemblyType 699 { 700 /** 701 * Writes to a file (which can be obtained by calling outputReg(). 702 */ 703 FileOriented, 704 705 /** 706 * Writes to a file bit (so BCF or BSF). 707 */ 708 BitOriented, 709 710 /** 711 * Affects the working register via a literal operation, with no 712 * branching (so excludes retlw). 713 */ 714 WorkingOriented, 715 716 /** 717 * Assembly instructions that don't come under the above categories 718 * (so control and branching instructions). 719 */ 720 Other, 721 722 /** 723 * The Instruction is not of Assembly InstructionType. 724 */ 725 None 726 }; 727 728 Instruction(); 729 virtual ~Instruction(); setCode(Code * code)730 void setCode( Code * code ) { m_pCode = code; } 731 732 /** 733 * This is used to decide how to output the instruction, and which 734 * instructions to avoid while optimizing. 735 */ type()736 virtual InstructionType type() const { return Assembly; } 737 /** 738 * @return the AssemblyType (None for non-Assembly instructions). 739 */ 740 virtual AssemblyType assemblyType() const = 0; 741 /** 742 * The text to output to the generated assembly. 743 */ 744 virtual QString code() const = 0; 745 /** 746 * The input processor state is used to generate the outputlinks and the 747 * output processor state. 748 */ setInputState(const ProcessorState & processorState)749 void setInputState( const ProcessorState & processorState ) { m_inputState = processorState; } 750 /** 751 * By using the ProcessorState, the Instruction should: 752 * * Find all instructions that could be executed after this instruction. 753 * * Generate the output ProcessorState. 754 * The default behaviour of this function is to link to the next 755 * sequential instruction, and to generate an unknown ProcessorState. 756 * @warning if your instruction depends on any bits, then it must 757 * reinherit this function and say so. 758 * @param instruction points at this instruction 759 */ 760 virtual void generateLinksAndStates( Code::iterator instruction ); 761 /** 762 * @return the processor behaviour for this instruction. 763 */ 764 virtual ProcessorBehaviour behaviour() const; 765 /** 766 * An input link is an instruction that might be executed immediately 767 * before this Instruction. 768 */ 769 void addInputLink( Instruction * inputLink ); 770 /** 771 * An output link is an instruction that might be executed immediately 772 * after this Instruction. 773 */ 774 void addOutputLink( Instruction * inputLink ); 775 /** 776 * The list of instructions that might be executed immediately before 777 * this instruction. 778 * @see addInputLink 779 */ inputLinks()780 InstructionList inputLinks() const { return m_inputLinks; } 781 /** 782 * The list of instructions that might be executed immediately after 783 * this instruction. Instruction does not generate these links; instead 784 * the list is generated Code::generateLinksAndStates function. 785 */ outputLinks()786 InstructionList outputLinks() const { return m_outputLinks; } 787 /** 788 * Remove the given input link from the instruction. 789 */ 790 void removeInputLink( Instruction * ins ); 791 /** 792 * Remove the given output link from the instruction. 793 */ 794 void removeOutputLink( Instruction * ins ); 795 /** 796 * Clears all input and output links from this instruction. This does 797 * not remove references to this instruction from other instructions. 798 */ 799 void clearLinks(); 800 /** 801 * An instruction may have zero, or more than zero labels associated 802 * with it - these will be printed before the instruction in the 803 * assembly output. 804 */ labels()805 QStringList labels() const { return m_labels; } 806 /** 807 * @see labels 808 */ 809 void addLabels( const QStringList & labels ); 810 /** 811 * @see labels 812 */ 813 void setLabels( const QStringList & labels ); 814 /** 815 * @see used 816 */ setUsed(bool used)817 void setUsed( bool used ) { m_bUsed = used; } 818 /** 819 * Used for optimization purposes in determining whether the instruction 820 * has been examined yet (to avoid infinite loops). 821 */ isUsed()822 bool isUsed() const { return m_bUsed; } 823 /** 824 * Set by the optimizer to indicate whether this instruction or any of 825 * its outputs overwrite any of the bits of the given register. 826 */ setRegisterDepends(uchar depends,const Register & reg)827 void setRegisterDepends( uchar depends, const Register & reg ) { m_registerDepends.reg(reg) = depends; } 828 /** 829 * @see setOutputsOverwriteWorking 830 */ registerDepends(const Register & reg)831 uchar registerDepends( const Register & reg ) { return m_registerDepends.reg(reg); } 832 /** 833 * Resets the overwrites. 834 */ resetRegisterDepends()835 void resetRegisterDepends() { m_registerDepends.reset(); } 836 /** 837 * @return the input processor state to this instruction. 838 * @see setInputState 839 */ inputState()840 ProcessorState inputState() const { return m_inputState; } 841 /** 842 * @return the output processor state from this instruction. 843 * @see generateLinksAndStates. 844 */ outputState()845 ProcessorState outputState() const { return m_outputState; } 846 /** 847 * Only applicable to Instructions that refer to a file. 848 */ file()849 Register file() const { return m_file; } 850 /** 851 * Only applicable to Instructions that refer to a bit (such as BCF). 852 */ bit()853 RegisterBit bit() const { return m_bit; } 854 /** 855 * Only applicable to instructions that refer to a literal (such as 856 * XORLW). 857 */ literal()858 uchar literal() const { return m_literal; } 859 /** 860 * Applicable only to instructions that save a result to working or file 861 * depending on the destination bit. 862 */ outputReg()863 Register outputReg() const { return (m_dest == 0) ? Register::WORKING : m_file; } 864 /** 865 * Applicable only to instructions that use the destination flag. 866 */ dest()867 unsigned dest() const { return m_dest; } 868 869 protected: 870 /** 871 * This function is provided for convenience; it creates links to the 872 * first or second instructions after this one, depending on the value 873 * of firstOutput and secondOutput. 874 * @see generateOutputLinks 875 */ 876 void makeOutputLinks( Code::iterator current, bool firstOutput = true, bool secondOutput = false ); 877 /** 878 * This function is provided for instructions that jump to a label (i.e. 879 * call and goto). 880 */ 881 void makeLabelOutputLink( const QString & label ); 882 883 RegisterDepends m_registerDepends; 884 bool m_bInputStateChanged; 885 bool m_bUsed; 886 bool m_bPositionAffectsBranching; 887 InstructionList m_inputLinks; 888 InstructionList m_outputLinks; 889 QStringList m_labels; 890 Code * m_pCode; 891 892 // Commonly needed member variables for assembly instructions 893 Register m_file; 894 RegisterBit m_bit; 895 QString m_raw; // Used by source code, raw asm, etc 896 uchar m_literal; 897 unsigned m_dest:1; // is 0 (W) or 1 (file). 898 ProcessorState m_inputState; 899 ProcessorState m_outputState; 900 901 private: // Disable copy constructor and operator= 902 Instruction( const Instruction & ); 903 Instruction &operator=( const Instruction & ); 904 }; 905 906 907 908 //BEGIN Byte-Oriented File Register Operations 909 class Instr_addwf : public Instruction 910 { 911 public: Instr_addwf(const Register & file,int dest)912 Instr_addwf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 913 QString code() const override; 914 void generateLinksAndStates( Code::iterator current ) override; 915 ProcessorBehaviour behaviour() const override; assemblyType()916 AssemblyType assemblyType() const override { return FileOriented; } 917 }; 918 919 920 class Instr_andwf : public Instruction 921 { 922 public: Instr_andwf(const Register & file,int dest)923 Instr_andwf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 924 QString code() const override; 925 void generateLinksAndStates( Code::iterator current ) override; 926 ProcessorBehaviour behaviour() const override; assemblyType()927 AssemblyType assemblyType() const override { return FileOriented; } 928 }; 929 930 931 class Instr_clrf : public Instruction 932 { 933 public: Instr_clrf(const Register & file)934 Instr_clrf( const Register & file ) { m_file = file; m_dest = 1; } 935 QString code() const override; 936 void generateLinksAndStates( Code::iterator current ) override; 937 ProcessorBehaviour behaviour() const override; assemblyType()938 AssemblyType assemblyType() const override { return FileOriented; } 939 }; 940 941 942 //TODO CLRW 943 //TODO COMF 944 945 946 class Instr_decf : public Instruction 947 { 948 public: Instr_decf(const Register & file,int dest)949 Instr_decf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 950 QString code() const override; 951 void generateLinksAndStates( Code::iterator current ) override; 952 ProcessorBehaviour behaviour() const override; assemblyType()953 AssemblyType assemblyType() const override { return FileOriented; } 954 }; 955 956 957 class Instr_decfsz : public Instruction 958 { 959 public: Instr_decfsz(const Register & file,int dest)960 Instr_decfsz( const Register & file, int dest ) { m_file = file; m_dest = dest; } 961 QString code() const override; 962 void generateLinksAndStates( Code::iterator current ) override; 963 ProcessorBehaviour behaviour() const override; assemblyType()964 AssemblyType assemblyType() const override { return FileOriented; } 965 }; 966 967 968 class Instr_incf : public Instruction 969 { 970 public: Instr_incf(const Register & file,int dest)971 Instr_incf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 972 QString code() const override; 973 void generateLinksAndStates( Code::iterator current ) override; 974 ProcessorBehaviour behaviour() const override; assemblyType()975 AssemblyType assemblyType() const override { return FileOriented; } 976 }; 977 978 979 //TODO INCFSZ 980 981 982 class Instr_iorwf : public Instruction 983 { 984 public: Instr_iorwf(const Register & file,int dest)985 Instr_iorwf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 986 QString code() const override; 987 void generateLinksAndStates( Code::iterator current ) override; 988 ProcessorBehaviour behaviour() const override; assemblyType()989 AssemblyType assemblyType() const override { return FileOriented; } 990 }; 991 992 993 class Instr_movf : public Instruction 994 { 995 public: Instr_movf(const Register & file,int dest)996 Instr_movf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 997 QString code() const override; 998 void generateLinksAndStates( Code::iterator current ) override; 999 ProcessorBehaviour behaviour() const override; assemblyType()1000 AssemblyType assemblyType() const override { return FileOriented; } 1001 }; 1002 1003 1004 class Instr_movwf : public Instruction 1005 { 1006 public: Instr_movwf(const Register & file)1007 Instr_movwf( const Register & file ) { m_file = file; m_dest = 1; } 1008 QString code() const override; 1009 void generateLinksAndStates( Code::iterator current ) override; 1010 ProcessorBehaviour behaviour() const override; assemblyType()1011 AssemblyType assemblyType() const override { return FileOriented; } 1012 }; 1013 1014 1015 //TODO NOP 1016 1017 1018 class Instr_rlf : public Instruction 1019 { 1020 public: Instr_rlf(const Register & file,int dest)1021 Instr_rlf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 1022 QString code() const override; 1023 void generateLinksAndStates( Code::iterator current ) override; 1024 ProcessorBehaviour behaviour() const override; assemblyType()1025 AssemblyType assemblyType() const override { return FileOriented; } 1026 }; 1027 1028 1029 class Instr_rrf : public Instruction 1030 { 1031 public: Instr_rrf(const Register & file,int dest)1032 Instr_rrf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 1033 QString code() const override; 1034 void generateLinksAndStates( Code::iterator current ) override; 1035 ProcessorBehaviour behaviour() const override; assemblyType()1036 AssemblyType assemblyType() const override { return FileOriented; } 1037 }; 1038 1039 1040 class Instr_subwf : public Instruction 1041 { 1042 public: Instr_subwf(const Register & file,int dest)1043 Instr_subwf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 1044 QString code() const override; 1045 void generateLinksAndStates( Code::iterator current ) override; 1046 ProcessorBehaviour behaviour() const override; assemblyType()1047 AssemblyType assemblyType() const override { return FileOriented; } 1048 }; 1049 1050 1051 class Instr_swapf : public Instruction 1052 { 1053 public: Instr_swapf(const Register & file,int dest)1054 Instr_swapf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 1055 QString code() const override; 1056 void generateLinksAndStates( Code::iterator current ) override; 1057 ProcessorBehaviour behaviour() const override; assemblyType()1058 AssemblyType assemblyType() const override { return FileOriented; } 1059 }; 1060 1061 1062 class Instr_xorwf : public Instruction 1063 { 1064 public: Instr_xorwf(const Register & file,int dest)1065 Instr_xorwf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 1066 QString code() const override; 1067 void generateLinksAndStates( Code::iterator current ) override; 1068 ProcessorBehaviour behaviour() const override; assemblyType()1069 AssemblyType assemblyType() const override { return FileOriented; } 1070 }; 1071 //END Byte-Oriented File Register Operations 1072 1073 1074 1075 //BEGIN Bit-Oriented File Register Operations 1076 class Instr_bcf : public Instruction 1077 { 1078 public: Instr_bcf(const Register & file,const RegisterBit & bit)1079 Instr_bcf( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; } 1080 QString code() const override; 1081 void generateLinksAndStates( Code::iterator current ) override; 1082 ProcessorBehaviour behaviour() const override; assemblyType()1083 AssemblyType assemblyType() const override { return BitOriented; } 1084 }; 1085 1086 1087 class Instr_bsf : public Instruction 1088 { 1089 public: Instr_bsf(const Register & file,const RegisterBit & bit)1090 Instr_bsf( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; } 1091 QString code() const override; 1092 void generateLinksAndStates( Code::iterator current ) override; 1093 ProcessorBehaviour behaviour() const override; assemblyType()1094 AssemblyType assemblyType() const override { return BitOriented; } 1095 }; 1096 1097 1098 class Instr_btfsc : public Instruction 1099 { 1100 public: Instr_btfsc(const Register & file,const RegisterBit & bit)1101 Instr_btfsc( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; } 1102 QString code() const override; 1103 void generateLinksAndStates( Code::iterator current ) override; 1104 ProcessorBehaviour behaviour() const override; assemblyType()1105 AssemblyType assemblyType() const override { return Other; } 1106 }; 1107 1108 1109 class Instr_btfss : public Instruction 1110 { 1111 public: Instr_btfss(const Register & file,const RegisterBit & bit)1112 Instr_btfss( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; } 1113 QString code() const override; 1114 void generateLinksAndStates( Code::iterator current ) override; 1115 ProcessorBehaviour behaviour() const override; assemblyType()1116 AssemblyType assemblyType() const override { return Other; } 1117 }; 1118 //END Bit-Oriented File Register Operations 1119 1120 1121 1122 //BEGIN Literal and Control Operations 1123 class Instr_addlw : public Instruction 1124 { 1125 public: Instr_addlw(int literal)1126 Instr_addlw( int literal ) { m_literal = literal; } 1127 QString code() const override; 1128 void generateLinksAndStates( Code::iterator current ) override; 1129 ProcessorBehaviour behaviour() const override; assemblyType()1130 AssemblyType assemblyType() const override { return WorkingOriented; } 1131 }; 1132 1133 1134 1135 class Instr_andlw : public Instruction 1136 { 1137 public: Instr_andlw(int literal)1138 Instr_andlw( int literal ) { m_literal = literal; } 1139 QString code() const override; 1140 void generateLinksAndStates( Code::iterator current ) override; 1141 ProcessorBehaviour behaviour() const override; assemblyType()1142 AssemblyType assemblyType() const override { return WorkingOriented; } 1143 }; 1144 1145 1146 class Instr_call : public Instruction 1147 { 1148 public: Instr_call(const QString & label)1149 Instr_call( const QString & label ) { m_label = label; } 1150 QString code() const override; 1151 void generateLinksAndStates( Code::iterator current ) override; 1152 ProcessorBehaviour behaviour() const override; assemblyType()1153 AssemblyType assemblyType() const override { return Other; } 1154 /** 1155 * Called from Code after all the output links have been generated. The 1156 * instruction that is called has its output links followed, and any 1157 * returns encountered are linked back to the instruction after this 1158 * one. 1159 * @param next the instruction after this one which the return points 1160 * will be linked to. 1161 */ 1162 void makeReturnLinks( Instruction * next ); 1163 label()1164 QString label() const { return m_label; } setLabel(const QString & label)1165 void setLabel( const QString & label ) { m_label = label; } 1166 1167 protected: 1168 /** 1169 * Used by makeReturnLinks. Recursively follows the instruction's output 1170 * links, until a return is found - then, link the return point back to 1171 * the instruction after this one. Call instructions found while 1172 * following the output are ignored. 1173 * @param returnPoint the instruction to link back to on finding a 1174 * return. 1175 */ 1176 void linkReturns( Instruction * current, Instruction * returnPoint ); 1177 1178 QString m_label; 1179 }; 1180 1181 1182 //TODO CLRWDT 1183 1184 1185 class Instr_goto : public Instruction 1186 { 1187 public: Instr_goto(const QString & label)1188 Instr_goto( const QString & label ) { m_label = label; } 1189 QString code() const override; 1190 void generateLinksAndStates( Code::iterator current ) override; 1191 ProcessorBehaviour behaviour() const override; assemblyType()1192 AssemblyType assemblyType() const override { return Other; } 1193 label()1194 QString label() const { return m_label; } setLabel(const QString & label)1195 void setLabel( const QString & label ) { m_label = label; } 1196 1197 protected: 1198 QString m_label; 1199 }; 1200 1201 1202 class Instr_iorlw : public Instruction 1203 { 1204 public: Instr_iorlw(int literal)1205 Instr_iorlw( int literal ) { m_literal = literal; } 1206 QString code() const override; 1207 void generateLinksAndStates( Code::iterator current ) override; 1208 ProcessorBehaviour behaviour() const override; assemblyType()1209 AssemblyType assemblyType() const override { return WorkingOriented; } 1210 }; 1211 1212 1213 class Instr_movlw : public Instruction 1214 { 1215 public: Instr_movlw(int literal)1216 Instr_movlw( int literal ) { m_literal = literal; } 1217 QString code() const override; 1218 void generateLinksAndStates( Code::iterator current ) override; 1219 ProcessorBehaviour behaviour() const override; assemblyType()1220 AssemblyType assemblyType() const override { return WorkingOriented; } 1221 }; 1222 1223 1224 class Instr_retfie : public Instruction 1225 { 1226 public: Instr_retfie()1227 Instr_retfie() {}; 1228 QString code() const override; 1229 void generateLinksAndStates( Code::iterator current ) override; 1230 ProcessorBehaviour behaviour() const override; assemblyType()1231 AssemblyType assemblyType() const override { return Other; } 1232 }; 1233 1234 1235 class Instr_retlw : public Instruction 1236 { 1237 public: Instr_retlw(int literal)1238 Instr_retlw( int literal ) { m_literal = literal; } 1239 QString code() const override; 1240 void generateLinksAndStates( Code::iterator current ) override; 1241 ProcessorBehaviour behaviour() const override; assemblyType()1242 AssemblyType assemblyType() const override { return Other; } 1243 }; 1244 1245 1246 class Instr_return : public Instruction 1247 { 1248 public: Instr_return()1249 Instr_return() {}; 1250 QString code() const override; 1251 void generateLinksAndStates( Code::iterator current ) override; 1252 ProcessorBehaviour behaviour() const override; assemblyType()1253 AssemblyType assemblyType() const override { return Other; } 1254 }; 1255 1256 1257 class Instr_sleep : public Instruction 1258 { 1259 public: Instr_sleep()1260 Instr_sleep() {}; 1261 QString code() const override; 1262 void generateLinksAndStates( Code::iterator current ) override; 1263 ProcessorBehaviour behaviour() const override; assemblyType()1264 AssemblyType assemblyType() const override { return Other; } 1265 }; 1266 1267 1268 class Instr_sublw : public Instruction 1269 { 1270 public: Instr_sublw(int literal)1271 Instr_sublw( int literal ) { m_literal = literal; } 1272 QString code() const override; 1273 void generateLinksAndStates( Code::iterator current ) override; 1274 ProcessorBehaviour behaviour() const override; assemblyType()1275 AssemblyType assemblyType() const override { return WorkingOriented; } 1276 }; 1277 1278 1279 class Instr_xorlw : public Instruction 1280 { 1281 public: Instr_xorlw(int literal)1282 Instr_xorlw( int literal ) { m_literal = literal; } 1283 QString code() const override; 1284 void generateLinksAndStates( Code::iterator current ) override; 1285 ProcessorBehaviour behaviour() const override; assemblyType()1286 AssemblyType assemblyType() const override { return WorkingOriented; } 1287 }; 1288 //END Literal and Control Operations 1289 1290 1291 1292 //BEGIN Microbe (non-assembly) Operations 1293 class Instr_sourceCode : public Instruction 1294 { 1295 public: Instr_sourceCode(const QString & source)1296 Instr_sourceCode( const QString & source ) { m_raw = source; } 1297 QString code() const override; type()1298 InstructionType type() const override { return Comment; } assemblyType()1299 AssemblyType assemblyType() const override { return None; } 1300 }; 1301 1302 1303 class Instr_asm : public Instruction 1304 { 1305 public: Instr_asm(const QString & raw)1306 Instr_asm( const QString & raw ) { m_raw = raw; } 1307 QString code() const override; type()1308 InstructionType type() const override { return Raw; } assemblyType()1309 AssemblyType assemblyType() const override { return None; } 1310 }; 1311 1312 1313 // Like Instr_asm, but does not put ;asm {} in, used 1314 // for internal things like gpasm directives etc... 1315 class Instr_raw : public Instruction 1316 { 1317 public: Instr_raw(const QString & raw)1318 Instr_raw( const QString & raw ) { m_raw = raw; } 1319 QString code() const override; type()1320 InstructionType type() const override { return Raw; } assemblyType()1321 AssemblyType assemblyType() const override { return None; } 1322 }; 1323 //END Microbe (non-assembly) Operations 1324 1325 1326 1327 #endif 1328