56dd85a7d999b7ba9a94305fcc7c9fd0d3bd7bef
[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/Target/TargetInstrInfo.h"
26 #include "ARMBaseInstrInfo.h"
27 #include "ARMRegisterInfo.h"
28 #include "ARMDisassembler.h"
29
30 namespace llvm {
31
32 class ARMUtils {
33 public:
34   static const char *OpcodeName(unsigned Opcode);
35 };
36
37 /////////////////////////////////////////////////////
38 //                                                 //
39 //  Enums and Utilities for ARM Instruction Format //
40 //                                                 //
41 /////////////////////////////////////////////////////
42
43 #define ARM_FORMATS                   \
44   ENTRY(ARM_FORMAT_PSEUDO,         0) \
45   ENTRY(ARM_FORMAT_MULFRM,         1) \
46   ENTRY(ARM_FORMAT_BRFRM,          2) \
47   ENTRY(ARM_FORMAT_BRMISCFRM,      3) \
48   ENTRY(ARM_FORMAT_DPFRM,          4) \
49   ENTRY(ARM_FORMAT_DPSOREGFRM,     5) \
50   ENTRY(ARM_FORMAT_LDFRM,          6) \
51   ENTRY(ARM_FORMAT_STFRM,          7) \
52   ENTRY(ARM_FORMAT_LDMISCFRM,      8) \
53   ENTRY(ARM_FORMAT_STMISCFRM,      9) \
54   ENTRY(ARM_FORMAT_LDSTMULFRM,    10) \
55   ENTRY(ARM_FORMAT_LDSTEXFRM,     11) \
56   ENTRY(ARM_FORMAT_ARITHMISCFRM,  12) \
57   ENTRY(ARM_FORMAT_SATFRM,        13) \
58   ENTRY(ARM_FORMAT_EXTFRM,        14) \
59   ENTRY(ARM_FORMAT_VFPUNARYFRM,   15) \
60   ENTRY(ARM_FORMAT_VFPBINARYFRM,  16) \
61   ENTRY(ARM_FORMAT_VFPCONV1FRM,   17) \
62   ENTRY(ARM_FORMAT_VFPCONV2FRM,   18) \
63   ENTRY(ARM_FORMAT_VFPCONV3FRM,   19) \
64   ENTRY(ARM_FORMAT_VFPCONV4FRM,   20) \
65   ENTRY(ARM_FORMAT_VFPCONV5FRM,   21) \
66   ENTRY(ARM_FORMAT_VFPLDSTFRM,    22) \
67   ENTRY(ARM_FORMAT_VFPLDSTMULFRM, 23) \
68   ENTRY(ARM_FORMAT_VFPMISCFRM,    24) \
69   ENTRY(ARM_FORMAT_THUMBFRM,      25) \
70   ENTRY(ARM_FORMAT_MISCFRM,       26) \
71   ENTRY(ARM_FORMAT_NEONGETLNFRM,  27) \
72   ENTRY(ARM_FORMAT_NEONSETLNFRM,  28) \
73   ENTRY(ARM_FORMAT_NEONDUPFRM,    29) \
74   ENTRY(ARM_FORMAT_NLdSt,         30) \
75   ENTRY(ARM_FORMAT_N1RegModImm,   31) \
76   ENTRY(ARM_FORMAT_N2Reg,         32) \
77   ENTRY(ARM_FORMAT_NVCVT,         33) \
78   ENTRY(ARM_FORMAT_NVecDupLn,     34) \
79   ENTRY(ARM_FORMAT_N2RegVecShL,   35) \
80   ENTRY(ARM_FORMAT_N2RegVecShR,   36) \
81   ENTRY(ARM_FORMAT_N3Reg,         37) \
82   ENTRY(ARM_FORMAT_N3RegVecSh,    38) \
83   ENTRY(ARM_FORMAT_NVecExtract,   39) \
84   ENTRY(ARM_FORMAT_NVecMulScalar, 40) \
85   ENTRY(ARM_FORMAT_NVTBL,         41)
86
87 // ARM instruction format specifies the encoding used by the instruction.
88 #define ENTRY(n, v) n = v,
89 typedef enum {
90   ARM_FORMATS
91   ARM_FORMAT_NA
92 } ARMFormat;
93 #undef ENTRY
94
95 // Converts enum to const char*.
96 static const inline char *stringForARMFormat(ARMFormat form) {
97 #define ENTRY(n, v) case n: return #n;
98   switch(form) {
99     ARM_FORMATS
100   case ARM_FORMAT_NA:
101   default:
102     return "";
103   }
104 #undef ENTRY
105 }
106
107 /// Expands on the enum definitions from ARMBaseInstrInfo.h.
108 /// They are being used by the disassembler implementation.
109 namespace ARMII {
110   enum {
111     NEONRegMask = 15,
112     GPRRegMask = 15,
113     NEON_RegRdShift = 12,
114     NEON_D_BitShift = 22,
115     NEON_RegRnShift = 16,
116     NEON_N_BitShift = 7,
117     NEON_RegRmShift = 0,
118     NEON_M_BitShift = 5
119   };
120 }
121
122 /// Utility function for extracting [From, To] bits from a uint32_t.
123 static inline unsigned slice(uint32_t Bits, unsigned From, unsigned To) {
124   assert(From < 32 && To < 32 && From >= To);
125   return (Bits >> To) & ((1 << (From - To + 1)) - 1);
126 }
127
128 /// Utility function for setting [From, To] bits to Val for a uint32_t.
129 static inline void setSlice(unsigned &Bits, unsigned From, unsigned To,
130                             unsigned Val) {
131   assert(From < 32 && To < 32 && From >= To);
132   uint32_t Mask = ((1 << (From - To + 1)) - 1);
133   Bits &= ~(Mask << To);
134   Bits |= (Val & Mask) << To;
135 }
136
137 /// Various utilities for checking the target specific flags.
138
139 /// A unary data processing instruction doesn't have an Rn operand.
140 static inline bool isUnaryDP(uint64_t TSFlags) {
141   return (TSFlags & ARMII::UnaryDP);
142 }
143
144 /// A NEON Domain instruction has cond field (Inst{31-28}) as 0b1111.
145 static inline bool isNEONDomain(uint64_t TSFlags) {
146   return (TSFlags & ARMII::DomainNEON) ||
147          (TSFlags & ARMII::DomainNEONA8);
148 }
149
150 /// This four-bit field describes the addressing mode used.
151 /// See also ARMBaseInstrInfo.h.
152 static inline unsigned getAddrMode(uint64_t TSFlags) {
153   return (TSFlags & ARMII::AddrModeMask);
154 }
155
156 /// {IndexModePre, IndexModePost}
157 /// Only valid for load and store ops.
158 /// See also ARMBaseInstrInfo.h.
159 static inline unsigned getIndexMode(uint64_t TSFlags) {
160   return (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
161 }
162
163 /// Pre-/post-indexed operations define an extra $base_wb in the OutOperandList.
164 static inline bool isPrePostLdSt(uint64_t TSFlags) {
165   return (TSFlags & ARMII::IndexModeMask) != 0;
166 }
167
168 // Forward declaration.
169 class ARMBasicMCBuilder;
170
171 // Builder Object is mostly ignored except in some Thumb disassemble functions.
172 typedef ARMBasicMCBuilder *BO;
173
174 /// DisassembleFP - DisassembleFP points to a function that disassembles an insn
175 /// and builds the MCOperand list upon disassembly.  It returns false on failure
176 /// or true on success.  The number of operands added is updated upon success.
177 typedef bool (*DisassembleFP)(MCInst &MI, unsigned Opcode, uint32_t insn,
178     unsigned short NumOps, unsigned &NumOpsAdded, BO Builder);
179
180 /// CreateMCBuilder - Return an ARMBasicMCBuilder that can build up the MC
181 /// infrastructure of an MCInst given the Opcode and Format of the instr.
182 /// Return NULL if it fails to create/return a proper builder.  API clients
183 /// are responsible for freeing up of the allocated memory.  Cacheing can be
184 /// performed by the API clients to improve performance.
185 extern ARMBasicMCBuilder *CreateMCBuilder(unsigned Opcode, ARMFormat Format);
186
187 /// ARMBasicMCBuilder - ARMBasicMCBuilder represents an ARM MCInst builder that
188 /// knows how to build up the MCOperand list.
189 class ARMBasicMCBuilder {
190   friend ARMBasicMCBuilder *CreateMCBuilder(unsigned Opcode, ARMFormat Format);
191   unsigned Opcode;
192   ARMFormat Format;
193   unsigned short NumOps;
194   DisassembleFP Disasm;
195   Session *SP;
196   int Err; // !=0 if the builder encounters some error condition during build.
197
198 private:
199   /// Opcode, Format, and NumOperands make up an ARM Basic MCBuilder.
200   ARMBasicMCBuilder(unsigned opc, ARMFormat format, unsigned short num);
201
202 public:
203   ARMBasicMCBuilder(ARMBasicMCBuilder &B)
204     : Opcode(B.Opcode), Format(B.Format), NumOps(B.NumOps), Disasm(B.Disasm),
205       SP(B.SP) {
206     Err = 0;
207   }
208
209   virtual ~ARMBasicMCBuilder() {}
210
211   void SetSession(Session *sp) {
212     SP = sp;
213   }
214
215   void SetErr(int ErrCode) {
216     Err = ErrCode;
217   }
218
219   /// DoPredicateOperands - DoPredicateOperands process the predicate operands
220   /// of some Thumb instructions which come before the reglist operands.  It
221   /// returns true if the two predicate operands have been processed.
222   bool DoPredicateOperands(MCInst& MI, unsigned Opcode,
223       uint32_t insn, unsigned short NumOpsRemaning);
224   
225   /// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process
226   /// the possible Predicate and SBitModifier, to build the remaining MCOperand
227   /// constituents.
228   bool TryPredicateAndSBitModifier(MCInst& MI, unsigned Opcode,
229       uint32_t insn, unsigned short NumOpsRemaning);
230
231   /// InITBlock - InITBlock returns true if we are inside an IT block.
232   bool InITBlock() {
233     if (SP)
234       return SP->ITCounter > 0;
235
236     return false;
237   }
238
239   /// Build - Build delegates to BuildIt to perform the heavy liftling.  After
240   /// that, it invokes RunBuildAfterHook where some housekeepings can be done.
241   virtual bool Build(MCInst &MI, uint32_t insn) {
242     bool Status = BuildIt(MI, insn);
243     return RunBuildAfterHook(Status, MI, insn);
244   }
245
246   /// BuildIt - BuildIt performs the build step for this ARM Basic MC Builder.
247   /// The general idea is to set the Opcode for the MCInst, followed by adding
248   /// the appropriate MCOperands to the MCInst.  ARM Basic MC Builder delegates
249   /// to the Format-specific disassemble function for disassembly, followed by
250   /// TryPredicateAndSBitModifier() for PredicateOperand and OptionalDefOperand
251   /// which follow the Dst/Src Operands.
252   virtual bool BuildIt(MCInst &MI, uint32_t insn);
253
254   /// RunBuildAfterHook - RunBuildAfterHook performs operations deemed necessary
255   /// after BuildIt is finished.
256   virtual bool RunBuildAfterHook(bool Status, MCInst &MI, uint32_t insn);
257
258 private:
259   /// Get condition of the current IT instruction.
260   unsigned GetITCond() {
261     assert(SP);
262     return slice(SP->ITState, 7, 4);
263   }
264 };
265
266 } // namespace llvm
267
268 #endif