Coverage Report

Created: 2024-08-21 06:24

/src/capstonenext/arch/ARM/ARMBaseInfo.h
Line
Count
Source (jump to first uncovered line)
1
//===-- ARMBaseInfo.h - Top level definitions for ARM ---*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file contains small standalone helper functions and enum definitions for
10
// the ARM target useful for the compiler back-end and the MC libraries.
11
// As such, it deliberately does not include references to LLVM core
12
// code gen types, passes, etc..
13
//
14
//===----------------------------------------------------------------------===//
15
16
#ifndef CS_ARM_BASEINFO_H
17
#define CS_ARM_BASEINFO_H
18
19
#include <assert.h>
20
#include <stdbool.h>
21
#include <stdint.h>
22
#include <string.h>
23
24
#include "../../MCInstPrinter.h"
25
#include "capstone/arm.h"
26
27
#define GET_INSTRINFO_ENUM
28
#include "ARMGenInstrInfo.inc"
29
30
// System Registers
31
typedef struct MClassSysReg {
32
  const char *Name;
33
  arm_sysop_reg sysreg;
34
  uint16_t M1Encoding12;
35
  uint16_t M2M3Encoding8;
36
  uint16_t Encoding;
37
  int FeaturesRequired[2];
38
} ARMSysReg_MClassSysReg;
39
40
// return true if FeaturesRequired are all present in ActiveFeatures
41
static inline bool hasRequiredFeatures(const ARMSysReg_MClassSysReg *TheReg,
42
               int ActiveFeatures)
43
0
{
44
0
  return (TheReg->FeaturesRequired[0] == ActiveFeatures ||
45
0
    TheReg->FeaturesRequired[1] == ActiveFeatures);
46
0
}
Unexecuted instantiation: ARMModule.c:hasRequiredFeatures
Unexecuted instantiation: ARMMapping.c:hasRequiredFeatures
Unexecuted instantiation: ARMBaseInfo.c:hasRequiredFeatures
Unexecuted instantiation: ARMDisassembler.c:hasRequiredFeatures
Unexecuted instantiation: ARMDisassemblerExtension.c:hasRequiredFeatures
Unexecuted instantiation: ARMInstPrinter.c:hasRequiredFeatures
47
48
// returns true if TestFeatures are all present in FeaturesRequired
49
static inline bool
50
MClassSysReg_isInRequiredFeatures(const ARMSysReg_MClassSysReg *TheReg,
51
          int TestFeatures)
52
7.16k
{
53
7.16k
  return (TheReg->FeaturesRequired[0] == TestFeatures ||
54
7.16k
    TheReg->FeaturesRequired[1] == TestFeatures);
55
7.16k
}
Unexecuted instantiation: ARMModule.c:MClassSysReg_isInRequiredFeatures
ARMMapping.c:MClassSysReg_isInRequiredFeatures
Line
Count
Source
52
3.18k
{
53
3.18k
  return (TheReg->FeaturesRequired[0] == TestFeatures ||
54
3.18k
    TheReg->FeaturesRequired[1] == TestFeatures);
55
3.18k
}
Unexecuted instantiation: ARMBaseInfo.c:MClassSysReg_isInRequiredFeatures
Unexecuted instantiation: ARMDisassembler.c:MClassSysReg_isInRequiredFeatures
Unexecuted instantiation: ARMDisassemblerExtension.c:MClassSysReg_isInRequiredFeatures
ARMInstPrinter.c:MClassSysReg_isInRequiredFeatures
Line
Count
Source
52
3.98k
{
53
3.98k
  return (TheReg->FeaturesRequired[0] == TestFeatures ||
54
3.98k
    TheReg->FeaturesRequired[1] == TestFeatures);
55
3.98k
}
56
57
#define GET_SUBTARGETINFO_ENUM
58
#include "ARMGenSubtargetInfo.inc"
59
60
// lookup system register using 12-bit SYSm value.
61
// Note: the search is uniqued using M1 mask
62
const ARMSysReg_MClassSysReg *
63
ARMSysReg_lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm);
64
// returns APSR with _<bits> qualifier.
65
// Note: ARMv7-M deprecates using MSR APSR without a _<bits> qualifier
66
const ARMSysReg_MClassSysReg *
67
ARMSysReg_lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm);
68
// lookup system registers using 8-bit SYSm value
69
const ARMSysReg_MClassSysReg *
70
ARMSysReg_lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm);
71
// end namespace ARMSysReg
72
73
// Banked Registers
74
typedef struct BankedReg {
75
  const char *Name;
76
  arm_sysop_reg sysreg;
77
  uint16_t Encoding;
78
} ARMBankedReg_BankedReg;
79
80
#define GET_BANKEDREG_DECL
81
#define GET_MCLASSSYSREG_DECL
82
#include "ARMGenSystemRegister.inc"
83
84
typedef enum IMod { ARM_PROC_IE = 2, ARM_PROC_ID = 3 } ARM_PROC_IMod;
85
86
typedef enum IFlags {
87
  ARM_PROC_F = 1,
88
  ARM_PROC_I = 2,
89
  ARM_PROC_A = 4
90
} ARM_PROC_IFlags;
91
92
inline static const char *ARM_PROC_IFlagsToString(unsigned val)
93
1.71k
{
94
1.71k
  switch (val) {
95
0
  default:
96
    // llvm_unreachable("Unknown iflags operand");
97
487
  case ARM_PROC_F:
98
487
    return "f";
99
735
  case ARM_PROC_I:
100
735
    return "i";
101
495
  case ARM_PROC_A:
102
495
    return "a";
103
1.71k
  }
104
1.71k
}
Unexecuted instantiation: ARMModule.c:ARM_PROC_IFlagsToString
Unexecuted instantiation: ARMMapping.c:ARM_PROC_IFlagsToString
Unexecuted instantiation: ARMBaseInfo.c:ARM_PROC_IFlagsToString
Unexecuted instantiation: ARMDisassembler.c:ARM_PROC_IFlagsToString
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_PROC_IFlagsToString
ARMInstPrinter.c:ARM_PROC_IFlagsToString
Line
Count
Source
93
1.71k
{
94
1.71k
  switch (val) {
95
0
  default:
96
    // llvm_unreachable("Unknown iflags operand");
97
487
  case ARM_PROC_F:
98
487
    return "f";
99
735
  case ARM_PROC_I:
100
735
    return "i";
101
495
  case ARM_PROC_A:
102
495
    return "a";
103
1.71k
  }
104
1.71k
}
105
106
inline static const char *ARM_PROC_IModToString(unsigned val)
107
1.59k
{
108
1.59k
  switch (val) {
109
0
  default:
110
    // llvm_unreachable("Unknown imod operand");
111
0
    assert(0);
112
1.17k
  case ARM_PROC_IE:
113
1.17k
    return "ie";
114
425
  case ARM_PROC_ID:
115
425
    return "id";
116
1.59k
  }
117
1.59k
}
Unexecuted instantiation: ARMModule.c:ARM_PROC_IModToString
Unexecuted instantiation: ARMMapping.c:ARM_PROC_IModToString
Unexecuted instantiation: ARMBaseInfo.c:ARM_PROC_IModToString
Unexecuted instantiation: ARMDisassembler.c:ARM_PROC_IModToString
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_PROC_IModToString
ARMInstPrinter.c:ARM_PROC_IModToString
Line
Count
Source
107
1.59k
{
108
1.59k
  switch (val) {
109
0
  default:
110
    // llvm_unreachable("Unknown imod operand");
111
0
    assert(0);
112
1.17k
  case ARM_PROC_IE:
113
1.17k
    return "ie";
114
425
  case ARM_PROC_ID:
115
425
    return "id";
116
1.59k
  }
117
1.59k
}
118
119
inline static const char *ARM_MB_MemBOptToString(unsigned val, bool HasV8)
120
2.18k
{
121
2.18k
  switch (val) {
122
0
  default:
123
    // llvm_unreachable("Unknown memory operation");
124
0
    assert(0);
125
414
  case ARM_MB_SY:
126
414
    return "sy";
127
101
  case ARM_MB_ST:
128
101
    return "st";
129
113
  case ARM_MB_LD:
130
113
    return HasV8 ? "ld" : "#0xd";
131
148
  case ARM_MB_RESERVED_12:
132
148
    return "#0xc";
133
34
  case ARM_MB_ISH:
134
34
    return "ish";
135
76
  case ARM_MB_ISHST:
136
76
    return "ishst";
137
68
  case ARM_MB_ISHLD:
138
68
    return HasV8 ? "ishld" : "#0x9";
139
77
  case ARM_MB_RESERVED_8:
140
77
    return "#0x8";
141
22
  case ARM_MB_NSH:
142
22
    return "nsh";
143
47
  case ARM_MB_NSHST:
144
47
    return "nshst";
145
36
  case ARM_MB_NSHLD:
146
36
    return HasV8 ? "nshld" : "#0x5";
147
70
  case ARM_MB_RESERVED_4:
148
70
    return "#0x4";
149
263
  case ARM_MB_OSH:
150
263
    return "osh";
151
235
  case ARM_MB_OSHST:
152
235
    return "oshst";
153
463
  case ARM_MB_OSHLD:
154
463
    return HasV8 ? "oshld" : "#0x1";
155
18
  case ARM_MB_RESERVED_0:
156
18
    return "#0x0";
157
2.18k
  }
158
2.18k
}
Unexecuted instantiation: ARMModule.c:ARM_MB_MemBOptToString
Unexecuted instantiation: ARMMapping.c:ARM_MB_MemBOptToString
Unexecuted instantiation: ARMBaseInfo.c:ARM_MB_MemBOptToString
Unexecuted instantiation: ARMDisassembler.c:ARM_MB_MemBOptToString
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_MB_MemBOptToString
ARMInstPrinter.c:ARM_MB_MemBOptToString
Line
Count
Source
120
2.18k
{
121
2.18k
  switch (val) {
122
0
  default:
123
    // llvm_unreachable("Unknown memory operation");
124
0
    assert(0);
125
414
  case ARM_MB_SY:
126
414
    return "sy";
127
101
  case ARM_MB_ST:
128
101
    return "st";
129
113
  case ARM_MB_LD:
130
113
    return HasV8 ? "ld" : "#0xd";
131
148
  case ARM_MB_RESERVED_12:
132
148
    return "#0xc";
133
34
  case ARM_MB_ISH:
134
34
    return "ish";
135
76
  case ARM_MB_ISHST:
136
76
    return "ishst";
137
68
  case ARM_MB_ISHLD:
138
68
    return HasV8 ? "ishld" : "#0x9";
139
77
  case ARM_MB_RESERVED_8:
140
77
    return "#0x8";
141
22
  case ARM_MB_NSH:
142
22
    return "nsh";
143
47
  case ARM_MB_NSHST:
144
47
    return "nshst";
145
36
  case ARM_MB_NSHLD:
146
36
    return HasV8 ? "nshld" : "#0x5";
147
70
  case ARM_MB_RESERVED_4:
148
70
    return "#0x4";
149
263
  case ARM_MB_OSH:
150
263
    return "osh";
151
235
  case ARM_MB_OSHST:
152
235
    return "oshst";
153
463
  case ARM_MB_OSHLD:
154
463
    return HasV8 ? "oshld" : "#0x1";
155
18
  case ARM_MB_RESERVED_0:
156
18
    return "#0x0";
157
2.18k
  }
158
2.18k
}
159
160
typedef enum TraceSyncBOpt { ARM_TSB_CSYNC = 0 } ARM_TSB_TraceSyncBOpt;
161
162
inline static const char *ARM_TSB_TraceSyncBOptToString(unsigned val)
163
0
{
164
0
  switch (val) {
165
0
  default:
166
    // llvm_unreachable("Unknown trace synchronization barrier operation");
167
0
    assert(0);
168
0
  case ARM_TSB_CSYNC:
169
0
    return "csync";
170
0
  }
171
0
}
Unexecuted instantiation: ARMModule.c:ARM_TSB_TraceSyncBOptToString
Unexecuted instantiation: ARMMapping.c:ARM_TSB_TraceSyncBOptToString
Unexecuted instantiation: ARMBaseInfo.c:ARM_TSB_TraceSyncBOptToString
Unexecuted instantiation: ARMDisassembler.c:ARM_TSB_TraceSyncBOptToString
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_TSB_TraceSyncBOptToString
Unexecuted instantiation: ARMInstPrinter.c:ARM_TSB_TraceSyncBOptToString
172
173
typedef enum InstSyncBOpt {
174
  ARM_ISB_RESERVED_0 = 0,
175
  ARM_ISB_RESERVED_1 = 1,
176
  ARM_ISB_RESERVED_2 = 2,
177
  ARM_ISB_RESERVED_3 = 3,
178
  ARM_ISB_RESERVED_4 = 4,
179
  ARM_ISB_RESERVED_5 = 5,
180
  ARM_ISB_RESERVED_6 = 6,
181
  ARM_ISB_RESERVED_7 = 7,
182
  ARM_ISB_RESERVED_8 = 8,
183
  ARM_ISB_RESERVED_9 = 9,
184
  ARM_ISB_RESERVED_10 = 10,
185
  ARM_ISB_RESERVED_11 = 11,
186
  ARM_ISB_RESERVED_12 = 12,
187
  ARM_ISB_RESERVED_13 = 13,
188
  ARM_ISB_RESERVED_14 = 14,
189
  ARM_ISB_SY = 15
190
} ARM_ISB_InstSyncBOpt;
191
192
inline static const char *ARM_ISB_InstSyncBOptToString(unsigned val)
193
490
{
194
490
  switch (val) {
195
0
  default:
196
    // llvm_unreachable("Unknown memory operation");
197
0
    assert(0);
198
12
  case ARM_ISB_RESERVED_0:
199
12
    return "#0x0";
200
3
  case ARM_ISB_RESERVED_1:
201
3
    return "#0x1";
202
1
  case ARM_ISB_RESERVED_2:
203
1
    return "#0x2";
204
39
  case ARM_ISB_RESERVED_3:
205
39
    return "#0x3";
206
30
  case ARM_ISB_RESERVED_4:
207
30
    return "#0x4";
208
1
  case ARM_ISB_RESERVED_5:
209
1
    return "#0x5";
210
0
  case ARM_ISB_RESERVED_6:
211
0
    return "#0x6";
212
395
  case ARM_ISB_RESERVED_7:
213
395
    return "#0x7";
214
2
  case ARM_ISB_RESERVED_8:
215
2
    return "#0x8";
216
0
  case ARM_ISB_RESERVED_9:
217
0
    return "#0x9";
218
2
  case ARM_ISB_RESERVED_10:
219
2
    return "#0xa";
220
0
  case ARM_ISB_RESERVED_11:
221
0
    return "#0xb";
222
0
  case ARM_ISB_RESERVED_12:
223
0
    return "#0xc";
224
4
  case ARM_ISB_RESERVED_13:
225
4
    return "#0xd";
226
0
  case ARM_ISB_RESERVED_14:
227
0
    return "#0xe";
228
1
  case ARM_ISB_SY:
229
1
    return "sy";
230
490
  }
231
490
}
Unexecuted instantiation: ARMModule.c:ARM_ISB_InstSyncBOptToString
Unexecuted instantiation: ARMMapping.c:ARM_ISB_InstSyncBOptToString
Unexecuted instantiation: ARMBaseInfo.c:ARM_ISB_InstSyncBOptToString
Unexecuted instantiation: ARMDisassembler.c:ARM_ISB_InstSyncBOptToString
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_ISB_InstSyncBOptToString
ARMInstPrinter.c:ARM_ISB_InstSyncBOptToString
Line
Count
Source
193
490
{
194
490
  switch (val) {
195
0
  default:
196
    // llvm_unreachable("Unknown memory operation");
197
0
    assert(0);
198
12
  case ARM_ISB_RESERVED_0:
199
12
    return "#0x0";
200
3
  case ARM_ISB_RESERVED_1:
201
3
    return "#0x1";
202
1
  case ARM_ISB_RESERVED_2:
203
1
    return "#0x2";
204
39
  case ARM_ISB_RESERVED_3:
205
39
    return "#0x3";
206
30
  case ARM_ISB_RESERVED_4:
207
30
    return "#0x4";
208
1
  case ARM_ISB_RESERVED_5:
209
1
    return "#0x5";
210
0
  case ARM_ISB_RESERVED_6:
211
0
    return "#0x6";
212
395
  case ARM_ISB_RESERVED_7:
213
395
    return "#0x7";
214
2
  case ARM_ISB_RESERVED_8:
215
2
    return "#0x8";
216
0
  case ARM_ISB_RESERVED_9:
217
0
    return "#0x9";
218
2
  case ARM_ISB_RESERVED_10:
219
2
    return "#0xa";
220
0
  case ARM_ISB_RESERVED_11:
221
0
    return "#0xb";
222
0
  case ARM_ISB_RESERVED_12:
223
0
    return "#0xc";
224
4
  case ARM_ISB_RESERVED_13:
225
4
    return "#0xd";
226
0
  case ARM_ISB_RESERVED_14:
227
0
    return "#0xe";
228
1
  case ARM_ISB_SY:
229
1
    return "sy";
230
490
  }
231
490
}
232
233
#define GET_REGINFO_ENUM
234
#include "ARMGenRegisterInfo.inc"
235
236
/// isARMLowRegister - Returns true if the register is a low register (r0-r7).
237
///
238
static inline bool isARMLowRegister(unsigned Reg)
239
0
{
240
0
  switch (Reg) {
241
0
  case ARM_R0:
242
0
  case ARM_R1:
243
0
  case ARM_R2:
244
0
  case ARM_R3:
245
0
  case ARM_R4:
246
0
  case ARM_R5:
247
0
  case ARM_R6:
248
0
  case ARM_R7:
249
0
    return true;
250
0
  default:
251
0
    return false;
252
0
  }
253
0
}
Unexecuted instantiation: ARMModule.c:isARMLowRegister
Unexecuted instantiation: ARMMapping.c:isARMLowRegister
Unexecuted instantiation: ARMBaseInfo.c:isARMLowRegister
Unexecuted instantiation: ARMDisassembler.c:isARMLowRegister
Unexecuted instantiation: ARMDisassemblerExtension.c:isARMLowRegister
Unexecuted instantiation: ARMInstPrinter.c:isARMLowRegister
254
255
/// ARMII - This namespace holds all of the target specific flags that
256
/// instruction info tracks.
257
///
258
/// ARM Index Modes
259
typedef enum IndexMode {
260
  ARMII_IndexModeNone = 0,
261
  ARMII_IndexModePre = 1,
262
  ARMII_IndexModePost = 2,
263
  ARMII_IndexModeUpd = 3
264
} ARMII_IndexMode;
265
266
/// ARM Addressing Modes
267
typedef enum AddrMode {
268
  ARMII_AddrModeNone = 0,
269
  ARMII_AddrMode1 = 1,
270
  ARMII_AddrMode2 = 2,
271
  ARMII_AddrMode3 = 3,
272
  ARMII_AddrMode4 = 4,
273
  ARMII_AddrMode5 = 5,
274
  ARMII_AddrMode6 = 6,
275
  ARMII_AddrModeT1_1 = 7,
276
  ARMII_AddrModeT1_2 = 8,
277
  ARMII_AddrModeT1_4 = 9,
278
  ARMII_AddrModeT1_s = 10,     // i8 * 4 for pc and sp relative data
279
  ARMII_AddrModeT2_i12 = 11,
280
  ARMII_AddrModeT2_i8 = 12,    // +/- i8
281
  ARMII_AddrModeT2_i8pos = 13, // + i8
282
  ARMII_AddrModeT2_i8neg = 14, // - i8
283
  ARMII_AddrModeT2_so = 15,
284
  ARMII_AddrModeT2_pc = 16,    // +/- i12 for pc relative data
285
  ARMII_AddrModeT2_i8s4 = 17,  // i8 * 4
286
  ARMII_AddrMode_i12 = 18,
287
  ARMII_AddrMode5FP16 = 19,    // i8 * 2
288
  ARMII_AddrModeT2_ldrex = 20, // i8 * 4, with unscaled offset in MCInst
289
  ARMII_AddrModeT2_i7s4 = 21,  // i7 * 4
290
  ARMII_AddrModeT2_i7s2 = 22,  // i7 * 2
291
  ARMII_AddrModeT2_i7 = 23,    // i7 * 1
292
} ARMII_AddrMode;
293
294
inline static const char *ARMII_AddrModeToString(ARMII_AddrMode addrmode)
295
0
{
296
0
  switch (addrmode) {
297
0
  case ARMII_AddrModeNone:
298
0
    return "AddrModeNone";
299
0
  case ARMII_AddrMode1:
300
0
    return "AddrMode1";
301
0
  case ARMII_AddrMode2:
302
0
    return "AddrMode2";
303
0
  case ARMII_AddrMode3:
304
0
    return "AddrMode3";
305
0
  case ARMII_AddrMode4:
306
0
    return "AddrMode4";
307
0
  case ARMII_AddrMode5:
308
0
    return "AddrMode5";
309
0
  case ARMII_AddrMode5FP16:
310
0
    return "AddrMode5FP16";
311
0
  case ARMII_AddrMode6:
312
0
    return "AddrMode6";
313
0
  case ARMII_AddrModeT1_1:
314
0
    return "AddrModeT1_1";
315
0
  case ARMII_AddrModeT1_2:
316
0
    return "AddrModeT1_2";
317
0
  case ARMII_AddrModeT1_4:
318
0
    return "AddrModeT1_4";
319
0
  case ARMII_AddrModeT1_s:
320
0
    return "AddrModeT1_s";
321
0
  case ARMII_AddrModeT2_i12:
322
0
    return "AddrModeT2_i12";
323
0
  case ARMII_AddrModeT2_i8:
324
0
    return "AddrModeT2_i8";
325
0
  case ARMII_AddrModeT2_i8pos:
326
0
    return "AddrModeT2_i8pos";
327
0
  case ARMII_AddrModeT2_i8neg:
328
0
    return "AddrModeT2_i8neg";
329
0
  case ARMII_AddrModeT2_so:
330
0
    return "AddrModeT2_so";
331
0
  case ARMII_AddrModeT2_pc:
332
0
    return "AddrModeT2_pc";
333
0
  case ARMII_AddrModeT2_i8s4:
334
0
    return "AddrModeT2_i8s4";
335
0
  case ARMII_AddrMode_i12:
336
0
    return "AddrMode_i12";
337
0
  case ARMII_AddrModeT2_ldrex:
338
0
    return "AddrModeT2_ldrex";
339
0
  case ARMII_AddrModeT2_i7s4:
340
0
    return "AddrModeT2_i7s4";
341
0
  case ARMII_AddrModeT2_i7s2:
342
0
    return "AddrModeT2_i7s2";
343
0
  case ARMII_AddrModeT2_i7:
344
0
    return "AddrModeT2_i7";
345
0
  }
346
0
}
Unexecuted instantiation: ARMModule.c:ARMII_AddrModeToString
Unexecuted instantiation: ARMMapping.c:ARMII_AddrModeToString
Unexecuted instantiation: ARMBaseInfo.c:ARMII_AddrModeToString
Unexecuted instantiation: ARMDisassembler.c:ARMII_AddrModeToString
Unexecuted instantiation: ARMDisassemblerExtension.c:ARMII_AddrModeToString
Unexecuted instantiation: ARMInstPrinter.c:ARMII_AddrModeToString
347
348
/// Target Operand Flag enum.
349
typedef enum TOF {
350
  //===------------------------------------------------------------------===//
351
  // ARM Specific MachineOperand flags.
352
353
  ARMII_MO_NO_FLAG = 0,
354
355
  /// MO_LO16 - On a symbol operand, this represents a relocation containing
356
  /// lower 16 bit of the address. Used only via movw instruction.
357
  ARMII_MO_LO16 = 0x1,
358
359
  /// MO_HI16 - On a symbol operand, this represents a relocation containing
360
  /// higher 16 bit of the address. Used only via movt instruction.
361
  ARMII_MO_HI16 = 0x2,
362
363
  /// MO_OPTION_MASK - Most flags are mutually exclusive; this mask selects
364
  /// just that part of the flag set.
365
  ARMII_MO_OPTION_MASK = 0x3,
366
367
  /// MO_COFFSTUB - On a symbol operand "FOO", this indicates that the
368
  /// reference is actually to the ".refptr.FOO" symbol.  This is used for
369
  /// stub symbols on windows.
370
  ARMII_MO_COFFSTUB = 0x4,
371
372
  /// MO_GOT - On a symbol operand, this represents a GOT relative relocation.
373
  ARMII_MO_GOT = 0x8,
374
375
  /// MO_SBREL - On a symbol operand, this represents a static base relative
376
  /// relocation. Used in movw and movt instructions.
377
  ARMII_MO_SBREL = 0x10,
378
379
  /// MO_DLLIMPORT - On a symbol operand, this represents that the reference
380
  /// to the symbol is for an import stub.  This is used for DLL import
381
  /// storage class indication on Windows.
382
  ARMII_MO_DLLIMPORT = 0x20,
383
384
  /// MO_SECREL - On a symbol operand this indicates that the immediate is
385
  /// the offset from beginning of section.
386
  ///
387
  /// This is the TLS offset for the COFF/Windows TLS mechanism.
388
  ARMII_MO_SECREL = 0x40,
389
390
  /// MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it
391
  /// represents a symbol which, if indirect, will get special Darwin mangling
392
  /// as a non-lazy-ptr indirect symbol (i.e. "L_FOO$non_lazy_ptr"). Can be
393
  /// combined with MO_LO16, MO_HI16 or MO_NO_FLAG (in a constant-pool, for
394
  /// example).
395
  ARMII_MO_NONLAZY = 0x80,
396
397
  // It's undefined behaviour if an enum overflows the range between its
398
  // smallest and largest values, but since these are |ed together, it can
399
  // happen. Put a sentinel in (values of this enum are stored as "unsigned
400
  // char").
401
  ARMII_MO_UNUSED_MAXIMUM = 0xff
402
} ARMII_TOF;
403
404
enum {
405
  //===------------------------------------------------------------------===//
406
  // Instruction Flags.
407
408
  //===------------------------------------------------------------------===//
409
  // This four-bit field describes the addressing mode used.
410
  ARMII_AddrModeMask =
411
    0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
412
413
  // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
414
  // and store ops only.  Generic "updating" flag is used for ld/st multiple.
415
  // The index mode enums are declared in ARMBaseInfo.h
416
  ARMII_IndexModeShift = 5,
417
  ARMII_IndexModeMask = 3 << ARMII_IndexModeShift,
418
419
  //===------------------------------------------------------------------===//
420
  // Instruction encoding formats.
421
  //
422
  ARMII_FormShift = 7,
423
  ARMII_FormMask = 0x3f << ARMII_FormShift,
424
425
  // Pseudo instructions
426
  ARMII_Pseudo = 0 << ARMII_FormShift,
427
428
  // Multiply instructions
429
  ARMII_MulFrm = 1 << ARMII_FormShift,
430
431
  // Branch instructions
432
  ARMII_BrFrm = 2 << ARMII_FormShift,
433
  ARMII_BrMiscFrm = 3 << ARMII_FormShift,
434
435
  // Data Processing instructions
436
  ARMII_DPFrm = 4 << ARMII_FormShift,
437
  ARMII_DPSoRegFrm = 5 << ARMII_FormShift,
438
439
  // Load and Store
440
  ARMII_LdFrm = 6 << ARMII_FormShift,
441
  ARMII_StFrm = 7 << ARMII_FormShift,
442
  ARMII_LdMiscFrm = 8 << ARMII_FormShift,
443
  ARMII_StMiscFrm = 9 << ARMII_FormShift,
444
  ARMII_LdStMulFrm = 10 << ARMII_FormShift,
445
446
  ARMII_LdStExFrm = 11 << ARMII_FormShift,
447
448
  // Miscellaneous arithmetic instructions
449
  ARMII_ArithMiscFrm = 12 << ARMII_FormShift,
450
  ARMII_SatFrm = 13 << ARMII_FormShift,
451
452
  // Extend instructions
453
  ARMII_ExtFrm = 14 << ARMII_FormShift,
454
455
  // VFP formats
456
  ARMII_VFPUnaryFrm = 15 << ARMII_FormShift,
457
  ARMII_VFPBinaryFrm = 16 << ARMII_FormShift,
458
  ARMII_VFPConv1Frm = 17 << ARMII_FormShift,
459
  ARMII_VFPConv2Frm = 18 << ARMII_FormShift,
460
  ARMII_VFPConv3Frm = 19 << ARMII_FormShift,
461
  ARMII_VFPConv4Frm = 20 << ARMII_FormShift,
462
  ARMII_VFPConv5Frm = 21 << ARMII_FormShift,
463
  ARMII_VFPLdStFrm = 22 << ARMII_FormShift,
464
  ARMII_VFPLdStMulFrm = 23 << ARMII_FormShift,
465
  ARMII_VFPMiscFrm = 24 << ARMII_FormShift,
466
467
  // Thumb format
468
  ARMII_ThumbFrm = 25 << ARMII_FormShift,
469
470
  // Miscelleaneous format
471
  ARMII_MiscFrm = 26 << ARMII_FormShift,
472
473
  // NEON formats
474
  ARMII_NGetLnFrm = 27 << ARMII_FormShift,
475
  ARMII_NSetLnFrm = 28 << ARMII_FormShift,
476
  ARMII_NDupFrm = 29 << ARMII_FormShift,
477
  ARMII_NLdStFrm = 30 << ARMII_FormShift,
478
  ARMII_N1RegModImmFrm = 31 << ARMII_FormShift,
479
  ARMII_N2RegFrm = 32 << ARMII_FormShift,
480
  ARMII_NVCVTFrm = 33 << ARMII_FormShift,
481
  ARMII_NVDupLnFrm = 34 << ARMII_FormShift,
482
  ARMII_N2RegVShLFrm = 35 << ARMII_FormShift,
483
  ARMII_N2RegVShRFrm = 36 << ARMII_FormShift,
484
  ARMII_N3RegFrm = 37 << ARMII_FormShift,
485
  ARMII_N3RegVShFrm = 38 << ARMII_FormShift,
486
  ARMII_NVExtFrm = 39 << ARMII_FormShift,
487
  ARMII_NVMulSLFrm = 40 << ARMII_FormShift,
488
  ARMII_NVTBLFrm = 41 << ARMII_FormShift,
489
  ARMII_N3RegCplxFrm = 43 << ARMII_FormShift,
490
491
  //===------------------------------------------------------------------===//
492
  // Misc flags.
493
494
  // UnaryDP - Indicates this is a unary data processing instruction, i.e.
495
  // it doesn't have a Rn operand.
496
  ARMII_UnaryDP = 1 << 13,
497
498
  // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
499
  // a 16-bit Thumb instruction if certain conditions are met.
500
  ARMII_Xform16Bit = 1 << 14,
501
502
  // ThumbArithFlagSetting - The instruction is a 16-bit flag setting Thumb
503
  // instruction. Used by the parser to determine whether to require the 'S'
504
  // suffix on the mnemonic (when not in an IT block) or preclude it (when
505
  // in an IT block).
506
  ARMII_ThumbArithFlagSetting = 1 << 19,
507
508
  // Whether an instruction can be included in an MVE tail-predicated loop,
509
  // though extra validity checks may need to be performed too.
510
  ARMII_ValidForTailPredication = 1 << 20,
511
512
  // Whether an instruction writes to the top/bottom half of a vector element
513
  // and leaves the other half untouched.
514
  ARMII_RetainsPreviousHalfElement = 1 << 21,
515
516
  // Whether the instruction produces a scalar result from vector operands.
517
  ARMII_HorizontalReduction = 1 << 22,
518
519
  // Whether this instruction produces a vector result that is larger than
520
  // its input, typically reading from the top/bottom halves of the input(s).
521
  ARMII_DoubleWidthResult = 1 << 23,
522
523
  // The vector element size for MVE instructions. 00 = i8, 01 = i16, 10 = i32
524
  // and 11 = i64. This is the largest type if multiple are present, so a
525
  // MVE_VMOVLs8bh is ize 01=i16, as it extends from a i8 to a i16. There are
526
  // some caveats so cannot be used blindly, such as exchanging VMLADAVA's and
527
  // complex instructions, which may use different input lanes.
528
  ARMII_VecSizeShift = 24,
529
  ARMII_VecSize = 3 << ARMII_VecSizeShift,
530
531
  //===------------------------------------------------------------------===//
532
  // Code domain.
533
  ARMII_DomainShift = 15,
534
  ARMII_DomainMask = 15 << ARMII_DomainShift,
535
  ARMII_DomainGeneral = 0 << ARMII_DomainShift,
536
  ARMII_DomainVFP = 1 << ARMII_DomainShift,
537
  ARMII_DomainNEON = 2 << ARMII_DomainShift,
538
  ARMII_DomainNEONA8 = 4 << ARMII_DomainShift,
539
  ARMII_DomainMVE = 8 << ARMII_DomainShift,
540
541
  //===------------------------------------------------------------------===//
542
  // Field shifts - such shifts are used to set field while generating
543
  // machine instructions.
544
  //
545
  // FIXME: This list will need adjusting/fixing as the MC code emitter
546
  // takes shape and the ARMCodeEmitter.cpp bits go away.
547
  ARMII_ShiftTypeShift = 4,
548
549
  ARMII_M_BitShift = 5,
550
  ARMII_ShiftImmShift = 5,
551
  ARMII_ShiftShift = 7,
552
  ARMII_N_BitShift = 7,
553
  ARMII_ImmHiShift = 8,
554
  ARMII_SoRotImmShift = 8,
555
  ARMII_RegRsShift = 8,
556
  ARMII_ExtRotImmShift = 10,
557
  ARMII_RegRdLoShift = 12,
558
  ARMII_RegRdShift = 12,
559
  ARMII_RegRdHiShift = 16,
560
  ARMII_RegRnShift = 16,
561
  ARMII_S_BitShift = 20,
562
  ARMII_W_BitShift = 21,
563
  ARMII_AM3_I_BitShift = 22,
564
  ARMII_D_BitShift = 22,
565
  ARMII_U_BitShift = 23,
566
  ARMII_P_BitShift = 24,
567
  ARMII_I_BitShift = 25,
568
  ARMII_CondShift = 28
569
};
570
571
const char *get_pred_mask(ARM_PredBlockMask pred_mask);
572
573
#endif // CS_ARM_BASEINFO_H