Line data Source code
1 : //===-- ARMBaseInfo.h - Top level definitions for ARM -------- --*- 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 contains small standalone helper functions and enum definitions for
11 : // the ARM target useful for the compiler back-end and the MC libraries.
12 : // As such, it deliberately does not include references to LLVM core
13 : // code gen types, passes, etc..
14 : //
15 : //===----------------------------------------------------------------------===//
16 :
17 : #ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMBASEINFO_H
18 : #define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMBASEINFO_H
19 :
20 : #include "ARMMCTargetDesc.h"
21 : #include "llvm/Support/ErrorHandling.h"
22 : #include "Utils/ARMBaseInfo.h"
23 :
24 : namespace llvm {
25 :
26 : namespace ARM_PROC {
27 : enum IMod {
28 : IE = 2,
29 : ID = 3
30 : };
31 :
32 : enum IFlags {
33 : F = 1,
34 : I = 2,
35 : A = 4
36 : };
37 :
38 : inline static const char *IFlagsToString(unsigned val) {
39 70 : switch (val) {
40 0 : default: llvm_unreachable("Unknown iflags operand");
41 : case F: return "f";
42 21 : case I: return "i";
43 16 : case A: return "a";
44 : }
45 : }
46 :
47 : inline static const char *IModToString(unsigned val) {
48 51 : switch (val) {
49 0 : default: llvm_unreachable("Unknown imod operand");
50 : case IE: return "ie";
51 16 : case ID: return "id";
52 : }
53 : }
54 : }
55 :
56 : namespace ARM_MB {
57 : // The Memory Barrier Option constants map directly to the 4-bit encoding of
58 : // the option field for memory barrier operations.
59 : enum MemBOpt {
60 : RESERVED_0 = 0,
61 : OSHLD = 1,
62 : OSHST = 2,
63 : OSH = 3,
64 : RESERVED_4 = 4,
65 : NSHLD = 5,
66 : NSHST = 6,
67 : NSH = 7,
68 : RESERVED_8 = 8,
69 : ISHLD = 9,
70 : ISHST = 10,
71 : ISH = 11,
72 : RESERVED_12 = 12,
73 : LD = 13,
74 : ST = 14,
75 : SY = 15
76 : };
77 :
78 634 : inline static const char *MemBOptToString(unsigned val, bool HasV8) {
79 634 : switch (val) {
80 0 : default: llvm_unreachable("Unknown memory operation");
81 : case SY: return "sy";
82 21 : case ST: return "st";
83 19 : case LD: return HasV8 ? "ld" : "#0xd";
84 14 : case RESERVED_12: return "#0xc";
85 243 : case ISH: return "ish";
86 33 : case ISHST: return "ishst";
87 20 : case ISHLD: return HasV8 ? "ishld" : "#0x9";
88 14 : case RESERVED_8: return "#0x8";
89 34 : case NSH: return "nsh";
90 29 : case NSHST: return "nshst";
91 18 : case NSHLD: return HasV8 ? "nshld" : "#0x5";
92 6 : case RESERVED_4: return "#0x4";
93 23 : case OSH: return "osh";
94 22 : case OSHST: return "oshst";
95 18 : case OSHLD: return HasV8 ? "oshld" : "#0x1";
96 6 : case RESERVED_0: return "#0x0";
97 : }
98 : }
99 : } // namespace ARM_MB
100 :
101 : namespace ARM_TSB {
102 : enum TraceSyncBOpt {
103 : CSYNC = 0
104 : };
105 :
106 : inline static const char *TraceSyncBOptToString(unsigned val) {
107 0 : switch (val) {
108 0 : default:
109 0 : llvm_unreachable("Unknown trace synchronization barrier operation");
110 0 : case CSYNC: return "csync";
111 : }
112 : }
113 : } // namespace ARM_TSB
114 :
115 : namespace ARM_ISB {
116 : enum InstSyncBOpt {
117 : RESERVED_0 = 0,
118 : RESERVED_1 = 1,
119 : RESERVED_2 = 2,
120 : RESERVED_3 = 3,
121 : RESERVED_4 = 4,
122 : RESERVED_5 = 5,
123 : RESERVED_6 = 6,
124 : RESERVED_7 = 7,
125 : RESERVED_8 = 8,
126 : RESERVED_9 = 9,
127 : RESERVED_10 = 10,
128 : RESERVED_11 = 11,
129 : RESERVED_12 = 12,
130 : RESERVED_13 = 13,
131 : RESERVED_14 = 14,
132 : SY = 15
133 : };
134 :
135 35 : inline static const char *InstSyncBOptToString(unsigned val) {
136 35 : switch (val) {
137 0 : default:
138 0 : llvm_unreachable("Unknown memory operation");
139 : case RESERVED_0: return "#0x0";
140 4 : case RESERVED_1: return "#0x1";
141 0 : case RESERVED_2: return "#0x2";
142 0 : case RESERVED_3: return "#0x3";
143 0 : case RESERVED_4: return "#0x4";
144 0 : case RESERVED_5: return "#0x5";
145 0 : case RESERVED_6: return "#0x6";
146 0 : case RESERVED_7: return "#0x7";
147 0 : case RESERVED_8: return "#0x8";
148 0 : case RESERVED_9: return "#0x9";
149 2 : case RESERVED_10: return "#0xa";
150 0 : case RESERVED_11: return "#0xb";
151 0 : case RESERVED_12: return "#0xc";
152 0 : case RESERVED_13: return "#0xd";
153 0 : case RESERVED_14: return "#0xe";
154 29 : case SY: return "sy";
155 : }
156 : }
157 : } // namespace ARM_ISB
158 :
159 : /// isARMLowRegister - Returns true if the register is a low register (r0-r7).
160 : ///
161 : static inline bool isARMLowRegister(unsigned Reg) {
162 : using namespace ARM;
163 31607 : switch (Reg) {
164 : case R0: case R1: case R2: case R3:
165 : case R4: case R5: case R6: case R7:
166 : return true;
167 : default:
168 : return false;
169 : }
170 : }
171 :
172 : /// ARMII - This namespace holds all of the target specific flags that
173 : /// instruction info tracks.
174 : ///
175 : namespace ARMII {
176 :
177 : /// ARM Index Modes
178 : enum IndexMode {
179 : IndexModeNone = 0,
180 : IndexModePre = 1,
181 : IndexModePost = 2,
182 : IndexModeUpd = 3
183 : };
184 :
185 : /// ARM Addressing Modes
186 : enum AddrMode {
187 : AddrModeNone = 0,
188 : AddrMode1 = 1,
189 : AddrMode2 = 2,
190 : AddrMode3 = 3,
191 : AddrMode4 = 4,
192 : AddrMode5 = 5,
193 : AddrMode6 = 6,
194 : AddrModeT1_1 = 7,
195 : AddrModeT1_2 = 8,
196 : AddrModeT1_4 = 9,
197 : AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
198 : AddrModeT2_i12 = 11,
199 : AddrModeT2_i8 = 12,
200 : AddrModeT2_so = 13,
201 : AddrModeT2_pc = 14, // +/- i12 for pc relative data
202 : AddrModeT2_i8s4 = 15, // i8 * 4
203 : AddrMode_i12 = 16,
204 : AddrMode5FP16 = 17, // i8 * 2
205 : AddrModeT2_ldrex = 18, // i8 * 4, with unscaled offset in MCInst
206 : };
207 :
208 : inline static const char *AddrModeToString(AddrMode addrmode) {
209 : switch (addrmode) {
210 : case AddrModeNone: return "AddrModeNone";
211 : case AddrMode1: return "AddrMode1";
212 : case AddrMode2: return "AddrMode2";
213 : case AddrMode3: return "AddrMode3";
214 : case AddrMode4: return "AddrMode4";
215 : case AddrMode5: return "AddrMode5";
216 : case AddrMode5FP16: return "AddrMode5FP16";
217 : case AddrMode6: return "AddrMode6";
218 : case AddrModeT1_1: return "AddrModeT1_1";
219 : case AddrModeT1_2: return "AddrModeT1_2";
220 : case AddrModeT1_4: return "AddrModeT1_4";
221 : case AddrModeT1_s: return "AddrModeT1_s";
222 : case AddrModeT2_i12: return "AddrModeT2_i12";
223 : case AddrModeT2_i8: return "AddrModeT2_i8";
224 : case AddrModeT2_so: return "AddrModeT2_so";
225 : case AddrModeT2_pc: return "AddrModeT2_pc";
226 : case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
227 : case AddrMode_i12: return "AddrMode_i12";
228 : case AddrModeT2_ldrex:return "AddrModeT2_ldrex";
229 : }
230 : }
231 :
232 : /// Target Operand Flag enum.
233 : enum TOF {
234 : //===------------------------------------------------------------------===//
235 : // ARM Specific MachineOperand flags.
236 :
237 : MO_NO_FLAG = 0,
238 :
239 : /// MO_LO16 - On a symbol operand, this represents a relocation containing
240 : /// lower 16 bit of the address. Used only via movw instruction.
241 : MO_LO16 = 0x1,
242 :
243 : /// MO_HI16 - On a symbol operand, this represents a relocation containing
244 : /// higher 16 bit of the address. Used only via movt instruction.
245 : MO_HI16 = 0x2,
246 :
247 : /// MO_OPTION_MASK - Most flags are mutually exclusive; this mask selects
248 : /// just that part of the flag set.
249 : MO_OPTION_MASK = 0x3,
250 :
251 : /// MO_COFFSTUB - On a symbol operand "FOO", this indicates that the
252 : /// reference is actually to the ".refptrp.FOO" symbol. This is used for
253 : /// stub symbols on windows.
254 : MO_COFFSTUB = 0x4,
255 :
256 : /// MO_GOT - On a symbol operand, this represents a GOT relative relocation.
257 : MO_GOT = 0x8,
258 :
259 : /// MO_SBREL - On a symbol operand, this represents a static base relative
260 : /// relocation. Used in movw and movt instructions.
261 : MO_SBREL = 0x10,
262 :
263 : /// MO_DLLIMPORT - On a symbol operand, this represents that the reference
264 : /// to the symbol is for an import stub. This is used for DLL import
265 : /// storage class indication on Windows.
266 : MO_DLLIMPORT = 0x20,
267 :
268 : /// MO_SECREL - On a symbol operand this indicates that the immediate is
269 : /// the offset from beginning of section.
270 : ///
271 : /// This is the TLS offset for the COFF/Windows TLS mechanism.
272 : MO_SECREL = 0x40,
273 :
274 : /// MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it
275 : /// represents a symbol which, if indirect, will get special Darwin mangling
276 : /// as a non-lazy-ptr indirect symbol (i.e. "L_FOO$non_lazy_ptr"). Can be
277 : /// combined with MO_LO16, MO_HI16 or MO_NO_FLAG (in a constant-pool, for
278 : /// example).
279 : MO_NONLAZY = 0x80,
280 :
281 : // It's undefined behaviour if an enum overflows the range between its
282 : // smallest and largest values, but since these are |ed together, it can
283 : // happen. Put a sentinel in (values of this enum are stored as "unsigned
284 : // char").
285 : MO_UNUSED_MAXIMUM = 0xff
286 : };
287 :
288 : enum {
289 : //===------------------------------------------------------------------===//
290 : // Instruction Flags.
291 :
292 : //===------------------------------------------------------------------===//
293 : // This four-bit field describes the addressing mode used.
294 : AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
295 :
296 : // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
297 : // and store ops only. Generic "updating" flag is used for ld/st multiple.
298 : // The index mode enums are declared in ARMBaseInfo.h
299 : IndexModeShift = 5,
300 : IndexModeMask = 3 << IndexModeShift,
301 :
302 : //===------------------------------------------------------------------===//
303 : // Instruction encoding formats.
304 : //
305 : FormShift = 7,
306 : FormMask = 0x3f << FormShift,
307 :
308 : // Pseudo instructions
309 : Pseudo = 0 << FormShift,
310 :
311 : // Multiply instructions
312 : MulFrm = 1 << FormShift,
313 :
314 : // Branch instructions
315 : BrFrm = 2 << FormShift,
316 : BrMiscFrm = 3 << FormShift,
317 :
318 : // Data Processing instructions
319 : DPFrm = 4 << FormShift,
320 : DPSoRegFrm = 5 << FormShift,
321 :
322 : // Load and Store
323 : LdFrm = 6 << FormShift,
324 : StFrm = 7 << FormShift,
325 : LdMiscFrm = 8 << FormShift,
326 : StMiscFrm = 9 << FormShift,
327 : LdStMulFrm = 10 << FormShift,
328 :
329 : LdStExFrm = 11 << FormShift,
330 :
331 : // Miscellaneous arithmetic instructions
332 : ArithMiscFrm = 12 << FormShift,
333 : SatFrm = 13 << FormShift,
334 :
335 : // Extend instructions
336 : ExtFrm = 14 << FormShift,
337 :
338 : // VFP formats
339 : VFPUnaryFrm = 15 << FormShift,
340 : VFPBinaryFrm = 16 << FormShift,
341 : VFPConv1Frm = 17 << FormShift,
342 : VFPConv2Frm = 18 << FormShift,
343 : VFPConv3Frm = 19 << FormShift,
344 : VFPConv4Frm = 20 << FormShift,
345 : VFPConv5Frm = 21 << FormShift,
346 : VFPLdStFrm = 22 << FormShift,
347 : VFPLdStMulFrm = 23 << FormShift,
348 : VFPMiscFrm = 24 << FormShift,
349 :
350 : // Thumb format
351 : ThumbFrm = 25 << FormShift,
352 :
353 : // Miscelleaneous format
354 : MiscFrm = 26 << FormShift,
355 :
356 : // NEON formats
357 : NGetLnFrm = 27 << FormShift,
358 : NSetLnFrm = 28 << FormShift,
359 : NDupFrm = 29 << FormShift,
360 : NLdStFrm = 30 << FormShift,
361 : N1RegModImmFrm= 31 << FormShift,
362 : N2RegFrm = 32 << FormShift,
363 : NVCVTFrm = 33 << FormShift,
364 : NVDupLnFrm = 34 << FormShift,
365 : N2RegVShLFrm = 35 << FormShift,
366 : N2RegVShRFrm = 36 << FormShift,
367 : N3RegFrm = 37 << FormShift,
368 : N3RegVShFrm = 38 << FormShift,
369 : NVExtFrm = 39 << FormShift,
370 : NVMulSLFrm = 40 << FormShift,
371 : NVTBLFrm = 41 << FormShift,
372 : N3RegCplxFrm = 43 << FormShift,
373 :
374 : //===------------------------------------------------------------------===//
375 : // Misc flags.
376 :
377 : // UnaryDP - Indicates this is a unary data processing instruction, i.e.
378 : // it doesn't have a Rn operand.
379 : UnaryDP = 1 << 13,
380 :
381 : // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
382 : // a 16-bit Thumb instruction if certain conditions are met.
383 : Xform16Bit = 1 << 14,
384 :
385 : // ThumbArithFlagSetting - The instruction is a 16-bit flag setting Thumb
386 : // instruction. Used by the parser to determine whether to require the 'S'
387 : // suffix on the mnemonic (when not in an IT block) or preclude it (when
388 : // in an IT block).
389 : ThumbArithFlagSetting = 1 << 18,
390 :
391 : //===------------------------------------------------------------------===//
392 : // Code domain.
393 : DomainShift = 15,
394 : DomainMask = 7 << DomainShift,
395 : DomainGeneral = 0 << DomainShift,
396 : DomainVFP = 1 << DomainShift,
397 : DomainNEON = 2 << DomainShift,
398 : DomainNEONA8 = 4 << DomainShift,
399 :
400 : //===------------------------------------------------------------------===//
401 : // Field shifts - such shifts are used to set field while generating
402 : // machine instructions.
403 : //
404 : // FIXME: This list will need adjusting/fixing as the MC code emitter
405 : // takes shape and the ARMCodeEmitter.cpp bits go away.
406 : ShiftTypeShift = 4,
407 :
408 : M_BitShift = 5,
409 : ShiftImmShift = 5,
410 : ShiftShift = 7,
411 : N_BitShift = 7,
412 : ImmHiShift = 8,
413 : SoRotImmShift = 8,
414 : RegRsShift = 8,
415 : ExtRotImmShift = 10,
416 : RegRdLoShift = 12,
417 : RegRdShift = 12,
418 : RegRdHiShift = 16,
419 : RegRnShift = 16,
420 : S_BitShift = 20,
421 : W_BitShift = 21,
422 : AM3_I_BitShift = 22,
423 : D_BitShift = 22,
424 : U_BitShift = 23,
425 : P_BitShift = 24,
426 : I_BitShift = 25,
427 : CondShift = 28
428 : };
429 :
430 : } // end namespace ARMII
431 :
432 : } // end namespace llvm;
433 :
434 : #endif
|