File indexing completed on 2024-07-21 08:05:26

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