Add qemu 2.4.0
[kvmfornfv.git] / qemu / disas / libvixl / a64 / disasm-a64.h
1 // Copyright 2013, ARM Limited
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 //   * Redistributions of source code must retain the above copyright notice,
8 //     this list of conditions and the following disclaimer.
9 //   * Redistributions in binary form must reproduce the above copyright notice,
10 //     this list of conditions and the following disclaimer in the documentation
11 //     and/or other materials provided with the distribution.
12 //   * Neither the name of ARM Limited nor the names of its contributors may be
13 //     used to endorse or promote products derived from this software without
14 //     specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 #ifndef VIXL_A64_DISASM_A64_H
28 #define VIXL_A64_DISASM_A64_H
29
30 #include "globals.h"
31 #include "utils.h"
32 #include "instructions-a64.h"
33 #include "decoder-a64.h"
34 #include "assembler-a64.h"
35
36 namespace vixl {
37
38 class Disassembler: public DecoderVisitor {
39  public:
40   Disassembler();
41   Disassembler(char* text_buffer, int buffer_size);
42   virtual ~Disassembler();
43   char* GetOutput();
44
45   // Declare all Visitor functions.
46   #define DECLARE(A) virtual void Visit##A(const Instruction* instr);
47   VISITOR_LIST(DECLARE)
48   #undef DECLARE
49
50  protected:
51   virtual void ProcessOutput(const Instruction* instr);
52
53   // Default output functions.  The functions below implement a default way of
54   // printing elements in the disassembly. A sub-class can override these to
55   // customize the disassembly output.
56
57   // Prints the name of a register.
58   virtual void AppendRegisterNameToOutput(const Instruction* instr,
59                                           const CPURegister& reg);
60
61   // Prints a PC-relative offset. This is used for example when disassembling
62   // branches to immediate offsets.
63   virtual void AppendPCRelativeOffsetToOutput(const Instruction* instr,
64                                               int64_t offset);
65
66   // Prints an address, in the general case. It can be code or data. This is
67   // used for example to print the target address of an ADR instruction.
68   virtual void AppendCodeRelativeAddressToOutput(const Instruction* instr,
69                                                  const void* addr);
70
71   // Prints the address of some code.
72   // This is used for example to print the target address of a branch to an
73   // immediate offset.
74   // A sub-class can for example override this method to lookup the address and
75   // print an appropriate name.
76   virtual void AppendCodeRelativeCodeAddressToOutput(const Instruction* instr,
77                                                      const void* addr);
78
79   // Prints the address of some data.
80   // This is used for example to print the source address of a load literal
81   // instruction.
82   virtual void AppendCodeRelativeDataAddressToOutput(const Instruction* instr,
83                                                      const void* addr);
84
85   // Same as the above, but for addresses that are not relative to the code
86   // buffer. They are currently not used by VIXL.
87   virtual void AppendAddressToOutput(const Instruction* instr,
88                                      const void* addr);
89   virtual void AppendCodeAddressToOutput(const Instruction* instr,
90                                          const void* addr);
91   virtual void AppendDataAddressToOutput(const Instruction* instr,
92                                          const void* addr);
93
94  public:
95   // Get/Set the offset that should be added to code addresses when printing
96   // code-relative addresses in the AppendCodeRelative<Type>AddressToOutput()
97   // helpers.
98   // Below is an example of how a branch immediate instruction in memory at
99   // address 0xb010200 would disassemble with different offsets.
100   // Base address | Disassembly
101   //          0x0 | 0xb010200:  b #+0xcc  (addr 0xb0102cc)
102   //      0x10000 | 0xb000200:  b #+0xcc  (addr 0xb0002cc)
103   //    0xb010200 |       0x0:  b #+0xcc  (addr 0xcc)
104   void MapCodeAddress(int64_t base_address, const Instruction* instr_address);
105   int64_t CodeRelativeAddress(const void* instr);
106
107  private:
108   void Format(
109       const Instruction* instr, const char* mnemonic, const char* format);
110   void Substitute(const Instruction* instr, const char* string);
111   int SubstituteField(const Instruction* instr, const char* format);
112   int SubstituteRegisterField(const Instruction* instr, const char* format);
113   int SubstituteImmediateField(const Instruction* instr, const char* format);
114   int SubstituteLiteralField(const Instruction* instr, const char* format);
115   int SubstituteBitfieldImmediateField(
116       const Instruction* instr, const char* format);
117   int SubstituteShiftField(const Instruction* instr, const char* format);
118   int SubstituteExtendField(const Instruction* instr, const char* format);
119   int SubstituteConditionField(const Instruction* instr, const char* format);
120   int SubstitutePCRelAddressField(const Instruction* instr, const char* format);
121   int SubstituteBranchTargetField(const Instruction* instr, const char* format);
122   int SubstituteLSRegOffsetField(const Instruction* instr, const char* format);
123   int SubstitutePrefetchField(const Instruction* instr, const char* format);
124   int SubstituteBarrierField(const Instruction* instr, const char* format);
125
126   bool RdIsZROrSP(const Instruction* instr) const {
127     return (instr->Rd() == kZeroRegCode);
128   }
129
130   bool RnIsZROrSP(const Instruction* instr) const {
131     return (instr->Rn() == kZeroRegCode);
132   }
133
134   bool RmIsZROrSP(const Instruction* instr) const {
135     return (instr->Rm() == kZeroRegCode);
136   }
137
138   bool RaIsZROrSP(const Instruction* instr) const {
139     return (instr->Ra() == kZeroRegCode);
140   }
141
142   bool IsMovzMovnImm(unsigned reg_size, uint64_t value);
143
144   int64_t code_address_offset() const { return code_address_offset_; }
145
146  protected:
147   void ResetOutput();
148   void AppendToOutput(const char* string, ...) PRINTF_CHECK(2, 3);
149
150   void set_code_address_offset(int64_t code_address_offset) {
151     code_address_offset_ = code_address_offset;
152   }
153
154   char* buffer_;
155   uint32_t buffer_pos_;
156   uint32_t buffer_size_;
157   bool own_buffer_;
158
159   int64_t code_address_offset_;
160 };
161
162
163 class PrintDisassembler: public Disassembler {
164  public:
165   explicit PrintDisassembler(FILE* stream) : stream_(stream) { }
166   virtual ~PrintDisassembler() { }
167
168  protected:
169   virtual void ProcessOutput(const Instruction* instr);
170
171  private:
172   FILE *stream_;
173 };
174 }  // namespace vixl
175
176 #endif  // VIXL_A64_DISASM_A64_H