00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef INSTRUCTION_H
00022 #define INSTRUCTION_H
00023
00024 #include <qmap.h>
00025 #include <qstring.h>
00026 #include <qstringlist.h>
00027 #include <qvaluelist.h>
00028
00029 class Code;
00030 class CodeIterator;
00031 class CodeConstIterator;
00032 class Instruction;
00033 class PIC14;
00034
00035 typedef QValueList<Instruction*> InstructionList;
00036
00037
00045 class Register
00046 {
00047 public:
00048 enum Type
00049 {
00050 TMR0,
00051 OPTION_REG,
00052 PCL,
00053 STATUS,
00054 FSR,
00055 PORTA,
00056 TRISA,
00057 PORTB,
00058 TRISB,
00059 EEDATA,
00060 EECON1,
00061 EEADR,
00062 EECON2,
00063 PCLATH,
00064 INTCON,
00065
00066
00067 WORKING,
00068 GPR,
00069 none,
00070 };
00071
00072
00073 enum Banks
00074 {
00075 Bank0 = 1 << 0,
00076 Bank1 = 1 << 1,
00077 };
00078
00083 Register( Type type = none );
00088 Register( const QString & name );
00093 Register( const char * name );
00098 bool operator < ( const Register & reg ) const;
00103 bool operator == ( const Register & reg ) const;
00108 uchar banks() const;
00113 bool bankDependent() const;
00117 QString name() const { return m_name; }
00121 Type type() const { return m_type; }
00129 bool affectsExternal() const;
00130
00131 protected:
00132 QString m_name;
00133 Type m_type;
00134 };
00135
00136
00137
00138 class RegisterBit
00139 {
00140 public:
00141 enum STATUS_bits
00142 {
00143 C = 0,
00144 DC = 1,
00145 Z = 2,
00146 NOT_PD = 3,
00147 NOT_TO = 4,
00148 RP0 = 5,
00149 RP1 = 6,
00150 IRP = 7,
00151 };
00152
00153 enum INTCON_bits
00154 {
00155 RBIF = 0,
00156 INTF = 1,
00157 T0IF = 2,
00158 RBIE = 3,
00159 INTE = 4,
00160 T0IE = 5,
00161 EEIE = 6,
00162 GIE = 7,
00163 };
00164
00165 enum OPTION_bits
00166 {
00167 PS0 = 0,
00168 PS1 = 1,
00169 PS2 = 2,
00170 PSA = 3,
00171 T0SE = 4,
00172 T0CS = 5,
00173 INTEDG = 6,
00174 NOT_RBPU = 7,
00175 };
00176
00177 enum EECON1_bits
00178 {
00179 RD = 0,
00180 WR = 1,
00181 WREN = 2,
00182 WRERR = 3,
00183 EEIF = 4,
00184 };
00188 RegisterBit( uchar bitPos = 0, Register::Type reg = Register::none );
00192 RegisterBit( const QString & name );
00196 RegisterBit( const char * name );
00202 Register::Type registerType() const { return m_registerType; }
00206 uchar bitPos() const { return m_bitPos; }
00210 uchar bit() const { return (1 << m_bitPos); }
00214 QString name() const { return m_name; }
00215
00216
00217 protected:
00221 void initFromName();
00222
00223 Register::Type m_registerType;
00224 uchar m_bitPos:3;
00225 QString m_name;
00226 };
00227
00228
00229
00230
00241 class RegisterState
00242 {
00243 public:
00244 RegisterState();
00245
00250 void merge( const RegisterState & state );
00254 void reset();
00258 uchar definiteZeros() const { return (~value) & known; }
00262 uchar definiteOnes() const { return value & known; }
00266 uchar unknown() const { return ~known; }
00271 uchar maxValue() const { return (value & known) | (~known); }
00276 uchar minValue() const { return (value & known); }
00280 bool operator == ( const RegisterState & state ) const;
00284 bool operator != ( const RegisterState & state ) const { return !( *this == state ); }
00288 void print();
00289
00291 uchar known;
00292
00294 uchar value;
00295 };
00296
00297
00304 class RegisterBehaviour
00305 {
00306 public:
00307 RegisterBehaviour();
00311 void reset();
00312
00321 uchar depends;
00322
00330 uchar indep;
00331 };
00332
00333
00334
00340 class ProcessorState
00341 {
00342 public:
00343 ProcessorState();
00347 void merge( const ProcessorState & state );
00351 void reset();
00355 RegisterState & reg( const Register & reg );
00359 RegisterState reg( const Register & reg ) const;
00363 bool operator == ( const ProcessorState & state ) const;
00367 bool operator != ( const ProcessorState & state ) const { return !( *this == state ); }
00371 void print();
00372
00374 RegisterState working;
00375
00377 RegisterState status;
00378
00379 protected:
00380 typedef QMap< Register, RegisterState > RegisterMap;
00385 RegisterMap m_registers;
00386 };
00387
00388
00394 class ProcessorBehaviour
00395 {
00396 public:
00397 ProcessorBehaviour();
00401 void reset();
00405 RegisterBehaviour & reg( const Register & reg );
00406
00408 RegisterBehaviour working;
00409
00411 RegisterBehaviour status;
00412
00413 protected:
00414 typedef QMap< Register, RegisterBehaviour > RegisterMap;
00419 RegisterMap m_registers;
00420 };
00421
00422
00431 class RegisterDepends
00432 {
00433 public:
00434 RegisterDepends();
00438 void reset();
00442 uchar & reg( const Register & reg );
00443
00445 uchar working;
00446
00448 uchar status;
00449
00450 protected:
00451 typedef QMap< Register, uchar > RegisterMap;
00456 RegisterMap m_registers;
00457 };
00458
00459
00460
00468 class Code
00469 {
00470 public:
00471 Code();
00472
00473 typedef CodeIterator iterator;
00474 typedef CodeConstIterator const_iterator;
00475
00476 enum InstructionPosition
00477 {
00478 InterruptHandler = 0,
00479 LookupTable = 1,
00480 Middle = 2,
00481 Subroutine = 3,
00482
00483 PositionCount = 4,
00484 };
00485
00486 CodeIterator begin();
00487 CodeIterator end();
00488 CodeConstIterator begin() const;
00489 CodeConstIterator end() const;
00490
00495 void queueLabel( const QString & label, InstructionPosition position = Middle );
00500 QStringList queuedLabels( InstructionPosition position ) const { return m_queuedLabels[position]; }
00504 void append( Instruction * instruction, InstructionPosition position = Middle );
00509 Instruction * instruction( const QString & label ) const;
00515 iterator find( Instruction * instruction );
00522 void removeInstruction( Instruction * instruction );
00527 QString generateCode( PIC14 * pic ) const;
00533 void merge( Code * code, InstructionPosition middleInsertionPosition = Middle );
00537 InstructionList * instructionList( InstructionPosition position ) { return & m_instructionLists[position]; }
00541 const InstructionList * instructionList( InstructionPosition position ) const { return & m_instructionLists[position]; }
00545 void generateLinksAndStates();
00549 void setAllUnused();
00555 void postCompileConstruct();
00556
00557 protected:
00562 QStringList findVariables() const;
00563
00564 InstructionList m_instructionLists[ PositionCount ];
00565 QStringList m_queuedLabels[ PositionCount ];
00566
00567 private:
00568 Code( const Code & );
00569 Code &operator=( const Code & );
00570 };
00571
00572
00579 class CodeIterator
00580 {
00581 public:
00582 bool operator != ( const CodeIterator & i ) const { return it != i.it; }
00583 bool operator == ( const CodeIterator & i ) const { return it == i.it; }
00584 CodeIterator & operator ++ ();
00585 Instruction * & operator * () { return *it; }
00591 CodeIterator & removeAndIncrement();
00596 void insertBefore( Instruction * ins );
00597
00598 InstructionList::iterator it;
00599 InstructionList::iterator listEnd;
00600 Code::InstructionPosition pos;
00601 Code * code;
00602 InstructionList * list;
00603 };
00604
00605
00611 class CodeConstIterator
00612 {
00613 public:
00614 bool operator != ( const CodeConstIterator & i ) const { return it != i.it; }
00615 bool operator == ( const CodeConstIterator & i ) const { return it == i.it; }
00616 CodeConstIterator & operator ++ ();
00617 const Instruction * operator * () const { return *it; }
00618
00619 InstructionList::const_iterator it;
00620 InstructionList::const_iterator listEnd;
00621 Code::InstructionPosition pos;
00622 const Code * code;
00623 const InstructionList * list;
00624 };
00625
00626
00631 class Instruction
00632 {
00633 public:
00634 enum InstructionType
00635 {
00636 Assembly,
00637 Raw,
00638 Comment,
00639 };
00644 enum AssemblyType
00645 {
00649 FileOriented,
00650
00654 BitOriented,
00655
00660 WorkingOriented,
00661
00666 Other,
00667
00671 None,
00672 };
00673
00674 Instruction();
00675 virtual ~Instruction();
00676 void setCode( Code * code ) { m_pCode = code; }
00677
00682 virtual InstructionType type() const { return Assembly; }
00686 virtual AssemblyType assemblyType() const = 0;
00690 virtual QString code() const = 0;
00695 void setInputState( const ProcessorState & processorState ) { m_inputState = processorState; }
00706 virtual void generateLinksAndStates( Code::iterator instruction );
00710 virtual ProcessorBehaviour behaviour() const;
00715 void addInputLink( Instruction * inputLink );
00720 void addOutputLink( Instruction * inputLink );
00726 InstructionList inputLinks() const { return m_inputLinks; }
00732 InstructionList outputLinks() const { return m_outputLinks; }
00736 void removeInputLink( Instruction * ins );
00740 void removeOutputLink( Instruction * ins );
00745 void clearLinks();
00751 QStringList labels() const { return m_labels; }
00755 void addLabels( const QStringList & labels );
00759 void setLabels( const QStringList & labels );
00763 void setUsed( bool used ) { m_bUsed = used; }
00768 bool isUsed() const { return m_bUsed; }
00773 void setRegisterDepends( uchar depends, const Register & reg ) { m_registerDepends.reg(reg) = depends; }
00777 uchar registerDepends( const Register & reg ) { return m_registerDepends.reg(reg); }
00781 void resetRegisterDepends() { m_registerDepends.reset(); }
00786 ProcessorState inputState() const { return m_inputState; }
00791 ProcessorState outputState() const { return m_outputState; }
00795 Register file() const { return m_file; }
00799 RegisterBit bit() const { return m_bit; }
00804 uchar literal() const { return m_literal; }
00809 Register outputReg() const { return (m_dest == 0) ? Register::WORKING : m_file; }
00813 unsigned dest() const { return m_dest; }
00814
00815 protected:
00822 void makeOutputLinks( Code::iterator current, bool firstOutput = true, bool secondOutput = false );
00827 void makeLabelOutputLink( const QString & label );
00828
00829 RegisterDepends m_registerDepends;
00830 bool m_bInputStateChanged;
00831 bool m_bUsed;
00832 bool m_bPositionAffectsBranching;
00833 InstructionList m_inputLinks;
00834 InstructionList m_outputLinks;
00835 QStringList m_labels;
00836 Code * m_pCode;
00837
00838
00839 Register m_file;
00840 RegisterBit m_bit;
00841 QString m_raw;
00842 uchar m_literal;
00843 unsigned m_dest:1;
00844 ProcessorState m_inputState;
00845 ProcessorState m_outputState;
00846
00847 private:
00848 Instruction( const Instruction & );
00849 Instruction &operator=( const Instruction & );
00850 };
00851
00852
00853
00854
00855 class Instr_addwf : public Instruction
00856 {
00857 public:
00858 Instr_addwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
00859 virtual QString code() const;
00860 virtual void generateLinksAndStates( Code::iterator current );
00861 virtual ProcessorBehaviour behaviour() const;
00862 virtual AssemblyType assemblyType() const { return FileOriented; }
00863 };
00864
00865
00866 class Instr_andwf : public Instruction
00867 {
00868 public:
00869 Instr_andwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
00870 virtual QString code() const;
00871 virtual void generateLinksAndStates( Code::iterator current );
00872 virtual ProcessorBehaviour behaviour() const;
00873 virtual AssemblyType assemblyType() const { return FileOriented; }
00874 };
00875
00876
00877 class Instr_clrf : public Instruction
00878 {
00879 public:
00880 Instr_clrf( const Register & file ) { m_file = file; m_dest = 1; }
00881 virtual QString code() const;
00882 virtual void generateLinksAndStates( Code::iterator current );
00883 virtual ProcessorBehaviour behaviour() const;
00884 virtual AssemblyType assemblyType() const { return FileOriented; }
00885 };
00886
00887
00888
00889
00890
00891
00892 class Instr_decf : public Instruction
00893 {
00894 public:
00895 Instr_decf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
00896 virtual QString code() const;
00897 virtual void generateLinksAndStates( Code::iterator current );
00898 virtual ProcessorBehaviour behaviour() const;
00899 virtual AssemblyType assemblyType() const { return FileOriented; }
00900 };
00901
00902
00903 class Instr_decfsz : public Instruction
00904 {
00905 public:
00906 Instr_decfsz( const Register & file, int dest ) { m_file = file; m_dest = dest; }
00907 virtual QString code() const;
00908 virtual void generateLinksAndStates( Code::iterator current );
00909 virtual ProcessorBehaviour behaviour() const;
00910 virtual AssemblyType assemblyType() const { return FileOriented; }
00911 };
00912
00913
00914 class Instr_incf : public Instruction
00915 {
00916 public:
00917 Instr_incf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
00918 virtual QString code() const;
00919 virtual void generateLinksAndStates( Code::iterator current );
00920 virtual ProcessorBehaviour behaviour() const;
00921 virtual AssemblyType assemblyType() const { return FileOriented; }
00922 };
00923
00924
00925
00926
00927
00928 class Instr_iorwf : public Instruction
00929 {
00930 public:
00931 Instr_iorwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
00932 virtual QString code() const;
00933 virtual void generateLinksAndStates( Code::iterator current );
00934 virtual ProcessorBehaviour behaviour() const;
00935 virtual AssemblyType assemblyType() const { return FileOriented; }
00936 };
00937
00938
00939 class Instr_movf : public Instruction
00940 {
00941 public:
00942 Instr_movf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
00943 virtual QString code() const;
00944 virtual void generateLinksAndStates( Code::iterator current );
00945 virtual ProcessorBehaviour behaviour() const;
00946 virtual AssemblyType assemblyType() const { return FileOriented; }
00947 };
00948
00949
00950 class Instr_movwf : public Instruction
00951 {
00952 public:
00953 Instr_movwf( const Register & file ) { m_file = file; m_dest = 1; }
00954 virtual QString code() const;
00955 virtual void generateLinksAndStates( Code::iterator current );
00956 virtual ProcessorBehaviour behaviour() const;
00957 virtual AssemblyType assemblyType() const { return FileOriented; }
00958 };
00959
00960
00961
00962
00963
00964 class Instr_rlf : public Instruction
00965 {
00966 public:
00967 Instr_rlf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
00968 virtual QString code() const;
00969 virtual void generateLinksAndStates( Code::iterator current );
00970 virtual ProcessorBehaviour behaviour() const;
00971 virtual AssemblyType assemblyType() const { return FileOriented; }
00972 };
00973
00974
00975 class Instr_rrf : public Instruction
00976 {
00977 public:
00978 Instr_rrf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
00979 virtual QString code() const;
00980 virtual void generateLinksAndStates( Code::iterator current );
00981 virtual ProcessorBehaviour behaviour() const;
00982 virtual AssemblyType assemblyType() const { return FileOriented; }
00983 };
00984
00985
00986 class Instr_subwf : public Instruction
00987 {
00988 public:
00989 Instr_subwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
00990 virtual QString code() const;
00991 virtual void generateLinksAndStates( Code::iterator current );
00992 virtual ProcessorBehaviour behaviour() const;
00993 virtual AssemblyType assemblyType() const { return FileOriented; }
00994 };
00995
00996
00997 class Instr_swapf : public Instruction
00998 {
00999 public:
01000 Instr_swapf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
01001 virtual QString code() const;
01002 virtual void generateLinksAndStates( Code::iterator current );
01003 virtual ProcessorBehaviour behaviour() const;
01004 virtual AssemblyType assemblyType() const { return FileOriented; }
01005 };
01006
01007
01008 class Instr_xorwf : public Instruction
01009 {
01010 public:
01011 Instr_xorwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
01012 virtual QString code() const;
01013 virtual void generateLinksAndStates( Code::iterator current );
01014 virtual ProcessorBehaviour behaviour() const;
01015 virtual AssemblyType assemblyType() const { return FileOriented; }
01016 };
01017
01018
01019
01020
01021
01022 class Instr_bcf : public Instruction
01023 {
01024 public:
01025 Instr_bcf( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; }
01026 virtual QString code() const;
01027 virtual void generateLinksAndStates( Code::iterator current );
01028 virtual ProcessorBehaviour behaviour() const;
01029 virtual AssemblyType assemblyType() const { return BitOriented; }
01030 };
01031
01032
01033 class Instr_bsf : public Instruction
01034 {
01035 public:
01036 Instr_bsf( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; }
01037 virtual QString code() const;
01038 virtual void generateLinksAndStates( Code::iterator current );
01039 virtual ProcessorBehaviour behaviour() const;
01040 virtual AssemblyType assemblyType() const { return BitOriented; }
01041 };
01042
01043
01044 class Instr_btfsc : public Instruction
01045 {
01046 public:
01047 Instr_btfsc( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; }
01048 virtual QString code() const;
01049 virtual void generateLinksAndStates( Code::iterator current );
01050 virtual ProcessorBehaviour behaviour() const;
01051 virtual AssemblyType assemblyType() const { return Other; }
01052 };
01053
01054
01055 class Instr_btfss : public Instruction
01056 {
01057 public:
01058 Instr_btfss( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; }
01059 virtual QString code() const;
01060 virtual void generateLinksAndStates( Code::iterator current );
01061 virtual ProcessorBehaviour behaviour() const;
01062 virtual AssemblyType assemblyType() const { return Other; }
01063 };
01064
01065
01066
01067
01068
01069 class Instr_addlw : public Instruction
01070 {
01071 public:
01072 Instr_addlw( int literal ) { m_literal = literal; }
01073 virtual QString code() const;
01074 virtual void generateLinksAndStates( Code::iterator current );
01075 virtual ProcessorBehaviour behaviour() const;
01076 virtual AssemblyType assemblyType() const { return WorkingOriented; }
01077 };
01078
01079
01080
01081 class Instr_andlw : public Instruction
01082 {
01083 public:
01084 Instr_andlw( int literal ) { m_literal = literal; }
01085 virtual QString code() const;
01086 virtual void generateLinksAndStates( Code::iterator current );
01087 virtual ProcessorBehaviour behaviour() const;
01088 virtual AssemblyType assemblyType() const { return WorkingOriented; }
01089 };
01090
01091
01092 class Instr_call : public Instruction
01093 {
01094 public:
01095 Instr_call( const QString & label ) { m_label = label; }
01096 virtual QString code() const;
01097 virtual void generateLinksAndStates( Code::iterator current );
01098 virtual ProcessorBehaviour behaviour() const;
01099 virtual AssemblyType assemblyType() const { return Other; }
01108 void makeReturnLinks( Instruction * next );
01109
01110 QString label() const { return m_label; }
01111 void setLabel( const QString & label ) { m_label = label; }
01112
01113 protected:
01122 void linkReturns( Instruction * current, Instruction * returnPoint );
01123
01124 QString m_label;
01125 };
01126
01127
01128
01129
01130
01131 class Instr_goto : public Instruction
01132 {
01133 public:
01134