File indexing completed on 2025-04-20 08:13:14
0001 /*************************************************************************** 0002 * Copyright (C) 2004-2005 by Daniel Clarke <daniel.jc@gmail.com> * 0003 * 2005 by David Saxton <david@bluehaze.org> * 0004 * * 0005 * 24-04-2007 * 0006 * Modified to add pic 16f877,16f627 and 16f628 * 0007 * by george john george@space-kerala.org * 0008 * supported by SPACE www.space-kerala.org * 0009 * * 0010 * This program is free software; you can redistribute it and/or modify * 0011 * it under the terms of the GNU General Public License as published by * 0012 * the Free Software Foundation; either version 2 of the License, or * 0013 * (at your option) any later version. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, * 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0018 * GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program; if not, write to the * 0022 * Free Software Foundation, Inc., * 0023 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0024 ***************************************************************************/ 0025 0026 #ifndef INSTRUCTION_H 0027 #define INSTRUCTION_H 0028 0029 #include <QMap> 0030 #include <QString> 0031 #include <QStringList> 0032 #include <QList> 0033 0034 class Code; 0035 class CodeIterator; 0036 class CodeConstIterator; 0037 class Instruction; 0038 class PIC14; 0039 0040 typedef QList<Instruction*> InstructionList; 0041 0042 0043 /** 0044 Abstraction for a Register - should be used instead of a register name. Contains 0045 info like whether or not the adressing of the register depends on the bank 0046 selection. 0047 0048 @author David Saxton 0049 */ 0050 class Register 0051 { 0052 public: 0053 enum Type 0054 { 0055 TMR0, 0056 OPTION_REG, 0057 PCL, 0058 STATUS, 0059 FSR, 0060 PORTA, 0061 TRISA, 0062 PORTB, 0063 TRISB, 0064 EEDATA, 0065 EECON1, 0066 EEADR, 0067 EECON2, 0068 PCLATH, 0069 INTCON, 0070 //modification start 0071 PORTC, 0072 PORTD, 0073 PORTE, 0074 TRISC, 0075 TRISD, 0076 TRISE, 0077 ADCON0, 0078 ADCON1, 0079 //modification end 0080 // The following three are "special" 0081 WORKING, // Not a register that is addressable by an address 0082 GPR, // Refers to the collection of General Purpose Registers 0083 //modification start 0084 PIR1, 0085 PIR2, 0086 TMR1L, 0087 TMR1H, 0088 T1CON, 0089 TMR2, 0090 T2CON, 0091 RCSTA, 0092 TXREG, 0093 RCREG, 0094 ADRESH, 0095 PIE1, 0096 TXSTA, 0097 ADRESL, 0098 EEDATH, 0099 EEADRH, 0100 SSPBUF, 0101 SSPCON, 0102 CCPR1L, 0103 CCPR1H, 0104 CCP1CON, 0105 CCPR2L, 0106 CCPR2H, 0107 CCP2CON, 0108 PIE2, 0109 PCON, 0110 SSPCON2, 0111 PR2, 0112 SSPADD, 0113 SSPSTAT, 0114 SPBRG, 0115 VRCON, 0116 CMCON, 0117 0118 //modification end 0119 none // used in default constructor 0120 //TODO 0121 //SSPBUF:SSPCON:CCPR1L:CCPR1H:CCP1CON:CCPR2L:CCPR2H:CCP2CON:--FOR BANK0 0122 //PIE2:PCON:SSPCON2:PR2:SSPADD:SSPSTAT:SPBRG:--------FOR BANK1 0123 }; 0124 0125 // These banks are used for ORing together in the banks() function 0126 enum Banks 0127 { 0128 Bank0 = 1 << 0, 0129 Bank1 = 1 << 1 0130 }; 0131 0132 /** 0133 * Creates a register of the given type, giving it the appropriate name. 0134 * Note that this constructor should not be used for GPR. 0135 */ 0136 Register( Type type = none ); 0137 /** 0138 * Construct a Register with the given name. If the name is not 0139 * recognized, then it is assumed to be a GPR register. 0140 */ 0141 Register( const QString & name ); 0142 /** 0143 * Construct a Register with the given name. If the name is not 0144 * recognized, then it is assumed to be a GPR register. 0145 */ 0146 Register( const char * name ); 0147 /** 0148 * @return less-than-equality between registers; name is only compared 0149 * if both registers have type GPR. 0150 */ 0151 bool operator < ( const Register & reg ) const; 0152 /** 0153 * @return equality between registers; name is only compared if both 0154 * registers have type GPR. 0155 */ 0156 bool operator == ( const Register & reg ) const; 0157 /** 0158 * @return 0x1 and 0x2 for being addressable from banks 0 and 1 0159 * respectively, OR'ed together. 0160 */ 0161 uchar banks() const; 0162 /** 0163 * Convenience function. 0164 * @see banks 0165 */ 0166 bool bankDependent() const; 0167 /** 0168 * Returns the name of the register, or the alias for the GPR. 0169 */ 0170 QString name() const { return m_name; } 0171 /** 0172 * @return the type of register. 0173 */ 0174 Type type() const { return m_type; } 0175 /** 0176 * From the Optimizer's perspective, it is OK to remove, change or add 0177 * any instruction so long as there are no visible external changes that 0178 * go against the original intention of the microbe source (a general 0179 * guiding principle). Therefore, this function returns true for PORT 0180 * and TRIS registers, false for everything else. 0181 */ 0182 bool affectsExternal() const; 0183 0184 protected: 0185 QString m_name; 0186 Type m_type; 0187 }; 0188 0189 0190 0191 class RegisterBit 0192 { 0193 public: 0194 enum STATUS_bits 0195 { 0196 C = 0, // Carry 0197 DC = 1, // Digit carry 0198 Z = 2, // Zero 0199 NOT_PD = 3, // Power-down 0200 NOT_TO = 4, // Time-out 0201 RP0 = 5, // Bank Select 0202 RP1 = 6, 0203 IRP = 7 0204 }; 0205 0206 enum INTCON_bits 0207 { 0208 RBIF = 0, 0209 INTF = 1, 0210 T0IF = 2, 0211 RBIE = 3, 0212 INTE = 4, 0213 T0IE = 5, 0214 EEIE = 6, 0215 GIE = 7 0216 }; 0217 0218 enum OPTION_bits 0219 { 0220 PS0 = 0, 0221 PS1 = 1, 0222 PS2 = 2, 0223 PSA = 3, 0224 T0SE = 4, 0225 T0CS = 5, 0226 INTEDG = 6, 0227 NOT_RBPU = 7 0228 }; 0229 0230 enum EECON1_bits 0231 { 0232 RD = 0, 0233 WR = 1, 0234 WREN = 2, 0235 WRERR = 3, 0236 EEIF = 4, 0237 EEPGD = 7 0238 }; 0239 /** 0240 * Constructs a bit of the given register type at the given position. 0241 */ 0242 RegisterBit( uchar bitPos = 0, Register::Type reg = Register::none ); 0243 /** 0244 * Construct a register bit with the given name. 0245 */ 0246 RegisterBit( const QString & name ); 0247 /** 0248 * Construct a register bit with the given name. 0249 */ 0250 RegisterBit( const char * name ); 0251 /** 0252 * @warning do not trust this value! actually, this function should be 0253 * removed, or the constructors fixed so that this value can be trusted. 0254 * @return the register type that the bit belongs to. 0255 */ 0256 Register::Type registerType() const { return m_registerType; } 0257 /** 0258 * @return the position of the bit, e.g. "5" for RP0. 0259 */ 0260 uchar bitPos() const { return m_bitPos; } 0261 /** 0262 * @return the bit, e.g. "0x20" for Z. 0263 */ 0264 uchar bit() const { return (1 << m_bitPos); } 0265 /** 0266 * @return the name of the bit, e.g. "Z" for Z. 0267 */ 0268 QString name() const { return m_name; } 0269 0270 0271 protected: 0272 /** 0273 * Determines the register type and bit pos from the bit name (m_name). 0274 */ 0275 void initFromName(); 0276 0277 Register::Type m_registerType; 0278 uchar m_bitPos:3; 0279 QString m_name; 0280 }; 0281 0282 0283 0284 0285 /** 0286 Contains information on the state of a register before an instruction is 0287 executed. 0288 0289 Note that all the "uchar" values in this class should be considered as the 8 0290 bits of a register. So for example, if known=0x2, then only the second bit of 0291 the register is known, and its value is given in the second bit of value. 0292 0293 @author David Saxton 0294 */ 0295 class RegisterState 0296 { 0297 public: 0298 RegisterState(); 0299 0300 /** 0301 * Merges the known and values together, (possibly) reducing what is 0302 * known. 0303 */ 0304 void merge( const RegisterState & state ); 0305 /** 0306 * Sets known to unknown and value to zero. 0307 */ 0308 void reset(); 0309 /** 0310 * Returns the bits that are definitely zero. 0311 */ 0312 uchar definiteZeros() const { return (~value) & known; } 0313 /** 0314 * Returns the bits that are definitely one. 0315 */ 0316 uchar definiteOnes() const { return value & known; } 0317 /** 0318 * Returns the bits that are unknown. 0319 */ 0320 uchar unknown() const { return ~known; } 0321 /** 0322 * @return the largest possible value that this register might be 0323 * storing, based on which bits are known and the value of those bits. 0324 */ 0325 uchar maxValue() const { return (value & known) | (~known); } 0326 /** 0327 * @return the smallest possible value that this register might be 0328 * storing, based on which bits are known and the value of those bits. 0329 */ 0330 uchar minValue() const { return (value & known); } 0331 /** 0332 * @return whether the known and value uchars are equal 0333 */ 0334 bool operator == ( const RegisterState & state ) const; 0335 /** 0336 * @return whether either of the known and value uchars are not equal. 0337 */ 0338 bool operator != ( const RegisterState & state ) const { return !( *this == state ); } 0339 /** 0340 * Prints known and value. 0341 */ 0342 void print(); 0343 0344 /// Whether or not the value is known (for each bit). 0345 uchar known; 0346 0347 /// The value of the register. 0348 uchar value; 0349 }; 0350 0351 0352 /** 0353 Setting and dependency information for register bits. See the respective member 0354 descriptions for more information. 0355 0356 @author David Saxton 0357 */ 0358 class RegisterBehaviour 0359 { 0360 public: 0361 RegisterBehaviour(); 0362 /** 0363 * Sets "depends", "indep" and "changes" to 0x0. 0364 */ 0365 void reset(); 0366 0367 /** 0368 * The bits whose value before the instruction is executed will affect 0369 * the processor state after execution. So for example, 0370 * in MOVLW this will be 0x0; 0371 * in ANDLW this will be the bits that are non-zero in the literal; 0372 * in BTFSC this will be the bit being tested (if this is the register 0373 * being tested). 0374 */ 0375 uchar depends; 0376 0377 /** 0378 * The bits whose value after the instruction is executed is independent 0379 * of the value before execution. So for example, 0380 * in MOVLW, this will be 0xff; 0381 * in ANDLW this will be the bits that are zero in the literal; 0382 * in BTFSC this will be 0x0. 0383 */ 0384 uchar indep; 0385 }; 0386 0387 0388 0389 /** 0390 Contains information on the state of a processor; e.g. register values 0391 0392 @author David Saxton 0393 */ 0394 class ProcessorState 0395 { 0396 public: 0397 ProcessorState(); 0398 /** 0399 * Calls merge for each RegisterState. 0400 */ 0401 void merge( const ProcessorState & state ); 0402 /** 0403 * Calls reset() for each RegisterState. 0404 */ 0405 void reset(); 0406 /** 0407 * @return state for the given register. 0408 */ 0409 RegisterState & reg( const Register & reg ); 0410 /** 0411 * @return state for the given register. 0412 */ 0413 RegisterState reg( const Register & reg ) const; 0414 /** 0415 * @return whether all the RegisterStates are identical 0416 */ 0417 bool operator == ( const ProcessorState & state ) const; 0418 /** 0419 * @return whether any of the RegisterStates are not equal. 0420 */ 0421 bool operator != ( const ProcessorState & state ) const { return !( *this == state ); } 0422 /** 0423 * Displays each register's name and calls RegisterState::print in turn. 0424 */ 0425 void print(); 0426 0427 /// The working register 0428 RegisterState working; 0429 0430 /// The status register 0431 RegisterState status; 0432 0433 protected: 0434 typedef QMap< Register, RegisterState > RegisterMap; 0435 /** 0436 * All registers other than working and status. Entries are created on 0437 * calls to reg with a new Register. 0438 */ 0439 RegisterMap m_registers; 0440 }; 0441 0442 0443 /** 0444 Contains behavioural information for each register. 0445 0446 @author David Saxton 0447 */ 0448 class ProcessorBehaviour 0449 { 0450 public: 0451 ProcessorBehaviour(); 0452 /** 0453 * Calls reset() for each RegisterBehaviour. 0454 */ 0455 void reset(); 0456 /** 0457 * @return behaviour for the given register. 0458 */ 0459 RegisterBehaviour & reg( const Register & reg ); 0460 0461 /// The working register 0462 RegisterBehaviour working; 0463 0464 /// The status register 0465 RegisterBehaviour status; 0466 0467 protected: 0468 typedef QMap< Register, RegisterBehaviour > RegisterMap; 0469 /** 0470 * All registers other than working and status. Entries are created on 0471 * calls to reg with a new Register. 0472 */ 0473 RegisterMap m_registers; 0474 }; 0475 0476 0477 /** 0478 Contains information on whether a register is overwritten before its value is 0479 used. Each uchar respresents the 8 bits of the register; if the bit is 1, then 0480 the corresponding bit of the register is used by the Instruction or one 0481 of its outputs before it is overwritten. 0482 0483 @author David Saxton 0484 */ 0485 class RegisterDepends 0486 { 0487 public: 0488 RegisterDepends(); 0489 /** 0490 * Sets all the depends values to 0x0. 0491 */ 0492 void reset(); 0493 /** 0494 * @return behaviour for the given register. 0495 */ 0496 uchar & reg( const Register & reg ); 0497 0498 /// The working register 0499 uchar working; 0500 0501 /// The status register 0502 uchar status; 0503 0504 protected: 0505 typedef QMap< Register, uchar > RegisterMap; 0506 /** 0507 * All registers other than working and status. Entries are created on 0508 * calls to reg with a new Register. 0509 */ 0510 RegisterMap m_registers; 0511 }; 0512 0513 0514 0515 /** 0516 Holds a program structure; an (ordered) list of blocks of code, each of which 0517 contains a list of instructions. The structure is such as to provide easy 0518 manipulation of the program, as well as aiding the optimizer. 0519 0520 @author David Saxton 0521 */ 0522 class Code 0523 { 0524 public: 0525 Code(); 0526 0527 typedef CodeIterator iterator; 0528 typedef CodeConstIterator const_iterator; 0529 0530 enum InstructionPosition 0531 { 0532 InterruptHandler = 0, 0533 LookupTable = 1, 0534 Middle = 2, ///< Used for main code 0535 Subroutine = 3, ///< Used for subroutines 0536 0537 PositionCount = 4 ///< This must remain the last item and be the number of valid positions 0538 }; 0539 0540 CodeIterator begin(); 0541 CodeIterator end(); 0542 CodeConstIterator begin() const; 0543 CodeConstIterator end() const; 0544 0545 /** 0546 * Queues a label to be given to the next instruction to be added in the 0547 * given position 0548 */ 0549 void queueLabel( const QString & label, InstructionPosition position = Middle ); 0550 /** 0551 * Returns the list of queued labels for the given position. This is 0552 * used in merging code, as we also need to merge any queued labels. 0553 */ 0554 QStringList queuedLabels( InstructionPosition position ) const { return m_queuedLabels[position]; } 0555 /** 0556 * Adds the Instruction at the given position. 0557 */ 0558 void append( Instruction * instruction, InstructionPosition position = Middle ); 0559 /** 0560 * @returns the Instruction with the given label (or null if no such 0561 * Instruction). 0562 */ 0563 Instruction * instruction( const QString & label ) const; 0564 /** 0565 * Look for an Assembly instruction (other types are ignored). 0566 * @return an iterator to the current instruction, or end if it wasn't 0567 * found. 0568 */ 0569 iterator find( Instruction * instruction ); 0570 /** 0571 * Removes the Instruction (regardless of position). 0572 * @warning You should always use only this function to remove an 0573 * instruction as this function handles stuff such as pushing labels 0574 * from this instruction onto the next before deletion. 0575 */ 0576 void removeInstruction( Instruction * instruction ); 0577 /** 0578 * Merges all the blocks output together with other magic such as adding 0579 * variables, gpasm directives, etc. 0580 */ 0581 QString generateCode( PIC14 * pic ) const; 0582 /** 0583 * Appends the InstructionLists to the end of the ones in this instance. 0584 * @param middleInsertionPosition is the position where the middle code 0585 * blocks of the given code will be merged at. 0586 */ 0587 void merge( Code * code, InstructionPosition middleInsertionPosition = Middle ); 0588 /** 0589 * @returns the InstructionList for the given insertion position. 0590 */ 0591 InstructionList * instructionList( InstructionPosition position ) { return & m_instructionLists[position]; } 0592 /** 0593 * @returns the InstructionList for the given insertion position. 0594 */ 0595 const InstructionList * instructionList( InstructionPosition position ) const { return & m_instructionLists[position]; } 0596 /** 0597 * Calls generateOutputLinks for each Instruction 0598 */ 0599 void generateLinksAndStates(); 0600 /** 0601 * Calls setUsed(false) for all instructions. 0602 */ 0603 void setAllUnused(); 0604 /** 0605 * Does any work that is needed to the code before it can be passed to 0606 * the optimizer (such as flushing out queued labels). This is called 0607 * after all the instructions have been added to the code. 0608 */ 0609 void postCompileConstruct(); 0610 0611 protected: 0612 /** 0613 * Used when generating the code. Finds the list of general purpose 0614 * registers that are referenced and returns their aliases. 0615 */ 0616 QStringList findVariables() const; 0617 0618 InstructionList m_instructionLists[ PositionCount ]; ///< @see InstructionPosition 0619 QStringList m_queuedLabels[ PositionCount ]; ///< @see InstructionPosition 0620 0621 private: // Disable copy constructor and operator= 0622 Code( const Code & ); 0623 Code &operator=( const Code & ); 0624 }; 0625 0626 0627 /** 0628 Iterates over all the instructions, going seamlessly between the different lists 0629 and avoiding the non-assembly instructions. 0630 0631 @author David Saxton 0632 */ 0633 class CodeIterator 0634 { 0635 public: 0636 bool operator != ( const CodeIterator & i ) const { return it != i.it; } 0637 bool operator == ( const CodeIterator & i ) const { return it == i.it; } 0638 CodeIterator & operator ++ (); 0639 Instruction * & operator * () { return *it; } 0640 /** 0641 * Deletes the instruction that this iterator is currently pointing at 0642 * (removing it from any lists), and increments the iterator to the next 0643 * instruction. 0644 */ 0645 CodeIterator & removeAndIncrement(); 0646 /** 0647 * Inserts the given instruction before the instruction pointed at by 0648 * this iterator. 0649 */ 0650 void insertBefore( Instruction * ins ); 0651 0652 InstructionList::iterator it; 0653 InstructionList::iterator listEnd; 0654 Code::InstructionPosition pos; 0655 Code * code; 0656 InstructionList * list; 0657 }; 0658 0659 0660 /** 0661 A const version of CodeIterator (cannot change instructions). 0662 0663 @author David Saxton 0664 */ 0665 class CodeConstIterator 0666 { 0667 public: 0668 bool operator != ( const CodeConstIterator & i ) const { return it != i.it; } 0669 bool operator == ( const CodeConstIterator & i ) const { return it == i.it; } 0670 CodeConstIterator & operator ++ (); 0671 const Instruction * operator * () const { return *it; } 0672 0673 InstructionList::const_iterator it; 0674 InstructionList::const_iterator listEnd; 0675 Code::InstructionPosition pos; 0676 const Code * code; 0677 const InstructionList * list; 0678 }; 0679 0680 0681 /** 0682 @author Daniel Clarke 0683 @author David Saxton 0684 */ 0685 class Instruction 0686 { 0687 public: 0688 enum InstructionType 0689 { 0690 Assembly, 0691 Raw, // User-inserted assembly 0692 Comment 0693 }; 0694 /** 0695 * Used in optimization. Note that this follows roughly, but not 0696 * exactly, the Microchip classifications of similar categories. 0697 */ 0698 enum AssemblyType 0699 { 0700 /** 0701 * Writes to a file (which can be obtained by calling outputReg(). 0702 */ 0703 FileOriented, 0704 0705 /** 0706 * Writes to a file bit (so BCF or BSF). 0707 */ 0708 BitOriented, 0709 0710 /** 0711 * Affects the working register via a literal operation, with no 0712 * branching (so excludes retlw). 0713 */ 0714 WorkingOriented, 0715 0716 /** 0717 * Assembly instructions that don't come under the above categories 0718 * (so control and branching instructions). 0719 */ 0720 Other, 0721 0722 /** 0723 * The Instruction is not of Assembly InstructionType. 0724 */ 0725 None 0726 }; 0727 0728 Instruction(); 0729 virtual ~Instruction(); 0730 void setCode( Code * code ) { m_pCode = code; } 0731 0732 /** 0733 * This is used to decide how to output the instruction, and which 0734 * instructions to avoid while optimizing. 0735 */ 0736 virtual InstructionType type() const { return Assembly; } 0737 /** 0738 * @return the AssemblyType (None for non-Assembly instructions). 0739 */ 0740 virtual AssemblyType assemblyType() const = 0; 0741 /** 0742 * The text to output to the generated assembly. 0743 */ 0744 virtual QString code() const = 0; 0745 /** 0746 * The input processor state is used to generate the outputlinks and the 0747 * output processor state. 0748 */ 0749 void setInputState( const ProcessorState & processorState ) { m_inputState = processorState; } 0750 /** 0751 * By using the ProcessorState, the Instruction should: 0752 * * Find all instructions that could be executed after this instruction. 0753 * * Generate the output ProcessorState. 0754 * The default behaviour of this function is to link to the next 0755 * sequential instruction, and to generate an unknown ProcessorState. 0756 * @warning if your instruction depends on any bits, then it must 0757 * reinherit this function and say so. 0758 * @param instruction points at this instruction 0759 */ 0760 virtual void generateLinksAndStates( Code::iterator instruction ); 0761 /** 0762 * @return the processor behaviour for this instruction. 0763 */ 0764 virtual ProcessorBehaviour behaviour() const; 0765 /** 0766 * An input link is an instruction that might be executed immediately 0767 * before this Instruction. 0768 */ 0769 void addInputLink( Instruction * inputLink ); 0770 /** 0771 * An output link is an instruction that might be executed immediately 0772 * after this Instruction. 0773 */ 0774 void addOutputLink( Instruction * inputLink ); 0775 /** 0776 * The list of instructions that might be executed immediately before 0777 * this instruction. 0778 * @see addInputLink 0779 */ 0780 InstructionList inputLinks() const { return m_inputLinks; } 0781 /** 0782 * The list of instructions that might be executed immediately after 0783 * this instruction. Instruction does not generate these links; instead 0784 * the list is generated Code::generateLinksAndStates function. 0785 */ 0786 InstructionList outputLinks() const { return m_outputLinks; } 0787 /** 0788 * Remove the given input link from the instruction. 0789 */ 0790 void removeInputLink( Instruction * ins ); 0791 /** 0792 * Remove the given output link from the instruction. 0793 */ 0794 void removeOutputLink( Instruction * ins ); 0795 /** 0796 * Clears all input and output links from this instruction. This does 0797 * not remove references to this instruction from other instructions. 0798 */ 0799 void clearLinks(); 0800 /** 0801 * An instruction may have zero, or more than zero labels associated 0802 * with it - these will be printed before the instruction in the 0803 * assembly output. 0804 */ 0805 QStringList labels() const { return m_labels; } 0806 /** 0807 * @see labels 0808 */ 0809 void addLabels( const QStringList & labels ); 0810 /** 0811 * @see labels 0812 */ 0813 void setLabels( const QStringList & labels ); 0814 /** 0815 * @see used 0816 */ 0817 void setUsed( bool used ) { m_bUsed = used; } 0818 /** 0819 * Used for optimization purposes in determining whether the instruction 0820 * has been examined yet (to avoid infinite loops). 0821 */ 0822 bool isUsed() const { return m_bUsed; } 0823 /** 0824 * Set by the optimizer to indicate whether this instruction or any of 0825 * its outputs overwrite any of the bits of the given register. 0826 */ 0827 void setRegisterDepends( uchar depends, const Register & reg ) { m_registerDepends.reg(reg) = depends; } 0828 /** 0829 * @see setOutputsOverwriteWorking 0830 */ 0831 uchar registerDepends( const Register & reg ) { return m_registerDepends.reg(reg); } 0832 /** 0833 * Resets the overwrites. 0834 */ 0835 void resetRegisterDepends() { m_registerDepends.reset(); } 0836 /** 0837 * @return the input processor state to this instruction. 0838 * @see setInputState 0839 */ 0840 ProcessorState inputState() const { return m_inputState; } 0841 /** 0842 * @return the output processor state from this instruction. 0843 * @see generateLinksAndStates. 0844 */ 0845 ProcessorState outputState() const { return m_outputState; } 0846 /** 0847 * Only applicable to Instructions that refer to a file. 0848 */ 0849 Register file() const { return m_file; } 0850 /** 0851 * Only applicable to Instructions that refer to a bit (such as BCF). 0852 */ 0853 RegisterBit bit() const { return m_bit; } 0854 /** 0855 * Only applicable to instructions that refer to a literal (such as 0856 * XORLW). 0857 */ 0858 uchar literal() const { return m_literal; } 0859 /** 0860 * Applicable only to instructions that save a result to working or file 0861 * depending on the destination bit. 0862 */ 0863 Register outputReg() const { return (m_dest == 0) ? Register::WORKING : m_file; } 0864 /** 0865 * Applicable only to instructions that use the destination flag. 0866 */ 0867 unsigned dest() const { return m_dest; } 0868 0869 protected: 0870 /** 0871 * This function is provided for convenience; it creates links to the 0872 * first or second instructions after this one, depending on the value 0873 * of firstOutput and secondOutput. 0874 * @see generateOutputLinks 0875 */ 0876 void makeOutputLinks( Code::iterator current, bool firstOutput = true, bool secondOutput = false ); 0877 /** 0878 * This function is provided for instructions that jump to a label (i.e. 0879 * call and goto). 0880 */ 0881 void makeLabelOutputLink( const QString & label ); 0882 0883 RegisterDepends m_registerDepends; 0884 bool m_bInputStateChanged; 0885 bool m_bUsed; 0886 bool m_bPositionAffectsBranching; 0887 InstructionList m_inputLinks; 0888 InstructionList m_outputLinks; 0889 QStringList m_labels; 0890 Code * m_pCode; 0891 0892 // Commonly needed member variables for assembly instructions 0893 Register m_file; 0894 RegisterBit m_bit; 0895 QString m_raw; // Used by source code, raw asm, etc 0896 uchar m_literal; 0897 unsigned m_dest:1; // is 0 (W) or 1 (file). 0898 ProcessorState m_inputState; 0899 ProcessorState m_outputState; 0900 0901 private: // Disable copy constructor and operator= 0902 Instruction( const Instruction & ); 0903 Instruction &operator=( const Instruction & ); 0904 }; 0905 0906 0907 0908 //BEGIN Byte-Oriented File Register Operations 0909 class Instr_addwf : public Instruction 0910 { 0911 public: 0912 Instr_addwf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 0913 QString code() const override; 0914 void generateLinksAndStates( Code::iterator current ) override; 0915 ProcessorBehaviour behaviour() const override; 0916 AssemblyType assemblyType() const override { return FileOriented; } 0917 }; 0918 0919 0920 class Instr_andwf : public Instruction 0921 { 0922 public: 0923 Instr_andwf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 0924 QString code() const override; 0925 void generateLinksAndStates( Code::iterator current ) override; 0926 ProcessorBehaviour behaviour() const override; 0927 AssemblyType assemblyType() const override { return FileOriented; } 0928 }; 0929 0930 0931 class Instr_clrf : public Instruction 0932 { 0933 public: 0934 Instr_clrf( const Register & file ) { m_file = file; m_dest = 1; } 0935 QString code() const override; 0936 void generateLinksAndStates( Code::iterator current ) override; 0937 ProcessorBehaviour behaviour() const override; 0938 AssemblyType assemblyType() const override { return FileOriented; } 0939 }; 0940 0941 0942 //TODO CLRW 0943 //TODO COMF 0944 0945 0946 class Instr_decf : public Instruction 0947 { 0948 public: 0949 Instr_decf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 0950 QString code() const override; 0951 void generateLinksAndStates( Code::iterator current ) override; 0952 ProcessorBehaviour behaviour() const override; 0953 AssemblyType assemblyType() const override { return FileOriented; } 0954 }; 0955 0956 0957 class Instr_decfsz : public Instruction 0958 { 0959 public: 0960 Instr_decfsz( const Register & file, int dest ) { m_file = file; m_dest = dest; } 0961 QString code() const override; 0962 void generateLinksAndStates( Code::iterator current ) override; 0963 ProcessorBehaviour behaviour() const override; 0964 AssemblyType assemblyType() const override { return FileOriented; } 0965 }; 0966 0967 0968 class Instr_incf : public Instruction 0969 { 0970 public: 0971 Instr_incf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 0972 QString code() const override; 0973 void generateLinksAndStates( Code::iterator current ) override; 0974 ProcessorBehaviour behaviour() const override; 0975 AssemblyType assemblyType() const override { return FileOriented; } 0976 }; 0977 0978 0979 //TODO INCFSZ 0980 0981 0982 class Instr_iorwf : public Instruction 0983 { 0984 public: 0985 Instr_iorwf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 0986 QString code() const override; 0987 void generateLinksAndStates( Code::iterator current ) override; 0988 ProcessorBehaviour behaviour() const override; 0989 AssemblyType assemblyType() const override { return FileOriented; } 0990 }; 0991 0992 0993 class Instr_movf : public Instruction 0994 { 0995 public: 0996 Instr_movf( const Register & file, int dest ) { m_file = file; m_dest = dest; } 0997 QString code() const override; 0998 void generateLinksAndStates( Code::iterator current ) override; 0999 ProcessorBehaviour behaviour() const override; 1000 AssemblyType assemblyType() const override { return FileOriented; } 1001 }; 1002 1003 1004 class Instr_movwf : public Instruction 1005 { 1006 public: 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; 1011 AssemblyType assemblyType() const override { return FileOriented; } 1012 }; 1013 1014 1015 //TODO NOP 1016 1017 1018 class Instr_rlf : public Instruction 1019 { 1020 public: 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; 1025 AssemblyType assemblyType() const override { return FileOriented; } 1026 }; 1027 1028 1029 class Instr_rrf : public Instruction 1030 { 1031 public: 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; 1036 AssemblyType assemblyType() const override { return FileOriented; } 1037 }; 1038 1039 1040 class Instr_subwf : public Instruction 1041 { 1042 public: 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; 1047 AssemblyType assemblyType() const override { return FileOriented; } 1048 }; 1049 1050 1051 class Instr_swapf : public Instruction 1052 { 1053 public: 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; 1058 AssemblyType assemblyType() const override { return FileOriented; } 1059 }; 1060 1061 1062 class Instr_xorwf : public Instruction 1063 { 1064 public: 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; 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: 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; 1083 AssemblyType assemblyType() const override { return BitOriented; } 1084 }; 1085 1086 1087 class Instr_bsf : public Instruction 1088 { 1089 public: 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; 1094 AssemblyType assemblyType() const override { return BitOriented; } 1095 }; 1096 1097 1098 class Instr_btfsc : public Instruction 1099 { 1100 public: 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; 1105 AssemblyType assemblyType() const override { return Other; } 1106 }; 1107 1108 1109 class Instr_btfss : public Instruction 1110 { 1111 public: 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; 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: 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; 1130 AssemblyType assemblyType() const override { return WorkingOriented; } 1131 }; 1132 1133 1134 1135 class Instr_andlw : public Instruction 1136 { 1137 public: 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; 1142 AssemblyType assemblyType() const override { return WorkingOriented; } 1143 }; 1144 1145 1146 class Instr_call : public Instruction 1147 { 1148 public: 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; 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 1164 QString label() const { return m_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: 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; 1192 AssemblyType assemblyType() const override { return Other; } 1193 1194 QString label() const { return m_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: 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; 1209 AssemblyType assemblyType() const override { return WorkingOriented; } 1210 }; 1211 1212 1213 class Instr_movlw : public Instruction 1214 { 1215 public: 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; 1220 AssemblyType assemblyType() const override { return WorkingOriented; } 1221 }; 1222 1223 1224 class Instr_retfie : public Instruction 1225 { 1226 public: 1227 Instr_retfie() {}; 1228 QString code() const override; 1229 void generateLinksAndStates( Code::iterator current ) override; 1230 ProcessorBehaviour behaviour() const override; 1231 AssemblyType assemblyType() const override { return Other; } 1232 }; 1233 1234 1235 class Instr_retlw : public Instruction 1236 { 1237 public: 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; 1242 AssemblyType assemblyType() const override { return Other; } 1243 }; 1244 1245 1246 class Instr_return : public Instruction 1247 { 1248 public: 1249 Instr_return() {}; 1250 QString code() const override; 1251 void generateLinksAndStates( Code::iterator current ) override; 1252 ProcessorBehaviour behaviour() const override; 1253 AssemblyType assemblyType() const override { return Other; } 1254 }; 1255 1256 1257 class Instr_sleep : public Instruction 1258 { 1259 public: 1260 Instr_sleep() {}; 1261 QString code() const override; 1262 void generateLinksAndStates( Code::iterator current ) override; 1263 ProcessorBehaviour behaviour() const override; 1264 AssemblyType assemblyType() const override { return Other; } 1265 }; 1266 1267 1268 class Instr_sublw : public Instruction 1269 { 1270 public: 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; 1275 AssemblyType assemblyType() const override { return WorkingOriented; } 1276 }; 1277 1278 1279 class Instr_xorlw : public Instruction 1280 { 1281 public: 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; 1286 AssemblyType assemblyType() const override { return WorkingOriented; } 1287 }; 1288 //END Literal and Control Operations 1289 1290 1291 1292 //BEGIN MicrobeApp (non-assembly) Operations 1293 class Instr_sourceCode : public Instruction 1294 { 1295 public: 1296 Instr_sourceCode( const QString & source ) { m_raw = source; } 1297 QString code() const override; 1298 InstructionType type() const override { return Comment; } 1299 AssemblyType assemblyType() const override { return None; } 1300 }; 1301 1302 1303 class Instr_asm : public Instruction 1304 { 1305 public: 1306 Instr_asm( const QString & raw ) { m_raw = raw; } 1307 QString code() const override; 1308 InstructionType type() const override { return Raw; } 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: 1318 Instr_raw( const QString & raw ) { m_raw = raw; } 1319 QString code() const override; 1320 InstructionType type() const override { return Raw; } 1321 AssemblyType assemblyType() const override { return None; } 1322 }; 1323 //END MicrobeApp (non-assembly) Operations 1324 1325 1326 1327 #endif