Coverage Report

Created: 2025-08-28 06:43

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