Coverage Report

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