Coverage Report

Created: 2025-07-01 07:03

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