Logo Search packages:      
Sourcecode: ktechlab version File versions  Download package

instruction.h

/***************************************************************************
 *   Copyright (C) 2004-2005 by Daniel Clarke <daniel.jc@gmail.com>        *
 *                      2005 by David Saxton <david@bluehaze.org>          *
 *                                                       *
 *   24-04-2007                                                            *
 *   Modified to add pic 16f877,16f627 and 16f628                    *
 *   by george john george@space-kerala.org                          *
 *   supported by SPACE www.space-kerala.org                         *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef INSTRUCTION_H
#define INSTRUCTION_H

#include <qmap.h>
#include <qstring.h>
#include <qstringlist.h>
#include <qvaluelist.h>

class Code;
class CodeIterator;
class CodeConstIterator;
class Instruction;
class PIC14;

typedef QValueList<Instruction*> InstructionList;


/**
Abstraction for a Register - should be used instead of a register name. Contains
info like whether or not the adressing of the register depends on the bank
selection.

@author David Saxton
*/
00050 class Register
{
      public:
            enum Type
            {
                  TMR0,
                  OPTION_REG,
                  PCL,
                  STATUS,
                  FSR,
                  PORTA,
                  TRISA,
                  PORTB,
                  TRISB,
                  EEDATA,
                  EECON1,
                  EEADR,
                  EECON2,
                  PCLATH,
                  INTCON,
//modification start
                  PORTC,
                  PORTD,
                  PORTE,
                  TRISC,
                  TRISD,
                  TRISE,
                  ADCON0,
                  ADCON1,
//modification end                  
                  // The following three are "special"
                  WORKING, // Not a register that is addressable by an address
                  GPR, // Refers to the collection of General Purpose Registers
//modification start
                  PIR1,
                  PIR2,
                  TMR1L,
                  TMR1H,
                  T1CON,
                  TMR2,
                  T2CON,
                  RCSTA,
                  TXREG,
                  RCREG,
                  ADRESH,
                  PIE1,
                  TXSTA,
                  ADRESL,
                  EEDATH,
                  EEADRH,
                  SSPBUF,
                  SSPCON,
                  CCPR1L,
                  CCPR1H,
                  CCP1CON,
                  CCPR2L,
                  CCPR2H,
                  CCP2CON,
                  PIE2,
                  PCON,
                  SSPCON2,
                  PR2,
                  SSPADD,
                  SSPSTAT,
                  SPBRG,
                  VRCON,
                  CMCON,

//modification end
                  none // used in default constructor
//TODO
//SSPBUF:SSPCON:CCPR1L:CCPR1H:CCP1CON:CCPR2L:CCPR2H:CCP2CON:--FOR BANK0 
//PIE2:PCON:SSPCON2:PR2:SSPADD:SSPSTAT:SPBRG:--------FOR BANK1
            };
            
            // These banks are used for ORing together in the banks() function
            enum Banks
            {
                  Bank0 = 1 << 0,
                  Bank1 = 1 << 1
            };
            
            /**
             * Creates a register of the given type, giving it the appropriate name.
             * Note that this constructor should not be used for GPR.
             */
            Register( Type type = none );
            /**
             * Construct a Register with the given name. If the name is not
             * recognized, then it is assumed to be a GPR register.
             */
            Register( const QString & name );
            /**
             * Construct a Register with the given name. If the name is not
             * recognized, then it is assumed to be a GPR register.
             */
            Register( const char * name );
            /**
             * @return less-than-equality between registers; name is only compared
             * if both registers have type GPR.
             */
            bool operator < ( const Register & reg ) const;
            /**
             * @return equality between registers; name is only compared if both
             * registers have type GPR.
             */
            bool operator == ( const Register & reg ) const;
            /**
             * @return 0x1 and 0x2 for being addressable from banks 0 and 1
             * respectively, OR'ed together.
             */
            uchar banks() const;
            /**
             * Convenience function.
             * @see banks
             */
            bool bankDependent() const;
            /**
             * Returns the name of the register, or the alias for the GPR.
             */
00170             QString name() const { return m_name; }
            /**
             * @return the type of register.
             */
00174             Type type() const { return m_type; }
            /**
             * From the Optimizer's perspective, it is OK to remove, change or add
             * any instruction so long as there are no visible external changes that
             * go against the original intention of the microbe source (a general
             * guiding principle). Therefore, this function returns true for PORT
             * and TRIS registers, false for everything else.
             */
            bool affectsExternal() const;
            
      protected:
            QString m_name;
            Type m_type;
};



class RegisterBit
{
      public:
            enum STATUS_bits
            {
                  C                 = 0, // Carry
                  DC                = 1, // Digit carry
                  Z                 = 2, // Zero
                  NOT_PD            = 3, // Power-down
                  NOT_TO            = 4, // Time-out
                  RP0               = 5, // Bank Select
                  RP1               = 6,
                  IRP               = 7
            };
            
            enum INTCON_bits
            {
                  RBIF        = 0,
                  INTF        = 1,
                  T0IF        = 2,
                  RBIE        = 3,
                  INTE        = 4,
                  T0IE        = 5,
                  EEIE        = 6,
                  GIE         = 7
            };
            
            enum OPTION_bits
            {
                  PS0         = 0,
                  PS1         = 1,
                  PS2         = 2,
                  PSA         = 3,
                  T0SE        = 4,
                  T0CS        = 5,
                  INTEDG            = 6,
                  NOT_RBPU    = 7
            };
            
            enum EECON1_bits
            {
                  RD          = 0,
                  WR          = 1,
                  WREN        = 2,
                  WRERR       = 3,
                  EEIF        = 4,
                  EEPGD           = 7
            };
            /**
             * Constructs a bit of the given register type at the given position.
             */
            RegisterBit( uchar bitPos = 0, Register::Type reg = Register::none );
            /**
             * Construct a register bit with the given name.
             */
            RegisterBit( const QString & name );
            /**
             * Construct a register bit with the given name.
             */
            RegisterBit( const char * name );
            /**
             * @warning do not trust this value! actually, this function should be
             * removed, or the constructors fixed so that this value can be trusted.
             * @return the register type that the bit belongs to.
             */
            Register::Type registerType() const { return m_registerType; }
            /**
             * @return the position of the bit, e.g. "5" for RP0.
             */
            uchar bitPos() const { return m_bitPos; }
            /**
             * @return the bit, e.g. "0x20" for Z.
             */
            uchar bit() const { return (1 << m_bitPos); }
            /**
             * @return the name of the bit, e.g. "Z" for Z.
             */
            QString name() const { return m_name; }
            
            
      protected:
            /**
             * Determines the register type and bit pos from the bit name (m_name).
             */
            void initFromName();
            
            Register::Type m_registerType;
            uchar m_bitPos:3;
            QString m_name;
};




/**
Contains information on the state of a register before an instruction is
executed.

Note that all the "uchar" values in this class should be considered as the 8
bits of a register. So for example, if known=0x2, then only the second bit of
the register is known, and its value is given in the second bit of value.

@author David Saxton
*/
00295 class RegisterState
{
      public:
            RegisterState();
            
            /**
             * Merges the known and values together, (possibly) reducing what is
             * known.
             */
            void merge( const RegisterState & state );
            /**
             * Sets known to unknown and value to zero.
             */
            void reset();
            /**
             * Returns the bits that are definitely zero.
             */
00312             uchar definiteZeros() const { return (~value) & known; }
            /**
             * Returns the bits that are definitely one.
             */
00316             uchar definiteOnes() const { return value & known; }
            /**
             * Returns the bits that are unknown.
             */
00320             uchar unknown() const { return ~known; }
            /**
             * @return the largest possible value that this register might be
             * storing, based on which bits are known and the value of those bits.
             */
00325             uchar maxValue() const { return (value & known) | (~known); }
            /**
             * @return the smallest possible value that this register might be
             * storing, based on which bits are known and the value of those bits.
             */
00330             uchar minValue() const { return (value & known); }
            /**
             * @return whether the known and value uchars are equal
             */
            bool operator == ( const RegisterState & state ) const;
            /**
             * @return whether either of the known and value uchars are not equal.
             */
00338             bool operator != ( const RegisterState & state ) const { return !( *this == state ); }
            /**
             * Prints known and value.
             */
            void print();
            
            /// Whether or not the value is known (for each bit).
00345             uchar known;
            
            /// The value of the register.
00348             uchar value;
};


/**
Setting and dependency information for register bits. See the respective member
descriptions for more information.

@author David Saxton
*/
00358 class RegisterBehaviour
{
      public:
            RegisterBehaviour();
            /**
             * Sets "depends", "indep" and "changes" to 0x0.
             */
            void reset();
            
            /**
             * The bits whose value before the instruction is executed will affect
             * the processor state after execution. So for example,
             *   in MOVLW this will be 0x0;
             *   in ANDLW this will be the bits that are non-zero in the literal;
             *   in BTFSC this will be the bit being tested (if this is the register
             *      being tested).
             */
00375             uchar depends;
            
            /**
             * The bits whose value after the instruction is executed is independent
             * of the value before execution. So for example,
             *   in MOVLW, this will be 0xff;
             *   in ANDLW this will be the bits that are zero in the literal;
             *   in BTFSC this will be 0x0.
             */
00384             uchar indep;
};



/**
Contains information on the state of a processor; e.g. register values

@author David Saxton
 */
00394 class ProcessorState
{
      public:
            ProcessorState();
            /**
             * Calls merge for each RegisterState.
             */
            void merge( const ProcessorState & state );
            /**
             * Calls reset() for each RegisterState.
             */
            void reset();
            /**
             * @return state for the given register.
             */
            RegisterState & reg( const Register & reg );
            /**
             * @return state for the given register.
             */
            RegisterState reg( const Register & reg ) const;
            /**
             * @return whether all the RegisterStates are identical
             */
            bool operator == ( const ProcessorState & state ) const;
            /**
             * @return whether any of the RegisterStates are not equal.
             */
00421             bool operator != ( const ProcessorState & state ) const { return !( *this == state ); }
            /**
             * Displays each register's name and calls RegisterState::print in turn.
             */
            void print();
            
            /// The working register
00428             RegisterState working;
            
            /// The status register
00431             RegisterState status;
            
      protected:
            typedef QMap< Register, RegisterState > RegisterMap;
            /**
             * All registers other than working and status. Entries are created on
             * calls to reg with a new Register.
             */
00439             RegisterMap m_registers;
};


/**
Contains behavioural information for each register.

@author David Saxton
*/
00448 class ProcessorBehaviour
{
      public:
            ProcessorBehaviour();
            /**
             * Calls reset() for each RegisterBehaviour.
             */
            void reset();
            /**
             * @return behaviour for the given register.
             */
            RegisterBehaviour & reg( const Register & reg );
            
            /// The working register
00462             RegisterBehaviour working;
            
            /// The status register
00465             RegisterBehaviour status;
            
      protected:
            typedef QMap< Register, RegisterBehaviour > RegisterMap;
            /**
             * All registers other than working and status. Entries are created on
             * calls to reg with a new Register.
             */
00473             RegisterMap m_registers;
};


/**
Contains information on whether a register is overwritten before its value is
used. Each uchar respresents the 8 bits of the register; if the bit is 1, then
the corresponding bit of the register is used by the Instruction or one
of its outputs before it is overwritten.

@author David Saxton
*/
00485 class RegisterDepends
{
      public:
            RegisterDepends();
            /**
             * Sets all the depends values to 0x0.
             */
            void reset();
            /**
             * @return behaviour for the given register.
             */
            uchar & reg( const Register & reg );
            
            /// The working register
00499             uchar working;
            
            /// The status register
00502             uchar status;
            
      protected:
            typedef QMap< Register, uchar > RegisterMap;
            /**
             * All registers other than working and status. Entries are created on
             * calls to reg with a new Register.
             */
00510             RegisterMap m_registers;
};



/**
Holds a program structure; an (ordered) list of blocks of code, each of which
contains a list of instructions. The structure is such as to provide easy
manipulation of the program, as well as aiding the optimizer.

@author David Saxton
*/
00522 class Code
{
      public:
            Code();
            
            typedef CodeIterator iterator;
            typedef CodeConstIterator const_iterator;
            
00530             enum InstructionPosition
            {
                  InterruptHandler  = 0,
                  LookupTable             = 1,
00534                   Middle                        = 2, ///< Used for main code
00535                   Subroutine              = 3, ///< Used for subroutines
                  
00537                   PositionCount           = 4 ///< This must remain the last item and be the number of valid positions
            };
            
            CodeIterator begin();
            CodeIterator end();
            CodeConstIterator begin() const;
            CodeConstIterator end() const;
            
            /**
             * Queues a label to be given to the next instruction to be added in the
             * given position
             */
            void queueLabel( const QString & label, InstructionPosition position = Middle );
            /**
             * Returns the list of queued labels for the given position. This is
             * used in merging code, as we also need to merge any queued labels.
             */
00554             QStringList queuedLabels( InstructionPosition position ) const { return m_queuedLabels[position]; }
            /**
             * Adds the Instruction at the given position.
             */
            void append( Instruction * instruction, InstructionPosition position = Middle );
            /**
             * @returns the Instruction with the given label (or null if no such
             * Instruction).
             */
            Instruction * instruction( const QString & label ) const;
            /**
             * Look for an Assembly instruction (other types are ignored).
             * @return an iterator to the current instruction, or end if it wasn't
             * found.
             */
            iterator find( Instruction * instruction );
            /**
             * Removes the Instruction (regardless of position).
             * @warning You should always use only this function to remove an
             * instruction as this function handles stuff such as pushing labels
             * from this instruction onto the next before deletion.
             */
            void removeInstruction( Instruction * instruction );
            /**
             * Merges all the blocks output together with other magic such as adding
             * variables, gpasm directives, etc.
             */
            QString generateCode( PIC14 * pic ) const;
            /**
             * Appends the InstructionLists to the end of the ones in this instance.
             * @param middleInsertionPosition is the position where the middle code
             * blocks of the given code will be merged at.
             */
            void merge( Code * code, InstructionPosition middleInsertionPosition = Middle );
            /**
             * @returns the InstructionList for the given insertion position.
             */
00591             InstructionList * instructionList( InstructionPosition position ) { return & m_instructionLists[position]; }
            /**
             * @returns the InstructionList for the given insertion position.
             */
00595             const InstructionList * instructionList( InstructionPosition position ) const { return & m_instructionLists[position]; }
            /**
             * Calls generateOutputLinks for each Instruction
             */
            void generateLinksAndStates();
            /**
             * Calls setUsed(false) for all instructions.
             */
            void setAllUnused();
            /**
             * Does any work that is needed to the code before it can be passed to
             * the optimizer (such as flushing out queued labels). This is called
             * after all the instructions have been added to the code.
             */
            void postCompileConstruct();
            
      protected:
            /**
             * Used when generating the code. Finds the list of general purpose
             * registers that are referenced and returns their aliases.
             */
            QStringList findVariables() const;
            
00618             InstructionList m_instructionLists[ PositionCount ]; ///< @see InstructionPosition
00619             QStringList m_queuedLabels[ PositionCount ]; ///< @see InstructionPosition
            
      private: // Disable copy constructor and operator=
            Code( const Code & );
            Code &operator=( const Code & );
};


/**
Iterates over all the instructions, going seamlessly between the different lists
and avoiding the non-assembly instructions.

@author David Saxton
 */
00633 class CodeIterator
{
      public:
            bool operator != ( const CodeIterator & i ) const { return it != i.it; }
            bool operator == ( const CodeIterator & i ) const { return it == i.it; }
            CodeIterator & operator ++ ();
            Instruction * & operator * () { return *it; }
            /**
             * Deletes the instruction that this iterator is currently pointing at
             * (removing it from any lists), and increments the iterator to the next
             * instruction.
             */
            CodeIterator & removeAndIncrement();
            /**
             * Inserts the given instruction before the instruction pointed at by
             * this iterator.
             */
            void insertBefore( Instruction * ins );
            
            InstructionList::iterator it;
            InstructionList::iterator listEnd;
            Code::InstructionPosition pos;
            Code * code;
            InstructionList * list;
};


/**
A const version of CodeIterator (cannot change instructions).

@author David Saxton
 */
00665 class CodeConstIterator
{
      public:
            bool operator != ( const CodeConstIterator & i ) const { return it != i.it; }
            bool operator == ( const CodeConstIterator & i ) const { return it == i.it; }
            CodeConstIterator & operator ++ ();
            const Instruction * operator * () const { return *it; }
            
            InstructionList::const_iterator it;
            InstructionList::const_iterator listEnd;
            Code::InstructionPosition pos;
            const Code * code;
            const InstructionList * list;
};


/**
@author Daniel Clarke
@author David Saxton
*/
00685 class Instruction
{
      public:
            enum InstructionType
            {
                  Assembly,
                  Raw, // User-inserted assembly
                  Comment
            };
            /**
             * Used in optimization. Note that this follows roughly, but not
             * exactly, the Microchip classifications of similar categories.
             */
00698             enum AssemblyType
            {
                  /**
                   * Writes to a file (which can be obtained by calling outputReg().
                   */
00703                   FileOriented,
                  
                  /**
                   * Writes to a file bit (so BCF or BSF).
                   */
00708                   BitOriented,
                  
                  /**
                   * Affects the working register via a literal operation, with no
                   * branching (so excludes retlw).
                   */
00714                   WorkingOriented,
                  
                  /**
                   * Assembly instructions that don't come under the above categories
                   * (so control and branching instructions).
                   */
00720                   Other,
                  
                  /**
                   * The Instruction is not of Assembly InstructionType.
                   */
00725                   None
            };

            Instruction();
            virtual ~Instruction();
            void setCode( Code * code ) { m_pCode = code; }
            
            /**
             * This is used to decide how to output the instruction, and which
             * instructions to avoid while optimizing.
             */
00736             virtual InstructionType type() const { return Assembly; }
            /**
             * @return the AssemblyType (None for non-Assembly instructions).
             */
            virtual AssemblyType assemblyType() const = 0;
            /**
             * The text to output to the generated assembly.
             */
            virtual QString code() const = 0;
            /**
             * The input processor state is used to generate the outputlinks and the
             * output processor state.
             */
00749             void setInputState( const ProcessorState & processorState ) { m_inputState = processorState; }
            /**
             * By using the ProcessorState, the Instruction should:
             * * Find all instructions that could be executed after this instruction.
             * * Generate the output ProcessorState.
             * The default behaviour of this function is to link to the next
             * sequential instruction, and to generate an unknown ProcessorState.
             * @warning if your instruction depends on any bits, then it must
             * reinherit this function and say so.
             * @param instruction points at this instruction
             */
            virtual void generateLinksAndStates( Code::iterator instruction );
            /**
             * @return the processor behaviour for this instruction.
             */
            virtual ProcessorBehaviour behaviour() const;
            /**
             * An input link is an instruction that might be executed immediately
             * before this Instruction.
             */
            void addInputLink( Instruction * inputLink );
            /**
             * An output link is an instruction that might be executed immediately
             * after this Instruction.
             */
            void addOutputLink( Instruction * inputLink );
            /**
             * The list of instructions that might be executed immediately before
             * this instruction.
             * @see addInputLink
             */
00780             InstructionList inputLinks() const { return m_inputLinks; }
            /**
             * The list of instructions that might be executed immediately after
             * this instruction. Instruction does not generate these links; instead
             * the list is generated Code::generateLinksAndStates function.
             */
00786             InstructionList outputLinks() const { return m_outputLinks; }
            /**
             * Remove the given input link from the instruction.
             */
            void removeInputLink( Instruction * ins );
            /**
             * Remove the given output link from the instruction.
             */
            void removeOutputLink( Instruction * ins );
            /**
             * Clears all input and output links from this instruction. This does
             * not remove references to this instruction from other instructions.
             */
            void clearLinks();
            /**
             * An instruction may have zero, or more than zero labels associated
             * with it - these will be printed before the instruction in the
             * assembly output.
             */
00805             QStringList labels() const { return m_labels; }
            /**
             * @see labels
             */
            void addLabels( const QStringList & labels );
            /**
             * @see labels
             */
            void setLabels( const QStringList & labels );
            /**
             * @see used
             */
00817             void setUsed( bool used ) { m_bUsed = used; }
            /**
             * Used for optimization purposes in determining whether the instruction
             * has been examined yet (to avoid infinite loops).
             */
00822             bool isUsed() const { return m_bUsed; }
            /**
             * Set by the optimizer to indicate whether this instruction or any of
             * its outputs overwrite any of the bits of the given register.
             */
00827             void setRegisterDepends( uchar depends, const Register & reg ) { m_registerDepends.reg(reg) = depends; }
            /**
             * @see setOutputsOverwriteWorking
             */
00831             uchar registerDepends( const Register & reg ) { return m_registerDepends.reg(reg); }
            /**
             * Resets the overwrites.
             */
00835             void resetRegisterDepends() { m_registerDepends.reset(); }
            /**
             * @return the input processor state to this instruction.
             * @see setInputState
             */
00840             ProcessorState inputState() const { return m_inputState; }
            /**
             * @return the output processor state from this instruction.
             * @see generateLinksAndStates.
             */
00845             ProcessorState outputState() const { return m_outputState; }
            /**
             * Only applicable to Instructions that refer to a file.
             */
00849             Register file() const { return m_file; }
            /**
             * Only applicable to Instructions that refer to a bit (such as BCF).
             */
00853             RegisterBit bit() const { return m_bit; }
            /**
             * Only applicable to instructions that refer to a literal (such as
             * XORLW).
             */
00858             uchar literal() const { return m_literal; }
            /**
             * Applicable only to instructions that save a result to working or file
             * depending on the destination bit.
             */
00863             Register outputReg() const { return (m_dest == 0) ? Register::WORKING : m_file; }
            /**
             * Applicable only to instructions that use the destination flag.
             */
00867             unsigned dest() const { return m_dest; }
            
      protected:
            /**
             * This function is provided for convenience; it creates links to the
             * first or second instructions after this one, depending on the value
             * of firstOutput and secondOutput.
             * @see generateOutputLinks
             */
            void makeOutputLinks( Code::iterator current, bool firstOutput = true, bool secondOutput = false );
            /**
             * This function is provided for instructions that jump to a label (i.e.
             * call and goto).
             */
            void makeLabelOutputLink( const QString & label );
            
            RegisterDepends m_registerDepends;
            bool m_bInputStateChanged;
            bool m_bUsed;
            bool m_bPositionAffectsBranching;
            InstructionList m_inputLinks;
            InstructionList m_outputLinks;
            QStringList m_labels;
            Code * m_pCode;
            
            // Commonly needed member variables for assembly instructions
            Register m_file;
            RegisterBit m_bit;
            QString m_raw; // Used by source code, raw asm, etc
            uchar m_literal;
            unsigned m_dest:1; // is 0 (W) or 1 (file).
            ProcessorState m_inputState;
            ProcessorState m_outputState;
            
      private: // Disable copy constructor and operator=
            Instruction( const Instruction & );
            Instruction &operator=( const Instruction & );
};



//BEGIN Byte-Oriented File Register Operations
class Instr_addwf : public Instruction
{
      public:
            Instr_addwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};


class Instr_andwf : public Instruction
{
      public:
            Instr_andwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};


class Instr_clrf : public Instruction
{
      public:
            Instr_clrf( const Register & file ) { m_file = file; m_dest = 1; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};


//TODO CLRW
//TODO COMF


class Instr_decf : public Instruction
{
      public:
            Instr_decf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};


class Instr_decfsz : public Instruction
{
      public:
            Instr_decfsz( const Register & file, int dest ) { m_file = file; m_dest = dest; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};


class Instr_incf : public Instruction
{
      public:
            Instr_incf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};


//TODO INCFSZ


class Instr_iorwf : public Instruction
{
      public:
            Instr_iorwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};


class Instr_movf : public Instruction
{
      public:
            Instr_movf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};


class Instr_movwf : public Instruction
{
      public:
            Instr_movwf( const Register & file ) { m_file = file; m_dest = 1; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};


//TODO NOP


class Instr_rlf : public Instruction
{
      public:
            Instr_rlf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};


class Instr_rrf : public Instruction
{
      public:
            Instr_rrf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};


class Instr_subwf : public Instruction
{
      public:
            Instr_subwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};


class Instr_swapf : public Instruction
{
      public:
            Instr_swapf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};


class Instr_xorwf : public Instruction
{
      public:
            Instr_xorwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return FileOriented; }
};
//END Byte-Oriented File Register Operations



//BEGIN Bit-Oriented File Register Operations
class Instr_bcf : public Instruction
{
      public:
            Instr_bcf( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return BitOriented; }
};


class Instr_bsf : public Instruction
{
      public:
            Instr_bsf( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return BitOriented; }
};


class Instr_btfsc : public Instruction
{
      public:
            Instr_btfsc( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return Other; }
};


class Instr_btfss : public Instruction
{
      public:
            Instr_btfss( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return Other; }
};
//END Bit-Oriented File Register Operations



//BEGIN Literal and Control Operations
class Instr_addlw : public Instruction
{
      public:
            Instr_addlw( int literal ) { m_literal = literal; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return WorkingOriented; }
};



class Instr_andlw : public Instruction
{
      public:
            Instr_andlw( int literal ) { m_literal = literal; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return WorkingOriented; }
};


class Instr_call : public Instruction
{
      public:
            Instr_call( const QString & label ) { m_label = label; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return Other; }
            /**
             * Called from Code after all the output links have been generated. The
             * instruction that is called has its output links followed, and any
             * returns encountered are linked back to the instruction after this
             * one.
             * @param next the instruction after this one which the return points
             * will be linked to.
             */
            void makeReturnLinks( Instruction * next );
            
            QString label() const { return m_label; }
            void setLabel( const QString & label ) { m_label = label; }
            
      protected:
            /**
             * Used by makeReturnLinks. Recursively follows the instruction's output
             * links, until a return is found - then, link the return point back to
             * the instruction after this one. Call instructions found while
             * following the output are ignored.
             * @param returnPoint the instruction to link back to on finding a
             * return.
             */
            void linkReturns( Instruction * current, Instruction * returnPoint );
            
            QString m_label;
};


//TODO CLRWDT


class Instr_goto : public Instruction
{
      public:
            Instr_goto( const QString & label ) { m_label = label; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return Other; }
            
            QString label() const { return m_label; }
            void setLabel( const QString & label ) { m_label = label; }
            
      protected:
            QString m_label;
};


class Instr_iorlw : public Instruction
{
      public:
            Instr_iorlw( int literal ) { m_literal = literal; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return WorkingOriented; }
};


class Instr_movlw : public Instruction
{
      public:
            Instr_movlw( int literal ) { m_literal = literal; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return WorkingOriented; }
};


class Instr_retfie : public Instruction
{
      public:
            Instr_retfie() {};
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return Other; }
};


class Instr_retlw : public Instruction
{
      public:
            Instr_retlw( int literal ) { m_literal = literal; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return Other; }
};


class Instr_return : public Instruction
{
      public:
            Instr_return() {};
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return Other; }
};


class Instr_sleep : public Instruction
{
      public:
            Instr_sleep() {};
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return Other; }
};


class Instr_sublw : public Instruction
{
      public:
            Instr_sublw( int literal ) { m_literal = literal; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return WorkingOriented; }
};


class Instr_xorlw : public Instruction
{
      public:
            Instr_xorlw( int literal ) { m_literal = literal; }
            virtual QString code() const;
            virtual void generateLinksAndStates( Code::iterator current );
            virtual ProcessorBehaviour behaviour() const;
            virtual AssemblyType assemblyType() const { return WorkingOriented; }
};
//END Literal and Control Operations



//BEGIN Microbe (non-assembly) Operations
class Instr_sourceCode : public Instruction
{
      public:
            Instr_sourceCode( const QString & source ) { m_raw = source; }
            virtual QString code() const;
            virtual InstructionType type() const { return Comment; }
            virtual AssemblyType assemblyType() const { return None; }
};


class Instr_asm : public Instruction
{
      public:
            Instr_asm( const QString & raw ) { m_raw = raw; }
            virtual QString code() const;
            virtual InstructionType type() const { return Raw; }
            virtual AssemblyType assemblyType() const { return None; }
};


// Like Instr_asm, but does not put ;asm {} in, used
// for internal things like gpasm directives etc...
class Instr_raw : public Instruction
{
      public:
            Instr_raw( const QString & raw ) { m_raw = raw; }
            virtual QString code() const;
            virtual InstructionType type() const { return Raw; }
            virtual AssemblyType assemblyType() const { return None; }
};
//END Microbe (non-assembly) Operations



#endif

Generated by  Doxygen 1.6.0   Back to index