Fixed some bugs.
[llvm/zpu.git] / lib / Target / ARM / Disassembler / ARMDisassemblerCore.h
blob9c30d332d1f200e13b1a34a8cb2c2967bec825bb
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.
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.
16 // It also contains code to represent the concepts of Builder and DisassembleFP
17 // to solve the problem of disassembling an ARM instr.
19 //===----------------------------------------------------------------------===//
21 #ifndef ARMDISASSEMBLERCORE_H
22 #define ARMDISASSEMBLERCORE_H
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/Target/TargetInstrInfo.h"
26 #include "ARMBaseInstrInfo.h"
27 #include "ARMRegisterInfo.h"
28 #include "ARMDisassembler.h"
30 namespace llvm {
32 class ARMUtils {
33 public:
34 static const char *OpcodeName(unsigned Opcode);
37 /////////////////////////////////////////////////////
38 // //
39 // Enums and Utilities for ARM Instruction Format //
40 // //
41 /////////////////////////////////////////////////////
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)
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
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 "";
104 #undef ENTRY
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
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);
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;
137 /// Various utilities for checking the target specific flags.
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);
144 /// This four-bit field describes the addressing mode used.
145 /// See also ARMBaseInstrInfo.h.
146 static inline unsigned getAddrMode(uint64_t TSFlags) {
147 return (TSFlags & ARMII::AddrModeMask);
150 /// {IndexModePre, IndexModePost}
151 /// Only valid for load and store ops.
152 /// See also ARMBaseInstrInfo.h.
153 static inline unsigned getIndexMode(uint64_t TSFlags) {
154 return (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
157 /// Pre-/post-indexed operations define an extra $base_wb in the OutOperandList.
158 static inline bool isPrePostLdSt(uint64_t TSFlags) {
159 return (TSFlags & ARMII::IndexModeMask) != 0;
162 // Forward declaration.
163 class ARMBasicMCBuilder;
165 // Builder Object is mostly ignored except in some Thumb disassemble functions.
166 typedef ARMBasicMCBuilder *BO;
168 /// DisassembleFP - DisassembleFP points to a function that disassembles an insn
169 /// and builds the MCOperand list upon disassembly. It returns false on failure
170 /// or true on success. The number of operands added is updated upon success.
171 typedef bool (*DisassembleFP)(MCInst &MI, unsigned Opcode, uint32_t insn,
172 unsigned short NumOps, unsigned &NumOpsAdded, BO Builder);
174 /// CreateMCBuilder - Return an ARMBasicMCBuilder that can build up the MC
175 /// infrastructure of an MCInst given the Opcode and Format of the instr.
176 /// Return NULL if it fails to create/return a proper builder. API clients
177 /// are responsible for freeing up of the allocated memory. Cacheing can be
178 /// performed by the API clients to improve performance.
179 extern ARMBasicMCBuilder *CreateMCBuilder(unsigned Opcode, ARMFormat Format);
181 /// ARMBasicMCBuilder - ARMBasicMCBuilder represents an ARM MCInst builder that
182 /// knows how to build up the MCOperand list.
183 class ARMBasicMCBuilder {
184 friend ARMBasicMCBuilder *CreateMCBuilder(unsigned Opcode, ARMFormat Format);
185 unsigned Opcode;
186 ARMFormat Format;
187 unsigned short NumOps;
188 DisassembleFP Disasm;
189 Session *SP;
190 int Err; // !=0 if the builder encounters some error condition during build.
192 private:
193 /// Opcode, Format, and NumOperands make up an ARM Basic MCBuilder.
194 ARMBasicMCBuilder(unsigned opc, ARMFormat format, unsigned short num);
196 public:
197 ARMBasicMCBuilder(ARMBasicMCBuilder &B)
198 : Opcode(B.Opcode), Format(B.Format), NumOps(B.NumOps), Disasm(B.Disasm),
199 SP(B.SP) {
200 Err = 0;
203 virtual ~ARMBasicMCBuilder() {}
205 void SetSession(Session *sp) {
206 SP = sp;
209 void SetErr(int ErrCode) {
210 Err = ErrCode;
213 /// DoPredicateOperands - DoPredicateOperands process the predicate operands
214 /// of some Thumb instructions which come before the reglist operands. It
215 /// returns true if the two predicate operands have been processed.
216 bool DoPredicateOperands(MCInst& MI, unsigned Opcode,
217 uint32_t insn, unsigned short NumOpsRemaning);
219 /// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process
220 /// the possible Predicate and SBitModifier, to build the remaining MCOperand
221 /// constituents.
222 bool TryPredicateAndSBitModifier(MCInst& MI, unsigned Opcode,
223 uint32_t insn, unsigned short NumOpsRemaning);
225 /// InITBlock - InITBlock returns true if we are inside an IT block.
226 bool InITBlock() {
227 if (SP)
228 return SP->ITCounter > 0;
230 return false;
233 /// Build - Build delegates to BuildIt to perform the heavy liftling. After
234 /// that, it invokes RunBuildAfterHook where some housekeepings can be done.
235 virtual bool Build(MCInst &MI, uint32_t insn) {
236 bool Status = BuildIt(MI, insn);
237 return RunBuildAfterHook(Status, MI, insn);
240 /// BuildIt - BuildIt performs the build step for this ARM Basic MC Builder.
241 /// The general idea is to set the Opcode for the MCInst, followed by adding
242 /// the appropriate MCOperands to the MCInst. ARM Basic MC Builder delegates
243 /// to the Format-specific disassemble function for disassembly, followed by
244 /// TryPredicateAndSBitModifier() for PredicateOperand and OptionalDefOperand
245 /// which follow the Dst/Src Operands.
246 virtual bool BuildIt(MCInst &MI, uint32_t insn);
248 /// RunBuildAfterHook - RunBuildAfterHook performs operations deemed necessary
249 /// after BuildIt is finished.
250 virtual bool RunBuildAfterHook(bool Status, MCInst &MI, uint32_t insn);
252 private:
253 /// Get condition of the current IT instruction.
254 unsigned GetITCond() {
255 assert(SP);
256 return slice(SP->ITState, 7, 4);
260 } // namespace llvm
262 #endif