c1ebd3edf82ddcc1aa5d44452583c5eac91fb3fb
[oota-llvm.git] / lib / Target / ARM / Disassembler / ARMDisassemblerCore.h
1 //===- ARMDisassemblerCore.h - ARM disassembler helpers ---------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is part of the ARM Disassembler.
11 //
12 // The first part defines the enumeration type of ARM instruction format, which
13 // specifies the encoding used by the instruction, as well as a helper function
14 // to convert the enums to printable char strings.
15 //
16 // It also contains code to represent the concepts of Builder and DisassembleFP
17 // to solve the problem of disassembling an ARM instr.
18 //
19 //===----------------------------------------------------------------------===//
20
21 #ifndef ARMDISASSEMBLERCORE_H
22 #define ARMDISASSEMBLERCORE_H
23
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/MC/MCExpr.h"
27 #include "llvm/MC/MCContext.h"
28 #include "llvm/Target/TargetInstrInfo.h"
29 #include "llvm-c/Disassembler.h"
30 #include "ARMBaseInstrInfo.h"
31 #include "ARMRegisterInfo.h"
32 #include "ARMDisassembler.h"
33
34 namespace llvm {
35 class MCContext;
36
37 class ARMUtils {
38 public:
39   static const char *OpcodeName(unsigned Opcode);
40 };
41
42 /////////////////////////////////////////////////////
43 //                                                 //
44 //  Enums and Utilities for ARM Instruction Format //
45 //                                                 //
46 /////////////////////////////////////////////////////
47
48 #define ARM_FORMATS                   \
49   ENTRY(ARM_FORMAT_PSEUDO,         0) \
50   ENTRY(ARM_FORMAT_MULFRM,         1) \
51   ENTRY(ARM_FORMAT_BRFRM,          2) \
52   ENTRY(ARM_FORMAT_BRMISCFRM,      3) \
53   ENTRY(ARM_FORMAT_DPFRM,          4) \
54   ENTRY(ARM_FORMAT_DPSOREGREGFRM,     5) \
55   ENTRY(ARM_FORMAT_LDFRM,          6) \
56   ENTRY(ARM_FORMAT_STFRM,          7) \
57   ENTRY(ARM_FORMAT_LDMISCFRM,      8) \
58   ENTRY(ARM_FORMAT_STMISCFRM,      9) \
59   ENTRY(ARM_FORMAT_LDSTMULFRM,    10) \
60   ENTRY(ARM_FORMAT_LDSTEXFRM,     11) \
61   ENTRY(ARM_FORMAT_ARITHMISCFRM,  12) \
62   ENTRY(ARM_FORMAT_SATFRM,        13) \
63   ENTRY(ARM_FORMAT_EXTFRM,        14) \
64   ENTRY(ARM_FORMAT_VFPUNARYFRM,   15) \
65   ENTRY(ARM_FORMAT_VFPBINARYFRM,  16) \
66   ENTRY(ARM_FORMAT_VFPCONV1FRM,   17) \
67   ENTRY(ARM_FORMAT_VFPCONV2FRM,   18) \
68   ENTRY(ARM_FORMAT_VFPCONV3FRM,   19) \
69   ENTRY(ARM_FORMAT_VFPCONV4FRM,   20) \
70   ENTRY(ARM_FORMAT_VFPCONV5FRM,   21) \
71   ENTRY(ARM_FORMAT_VFPLDSTFRM,    22) \
72   ENTRY(ARM_FORMAT_VFPLDSTMULFRM, 23) \
73   ENTRY(ARM_FORMAT_VFPMISCFRM,    24) \
74   ENTRY(ARM_FORMAT_THUMBFRM,      25) \
75   ENTRY(ARM_FORMAT_MISCFRM,       26) \
76   ENTRY(ARM_FORMAT_NEONGETLNFRM,  27) \
77   ENTRY(ARM_FORMAT_NEONSETLNFRM,  28) \
78   ENTRY(ARM_FORMAT_NEONDUPFRM,    29) \
79   ENTRY(ARM_FORMAT_NLdSt,         30) \
80   ENTRY(ARM_FORMAT_N1RegModImm,   31) \
81   ENTRY(ARM_FORMAT_N2Reg,         32) \
82   ENTRY(ARM_FORMAT_NVCVT,         33) \
83   ENTRY(ARM_FORMAT_NVecDupLn,     34) \
84   ENTRY(ARM_FORMAT_N2RegVecShL,   35) \
85   ENTRY(ARM_FORMAT_N2RegVecShR,   36) \
86   ENTRY(ARM_FORMAT_N3Reg,         37) \
87   ENTRY(ARM_FORMAT_N3RegVecSh,    38) \
88   ENTRY(ARM_FORMAT_NVecExtract,   39) \
89   ENTRY(ARM_FORMAT_NVecMulScalar, 40) \
90   ENTRY(ARM_FORMAT_NVTBL,         41) \
91   ENTRY(ARM_FORMAT_DPSOREGIMMFRM, 42)
92
93 // ARM instruction format specifies the encoding used by the instruction.
94 #define ENTRY(n, v) n = v,
95 typedef enum {
96   ARM_FORMATS
97   ARM_FORMAT_NA
98 } ARMFormat;
99 #undef ENTRY
100
101 // Converts enum to const char*.
102 static const inline char *stringForARMFormat(ARMFormat form) {
103 #define ENTRY(n, v) case n: return #n;
104   switch(form) {
105     ARM_FORMATS
106   case ARM_FORMAT_NA:
107   default:
108     return "";
109   }
110 #undef ENTRY
111 }
112
113 /// Expands on the enum definitions from ARMBaseInstrInfo.h.
114 /// They are being used by the disassembler implementation.
115 namespace ARMII {
116   enum {
117     NEONRegMask = 15,
118     GPRRegMask = 15,
119     NEON_RegRdShift = 12,
120     NEON_D_BitShift = 22,
121     NEON_RegRnShift = 16,
122     NEON_N_BitShift = 7,
123     NEON_RegRmShift = 0,
124     NEON_M_BitShift = 5
125   };
126 }
127
128 /// Utility function for extracting [From, To] bits from a uint32_t.
129 static inline unsigned slice(uint32_t Bits, unsigned From, unsigned To) {
130   assert(From < 32 && To < 32 && From >= To);
131   return (Bits >> To) & ((1 << (From - To + 1)) - 1);
132 }
133
134 /// Utility function for setting [From, To] bits to Val for a uint32_t.
135 static inline void setSlice(unsigned &Bits, unsigned From, unsigned To,
136                             unsigned Val) {
137   assert(From < 32 && To < 32 && From >= To);
138   uint32_t Mask = ((1 << (From - To + 1)) - 1);
139   Bits &= ~(Mask << To);
140   Bits |= (Val & Mask) << To;
141 }
142
143 // Return an integer result equal to the number of bits of x that are ones.
144 static inline uint32_t
145 BitCount (uint64_t x)
146 {
147     // c accumulates the total bits set in x
148     uint32_t c;
149     for (c = 0; x; ++c)
150     {
151         x &= x - 1; // clear the least significant bit set
152     }
153     return c;
154 }
155
156 static inline bool
157 BitIsSet (const uint64_t value, const uint64_t bit)
158 {
159     return (value & (1ull << bit)) != 0;
160 }
161
162 static inline bool
163 BitIsClear (const uint64_t value, const uint64_t bit)
164 {
165     return (value & (1ull << bit)) == 0;
166 }
167
168 /// Various utilities for checking the target specific flags.
169
170 /// A unary data processing instruction doesn't have an Rn operand.
171 static inline bool isUnaryDP(uint64_t TSFlags) {
172   return (TSFlags & ARMII::UnaryDP);
173 }
174
175 /// A NEON Domain instruction has cond field (Inst{31-28}) as 0b1111.
176 static inline bool isNEONDomain(uint64_t TSFlags) {
177   return (TSFlags & ARMII::DomainNEON) ||
178          (TSFlags & ARMII::DomainNEONA8);
179 }
180
181 /// This four-bit field describes the addressing mode used.
182 /// See also ARMBaseInstrInfo.h.
183 static inline unsigned getAddrMode(uint64_t TSFlags) {
184   return (TSFlags & ARMII::AddrModeMask);
185 }
186
187 /// {IndexModePre, IndexModePost}
188 /// Only valid for load and store ops.
189 /// See also ARMBaseInstrInfo.h.
190 static inline unsigned getIndexMode(uint64_t TSFlags) {
191   return (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
192 }
193
194 /// Pre-/post-indexed operations define an extra $base_wb in the OutOperandList.
195 static inline bool isPrePostLdSt(uint64_t TSFlags) {
196   return (TSFlags & ARMII::IndexModeMask) != 0;
197 }
198
199 // Forward declaration.
200 class ARMBasicMCBuilder;
201
202 // Builder Object is mostly ignored except in some Thumb disassemble functions.
203 typedef ARMBasicMCBuilder *BO;
204
205 /// DisassembleFP - DisassembleFP points to a function that disassembles an insn
206 /// and builds the MCOperand list upon disassembly.  It returns false on failure
207 /// or true on success.  The number of operands added is updated upon success.
208 typedef bool (*DisassembleFP)(MCInst &MI, unsigned Opcode, uint32_t insn,
209     unsigned short NumOps, unsigned &NumOpsAdded, BO Builder);
210
211 /// CreateMCBuilder - Return an ARMBasicMCBuilder that can build up the MC
212 /// infrastructure of an MCInst given the Opcode and Format of the instr.
213 /// Return NULL if it fails to create/return a proper builder.  API clients
214 /// are responsible for freeing up of the allocated memory.  Cacheing can be
215 /// performed by the API clients to improve performance.
216 extern ARMBasicMCBuilder *CreateMCBuilder(unsigned Opcode, ARMFormat Format);
217
218 /// ARMBasicMCBuilder - ARMBasicMCBuilder represents an ARM MCInst builder that
219 /// knows how to build up the MCOperand list.
220 class ARMBasicMCBuilder {
221   friend ARMBasicMCBuilder *CreateMCBuilder(unsigned Opcode, ARMFormat Format);
222   unsigned Opcode;
223   ARMFormat Format;
224   unsigned short NumOps;
225   DisassembleFP Disasm;
226   Session *SP;
227   int Err; // !=0 if the builder encounters some error condition during build.
228
229 private:
230   /// Opcode, Format, and NumOperands make up an ARM Basic MCBuilder.
231   ARMBasicMCBuilder(unsigned opc, ARMFormat format, unsigned short num);
232
233 public:
234   ARMBasicMCBuilder(ARMBasicMCBuilder &B)
235     : Opcode(B.Opcode), Format(B.Format), NumOps(B.NumOps), Disasm(B.Disasm),
236       SP(B.SP), GetOpInfo(0), DisInfo(0), Ctx(0) {
237     Err = 0;
238   }
239
240   virtual ~ARMBasicMCBuilder() {}
241
242   void SetSession(Session *sp) {
243     SP = sp;
244   }
245
246   void SetErr(int ErrCode) {
247     Err = ErrCode;
248   }
249
250   /// DoPredicateOperands - DoPredicateOperands process the predicate operands
251   /// of some Thumb instructions which come before the reglist operands.  It
252   /// returns true if the two predicate operands have been processed.
253   bool DoPredicateOperands(MCInst& MI, unsigned Opcode,
254       uint32_t insn, unsigned short NumOpsRemaning);
255   
256   /// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process
257   /// the possible Predicate and SBitModifier, to build the remaining MCOperand
258   /// constituents.
259   bool TryPredicateAndSBitModifier(MCInst& MI, unsigned Opcode,
260       uint32_t insn, unsigned short NumOpsRemaning);
261
262   /// InITBlock - InITBlock returns true if we are inside an IT block.
263   bool InITBlock() {
264     if (SP)
265       return SP->ITCounter > 0;
266
267     return false;
268   }
269
270   /// Build - Build delegates to BuildIt to perform the heavy liftling.  After
271   /// that, it invokes RunBuildAfterHook where some housekeepings can be done.
272   virtual bool Build(MCInst &MI, uint32_t insn) {
273     bool Status = BuildIt(MI, insn);
274     return RunBuildAfterHook(Status, MI, insn);
275   }
276
277   /// BuildIt - BuildIt performs the build step for this ARM Basic MC Builder.
278   /// The general idea is to set the Opcode for the MCInst, followed by adding
279   /// the appropriate MCOperands to the MCInst.  ARM Basic MC Builder delegates
280   /// to the Format-specific disassemble function for disassembly, followed by
281   /// TryPredicateAndSBitModifier() for PredicateOperand and OptionalDefOperand
282   /// which follow the Dst/Src Operands.
283   virtual bool BuildIt(MCInst &MI, uint32_t insn);
284
285   /// RunBuildAfterHook - RunBuildAfterHook performs operations deemed necessary
286   /// after BuildIt is finished.
287   virtual bool RunBuildAfterHook(bool Status, MCInst &MI, uint32_t insn);
288
289 private:
290   /// Get condition of the current IT instruction.
291   unsigned GetITCond() {
292     assert(SP);
293     return slice(SP->ITState, 7, 4);
294   }
295
296 private:
297   //
298   // Hooks for symbolic disassembly via the public 'C' interface.
299   //
300   // The function to get the symbolic information for operands.
301   LLVMOpInfoCallback GetOpInfo;
302   // The pointer to the block of symbolic information for above call back.
303   void *DisInfo;
304   // The assembly context for creating symbols and MCExprs in place of
305   // immediate operands when there is symbolic information.
306   MCContext *Ctx;
307   // The address of the instruction being disassembled.
308   uint64_t Address;
309
310 public:
311   void setupBuilderForSymbolicDisassembly(LLVMOpInfoCallback getOpInfo,
312                                           void *disInfo, MCContext *ctx,
313                                           uint64_t address) {
314     GetOpInfo = getOpInfo;
315     DisInfo = disInfo;
316     Ctx = ctx;
317     Address = address;
318   }
319
320   uint64_t getBuilderAddress() const { return Address; }
321
322   /// tryAddingSymbolicOperand - tryAddingSymbolicOperand trys to add a symbolic
323   /// operand in place of the immediate Value in the MCInst.  The immediate
324   /// Value has had any PC adjustment made by the caller.  If the getOpInfo()
325   /// function was set as part of the setupBuilderForSymbolicDisassembly() call
326   /// then that function is called to get any symbolic information at the
327   /// builder's Address for this instrution.  If that returns non-zero then the
328   /// symbolic information it returns is used to create an MCExpr and that is
329   /// added as an operand to the MCInst.  This function returns true if it adds
330   /// an operand to the MCInst and false otherwise.
331   bool tryAddingSymbolicOperand(uint64_t Value, uint64_t InstSize, MCInst &MI);
332
333 };
334
335 } // namespace llvm
336
337 #endif