Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions -------===//
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
#include "ARMFeatures.h"
10
#include "ARMBaseInstrInfo.h"
11
#include "Utils/ARMBaseInfo.h"
12
#include "MCTargetDesc/ARMAddressingModes.h"
13
#include "MCTargetDesc/ARMBaseInfo.h"
14
#include "MCTargetDesc/ARMInstPrinter.h"
15
#include "MCTargetDesc/ARMMCExpr.h"
16
#include "MCTargetDesc/ARMMCTargetDesc.h"
17
#include "TargetInfo/ARMTargetInfo.h"
18
#include "llvm/ADT/APFloat.h"
19
#include "llvm/ADT/APInt.h"
20
#include "llvm/ADT/None.h"
21
#include "llvm/ADT/STLExtras.h"
22
#include "llvm/ADT/SmallSet.h"
23
#include "llvm/ADT/SmallVector.h"
24
#include "llvm/ADT/StringMap.h"
25
#include "llvm/ADT/StringRef.h"
26
#include "llvm/ADT/StringSwitch.h"
27
#include "llvm/ADT/Triple.h"
28
#include "llvm/ADT/Twine.h"
29
#include "llvm/MC/MCContext.h"
30
#include "llvm/MC/MCExpr.h"
31
#include "llvm/MC/MCInst.h"
32
#include "llvm/MC/MCInstrDesc.h"
33
#include "llvm/MC/MCInstrInfo.h"
34
#include "llvm/MC/MCObjectFileInfo.h"
35
#include "llvm/MC/MCParser/MCAsmLexer.h"
36
#include "llvm/MC/MCParser/MCAsmParser.h"
37
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
38
#include "llvm/MC/MCParser/MCAsmParserUtils.h"
39
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
40
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
41
#include "llvm/MC/MCRegisterInfo.h"
42
#include "llvm/MC/MCSection.h"
43
#include "llvm/MC/MCStreamer.h"
44
#include "llvm/MC/MCSubtargetInfo.h"
45
#include "llvm/MC/MCSymbol.h"
46
#include "llvm/MC/SubtargetFeature.h"
47
#include "llvm/Support/ARMBuildAttributes.h"
48
#include "llvm/Support/ARMEHABI.h"
49
#include "llvm/Support/Casting.h"
50
#include "llvm/Support/CommandLine.h"
51
#include "llvm/Support/Compiler.h"
52
#include "llvm/Support/ErrorHandling.h"
53
#include "llvm/Support/MathExtras.h"
54
#include "llvm/Support/SMLoc.h"
55
#include "llvm/Support/TargetParser.h"
56
#include "llvm/Support/TargetRegistry.h"
57
#include "llvm/Support/raw_ostream.h"
58
#include <algorithm>
59
#include <cassert>
60
#include <cstddef>
61
#include <cstdint>
62
#include <iterator>
63
#include <limits>
64
#include <memory>
65
#include <string>
66
#include <utility>
67
#include <vector>
68
69
#define DEBUG_TYPE "asm-parser"
70
71
using namespace llvm;
72
73
namespace llvm {
74
extern const MCInstrDesc ARMInsts[];
75
} // end namespace llvm
76
77
namespace {
78
79
enum class ImplicitItModeTy { Always, Never, ARMOnly, ThumbOnly };
80
81
static cl::opt<ImplicitItModeTy> ImplicitItMode(
82
    "arm-implicit-it", cl::init(ImplicitItModeTy::ARMOnly),
83
    cl::desc("Allow conditional instructions outdside of an IT block"),
84
    cl::values(clEnumValN(ImplicitItModeTy::Always, "always",
85
                          "Accept in both ISAs, emit implicit ITs in Thumb"),
86
               clEnumValN(ImplicitItModeTy::Never, "never",
87
                          "Warn in ARM, reject in Thumb"),
88
               clEnumValN(ImplicitItModeTy::ARMOnly, "arm",
89
                          "Accept in ARM, reject in Thumb"),
90
               clEnumValN(ImplicitItModeTy::ThumbOnly, "thumb",
91
                          "Warn in ARM, emit implicit ITs in Thumb")));
92
93
static cl::opt<bool> AddBuildAttributes("arm-add-build-attributes",
94
                                        cl::init(false));
95
96
enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
97
98
4.90k
static inline unsigned extractITMaskBit(unsigned Mask, unsigned Position) {
99
4.90k
  // Position==0 means we're not in an IT block at all. Position==1
100
4.90k
  // means we want the first state bit, which is always 0 (Then).
101
4.90k
  // Position==2 means we want the second state bit, stored at bit 3
102
4.90k
  // of Mask, and so on downwards. So (5 - Position) will shift the
103
4.90k
  // right bit down to bit 0, including the always-0 bit at bit 4 for
104
4.90k
  // the mandatory initial Then.
105
4.90k
  return (Mask >> (5 - Position) & 1);
106
4.90k
}
107
108
class UnwindContext {
109
  using Locs = SmallVector<SMLoc, 4>;
110
111
  MCAsmParser &Parser;
112
  Locs FnStartLocs;
113
  Locs CantUnwindLocs;
114
  Locs PersonalityLocs;
115
  Locs PersonalityIndexLocs;
116
  Locs HandlerDataLocs;
117
  int FPReg;
118
119
public:
120
2.40k
  UnwindContext(MCAsmParser &P) : Parser(P), FPReg(ARM::SP) {}
121
122
951
  bool hasFnStart() const { return !FnStartLocs.empty(); }
123
169
  bool cantUnwind() const { return !CantUnwindLocs.empty(); }
124
293
  bool hasHandlerData() const { return !HandlerDataLocs.empty(); }
125
126
159
  bool hasPersonality() const {
127
159
    return !(PersonalityLocs.empty() && 
PersonalityIndexLocs.empty()154
);
128
159
  }
129
130
249
  void recordFnStart(SMLoc L) { FnStartLocs.push_back(L); }
131
62
  void recordCantUnwind(SMLoc L) { CantUnwindLocs.push_back(L); }
132
78
  void recordPersonality(SMLoc L) { PersonalityLocs.push_back(L); }
133
77
  void recordHandlerData(SMLoc L) { HandlerDataLocs.push_back(L); }
134
16
  void recordPersonalityIndex(SMLoc L) { PersonalityIndexLocs.push_back(L); }
135
136
46
  void saveFPReg(int Reg) { FPReg = Reg; }
137
14
  int getFPReg() const { return FPReg; }
138
139
1
  void emitFnStartLocNotes() const {
140
1
    for (Locs::const_iterator FI = FnStartLocs.begin(), FE = FnStartLocs.end();
141
2
         FI != FE; 
++FI1
)
142
1
      Parser.Note(*FI, ".fnstart was specified here");
143
1
  }
144
145
3
  void emitCantUnwindLocNotes() const {
146
3
    for (Locs::const_iterator UI = CantUnwindLocs.begin(),
147
6
                              UE = CantUnwindLocs.end(); UI != UE; 
++UI3
)
148
3
      Parser.Note(*UI, ".cantunwind was specified here");
149
3
  }
150
151
3
  void emitHandlerDataLocNotes() const {
152
3
    for (Locs::const_iterator HI = HandlerDataLocs.begin(),
153
6
                              HE = HandlerDataLocs.end(); HI != HE; 
++HI3
)
154
3
      Parser.Note(*HI, ".handlerdata was specified here");
155
3
  }
156
157
6
  void emitPersonalityLocNotes() const {
158
6
    for (Locs::const_iterator PI = PersonalityLocs.begin(),
159
6
                              PE = PersonalityLocs.end(),
160
6
                              PII = PersonalityIndexLocs.begin(),
161
6
                              PIE = PersonalityIndexLocs.end();
162
19
         PI != PE || 
PII != PIE9
;) {
163
13
      if (PI != PE && 
(10
PII == PIE10
||
PI->getPointer() < PII->getPointer()1
))
164
10
        Parser.Note(*PI++, ".personality was specified here");
165
3
      else if (PII != PIE && (PI == PE || 
PII->getPointer() < PI->getPointer()0
))
166
3
        Parser.Note(*PII++, ".personalityindex was specified here");
167
3
      else
168
3
        
llvm_unreachable0
(".personality and .personalityindex cannot be "
169
13
                         "at the same location");
170
13
    }
171
6
  }
172
173
493
  void reset() {
174
493
    FnStartLocs = Locs();
175
493
    CantUnwindLocs = Locs();
176
493
    PersonalityLocs = Locs();
177
493
    HandlerDataLocs = Locs();
178
493
    PersonalityIndexLocs = Locs();
179
493
    FPReg = ARM::SP;
180
493
  }
181
};
182
183
184
class ARMAsmParser : public MCTargetAsmParser {
185
  const MCRegisterInfo *MRI;
186
  UnwindContext UC;
187
188
2.98k
  ARMTargetStreamer &getTargetStreamer() {
189
2.98k
    assert(getParser().getStreamer().getTargetStreamer() &&
190
2.98k
           "do not have a target streamer");
191
2.98k
    MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
192
2.98k
    return static_cast<ARMTargetStreamer &>(TS);
193
2.98k
  }
194
195
  // Map of register aliases registers via the .req directive.
196
  StringMap<unsigned> RegisterReqs;
197
198
  bool NextSymbolIsThumb;
199
200
24.3k
  bool useImplicitITThumb() const {
201
24.3k
    return ImplicitItMode == ImplicitItModeTy::Always ||
202
24.3k
           
ImplicitItMode == ImplicitItModeTy::ThumbOnly24.1k
;
203
24.3k
  }
204
205
7.64k
  bool useImplicitITARM() const {
206
7.64k
    return ImplicitItMode == ImplicitItModeTy::Always ||
207
7.64k
           
ImplicitItMode == ImplicitItModeTy::ARMOnly7.63k
;
208
7.64k
  }
209
210
  struct {
211
    ARMCC::CondCodes Cond;    // Condition for IT block.
212
    unsigned Mask:4;          // Condition mask for instructions.
213
                              // Starting at first 1 (from lsb).
214
                              //   '1'  condition as indicated in IT.
215
                              //   '0'  inverse of condition (else).
216
                              // Count of instructions in IT block is
217
                              // 4 - trailingzeroes(mask)
218
                              // Note that this does not have the same encoding
219
                              // as in the IT instruction, which also depends
220
                              // on the low bit of the condition code.
221
222
    unsigned CurPosition;     // Current position in parsing of IT
223
                              // block. In range [0,4], with 0 being the IT
224
                              // instruction itself. Initialized according to
225
                              // count of instructions in block.  ~0U if no
226
                              // active IT block.
227
228
    bool IsExplicit;          // true  - The IT instruction was present in the
229
                              //         input, we should not modify it.
230
                              // false - The IT instruction was added
231
                              //         implicitly, we can extend it if that
232
                              //         would be legal.
233
  } ITState;
234
235
  SmallVector<MCInst, 4> PendingConditionalInsts;
236
237
22.5k
  void flushPendingInstructions(MCStreamer &Out) override {
238
22.5k
    if (!inImplicitITBlock()) {
239
22.4k
      assert(PendingConditionalInsts.size() == 0);
240
22.4k
      return;
241
22.4k
    }
242
94
243
94
    // Emit the IT instruction
244
94
    MCInst ITInst;
245
94
    ITInst.setOpcode(ARM::t2IT);
246
94
    ITInst.addOperand(MCOperand::createImm(ITState.Cond));
247
94
    ITInst.addOperand(MCOperand::createImm(ITState.Mask));
248
94
    Out.EmitInstruction(ITInst, getSTI());
249
94
250
94
    // Emit the conditonal instructions
251
94
    assert(PendingConditionalInsts.size() <= 4);
252
114
    for (const MCInst &Inst : PendingConditionalInsts) {
253
114
      Out.EmitInstruction(Inst, getSTI());
254
114
    }
255
94
    PendingConditionalInsts.clear();
256
94
257
94
    // Clear the IT state
258
94
    ITState.Mask = 0;
259
94
    ITState.CurPosition = ~0U;
260
94
  }
261
262
200k
  bool inITBlock() { return ITState.CurPosition != ~0U; }
263
73.7k
  bool inExplicitITBlock() { return inITBlock() && 
ITState.IsExplicit9.45k
; }
264
22.7k
  bool inImplicitITBlock() { return inITBlock() && 
!ITState.IsExplicit132
; }
265
266
4.60k
  bool lastInITBlock() {
267
4.60k
    return ITState.CurPosition == 4 - countTrailingZeros(ITState.Mask);
268
4.60k
  }
269
270
33.9k
  void forwardITPosition() {
271
33.9k
    if (!inITBlock()) 
return25.3k
;
272
8.57k
    // Move to the next instruction in the IT block, if there is one. If not,
273
8.57k
    // mark the block as done, except for implicit IT blocks, which we leave
274
8.57k
    // open until we find an instruction that can't be added to it.
275
8.57k
    unsigned TZ = countTrailingZeros(ITState.Mask);
276
8.57k
    if (++ITState.CurPosition == 5 - TZ && 
ITState.IsExplicit3.90k
)
277
3.79k
      ITState.CurPosition = ~0U; // Done with the IT block after this.
278
8.57k
  }
279
280
  // Rewind the state of the current IT block, removing the last slot from it.
281
9
  void rewindImplicitITPosition() {
282
9
    assert(inImplicitITBlock());
283
9
    assert(ITState.CurPosition > 1);
284
9
    ITState.CurPosition--;
285
9
    unsigned TZ = countTrailingZeros(ITState.Mask);
286
9
    unsigned NewMask = 0;
287
9
    NewMask |= ITState.Mask & (0xC << TZ);
288
9
    NewMask |= 0x2 << TZ;
289
9
    ITState.Mask = NewMask;
290
9
  }
291
292
  // Rewind the state of the current IT block, removing the last slot from it.
293
  // If we were at the first slot, this closes the IT block.
294
0
  void discardImplicitITBlock() {
295
0
    assert(inImplicitITBlock());
296
0
    assert(ITState.CurPosition == 1);
297
0
    ITState.CurPosition = ~0U;
298
0
  }
299
300
  // Return the low-subreg of a given Q register.
301
30
  unsigned getDRegFromQReg(unsigned QReg) const {
302
30
    return MRI->getSubReg(QReg, ARM::dsub_0);
303
30
  }
304
305
  // Get the condition code corresponding to the current IT block slot.
306
4.78k
  ARMCC::CondCodes currentITCond() {
307
4.78k
    unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition);
308
4.78k
    return MaskBit ? 
ARMCC::getOppositeCondition(ITState.Cond)344
:
ITState.Cond4.44k
;
309
4.78k
  }
310
311
  // Invert the condition of the current IT block slot without changing any
312
  // other slots in the same block.
313
5
  void invertCurrentITCondition() {
314
5
    if (ITState.CurPosition == 1) {
315
0
      ITState.Cond = ARMCC::getOppositeCondition(ITState.Cond);
316
5
    } else {
317
5
      ITState.Mask ^= 1 << (5 - ITState.CurPosition);
318
5
    }
319
5
  }
320
321
  // Returns true if the current IT block is full (all 4 slots used).
322
114
  bool isITBlockFull() {
323
114
    return inITBlock() && (ITState.Mask & 1);
324
114
  }
325
326
  // Extend the current implicit IT block to have one more slot with the given
327
  // condition code.
328
29
  void extendImplicitITBlock(ARMCC::CondCodes Cond) {
329
29
    assert(inImplicitITBlock());
330
29
    assert(!isITBlockFull());
331
29
    assert(Cond == ITState.Cond ||
332
29
           Cond == ARMCC::getOppositeCondition(ITState.Cond));
333
29
    unsigned TZ = countTrailingZeros(ITState.Mask);
334
29
    unsigned NewMask = 0;
335
29
    // Keep any existing condition bits.
336
29
    NewMask |= ITState.Mask & (0xE << TZ);
337
29
    // Insert the new condition bit.
338
29
    NewMask |= (Cond != ITState.Cond) << TZ;
339
29
    // Move the trailing 1 down one bit.
340
29
    NewMask |= 1 << (TZ - 1);
341
29
    ITState.Mask = NewMask;
342
29
  }
343
344
  // Create a new implicit IT block with a dummy condition code.
345
94
  void startImplicitITBlock() {
346
94
    assert(!inITBlock());
347
94
    ITState.Cond = ARMCC::AL;
348
94
    ITState.Mask = 8;
349
94
    ITState.CurPosition = 1;
350
94
    ITState.IsExplicit = false;
351
94
  }
352
353
  // Create a new explicit IT block with the given condition and mask.
354
  // The mask should be in the format used in ARMOperand and
355
  // MCOperand, with a 1 implying 'e', regardless of the low bit of
356
  // the condition.
357
3.80k
  void startExplicitITBlock(ARMCC::CondCodes Cond, unsigned Mask) {
358
3.80k
    assert(!inITBlock());
359
3.80k
    ITState.Cond = Cond;
360
3.80k
    ITState.Mask = Mask;
361
3.80k
    ITState.CurPosition = 0;
362
3.80k
    ITState.IsExplicit = true;
363
3.80k
  }
364
365
  struct {
366
    unsigned Mask : 4;
367
    unsigned CurPosition;
368
  } VPTState;
369
67.7k
  bool inVPTBlock() { return VPTState.CurPosition != ~0U; }
370
33.9k
  void forwardVPTPosition() {
371
33.9k
    if (!inVPTBlock()) 
return33.7k
;
372
185
    unsigned TZ = countTrailingZeros(VPTState.Mask);
373
185
    if (++VPTState.CurPosition == 5 - TZ)
374
59
      VPTState.CurPosition = ~0U;
375
185
  }
376
377
3.60k
  void Note(SMLoc L, const Twine &Msg, SMRange Range = None) {
378
3.60k
    return getParser().Note(L, Msg, Range);
379
3.60k
  }
380
381
2.16k
  bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) {
382
2.16k
    return getParser().Warning(L, Msg, Range);
383
2.16k
  }
384
385
7.04k
  bool Error(SMLoc L, const Twine &Msg, SMRange Range = None) {
386
7.04k
    return getParser().Error(L, Msg, Range);
387
7.04k
  }
388
389
  bool validatetLDMRegList(const MCInst &Inst, const OperandVector &Operands,
390
                           unsigned ListNo, bool IsARPop = false);
391
  bool validatetSTMRegList(const MCInst &Inst, const OperandVector &Operands,
392
                           unsigned ListNo);
393
394
  int tryParseRegister();
395
  bool tryParseRegisterWithWriteBack(OperandVector &);
396
  int tryParseShiftRegister(OperandVector &);
397
  bool parseRegisterList(OperandVector &, bool EnforceOrder = true);
398
  bool parseMemory(OperandVector &);
399
  bool parseOperand(OperandVector &, StringRef Mnemonic);
400
  bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
401
  bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
402
                              unsigned &ShiftAmount);
403
  bool parseLiteralValues(unsigned Size, SMLoc L);
404
  bool parseDirectiveThumb(SMLoc L);
405
  bool parseDirectiveARM(SMLoc L);
406
  bool parseDirectiveThumbFunc(SMLoc L);
407
  bool parseDirectiveCode(SMLoc L);
408
  bool parseDirectiveSyntax(SMLoc L);
409
  bool parseDirectiveReq(StringRef Name, SMLoc L);
410
  bool parseDirectiveUnreq(SMLoc L);
411
  bool parseDirectiveArch(SMLoc L);
412
  bool parseDirectiveEabiAttr(SMLoc L);
413
  bool parseDirectiveCPU(SMLoc L);
414
  bool parseDirectiveFPU(SMLoc L);
415
  bool parseDirectiveFnStart(SMLoc L);
416
  bool parseDirectiveFnEnd(SMLoc L);
417
  bool parseDirectiveCantUnwind(SMLoc L);
418
  bool parseDirectivePersonality(SMLoc L);
419
  bool parseDirectiveHandlerData(SMLoc L);
420
  bool parseDirectiveSetFP(SMLoc L);
421
  bool parseDirectivePad(SMLoc L);
422
  bool parseDirectiveRegSave(SMLoc L, bool IsVector);
423
  bool parseDirectiveInst(SMLoc L, char Suffix = '\0');
424
  bool parseDirectiveLtorg(SMLoc L);
425
  bool parseDirectiveEven(SMLoc L);
426
  bool parseDirectivePersonalityIndex(SMLoc L);
427
  bool parseDirectiveUnwindRaw(SMLoc L);
428
  bool parseDirectiveTLSDescSeq(SMLoc L);
429
  bool parseDirectiveMovSP(SMLoc L);
430
  bool parseDirectiveObjectArch(SMLoc L);
431
  bool parseDirectiveArchExtension(SMLoc L);
432
  bool parseDirectiveAlign(SMLoc L);
433
  bool parseDirectiveThumbSet(SMLoc L);
434
435
  bool isMnemonicVPTPredicable(StringRef Mnemonic, StringRef ExtraToken);
436
  StringRef splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
437
                          unsigned &PredicationCode,
438
                          unsigned &VPTPredicationCode, bool &CarrySetting,
439
                          unsigned &ProcessorIMod, StringRef &ITMask);
440
  void getMnemonicAcceptInfo(StringRef Mnemonic, StringRef ExtraToken,
441
                             StringRef FullInst, bool &CanAcceptCarrySet,
442
                             bool &CanAcceptPredicationCode,
443
                             bool &CanAcceptVPTPredicationCode);
444
445
  void tryConvertingToTwoOperandForm(StringRef Mnemonic, bool CarrySetting,
446
                                     OperandVector &Operands);
447
698k
  bool isThumb() const {
448
698k
    // FIXME: Can tablegen auto-generate this?
449
698k
    return getSTI().getFeatureBits()[ARM::ModeThumb];
450
698k
  }
451
452
116k
  bool isThumbOne() const {
453
116k
    return isThumb() && 
!getSTI().getFeatureBits()[ARM::FeatureThumb2]93.2k
;
454
116k
  }
455
456
264k
  bool isThumbTwo() const {
457
264k
    return isThumb() && 
getSTI().getFeatureBits()[ARM::FeatureThumb2]201k
;
458
264k
  }
459
460
1.65k
  bool hasThumb() const {
461
1.65k
    return getSTI().getFeatureBits()[ARM::HasV4TOps];
462
1.65k
  }
463
464
316
  bool hasThumb2() const {
465
316
    return getSTI().getFeatureBits()[ARM::FeatureThumb2];
466
316
  }
467
468
47
  bool hasV6Ops() const {
469
47
    return getSTI().getFeatureBits()[ARM::HasV6Ops];
470
47
  }
471
472
79
  bool hasV6T2Ops() const {
473
79
    return getSTI().getFeatureBits()[ARM::HasV6T2Ops];
474
79
  }
475
476
1.89k
  bool hasV6MOps() const {
477
1.89k
    return getSTI().getFeatureBits()[ARM::HasV6MOps];
478
1.89k
  }
479
480
106
  bool hasV7Ops() const {
481
106
    return getSTI().getFeatureBits()[ARM::HasV7Ops];
482
106
  }
483
484
21.3k
  bool hasV8Ops() const {
485
21.3k
    return getSTI().getFeatureBits()[ARM::HasV8Ops];
486
21.3k
  }
487
488
208
  bool hasV8MBaseline() const {
489
208
    return getSTI().getFeatureBits()[ARM::HasV8MBaselineOps];
490
208
  }
491
492
0
  bool hasV8MMainline() const {
493
0
    return getSTI().getFeatureBits()[ARM::HasV8MMainlineOps];
494
0
  }
495
0
  bool hasV8_1MMainline() const {
496
0
    return getSTI().getFeatureBits()[ARM::HasV8_1MMainlineOps];
497
0
  }
498
207k
  bool hasMVE() const {
499
207k
    return getSTI().getFeatureBits()[ARM::HasMVEIntegerOps];
500
207k
  }
501
0
  bool hasMVEFloat() const {
502
0
    return getSTI().getFeatureBits()[ARM::HasMVEFloatOps];
503
0
  }
504
0
  bool has8MSecExt() const {
505
0
    return getSTI().getFeatureBits()[ARM::Feature8MSecExt];
506
0
  }
507
508
402
  bool hasARM() const {
509
402
    return !getSTI().getFeatureBits()[ARM::FeatureNoARM];
510
402
  }
511
512
0
  bool hasDSP() const {
513
0
    return getSTI().getFeatureBits()[ARM::FeatureDSP];
514
0
  }
515
516
77.0k
  bool hasD32() const {
517
77.0k
    return getSTI().getFeatureBits()[ARM::FeatureD32];
518
77.0k
  }
519
520
0
  bool hasV8_1aOps() const {
521
0
    return getSTI().getFeatureBits()[ARM::HasV8_1aOps];
522
0
  }
523
524
2
  bool hasRAS() const {
525
2
    return getSTI().getFeatureBits()[ARM::FeatureRAS];
526
2
  }
527
528
765
  void SwitchMode() {
529
765
    MCSubtargetInfo &STI = copySTI();
530
765
    auto FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
531
765
    setAvailableFeatures(FB);
532
765
  }
533
534
  void FixModeAfterArchChange(bool WasThumb, SMLoc Loc);
535
536
3.35k
  bool isMClass() const {
537
3.35k
    return getSTI().getFeatureBits()[ARM::FeatureMClass];
538
3.35k
  }
539
540
  /// @name Auto-generated Match Functions
541
  /// {
542
543
#define GET_ASSEMBLER_HEADER
544
#include "ARMGenAsmMatcher.inc"
545
546
  /// }
547
548
  OperandMatchResultTy parseITCondCode(OperandVector &);
549
  OperandMatchResultTy parseCoprocNumOperand(OperandVector &);
550
  OperandMatchResultTy parseCoprocRegOperand(OperandVector &);
551
  OperandMatchResultTy parseCoprocOptionOperand(OperandVector &);
552
  OperandMatchResultTy parseMemBarrierOptOperand(OperandVector &);
553
  OperandMatchResultTy parseTraceSyncBarrierOptOperand(OperandVector &);
554
  OperandMatchResultTy parseInstSyncBarrierOptOperand(OperandVector &);
555
  OperandMatchResultTy parseProcIFlagsOperand(OperandVector &);
556
  OperandMatchResultTy parseMSRMaskOperand(OperandVector &);
557
  OperandMatchResultTy parseBankedRegOperand(OperandVector &);
558
  OperandMatchResultTy parsePKHImm(OperandVector &O, StringRef Op, int Low,
559
                                   int High);
560
22
  OperandMatchResultTy parsePKHLSLImm(OperandVector &O) {
561
22
    return parsePKHImm(O, "lsl", 0, 31);
562
22
  }
563
14
  OperandMatchResultTy parsePKHASRImm(OperandVector &O) {
564
14
    return parsePKHImm(O, "asr", 1, 32);
565
14
  }
566
  OperandMatchResultTy parseSetEndImm(OperandVector &);
567
  OperandMatchResultTy parseShifterImm(OperandVector &);
568
  OperandMatchResultTy parseRotImm(OperandVector &);
569
  OperandMatchResultTy parseModImm(OperandVector &);
570
  OperandMatchResultTy parseBitfield(OperandVector &);
571
  OperandMatchResultTy parsePostIdxReg(OperandVector &);
572
  OperandMatchResultTy parseAM3Offset(OperandVector &);
573
  OperandMatchResultTy parseFPImm(OperandVector &);
574
  OperandMatchResultTy parseVectorList(OperandVector &);
575
  OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index,
576
                                       SMLoc &EndLoc);
577
578
  // Asm Match Converter Methods
579
  void cvtThumbMultiply(MCInst &Inst, const OperandVector &);
580
  void cvtThumbBranches(MCInst &Inst, const OperandVector &);
581
  void cvtMVEVMOVQtoDReg(MCInst &Inst, const OperandVector &);
582
583
  bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
584
  bool processInstruction(MCInst &Inst, const OperandVector &Ops, MCStreamer &Out);
585
  bool shouldOmitCCOutOperand(StringRef Mnemonic, OperandVector &Operands);
586
  bool shouldOmitPredicateOperand(StringRef Mnemonic, OperandVector &Operands);
587
  bool shouldOmitVectorPredicateOperand(StringRef Mnemonic, OperandVector &Operands);
588
  bool isITBlockTerminator(MCInst &Inst) const;
589
  void fixupGNULDRDAlias(StringRef Mnemonic, OperandVector &Operands);
590
  bool validateLDRDSTRD(MCInst &Inst, const OperandVector &Operands,
591
                        bool Load, bool ARMMode, bool Writeback);
592
593
public:
594
  enum ARMMatchResultTy {
595
    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
596
    Match_RequiresNotITBlock,
597
    Match_RequiresV6,
598
    Match_RequiresThumb2,
599
    Match_RequiresV8,
600
    Match_RequiresFlagSetting,
601
#define GET_OPERAND_DIAGNOSTIC_TYPES
602
#include "ARMGenAsmMatcher.inc"
603
604
  };
605
606
  ARMAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
607
               const MCInstrInfo &MII, const MCTargetOptions &Options)
608
2.40k
    : MCTargetAsmParser(Options, STI, MII), UC(Parser) {
609
2.40k
    MCAsmParserExtension::Initialize(Parser);
610
2.40k
611
2.40k
    // Cache the MCRegisterInfo.
612
2.40k
    MRI = getContext().getRegisterInfo();
613
2.40k
614
2.40k
    // Initialize the set of available features.
615
2.40k
    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
616
2.40k
617
2.40k
    // Add build attributes based on the selected target.
618
2.40k
    if (AddBuildAttributes)
619
719
      getTargetStreamer().emitTargetAttributes(STI);
620
2.40k
621
2.40k
    // Not in an ITBlock to start with.
622
2.40k
    ITState.CurPosition = ~0U;
623
2.40k
624
2.40k
    VPTState.CurPosition = ~0U;
625
2.40k
626
2.40k
    NextSymbolIsThumb = false;
627
2.40k
  }
628
629
  // Implementation of the MCTargetAsmParser interface:
630
  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
631
  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
632
                        SMLoc NameLoc, OperandVector &Operands) override;
633
  bool ParseDirective(AsmToken DirectiveID) override;
634
635
  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
636
                                      unsigned Kind) override;
637
  unsigned checkTargetMatchPredicate(MCInst &Inst) override;
638
639
  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
640
                               OperandVector &Operands, MCStreamer &Out,
641
                               uint64_t &ErrorInfo,
642
                               bool MatchingInlineAsm) override;
643
  unsigned MatchInstruction(OperandVector &Operands, MCInst &Inst,
644
                            SmallVectorImpl<NearMissInfo> &NearMisses,
645
                            bool MatchingInlineAsm, bool &EmitInITBlock,
646
                            MCStreamer &Out);
647
648
  struct NearMissMessage {
649
    SMLoc Loc;
650
    SmallString<128> Message;
651
  };
652
653
  const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
654
655
  void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
656
                        SmallVectorImpl<NearMissMessage> &NearMissesOut,
657
                        SMLoc IDLoc, OperandVector &Operands);
658
  void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
659
                        OperandVector &Operands);
660
661
  void doBeforeLabelEmit(MCSymbol *Symbol) override;
662
663
  void onLabelParsed(MCSymbol *Symbol) override;
664
};
665
666
/// ARMOperand - Instances of this class represent a parsed ARM machine
667
/// operand.
668
class ARMOperand : public MCParsedAsmOperand {
669
  enum KindTy {
670
    k_CondCode,
671
    k_VPTPred,
672
    k_CCOut,
673
    k_ITCondMask,
674
    k_CoprocNum,
675
    k_CoprocReg,
676
    k_CoprocOption,
677
    k_Immediate,
678
    k_MemBarrierOpt,
679
    k_InstSyncBarrierOpt,
680
    k_TraceSyncBarrierOpt,
681
    k_Memory,
682
    k_PostIndexRegister,
683
    k_MSRMask,
684
    k_BankedReg,
685
    k_ProcIFlags,
686
    k_VectorIndex,
687
    k_Register,
688
    k_RegisterList,
689
    k_RegisterListWithAPSR,
690
    k_DPRRegisterList,
691
    k_SPRRegisterList,
692
    k_FPSRegisterListWithVPR,
693
    k_FPDRegisterListWithVPR,
694
    k_VectorList,
695
    k_VectorListAllLanes,
696
    k_VectorListIndexed,
697
    k_ShiftedRegister,
698
    k_ShiftedImmediate,
699
    k_ShifterImmediate,
700
    k_RotateImmediate,
701
    k_ModifiedImmediate,
702
    k_ConstantPoolImmediate,
703
    k_BitfieldDescriptor,
704
    k_Token,
705
  } Kind;
706
707
  SMLoc StartLoc, EndLoc, AlignmentLoc;
708
  SmallVector<unsigned, 8> Registers;
709
710
  struct CCOp {
711
    ARMCC::CondCodes Val;
712
  };
713
714
  struct VCCOp {
715
    ARMVCC::VPTCodes Val;
716
  };
717
718
  struct CopOp {
719
    unsigned Val;
720
  };
721
722
  struct CoprocOptionOp {
723
    unsigned Val;
724
  };
725
726
  struct ITMaskOp {
727
    unsigned Mask:4;
728
  };
729
730
  struct MBOptOp {
731
    ARM_MB::MemBOpt Val;
732
  };
733
734
  struct ISBOptOp {
735
    ARM_ISB::InstSyncBOpt Val;
736
  };
737
738
  struct TSBOptOp {
739
    ARM_TSB::TraceSyncBOpt Val;
740
  };
741
742
  struct IFlagsOp {
743
    ARM_PROC::IFlags Val;
744
  };
745
746
  struct MMaskOp {
747
    unsigned Val;
748
  };
749
750
  struct BankedRegOp {
751
    unsigned Val;
752
  };
753
754
  struct TokOp {
755
    const char *Data;
756
    unsigned Length;
757
  };
758
759
  struct RegOp {
760
    unsigned RegNum;
761
  };
762
763
  // A vector register list is a sequential list of 1 to 4 registers.
764
  struct VectorListOp {
765
    unsigned RegNum;
766
    unsigned Count;
767
    unsigned LaneIndex;
768
    bool isDoubleSpaced;
769
  };
770
771
  struct VectorIndexOp {
772
    unsigned Val;
773
  };
774
775
  struct ImmOp {
776
    const MCExpr *Val;
777
  };
778
779
  /// Combined record for all forms of ARM address expressions.
780
  struct MemoryOp {
781
    unsigned BaseRegNum;
782
    // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
783
    // was specified.
784
    const MCConstantExpr *OffsetImm;  // Offset immediate value
785
    unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
786
    ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
787
    unsigned ShiftImm;        // shift for OffsetReg.
788
    unsigned Alignment;       // 0 = no alignment specified
789
    // n = alignment in bytes (2, 4, 8, 16, or 32)
790
    unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
791
  };
792
793
  struct PostIdxRegOp {
794
    unsigned RegNum;
795
    bool isAdd;
796
    ARM_AM::ShiftOpc ShiftTy;
797
    unsigned ShiftImm;
798
  };
799
800
  struct ShifterImmOp {
801
    bool isASR;
802
    unsigned Imm;
803
  };
804
805
  struct RegShiftedRegOp {
806
    ARM_AM::ShiftOpc ShiftTy;
807
    unsigned SrcReg;
808
    unsigned ShiftReg;
809
    unsigned ShiftImm;
810
  };
811
812
  struct RegShiftedImmOp {
813
    ARM_AM::ShiftOpc ShiftTy;
814
    unsigned SrcReg;
815
    unsigned ShiftImm;
816
  };
817
818
  struct RotImmOp {
819
    unsigned Imm;
820
  };
821
822
  struct ModImmOp {
823
    unsigned Bits;
824
    unsigned Rot;
825
  };
826
827
  struct BitfieldOp {
828
    unsigned LSB;
829
    unsigned Width;
830
  };
831
832
  union {
833
    struct CCOp CC;
834
    struct VCCOp VCC;
835
    struct CopOp Cop;
836
    struct CoprocOptionOp CoprocOption;
837
    struct MBOptOp MBOpt;
838
    struct ISBOptOp ISBOpt;
839
    struct TSBOptOp TSBOpt;
840
    struct ITMaskOp ITMask;
841
    struct IFlagsOp IFlags;
842
    struct MMaskOp MMask;
843
    struct BankedRegOp BankedReg;
844
    struct TokOp Tok;
845
    struct RegOp Reg;
846
    struct VectorListOp VectorList;
847
    struct VectorIndexOp VectorIndex;
848
    struct ImmOp Imm;
849
    struct MemoryOp Memory;
850
    struct PostIdxRegOp PostIdxReg;
851
    struct ShifterImmOp ShifterImm;
852
    struct RegShiftedRegOp RegShiftedReg;
853
    struct RegShiftedImmOp RegShiftedImm;
854
    struct RotImmOp RotImm;
855
    struct ModImmOp ModImm;
856
    struct BitfieldOp Bitfield;
857
  };
858
859
public:
860
193k
  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
861
862
  /// getStartLoc - Get the location of the first token of this operand.
863
41.2k
  SMLoc getStartLoc() const override { return StartLoc; }
864
865
  /// getEndLoc - Get the location of the last token of this operand.
866
109
  SMLoc getEndLoc() const override { return EndLoc; }
867
868
  /// getLocRange - Get the range between the first and last token of this
869
  /// operand.
870
32
  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
871
872
  /// getAlignmentLoc - Get the location of the Alignment token of this operand.
873
0
  SMLoc getAlignmentLoc() const {
874
0
    assert(Kind == k_Memory && "Invalid access!");
875
0
    return AlignmentLoc;
876
0
  }
877
878
80.7k
  ARMCC::CondCodes getCondCode() const {
879
80.7k
    assert(Kind == k_CondCode && "Invalid access!");
880
80.7k
    return CC.Val;
881
80.7k
  }
882
883
4.64k
  ARMVCC::VPTCodes getVPTPred() const {
884
4.64k
    assert(isVPTPred() && "Invalid access!");
885
4.64k
    return VCC.Val;
886
4.64k
  }
887
888
3.31k
  unsigned getCoproc() const {
889
3.31k
    assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
890
3.31k
    return Cop.Val;
891
3.31k
  }
892
893
396k
  StringRef getToken() const {
894
396k
    assert(Kind == k_Token && "Invalid access!");
895
396k
    return StringRef(Tok.Data, Tok.Length);
896
396k
  }
897
898
518k
  unsigned getReg() const override {
899
518k
    assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
900
518k
    return Reg.RegNum;
901
518k
  }
902
903
1.69k
  const SmallVectorImpl<unsigned> &getRegList() const {
904
1.69k
    assert((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
905
1.69k
            Kind == k_DPRRegisterList || Kind == k_SPRRegisterList ||
906
1.69k
            Kind == k_FPSRegisterListWithVPR ||
907
1.69k
            Kind == k_FPDRegisterListWithVPR) &&
908
1.69k
           "Invalid access!");
909
1.69k
    return Registers;
910
1.69k
  }
911
912
33.0k
  const MCExpr *getImm() const {
913
33.0k
    assert(isImm() && "Invalid access!");
914
33.0k
    return Imm.Val;
915
33.0k
  }
916
917
927
  const MCExpr *getConstantPoolImm() const {
918
927
    assert(isConstantPoolImm() && "Invalid access!");
919
927
    return Imm.Val;
920
927
  }
921
922
451
  unsigned getVectorIndex() const {
923
451
    assert(Kind == k_VectorIndex && "Invalid access!");
924
451
    return VectorIndex.Val;
925
451
  }
926
927
256
  ARM_MB::MemBOpt getMemBarrierOpt() const {
928
256
    assert(Kind == k_MemBarrierOpt && "Invalid access!");
929
256
    return MBOpt.Val;
930
256
  }
931
932
18
  ARM_ISB::InstSyncBOpt getInstSyncBarrierOpt() const {
933
18
    assert(Kind == k_InstSyncBarrierOpt && "Invalid access!");
934
18
    return ISBOpt.Val;
935
18
  }
936
937
2
  ARM_TSB::TraceSyncBOpt getTraceSyncBarrierOpt() const {
938
2
    assert(Kind == k_TraceSyncBarrierOpt && "Invalid access!");
939
2
    return TSBOpt.Val;
940
2
  }
941
942
71
  ARM_PROC::IFlags getProcIFlags() const {
943
71
    assert(Kind == k_ProcIFlags && "Invalid access!");
944
71
    return IFlags.Val;
945
71
  }
946
947
342
  unsigned getMSRMask() const {
948
342
    assert(Kind == k_MSRMask && "Invalid access!");
949
342
    return MMask.Val;
950
342
  }
951
952
198
  unsigned getBankedReg() const {
953
198
    assert(Kind == k_BankedReg && "Invalid access!");
954
198
    return BankedReg.Val;
955
198
  }
956
957
4.13k
  bool isCoprocNum() const { return Kind == k_CoprocNum; }
958
4.70k
  bool isCoprocReg() const { return Kind == k_CoprocReg; }
959
526
  bool isCoprocOption() const { return Kind == k_CoprocOption; }
960
436k
  bool isCondCode() const { return Kind == k_CondCode; }
961
29.0k
  bool isVPTPred() const { return Kind == k_VPTPred; }
962
100k
  bool isCCOut() const { return Kind == k_CCOut; }
963
8.09k
  bool isITMask() const { return Kind == k_ITCondMask; }
964
10.3k
  bool isITCondCode() const { return Kind == k_CondCode; }
965
104k
  bool isImm() const override {
966
104k
    return Kind == k_Immediate;
967
104k
  }
968
969
1.76k
  bool isARMBranchTarget() const {
970
1.76k
    if (!isImm()) 
return false480
;
971
1.28k
972
1.28k
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
973
158
      return CE->getValue() % 4 == 0;
974
1.12k
    return true;
975
1.12k
  }
976
977
978
524
  bool isThumbBranchTarget() const {
979
524
    if (!isImm()) 
return false184
;
980
340
981
340
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
982
40
      return CE->getValue() % 2 == 0;
983
300
    return true;
984
300
  }
985
986
  // checks whether this operand is an unsigned offset which fits is a field
987
  // of specified width and scaled by a specific number of bits
988
  template<unsigned width, unsigned scale>
989
447
  bool isUnsignedOffset() const {
990
447
    if (!isImm()) 
return false7
;
991
440
    if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true84
;
992
356
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
993
332
      int64_t Val = CE->getValue();
994
332
      int64_t Align = 1LL << scale;
995
332
      int64_t Max = Align * ((1LL << width) - 1);
996
332
      return ((Val % Align) == 0) && 
(Val >= 0)303
&&
(Val <= Max)286
;
997
332
    }
998
24
    return false;
999
24
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isUnsignedOffset<8u, 2u>() const
Line
Count
Source
989
78
  bool isUnsignedOffset() const {
990
78
    if (!isImm()) 
return false7
;
991
71
    if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true21
;
992
50
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
993
26
      int64_t Val = CE->getValue();
994
26
      int64_t Align = 1LL << scale;
995
26
      int64_t Max = Align * ((1LL << width) - 1);
996
26
      return ((Val % Align) == 0) && 
(Val >= 0)16
&&
(Val <= Max)12
;
997
26
    }
998
24
    return false;
999
24
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isUnsignedOffset<11u, 1u>() const
Line
Count
Source
989
271
  bool isUnsignedOffset() const {
990
271
    if (!isImm()) 
return false0
;
991
271
    if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true23
;
992
248
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
993
248
      int64_t Val = CE->getValue();
994
248
      int64_t Align = 1LL << scale;
995
248
      int64_t Max = Align * ((1LL << width) - 1);
996
248
      return ((Val % Align) == 0) && 
(Val >= 0)237
&&
(Val <= Max)234
;
997
248
    }
998
0
    return false;
999
0
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isUnsignedOffset<6u, 1u>() const
Line
Count
Source
989
44
  bool isUnsignedOffset() const {
990
44
    if (!isImm()) 
return false0
;
991
44
    if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true30
;
992
14
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
993
14
      int64_t Val = CE->getValue();
994
14
      int64_t Align = 1LL << scale;
995
14
      int64_t Max = Align * ((1LL << width) - 1);
996
14
      return ((Val % Align) == 0) && (Val >= 0) && 
(Val <= Max)12
;
997
14
    }
998
0
    return false;
999
0
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isUnsignedOffset<4u, 1u>() const
Line
Count
Source
989
54
  bool isUnsignedOffset() const {
990
54
    if (!isImm()) 
return false0
;
991
54
    if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true10
;
992
44
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
993
44
      int64_t Val = CE->getValue();
994
44
      int64_t Align = 1LL << scale;
995
44
      int64_t Max = Align * ((1LL << width) - 1);
996
44
      return ((Val % Align) == 0) && 
(Val >= 0)36
&&
(Val <= Max)28
;
997
44
    }
998
0
    return false;
999
0
  }
1000
1001
  // checks whether this operand is an signed offset which fits is a field
1002
  // of specified width and scaled by a specific number of bits
1003
  template<unsigned width, unsigned scale>
1004
1.79k
  bool isSignedOffset() const {
1005
1.79k
    if (!isImm()) 
return false0
;
1006
1.79k
    if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true1.44k
;
1007
354
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1008
353
      int64_t Val = CE->getValue();
1009
353
      int64_t Align = 1LL << scale;
1010
353
      int64_t Max = Align * ((1LL << (width-1)) - 1);
1011
353
      int64_t Min = -Align * (1LL << (width-1));
1012
353
      return ((Val % Align) == 0) && 
(Val >= Min)329
&&
(Val <= Max)291
;
1013
353
    }
1014
1
    return false;
1015
1
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isSignedOffset<11u, 1u>() const
Line
Count
Source
1004
298
  bool isSignedOffset() const {
1005
298
    if (!isImm()) 
return false0
;
1006
298
    if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true176
;
1007
122
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1008
121
      int64_t Val = CE->getValue();
1009
121
      int64_t Align = 1LL << scale;
1010
121
      int64_t Max = Align * ((1LL << (width-1)) - 1);
1011
121
      int64_t Min = -Align * (1LL << (width-1));
1012
121
      return ((Val % Align) == 0) && 
(Val >= Min)114
&&
(Val <= Max)100
;
1013
121
    }
1014
1
    return false;
1015
1
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isSignedOffset<8u, 1u>() const
Line
Count
Source
1004
1.29k
  bool isSignedOffset() const {
1005
1.29k
    if (!isImm()) 
return false0
;
1006
1.29k
    if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true1.19k
;
1007
99
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1008
99
      int64_t Val = CE->getValue();
1009
99
      int64_t Align = 1LL << scale;
1010
99
      int64_t Max = Align * ((1LL << (width-1)) - 1);
1011
99
      int64_t Min = -Align * (1LL << (width-1));
1012
99
      return ((Val % Align) == 0) && 
(Val >= Min)92
&&
(Val <= Max)78
;
1013
99
    }
1014
0
    return false;
1015
0
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isSignedOffset<24u, 1u>() const
Line
Count
Source
1004
102
  bool isSignedOffset() const {
1005
102
    if (!isImm()) 
return false0
;
1006
102
    if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true38
;
1007
64
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1008
64
      int64_t Val = CE->getValue();
1009
64
      int64_t Align = 1LL << scale;
1010
64
      int64_t Max = Align * ((1LL << (width-1)) - 1);
1011
64
      int64_t Min = -Align * (1LL << (width-1));
1012
64
      return ((Val % Align) == 0) && 
(Val >= Min)59
&&
(Val <= Max)57
;
1013
64
    }
1014
0
    return false;
1015
0
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isSignedOffset<20u, 1u>() const
Line
Count
Source
1004
75
  bool isSignedOffset() const {
1005
75
    if (!isImm()) 
return false0
;
1006
75
    if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true26
;
1007
49
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1008
49
      int64_t Val = CE->getValue();
1009
49
      int64_t Align = 1LL << scale;
1010
49
      int64_t Max = Align * ((1LL << (width-1)) - 1);
1011
49
      int64_t Min = -Align * (1LL << (width-1));
1012
49
      return ((Val % Align) == 0) && 
(Val >= Min)44
&&
(Val <= Max)42
;
1013
49
    }
1014
0
    return false;
1015
0
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isSignedOffset<16u, 1u>() const
Line
Count
Source
1004
18
  bool isSignedOffset() const {
1005
18
    if (!isImm()) 
return false0
;
1006
18
    if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true4
;
1007
14
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1008
14
      int64_t Val = CE->getValue();
1009
14
      int64_t Align = 1LL << scale;
1010
14
      int64_t Max = Align * ((1LL << (width-1)) - 1);
1011
14
      int64_t Min = -Align * (1LL << (width-1));
1012
14
      return ((Val % Align) == 0) && (Val >= Min) && 
(Val <= Max)10
;
1013
14
    }
1014
0
    return false;
1015
0
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isSignedOffset<18u, 1u>() const
Line
Count
Source
1004
8
  bool isSignedOffset() const {
1005
8
    if (!isImm()) 
return false0
;
1006
8
    if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true2
;
1007
6
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1008
6
      int64_t Val = CE->getValue();
1009
6
      int64_t Align = 1LL << scale;
1010
6
      int64_t Max = Align * ((1LL << (width-1)) - 1);
1011
6
      int64_t Min = -Align * (1LL << (width-1));
1012
6
      return ((Val % Align) == 0) && (Val >= Min) && 
(Val <= Max)4
;
1013
6
    }
1014
0
    return false;
1015
0
  }
1016
1017
  // checks whether this operand is an offset suitable for the LE /
1018
  // LETP instructions in Arm v8.1M
1019
498
  bool isLEOffset() const {
1020
498
    if (!isImm()) 
return false169
;
1021
329
    if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true8
;
1022
321
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1023
321
      int64_t Val = CE->getValue();
1024
321
      return Val < 0 && 
Val >= -4094316
&&
(Val & 1) == 0311
;
1025
321
    }
1026
0
    return false;
1027
0
  }
1028
1029
  // checks whether this operand is a memory operand computed as an offset
1030
  // applied to PC. the offset may have 8 bits of magnitude and is represented
1031
  // with two bits of shift. textually it may be either [pc, #imm], #imm or
1032
  // relocable expression...
1033
720
  bool isThumbMemPC() const {
1034
720
    int64_t Val = 0;
1035
720
    if (isImm()) {
1036
48
      if (isa<MCSymbolRefExpr>(Imm.Val)) 
return true36
;
1037
12
      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val);
1038
12
      if (!CE) 
return false6
;
1039
6
      Val = CE->getValue();
1040
6
    }
1041
672
    else if (isGPRMem()) {
1042
231
      if(!Memory.OffsetImm || 
Memory.OffsetRegNum142
)
return false89
;
1043
142
      if(Memory.BaseRegNum != ARM::PC) 
return false100
;
1044
42
      Val = Memory.OffsetImm->getValue();
1045
42
    }
1046
441
    else return false;
1047
48
    return ((Val % 4) == 0) && 
(Val >= 0)42
&&
(Val <= 1020)28
;
1048
48
  }
1049
1050
453
  bool isFPImm() const {
1051
453
    if (!isImm()) 
return false235
;
1052
218
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1053
218
    if (!CE) 
return false3
;
1054
215
    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
1055
215
    return Val != -1;
1056
215
  }
1057
1058
  template<int64_t N, int64_t M>
1059
18.4k
  bool isImmediate() const {
1060
18.4k
    if (!isImm()) 
return false10.2k
;
1061
8.21k
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
8.21k
    if (!CE) 
return false42
;
1063
8.17k
    int64_t Value = CE->getValue();
1064
8.17k
    return Value >= N && 
Value <= M7.62k
;
1065
8.17k
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 7ll>() const
Line
Count
Source
1059
3.67k
  bool isImmediate() const {
1060
3.67k
    if (!isImm()) 
return false1.85k
;
1061
1.82k
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
1.82k
    if (!CE) 
return false12
;
1063
1.80k
    int64_t Value = CE->getValue();
1064
1.80k
    return Value >= N && 
Value <= M1.80k
;
1065
1.80k
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 15ll>() const
Line
Count
Source
1059
494
  bool isImmediate() const {
1060
494
    if (!isImm()) 
return false80
;
1061
414
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
414
    if (!CE) 
return false1
;
1063
413
    int64_t Value = CE->getValue();
1064
413
    return Value >= N && 
Value <= M409
;
1065
413
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 1ll>() const
Line
Count
Source
1059
91
  bool isImmediate() const {
1060
91
    if (!isImm()) 
return false9
;
1061
82
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
82
    if (!CE) 
return false8
;
1063
74
    int64_t Value = CE->getValue();
1064
74
    return Value >= N && 
Value <= M66
;
1065
74
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 239ll>() const
Line
Count
Source
1059
67
  bool isImmediate() const {
1060
67
    if (!isImm()) 
return false24
;
1061
43
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
43
    if (!CE) 
return false0
;
1063
43
    int64_t Value = CE->getValue();
1064
43
    return Value >= N && Value <= M;
1065
43
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 255ll>() const
Line
Count
Source
1059
4.46k
  bool isImmediate() const {
1060
4.46k
    if (!isImm()) 
return false3.68k
;
1061
781
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
781
    if (!CE) 
return false5
;
1063
776
    int64_t Value = CE->getValue();
1064
776
    return Value >= N && 
Value <= M754
;
1065
776
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 31ll>() const
Line
Count
Source
1059
1.92k
  bool isImmediate() const {
1060
1.92k
    if (!isImm()) 
return false1.01k
;
1061
911
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
911
    if (!CE) 
return false4
;
1063
907
    int64_t Value = CE->getValue();
1064
907
    return Value >= N && 
Value <= M899
;
1065
907
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 32ll>() const
Line
Count
Source
1059
217
  bool isImmediate() const {
1060
217
    if (!isImm()) 
return false193
;
1061
24
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
24
    if (!CE) 
return false0
;
1063
24
    int64_t Value = CE->getValue();
1064
24
    return Value >= N && Value <= M;
1065
24
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 3ll>() const
Line
Count
Source
1059
21
  bool isImmediate() const {
1060
21
    if (!isImm()) 
return false9
;
1061
12
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
12
    if (!CE) 
return false0
;
1063
12
    int64_t Value = CE->getValue();
1064
12
    return Value >= N && Value <= M;
1065
12
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 63ll>() const
Line
Count
Source
1059
26
  bool isImmediate() const {
1060
26
    if (!isImm()) 
return false0
;
1061
26
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
26
    if (!CE) 
return false0
;
1063
26
    int64_t Value = CE->getValue();
1064
26
    return Value >= N && 
Value <= M20
;
1065
26
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 65535ll>() const
Line
Count
Source
1059
75
  bool isImmediate() const {
1060
75
    if (!isImm()) 
return false10
;
1061
65
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
65
    if (!CE) 
return false0
;
1063
65
    int64_t Value = CE->getValue();
1064
65
    return Value >= N && 
Value <= M55
;
1065
65
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<16ll, 16ll>() const
Line
Count
Source
1059
6
  bool isImmediate() const {
1060
6
    if (!isImm()) 
return false0
;
1061
6
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
6
    if (!CE) 
return false0
;
1063
6
    int64_t Value = CE->getValue();
1064
6
    return Value >= N && 
Value <= M4
;
1065
6
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<1ll, 15ll>() const
Line
Count
Source
1059
92
  bool isImmediate() const {
1060
92
    if (!isImm()) 
return false0
;
1061
92
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
92
    if (!CE) 
return false0
;
1063
92
    int64_t Value = CE->getValue();
1064
92
    return Value >= N && 
Value <= M84
;
1065
92
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<1ll, 16ll>() const
Line
Count
Source
1059
1.16k
  bool isImmediate() const {
1060
1.16k
    if (!isImm()) 
return false376
;
1061
790
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
790
    if (!CE) 
return false0
;
1063
790
    int64_t Value = CE->getValue();
1064
790
    return Value >= N && 
Value <= M770
;
1065
790
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<1ll, 31ll>() const
Line
Count
Source
1059
591
  bool isImmediate() const {
1060
591
    if (!isImm()) 
return false301
;
1061
290
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
290
    if (!CE) 
return false0
;
1063
290
    int64_t Value = CE->getValue();
1064
290
    return Value >= N && 
Value <= M203
;
1065
290
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<1ll, 32ll>() const
Line
Count
Source
1059
1.98k
  bool isImmediate() const {
1060
1.98k
    if (!isImm()) 
return false868
;
1061
1.11k
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
1.11k
    if (!CE) 
return false0
;
1063
1.11k
    int64_t Value = CE->getValue();
1064
1.11k
    return Value >= N && 
Value <= M1.07k
;
1065
1.11k
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<1ll, 7ll>() const
Line
Count
Source
1059
66
  bool isImmediate() const {
1060
66
    if (!isImm()) 
return false0
;
1061
66
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
66
    if (!CE) 
return false0
;
1063
66
    int64_t Value = CE->getValue();
1064
66
    return Value >= N && 
Value <= M58
;
1065
66
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 16777215ll>() const
Line
Count
Source
1059
22
  bool isImmediate() const {
1060
22
    if (!isImm()) 
return false0
;
1061
22
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
22
    if (!CE) 
return false0
;
1063
22
    int64_t Value = CE->getValue();
1064
22
    return Value >= N && 
Value <= M18
;
1065
22
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<256ll, 65535ll>() const
Line
Count
Source
1059
1.18k
  bool isImmediate() const {
1060
1.18k
    if (!isImm()) 
return false856
;
1061
327
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
327
    if (!CE) 
return false12
;
1063
315
    int64_t Value = CE->getValue();
1064
315
    return Value >= N && 
Value <= M26
;
1065
315
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<32ll, 32ll>() const
Line
Count
Source
1059
4
  bool isImmediate() const {
1060
4
    if (!isImm()) 
return false0
;
1061
4
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
4
    if (!CE) 
return false0
;
1063
4
    int64_t Value = CE->getValue();
1064
4
    return Value >= N && 
Value <= M2
;
1065
4
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<8ll, 8ll>() const
Line
Count
Source
1059
2
  bool isImmediate() const {
1060
2
    if (!isImm()) 
return false0
;
1061
2
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
2
    if (!CE) 
return false0
;
1063
2
    int64_t Value = CE->getValue();
1064
2
    return Value >= N && Value <= M;
1065
2
  }
Unexecuted instantiation: ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<8ll, 255ll>() const
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 33ll>() const
Line
Count
Source
1059
12
  bool isImmediate() const {
1060
12
    if (!isImm()) 
return false0
;
1061
12
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
12
    if (!CE) 
return false0
;
1063
12
    int64_t Value = CE->getValue();
1064
12
    return Value >= N && Value <= M;
1065
12
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 17ll>() const
Line
Count
Source
1059
168
  bool isImmediate() const {
1060
168
    if (!isImm()) 
return false0
;
1061
168
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
168
    if (!CE) 
return false0
;
1063
168
    int64_t Value = CE->getValue();
1064
168
    return Value >= N && Value <= M;
1065
168
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<1ll, 33ll>() const
Line
Count
Source
1059
120
  bool isImmediate() const {
1060
120
    if (!isImm()) 
return false0
;
1061
120
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
120
    if (!CE) 
return false0
;
1063
120
    int64_t Value = CE->getValue();
1064
120
    return Value >= N && Value <= M;
1065
120
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 4095ll>() const
Line
Count
Source
1059
368
  bool isImmediate() const {
1060
368
    if (!isImm()) 
return false227
;
1061
141
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
141
    if (!CE) 
return false0
;
1063
141
    int64_t Value = CE->getValue();
1064
141
    return Value >= N && 
Value <= M131
;
1065
141
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<1ll, 64ll>() const
Line
Count
Source
1059
669
  bool isImmediate() const {
1060
669
    if (!isImm()) 
return false354
;
1061
315
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
315
    if (!CE) 
return false0
;
1063
315
    int64_t Value = CE->getValue();
1064
315
    return Value >= N && Value <= M;
1065
315
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<1ll, 8ll>() const
Line
Count
Source
1059
878
  bool isImmediate() const {
1060
878
    if (!isImm()) 
return false376
;
1061
502
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
502
    if (!CE) 
return false0
;
1063
502
    int64_t Value = CE->getValue();
1064
502
    return Value >= N && 
Value <= M494
;
1065
502
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<-127ll, 127ll>() const
Line
Count
Source
1059
76
  bool isImmediate() const {
1060
76
    if (!isImm()) 
return false14
;
1061
62
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1062
62
    if (!CE) 
return false0
;
1063
62
    int64_t Value = CE->getValue();
1064
62
    return Value >= N && Value <= M;
1065
62
  }
Unexecuted instantiation: ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediate<0ll, 16777216ll>() const
1066
1067
  template<int64_t N, int64_t M>
1068
1.10k
  bool isImmediateS4() const {
1069
1.10k
    if (!isImm()) 
return false288
;
1070
815
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1071
815
    if (!CE) 
return false0
;
1072
815
    int64_t Value = CE->getValue();
1073
815
    return ((Value & 3) == 0) && 
Value >= N714
&&
Value <= M704
;
1074
815
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediateS4<0ll, 508ll>() const
Line
Count
Source
1068
356
  bool isImmediateS4() const {
1069
356
    if (!isImm()) 
return false211
;
1070
145
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1071
145
    if (!CE) 
return false0
;
1072
145
    int64_t Value = CE->getValue();
1073
145
    return ((Value & 3) == 0) && 
Value >= N133
&&
Value <= M125
;
1074
145
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediateS4<0ll, 1020ll>() const
Line
Count
Source
1068
170
  bool isImmediateS4() const {
1069
170
    if (!isImm()) 
return false24
;
1070
146
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1071
146
    if (!CE) 
return false0
;
1072
146
    int64_t Value = CE->getValue();
1073
146
    return ((Value & 3) == 0) && 
Value >= N129
&&
Value <= M127
;
1074
146
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediateS4<-508ll, 508ll>() const
Line
Count
Source
1068
550
  bool isImmediateS4() const {
1069
550
    if (!isImm()) 
return false34
;
1070
516
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1071
516
    if (!CE) 
return false0
;
1072
516
    int64_t Value = CE->getValue();
1073
516
    return ((Value & 3) == 0) && 
Value >= N444
&&
Value <= M444
;
1074
516
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediateS4<-511ll, 511ll>() const
Line
Count
Source
1068
27
  bool isImmediateS4() const {
1069
27
    if (!isImm()) 
return false19
;
1070
8
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1071
8
    if (!CE) 
return false0
;
1072
8
    int64_t Value = CE->getValue();
1073
8
    return ((Value & 3) == 0) && Value >= N && Value <= M;
1074
8
  }
Unexecuted instantiation: ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isImmediateS4<-1020ll, 1020ll>() const
1075
  template<int64_t N, int64_t M>
1076
40
  bool isImmediateS2() const {
1077
40
    if (!isImm()) 
return false9
;
1078
31
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1079
31
    if (!CE) 
return false0
;
1080
31
    int64_t Value = CE->getValue();
1081
31
    return ((Value & 1) == 0) && Value >= N && Value <= M;
1082
31
  }
1083
168
  bool isFBits16() const {
1084
168
    return isImmediate<0, 17>();
1085
168
  }
1086
120
  bool isFBits32() const {
1087
120
    return isImmediate<1, 33>();
1088
120
  }
1089
0
  bool isImm8s4() const {
1090
0
    return isImmediateS4<-1020, 1020>();
1091
0
  }
1092
550
  bool isImm7s4() const {
1093
550
    return isImmediateS4<-508, 508>();
1094
550
  }
1095
76
  bool isImm7Shift0() const {
1096
76
    return isImmediate<-127, 127>();
1097
76
  }
1098
40
  bool isImm7Shift1() const {
1099
40
    return isImmediateS2<-255, 255>();
1100
40
  }
1101
27
  bool isImm7Shift2() const {
1102
27
    return isImmediateS4<-511, 511>();
1103
27
  }
1104
0
  bool isImm7() const {
1105
0
    return isImmediate<-127, 127>();
1106
0
  }
1107
170
  bool isImm0_1020s4() const {
1108
170
    return isImmediateS4<0, 1020>();
1109
170
  }
1110
356
  bool isImm0_508s4() const {
1111
356
    return isImmediateS4<0, 508>();
1112
356
  }
1113
256
  bool isImm0_508s4Neg() const {
1114
256
    if (!isImm()) 
return false189
;
1115
67
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1116
67
    if (!CE) 
return false0
;
1117
67
    int64_t Value = -CE->getValue();
1118
67
    // explicitly exclude zero. we want that to use the normal 0_508 version.
1119
67
    return ((Value & 3) == 0) && 
Value > 056
&&
Value <= 5086
;
1120
67
  }
1121
1122
257
  bool isImm0_4095Neg() const {
1123
257
    if (!isImm()) 
return false234
;
1124
23
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1125
23
    if (!CE) 
return false0
;
1126
23
    // isImm0_4095Neg is used with 32-bit immediates only.
1127
23
    // 32-bit immediates are zero extended to 64-bit when parsed,
1128
23
    // thus simple -CE->getValue() results in a big negative number,
1129
23
    // not a small positive number as intended
1130
23
    if ((CE->getValue() >> 32) > 0) 
return false0
;
1131
23
    uint32_t Value = -static_cast<uint32_t>(CE->getValue());
1132
23
    return Value > 0 && Value < 4096;
1133
23
  }
1134
1135
422
  bool isImm0_7() const {
1136
422
    return isImmediate<0, 7>();
1137
422
  }
1138
1139
0
  bool isImm1_16() const {
1140
0
    return isImmediate<1, 16>();
1141
0
  }
1142
1143
0
  bool isImm1_32() const {
1144
0
    return isImmediate<1, 32>();
1145
0
  }
1146
1147
0
  bool isImm8_255() const {
1148
0
    return isImmediate<8, 255>();
1149
0
  }
1150
1151
0
  bool isImm256_65535Expr() const {
1152
0
    if (!isImm()) return false;
1153
0
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1154
0
    // If it's not a constant expression, it'll generate a fixup and be
1155
0
    // handled later.
1156
0
    if (!CE) return true;
1157
0
    int64_t Value = CE->getValue();
1158
0
    return Value >= 256 && Value < 65536;
1159
0
  }
1160
1161
611
  bool isImm0_65535Expr() const {
1162
611
    if (!isImm()) 
return false143
;
1163
468
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1164
468
    // If it's not a constant expression, it'll generate a fixup and be
1165
468
    // handled later.
1166
468
    if (!CE) 
return true323
;
1167
145
    int64_t Value = CE->getValue();
1168
145
    return Value >= 0 && 
Value < 65536141
;
1169
145
  }
1170
1171
0
  bool isImm24bit() const {
1172
0
    return isImmediate<0, 0xffffff + 1>();
1173
0
  }
1174
1175
0
  bool isImmThumbSR() const {
1176
0
    return isImmediate<1, 33>();
1177
0
  }
1178
1179
  template<int shift>
1180
268
  bool isExpImmValue(uint64_t Value) const {
1181
268
    uint64_t mask = (1 << shift) - 1;
1182
268
    if ((Value & mask) != 0 || 
(Value >> shift) > 0xff150
)
1183
236
      return false;
1184
32
    return true;
1185
32
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isExpImmValue<0>(unsigned long long) const
Line
Count
Source
1180
104
  bool isExpImmValue(uint64_t Value) const {
1181
104
    uint64_t mask = (1 << shift) - 1;
1182
104
    if ((Value & mask) != 0 || (Value >> shift) > 0xff)
1183
94
      return false;
1184
10
    return true;
1185
10
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isExpImmValue<8>(unsigned long long) const
Line
Count
Source
1180
94
  bool isExpImmValue(uint64_t Value) const {
1181
94
    uint64_t mask = (1 << shift) - 1;
1182
94
    if ((Value & mask) != 0 || 
(Value >> shift) > 0xff34
)
1183
80
      return false;
1184
14
    return true;
1185
14
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isExpImmValue<16>(unsigned long long) const
Line
Count
Source
1180
37
  bool isExpImmValue(uint64_t Value) const {
1181
37
    uint64_t mask = (1 << shift) - 1;
1182
37
    if ((Value & mask) != 0 || 
(Value >> shift) > 0xff8
)
1183
33
      return false;
1184
4
    return true;
1185
4
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isExpImmValue<24>(unsigned long long) const
Line
Count
Source
1180
33
  bool isExpImmValue(uint64_t Value) const {
1181
33
    uint64_t mask = (1 << shift) - 1;
1182
33
    if ((Value & mask) != 0 || 
(Value >> shift) > 0xff4
)
1183
29
      return false;
1184
4
    return true;
1185
4
  }
1186
1187
  template<int shift>
1188
348
  bool isExpImm() const {
1189
348
    if (!isImm()) 
return false298
;
1190
50
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1191
50
    if (!CE) 
return false0
;
1192
50
1193
50
    return isExpImmValue<shift>(CE->getValue());
1194
50
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isExpImm<0>() const
Line
Count
Source
1188
121
  bool isExpImm() const {
1189
121
    if (!isImm()) 
return false99
;
1190
22
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1191
22
    if (!CE) 
return false0
;
1192
22
1193
22
    return isExpImmValue<shift>(CE->getValue());
1194
22
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isExpImm<8>() const
Line
Count
Source
1188
117
  bool isExpImm() const {
1189
117
    if (!isImm()) 
return false99
;
1190
18
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1191
18
    if (!CE) 
return false0
;
1192
18
1193
18
    return isExpImmValue<shift>(CE->getValue());
1194
18
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isExpImm<16>() const
Line
Count
Source
1188
55
  bool isExpImm() const {
1189
55
    if (!isImm()) 
return false50
;
1190
5
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1191
5
    if (!CE) 
return false0
;
1192
5
1193
5
    return isExpImmValue<shift>(CE->getValue());
1194
5
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isExpImm<24>() const
Line
Count
Source
1188
55
  bool isExpImm() const {
1189
55
    if (!isImm()) 
return false50
;
1190
5
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1191
5
    if (!CE) 
return false0
;
1192
5
1193
5
    return isExpImmValue<shift>(CE->getValue());
1194
5
  }
1195
1196
  template<int shift, int size>
1197
530
  bool isInvertedExpImm() const {
1198
530
    if (!isImm()) 
return false312
;
1199
218
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1200
218
    if (!CE) 
return false0
;
1201
218
1202
218
    uint64_t OriginalValue = CE->getValue();
1203
218
    uint64_t InvertedValue = OriginalValue ^ (((uint64_t)1 << size) - 1);
1204
218
    return isExpImmValue<shift>(InvertedValue);
1205
218
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isInvertedExpImm<0, 16>() const
Line
Count
Source
1197
96
  bool isInvertedExpImm() const {
1198
96
    if (!isImm()) 
return false52
;
1199
44
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1200
44
    if (!CE) 
return false0
;
1201
44
1202
44
    uint64_t OriginalValue = CE->getValue();
1203
44
    uint64_t InvertedValue = OriginalValue ^ (((uint64_t)1 << size) - 1);
1204
44
    return isExpImmValue<shift>(InvertedValue);
1205
44
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isInvertedExpImm<8, 16>() const
Line
Count
Source
1197
92
  bool isInvertedExpImm() const {
1198
92
    if (!isImm()) 
return false52
;
1199
40
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1200
40
    if (!CE) 
return false0
;
1201
40
1202
40
    uint64_t OriginalValue = CE->getValue();
1203
40
    uint64_t InvertedValue = OriginalValue ^ (((uint64_t)1 << size) - 1);
1204
40
    return isExpImmValue<shift>(InvertedValue);
1205
40
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isInvertedExpImm<0, 32>() const
Line
Count
Source
1197
90
  bool isInvertedExpImm() const {
1198
90
    if (!isImm()) 
return false52
;
1199
38
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1200
38
    if (!CE) 
return false0
;
1201
38
1202
38
    uint64_t OriginalValue = CE->getValue();
1203
38
    uint64_t InvertedValue = OriginalValue ^ (((uint64_t)1 << size) - 1);
1204
38
    return isExpImmValue<shift>(InvertedValue);
1205
38
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isInvertedExpImm<8, 32>() const
Line
Count
Source
1197
88
  bool isInvertedExpImm() const {
1198
88
    if (!isImm()) 
return false52
;
1199
36
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1200
36
    if (!CE) 
return false0
;
1201
36
1202
36
    uint64_t OriginalValue = CE->getValue();
1203
36
    uint64_t InvertedValue = OriginalValue ^ (((uint64_t)1 << size) - 1);
1204
36
    return isExpImmValue<shift>(InvertedValue);
1205
36
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isInvertedExpImm<16, 32>() const
Line
Count
Source
1197
84
  bool isInvertedExpImm() const {
1198
84
    if (!isImm()) 
return false52
;
1199
32
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1200
32
    if (!CE) 
return false0
;
1201
32
1202
32
    uint64_t OriginalValue = CE->getValue();
1203
32
    uint64_t InvertedValue = OriginalValue ^ (((uint64_t)1 << size) - 1);
1204
32
    return isExpImmValue<shift>(InvertedValue);
1205
32
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isInvertedExpImm<24, 32>() const
Line
Count
Source
1197
80
  bool isInvertedExpImm() const {
1198
80
    if (!isImm()) 
return false52
;
1199
28
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1200
28
    if (!CE) 
return false0
;
1201
28
1202
28
    uint64_t OriginalValue = CE->getValue();
1203
28
    uint64_t InvertedValue = OriginalValue ^ (((uint64_t)1 << size) - 1);
1204
28
    return isExpImmValue<shift>(InvertedValue);
1205
28
  }
1206
1207
0
  bool isPKHLSLImm() const {
1208
0
    return isImmediate<0, 32>();
1209
0
  }
1210
1211
12
  bool isPKHASRImm() const {
1212
12
    return isImmediate<0, 33>();
1213
12
  }
1214
1215
33
  bool isAdrLabel() const {
1216
33
    // If we have an immediate that's not a constant, treat it as a label
1217
33
    // reference needing a fixup.
1218
33
    if (isImm() && 
!isa<MCConstantExpr>(getImm())26
)
1219
12
      return true;
1220
21
1221
21
    // If it is a constant, it must fit into a modified immediate encoding.
1222
21
    if (!isImm()) 
return false7
;
1223
14
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1224
14
    if (!CE) 
return false0
;
1225
14
    int64_t Value = CE->getValue();
1226
14
    return (ARM_AM::getSOImmVal(Value) != -1 ||
1227
14
            
ARM_AM::getSOImmVal(-Value) != -14
);
1228
14
  }
1229
1230
10.8k
  bool isT2SOImm() const {
1231
10.8k
    // If we have an immediate that's not a constant, treat it as an expression
1232
10.8k
    // needing a fixup.
1233
10.8k
    if (isImm() && 
!isa<MCConstantExpr>(getImm())2.27k
) {
1234
42
      // We want to avoid matching :upper16: and :lower16: as we want these
1235
42
      // expressions to match in isImm0_65535Expr()
1236
42
      const ARMMCExpr *ARM16Expr = dyn_cast<ARMMCExpr>(getImm());
1237
42
      return (!ARM16Expr || 
(8
ARM16Expr->getKind() != ARMMCExpr::VK_ARM_HI168
&&
1238
8
                             
ARM16Expr->getKind() != ARMMCExpr::VK_ARM_LO167
));
1239
42
    }
1240
10.8k
    if (!isImm()) 
return false8.60k
;
1241
2.23k
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1242
2.23k
    if (!CE) 
return false0
;
1243
2.23k
    int64_t Value = CE->getValue();
1244
2.23k
    return ARM_AM::getT2SOImmVal(Value) != -1;
1245
2.23k
  }
1246
1247
3.01k
  bool isT2SOImmNot() const {
1248
3.01k
    if (!isImm()) 
return false2.76k
;
1249
249
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1250
249
    if (!CE) 
return false11
;
1251
238
    int64_t Value = CE->getValue();
1252
238
    return ARM_AM::getT2SOImmVal(Value) == -1 &&
1253
238
      
ARM_AM::getT2SOImmVal(~Value) != -1107
;
1254
238
  }
1255
1256
8.10k
  bool isT2SOImmNeg() const {
1257
8.10k
    if (!isImm()) 
return false7.43k
;
1258
666
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1259
666
    if (!CE) 
return false25
;
1260
641
    int64_t Value = CE->getValue();
1261
641
    // Only use this when not representable as a plain so_imm.
1262
641
    return ARM_AM::getT2SOImmVal(Value) == -1 &&
1263
641
      
ARM_AM::getT2SOImmVal(-Value) != -183
;
1264
641
  }
1265
1266
0
  bool isSetEndImm() const {
1267
0
    if (!isImm()) return false;
1268
0
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1269
0
    if (!CE) return false;
1270
0
    int64_t Value = CE->getValue();
1271
0
    return Value == 1 || Value == 0;
1272
0
  }
1273
1274
797k
  bool isReg() const override { return Kind == k_Register; }
1275
2.26k
  bool isRegList() const { return Kind == k_RegisterList; }
1276
8
  bool isRegListWithAPSR() const {
1277
8
    return Kind == k_RegisterListWithAPSR || Kind == k_RegisterList;
1278
8
  }
1279
402
  bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
1280
222
  bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
1281
14
  bool isFPSRegListWithVPR() const { return Kind == k_FPSRegisterListWithVPR; }
1282
16
  bool isFPDRegListWithVPR() const { return Kind == k_FPDRegisterListWithVPR; }
1283
1.84M
  bool isToken() const override { return Kind == k_Token; }
1284
420
  bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
1285
36
  bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; }
1286
14
  bool isTraceSyncBarrierOpt() const { return Kind == k_TraceSyncBarrierOpt; }
1287
0
  bool isMem() const override {
1288
0
      return isGPRMem() || isMVEMem();
1289
0
  }
1290
2.49k
  bool isMVEMem() const {
1291
2.49k
    if (Kind != k_Memory)
1292
0
      return false;
1293
2.49k
    if (Memory.BaseRegNum &&
1294
2.49k
        !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.BaseRegNum) &&
1295
2.49k
        
!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Memory.BaseRegNum)609
)
1296
0
      return false;
1297
2.49k
    if (Memory.OffsetRegNum &&
1298
2.49k
        !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1299
622
            Memory.OffsetRegNum))
1300
0
      return false;
1301
2.49k
    return true;
1302
2.49k
  }
1303
125k
  bool isGPRMem() const {
1304
125k
    if (Kind != k_Memory)
1305
5.86k
      return false;
1306
119k
    if (Memory.BaseRegNum &&
1307
119k
        !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.BaseRegNum))
1308
296
      return false;
1309
119k
    if (Memory.OffsetRegNum &&
1310
119k
        
!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.OffsetRegNum)2.42k
)
1311
489
      return false;
1312
118k
    return true;
1313
118k
  }
1314
52
  bool isShifterImm() const { return Kind == k_ShifterImmediate; }
1315
8.06k
  bool isRegShiftedReg() const {
1316
8.06k
    return Kind == k_ShiftedRegister &&
1317
8.06k
           ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1318
247
               RegShiftedReg.SrcReg) &&
1319
8.06k
           ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1320
247
               RegShiftedReg.ShiftReg);
1321
8.06k
  }
1322
18.7k
  bool isRegShiftedImm() const {
1323
18.7k
    return Kind == k_ShiftedImmediate &&
1324
18.7k
           ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1325
2.53k
               RegShiftedImm.SrcReg);
1326
18.7k
  }
1327
342
  bool isRotImm() const { return Kind == k_RotateImmediate; }
1328
1329
  template<unsigned Min, unsigned Max>
1330
74
  bool isPowerTwoInRange() const {
1331
74
    if (!isImm()) 
return false0
;
1332
74
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1333
74
    if (!CE) 
return false0
;
1334
74
    int64_t Value = CE->getValue();
1335
74
    return Value > 0 && countPopulation((uint64_t)Value) == 1 &&
1336
74
           
Value >= Min50
&&
Value <= Max50
;
1337
74
  }
1338
7.70k
  bool isModImm() const { return Kind == k_ModifiedImmediate; }
1339
1340
1.67k
  bool isModImmNot() const {
1341
1.67k
    if (!isImm()) 
return false1.60k
;
1342
77
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1343
77
    if (!CE) 
return false0
;
1344
77
    int64_t Value = CE->getValue();
1345
77
    return ARM_AM::getSOImmVal(~Value) != -1;
1346
77
  }
1347
1348
4.53k
  bool isModImmNeg() const {
1349
4.53k
    if (!isImm()) 
return false4.37k
;
1350
153
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1351
153
    if (!CE) 
return false5
;
1352
148
    int64_t Value = CE->getValue();
1353
148
    return ARM_AM::getSOImmVal(Value) == -1 &&
1354
148
      
ARM_AM::getSOImmVal(-Value) != -139
;
1355
148
  }
1356
1357
1.78k
  bool isThumbModImmNeg1_7() const {
1358
1.78k
    if (!isImm()) 
return false1.68k
;
1359
99
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1360
99
    if (!CE) 
return false12
;
1361
87
    int32_t Value = -(int32_t)CE->getValue();
1362
87
    return 0 < Value && 
Value < 821
;
1363
87
  }
1364
1365
2.76k
  bool isThumbModImmNeg8_255() const {
1366
2.76k
    if (!isImm()) 
return false2.70k
;
1367
53
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1368
53
    if (!CE) 
return false0
;
1369
53
    int32_t Value = -(int32_t)CE->getValue();
1370
53
    return 7 < Value && 
Value < 2568
;
1371
53
  }
1372
1373
1.29k
  bool isConstantPoolImm() const { return Kind == k_ConstantPoolImmediate; }
1374
45
  bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
1375
175
  bool isPostIdxRegShifted() const {
1376
175
    return Kind == k_PostIndexRegister &&
1377
175
           
ARMMCRegisterClasses[ARM::GPRRegClassID].contains(PostIdxReg.RegNum)76
;
1378
175
  }
1379
108
  bool isPostIdxReg() const {
1380
108
    return isPostIdxRegShifted() && 
PostIdxReg.ShiftTy == ARM_AM::no_shift35
;
1381
108
  }
1382
101k
  bool isMemNoOffset(bool alignOK = false, unsigned Alignment = 0) const {
1383
101k
    if (!isGPRMem())
1384
331
      return false;
1385
101k
    // No offset of any kind.
1386
101k
    return Memory.OffsetRegNum == 0 && 
Memory.OffsetImm == nullptr101k
&&
1387
101k
     
(101k
alignOK101k
||
Memory.Alignment == Alignment101k
);
1388
101k
  }
1389
1.95k
  bool isMemNoOffsetT2(bool alignOK = false, unsigned Alignment = 0) const {
1390
1.95k
    if (!isGPRMem())
1391
220
      return false;
1392
1.73k
1393
1.73k
    if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1394
1.73k
            Memory.BaseRegNum))
1395
186
      return false;
1396
1.55k
1397
1.55k
    // No offset of any kind.
1398
1.55k
    return Memory.OffsetRegNum == 0 && Memory.OffsetImm == nullptr &&
1399
1.55k
     
(827
alignOK827
||
Memory.Alignment == Alignment827
);
1400
1.55k
  }
1401
252
  bool isMemNoOffsetT2NoSp(bool alignOK = false, unsigned Alignment = 0) const {
1402
252
    if (!isGPRMem())
1403
68
      return false;
1404
184
1405
184
    if (!ARMMCRegisterClasses[ARM::rGPRRegClassID].contains(
1406
184
            Memory.BaseRegNum))
1407
23
      return false;
1408
161
1409
161
    // No offset of any kind.
1410
161
    return Memory.OffsetRegNum == 0 && Memory.OffsetImm == nullptr &&
1411
161
     
(116
alignOK116
||
Memory.Alignment == Alignment116
);
1412
161
  }
1413
298
  bool isMemNoOffsetT(bool alignOK = false, unsigned Alignment = 0) const {
1414
298
    if (!isGPRMem())
1415
35
      return false;
1416
263
1417
263
    if (!ARMMCRegisterClasses[ARM::tGPRRegClassID].contains(
1418
263
            Memory.BaseRegNum))
1419
14
      return false;
1420
249
1421
249
    // No offset of any kind.
1422
249
    return Memory.OffsetRegNum == 0 && Memory.OffsetImm == nullptr &&
1423
249
     
(101
alignOK101
||
Memory.Alignment == Alignment101
);
1424
249
  }
1425
506
  bool isMemPCRelImm12() const {
1426
506
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0253
||
Memory.Alignment != 0221
)
1427
285
      return false;
1428
221
    // Base register must be PC.
1429
221
    if (Memory.BaseRegNum != ARM::PC)
1430
152
      return false;
1431
69
    // Immediate offset in range [-4095, 4095].
1432
69
    if (!Memory.OffsetImm) 
return true0
;
1433
69
    int64_t Val = Memory.OffsetImm->getValue();
1434
69
    return (Val > -4096 && 
Val < 409652
) ||
1435
69
           
(Val == std::numeric_limits<int32_t>::min())17
;
1436
69
  }
1437
1438
0
  bool isAlignedMemory() const {
1439
0
    return isMemNoOffset(true);
1440
0
  }
1441
1442
4.09k
  bool isAlignedMemoryNone() const {
1443
4.09k
    return isMemNoOffset(false, 0);
1444
4.09k
  }
1445
1446
3.47k
  bool isDupAlignedMemoryNone() const {
1447
3.47k
    return isMemNoOffset(false, 0);
1448
3.47k
  }
1449
1450
1.26k
  bool isAlignedMemory16() const {
1451
1.26k
    if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
1452
236
      return true;
1453
1.02k
    return isMemNoOffset(false, 0);
1454
1.02k
  }
1455
1456
1.68k
  bool isDupAlignedMemory16() const {
1457
1.68k
    if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
1458
276
      return true;
1459
1.41k
    return isMemNoOffset(false, 0);
1460
1.41k
  }
1461
1462
1.99k
  bool isAlignedMemory32() const {
1463
1.99k
    if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
1464
354
      return true;
1465
1.64k
    return isMemNoOffset(false, 0);
1466
1.64k
  }
1467
1468
2.56k
  bool isDupAlignedMemory32() const {
1469
2.56k
    if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
1470
415
      return true;
1471
2.14k
    return isMemNoOffset(false, 0);
1472
2.14k
  }
1473
1474
12.6k
  bool isAlignedMemory64() const {
1475
12.6k
    if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1476
1.66k
      return true;
1477
11.0k
    return isMemNoOffset(false, 0);
1478
11.0k
  }
1479
1480
1.74k
  bool isDupAlignedMemory64() const {
1481
1.74k
    if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1482
237
      return true;
1483
1.50k
    return isMemNoOffset(false, 0);
1484
1.50k
  }
1485
1486
8.47k
  bool isAlignedMemory64or128() const {
1487
8.47k
    if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1488
1.25k
      return true;
1489
7.22k
    if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1490
1.23k
      return true;
1491
5.99k
    return isMemNoOffset(false, 0);
1492
5.99k
  }
1493
1494
793
  bool isDupAlignedMemory64or128() const {
1495
793
    if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1496
97
      return true;
1497
696
    if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1498
108
      return true;
1499
588
    return isMemNoOffset(false, 0);
1500
588
  }
1501
1502
8.72k
  bool isAlignedMemory64or128or256() const {
1503
8.72k
    if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1504
1.26k
      return true;
1505
7.45k
    if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1506
1.21k
      return true;
1507
6.24k
    if (isMemNoOffset(false, 32)) // alignment in bytes for 256-bits is 32.
1508
1.48k
      return true;
1509
4.75k
    return isMemNoOffset(false, 0);
1510
4.75k
  }
1511
1512
0
  bool isAddrMode2() const {
1513
0
    if (!isGPRMem() || Memory.Alignment != 0) return false;
1514
0
    // Check for register offset.
1515
0
    if (Memory.OffsetRegNum) return true;
1516
0
    // Immediate offset in range [-4095, 4095].
1517
0
    if (!Memory.OffsetImm) return true;
1518
0
    int64_t Val = Memory.OffsetImm->getValue();
1519
0
    return Val > -4096 && Val < 4096;
1520
0
  }
1521
1522
106
  bool isAM2OffsetImm() const {
1523
106
    if (!isImm()) 
return false63
;
1524
43
    // Immediate offset in range [-4095, 4095].
1525
43
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1526
43
    if (!CE) 
return false0
;
1527
43
    int64_t Val = CE->getValue();
1528
43
    return (Val == std::numeric_limits<int32_t>::min()) ||
1529
43
           
(41
Val > -409641
&&
Val < 409641
);
1530
43
  }
1531
1532
711
  bool isAddrMode3() const {
1533
711
    // If we have an immediate that's not a constant, treat it as a label
1534
711
    // reference needing a fixup. If it is a constant, it's something else
1535
711
    // and we reject it.
1536
711
    if (isImm() && 
!isa<MCConstantExpr>(getImm())2
)
1537
2
      return true;
1538
709
    if (!isGPRMem() || 
Memory.Alignment != 0527
)
return false182
;
1539
527
    // No shifts are legal for AM3.
1540
527
    if (Memory.ShiftType != ARM_AM::no_shift) 
return false0
;
1541
527
    // Check for register offset.
1542
527
    if (Memory.OffsetRegNum) 
return true60
;
1543
467
    // Immediate offset in range [-255, 255].
1544
467
    if (!Memory.OffsetImm) 
return true261
;
1545
206
    int64_t Val = Memory.OffsetImm->getValue();
1546
206
    // The #-0 offset is encoded as std::numeric_limits<int32_t>::min(), and we
1547
206
    // have to check for this too.
1548
206
    return (Val > -256 && 
Val < 256184
) ||
1549
206
           
Val == std::numeric_limits<int32_t>::min()36
;
1550
206
  }
1551
1552
83
  bool isAM3Offset() const {
1553
83
    if (isPostIdxReg())
1554
23
      return true;
1555
60
    if (!isImm())
1556
4
      return false;
1557
56
    // Immediate offset in range [-255, 255].
1558
56
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1559
56
    if (!CE) 
return false0
;
1560
56
    int64_t Val = CE->getValue();
1561
56
    // Special case, #-0 is std::numeric_limits<int32_t>::min().
1562
56
    return (Val > -256 && 
Val < 25654
) ||
1563
56
           
Val == std::numeric_limits<int32_t>::min()3
;
1564
56
  }
1565
1566
2.97k
  bool isAddrMode5() const {
1567
2.97k
    // If we have an immediate that's not a constant, treat it as a label
1568
2.97k
    // reference needing a fixup. If it is a constant, it's something else
1569
2.97k
    // and we reject it.
1570
2.97k
    if (isImm() && 
!isa<MCConstantExpr>(getImm())1
)
1571
1
      return true;
1572
2.96k
    if (!isGPRMem() || 
Memory.Alignment != 02.75k
)
return false216
;
1573
2.75k
    // Check for register offset.
1574
2.75k
    if (Memory.OffsetRegNum) 
return false0
;
1575
2.75k
    // Immediate offset in range [-1020, 1020] and a multiple of 4.
1576
2.75k
    if (!Memory.OffsetImm) 
return true1.59k
;
1577
1.16k
    int64_t Val = Memory.OffsetImm->getValue();
1578
1.16k
    return (Val >= -1020 && 
Val <= 1020776
&&
((Val & 3) == 0)776
) ||
1579
1.16k
      
Val == std::numeric_limits<int32_t>::min()438
;
1580
1.16k
  }
1581
1582
97
  bool isAddrMode5FP16() const {
1583
97
    // If we have an immediate that's not a constant, treat it as a label
1584
97
    // reference needing a fixup. If it is a constant, it's something else
1585
97
    // and we reject it.
1586
97
    if (isImm() && 
!isa<MCConstantExpr>(getImm())2
)
1587
2
      return true;
1588
95
    if (!isGPRMem() || Memory.Alignment != 0) 
return false0
;
1589
95
    // Check for register offset.
1590
95
    if (Memory.OffsetRegNum) 
return false0
;
1591
95
    // Immediate offset in range [-510, 510] and a multiple of 2.
1592
95
    if (!Memory.OffsetImm) 
return true25
;
1593
70
    int64_t Val = Memory.OffsetImm->getValue();
1594
70
    return (Val >= -510 && 
Val <= 51069
&&
((Val & 1) == 0)69
) ||
1595
70
           
Val == std::numeric_limits<int32_t>::min()1
;
1596
70
  }
1597
1598
7
  bool isMemTBB() const {
1599
7
    if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1600
7
        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
1601
0
      return false;
1602
7
    return true;
1603
7
  }
1604
1605
7
  bool isMemTBH() const {
1606
7
    if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1607
7
        Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
1608
7
        Memory.Alignment != 0 )
1609
0
      return false;
1610
7
    return true;
1611
7
  }
1612
1613
805
  bool isMemRegOffset() const {
1614
805
    if (!isGPRMem() || 
!Memory.OffsetRegNum372
||
Memory.Alignment != 0115
)
1615
690
      return false;
1616
115
    return true;
1617
115
  }
1618
1619
1.13k
  bool isT2MemRegOffset() const {
1620
1.13k
    if (!isGPRMem() || 
!Memory.OffsetRegNum780
||
Memory.isNegative370
||
1621
1.13k
        
Memory.Alignment != 0358
||
Memory.BaseRegNum == ARM::PC358
)
1622
787
      return false;
1623
348
    // Only lsl #{0, 1, 2, 3} allowed.
1624
348
    if (Memory.ShiftType == ARM_AM::no_shift)
1625
264
      return true;
1626
84
    if (Memory.ShiftType != ARM_AM::lsl || 
Memory.ShiftImm > 381
)
1627
3
      return false;
1628
81
    return true;
1629
81
  }
1630
1631
1.40k
  bool isMemThumbRR() const {
1632
1.40k
    // Thumb reg+reg addressing is simple. Just two registers, a base and
1633
1.40k
    // an offset. No shifts, negations or any other complicating factors.
1634
1.40k
    if (!isGPRMem() || 
!Memory.OffsetRegNum867
||
Memory.isNegative268
||
1635
1.40k
        
Memory.ShiftType != ARM_AM::no_shift252
||
Memory.Alignment != 0168
)
1636
1.23k
      return false;
1637
168
    return isARMLowRegister(Memory.BaseRegNum) &&
1638
168
      
(70
!Memory.OffsetRegNum70
||
isARMLowRegister(Memory.OffsetRegNum)70
);
1639
168
  }
1640
1641
682
  bool isMemThumbRIs4() const {
1642
682
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0396
||
1643
682
        
!isARMLowRegister(Memory.BaseRegNum)323
||
Memory.Alignment != 0184
)
1644
498
      return false;
1645
184
    // Immediate offset, multiple of 4 in range [0, 124].
1646
184
    if (!Memory.OffsetImm) 
return true93
;
1647
91
    int64_t Val = Memory.OffsetImm->getValue();
1648
91
    return Val >= 0 && 
Val <= 12478
&&
(Val % 4) == 064
;
1649
91
  }
1650
1651
253
  bool isMemThumbRIs2() const {
1652
253
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0173
||
1653
253
        
!isARMLowRegister(Memory.BaseRegNum)129
||
Memory.Alignment != 091
)
1654
162
      return false;
1655
91
    // Immediate offset, multiple of 4 in range [0, 62].
1656
91
    if (!Memory.OffsetImm) 
return true34
;
1657
57
    int64_t Val = Memory.OffsetImm->getValue();
1658
57
    return Val >= 0 && 
Val <= 6244
&&
(Val % 2) == 040
;
1659
57
  }
1660
1661
311
  bool isMemThumbRIs1() const {
1662
311
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0233
||
1663
311
        
!isARMLowRegister(Memory.BaseRegNum)154
||
Memory.Alignment != 0100
)
1664
211
      return false;
1665
100
    // Immediate offset in range [0, 31].
1666
100
    if (!Memory.OffsetImm) 
return true44
;
1667
56
    int64_t Val = Memory.OffsetImm->getValue();
1668
56
    return Val >= 0 && 
Val <= 3144
;
1669
56
  }
1670
1671
598
  bool isMemThumbSPI() const {
1672
598
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0312
||
1673
598
        
Memory.BaseRegNum != ARM::SP248
||
Memory.Alignment != 066
)
1674
532
      return false;
1675
66
    // Immediate offset, multiple of 4 in range [0, 1020].
1676
66
    if (!Memory.OffsetImm) 
return true29
;
1677
37
    int64_t Val = Memory.OffsetImm->getValue();
1678
37
    return Val >= 0 && 
Val <= 102032
&&
(Val % 4) == 032
;
1679
37
  }
1680
1681
421
  bool isMemImm8s4Offset() const {
1682
421
    // If we have an immediate that's not a constant, treat it as a label
1683
421
    // reference needing a fixup. If it is a constant, it's something else
1684
421
    // and we reject it.
1685
421
    if (isImm() && 
!isa<MCConstantExpr>(getImm())2
)
1686
2
      return true;
1687
419
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0415
||
Memory.Alignment != 0399
)
1688
20
      return false;
1689
399
    // Immediate offset a multiple of 4 in range [-1020, 1020].
1690
399
    if (!Memory.OffsetImm) 
return true225
;
1691
174
    int64_t Val = Memory.OffsetImm->getValue();
1692
174
    // Special case, #-0 is std::numeric_limits<int32_t>::min().
1693
174
    return (Val >= -1020 && 
Val <= 1020116
&&
(Val & 3) == 0116
) ||
1694
174
           
Val == std::numeric_limits<int32_t>::min()62
;
1695
174
  }
1696
4.37k
  bool isMemImm7s4Offset() const {
1697
4.37k
    // If we have an immediate that's not a constant, treat it as a label
1698
4.37k
    // reference needing a fixup. If it is a constant, it's something else
1699
4.37k
    // and we reject it.
1700
4.37k
    if (isImm() && 
!isa<MCConstantExpr>(getImm())6
)
1701
6
      return true;
1702
4.37k
    if (!isGPRMem() || 
Memory.OffsetRegNum != 03.56k
||
Memory.Alignment != 03.56k
||
1703
4.37k
        !ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1704
3.56k
            Memory.BaseRegNum))
1705
1.16k
      return false;
1706
3.20k
    // Immediate offset a multiple of 4 in range [-508, 508].
1707
3.20k
    if (!Memory.OffsetImm) 
return true1.62k
;
1708
1.58k
    int64_t Val = Memory.OffsetImm->getValue();
1709
1.58k
    // Special case, #-0 is INT32_MIN.
1710
1.58k
    return (Val >= -508 && Val <= 508 && 
(Val & 3) == 01.44k
) ||
Val == INT32_MIN360
;
1711
1.58k
  }
1712
364
  bool isMemImm0_1020s4Offset() const {
1713
364
    if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1714
0
      return false;
1715
364
    // Immediate offset a multiple of 4 in range [0, 1020].
1716
364
    if (!Memory.OffsetImm) 
return true350
;
1717
14
    int64_t Val = Memory.OffsetImm->getValue();
1718
14
    return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1719
14
  }
1720
1721
356
  bool isMemImm8Offset() const {
1722
356
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0322
||
Memory.Alignment != 0289
)
1723
67
      return false;
1724
289
    // Base reg of PC isn't allowed for these encodings.
1725
289
    if (Memory.BaseRegNum == ARM::PC) 
return false10
;
1726
279
    // Immediate offset in range [-255, 255].
1727
279
    if (!Memory.OffsetImm) 
return true163
;
1728
116
    int64_t Val = Memory.OffsetImm->getValue();
1729
116
    return (Val == std::numeric_limits<int32_t>::min()) ||
1730
116
           
(112
Val > -256112
&&
Val < 256112
);
1731
116
  }
1732
1733
  template<unsigned Bits, unsigned RegClassID>
1734
1.84k
  bool isMemImm7ShiftedOffset() const {
1735
1.84k
    if (!isGPRMem() || 
Memory.OffsetRegNum != 01.36k
||
Memory.Alignment != 01.36k
||
1736
1.84k
        
!ARMMCRegisterClasses[RegClassID].contains(Memory.BaseRegNum)1.36k
)
1737
580
      return false;
1738
1.26k
1739
1.26k
    // Expect an immediate offset equal to an element of the range
1740
1.26k
    // [-127, 127], shifted left by Bits.
1741
1.26k
1742
1.26k
    if (!Memory.OffsetImm) 
return true517
;
1743
748
    int64_t Val = Memory.OffsetImm->getValue();
1744
748
1745
748
    // INT32_MIN is a special-case value (indicating the encoding with
1746
748
    // zero offset and the subtract bit set)
1747
748
    if (Val == INT32_MIN)
1748
748
      
return true0
;
1749
748
1750
748
    unsigned Divisor = 1U << Bits;
1751
748
1752
748
    // Check that the low bits are zero
1753
748
    if (Val % Divisor != 0)
1754
2
      return false;
1755
746
1756
746
    // Check that the remaining offset is within range.
1757
746
    Val /= Divisor;
1758
746
    return (Val >= -127 && 
Val <= 127726
);
1759
746
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemImm7ShiftedOffset<0u, 8u>() const
Line
Count
Source
1734
134
  bool isMemImm7ShiftedOffset() const {
1735
134
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0113
||
Memory.Alignment != 0113
||
1736
134
        
!ARMMCRegisterClasses[RegClassID].contains(Memory.BaseRegNum)113
)
1737
21
      return false;
1738
113
1739
113
    // Expect an immediate offset equal to an element of the range
1740
113
    // [-127, 127], shifted left by Bits.
1741
113
1742
113
    if (!Memory.OffsetImm) 
return true49
;
1743
64
    int64_t Val = Memory.OffsetImm->getValue();
1744
64
1745
64
    // INT32_MIN is a special-case value (indicating the encoding with
1746
64
    // zero offset and the subtract bit set)
1747
64
    if (Val == INT32_MIN)
1748
64
      
return true0
;
1749
64
1750
64
    unsigned Divisor = 1U << Bits;
1751
64
1752
64
    // Check that the low bits are zero
1753
64
    if (Val % Divisor != 0)
1754
0
      return false;
1755
64
1756
64
    // Check that the remaining offset is within range.
1757
64
    Val /= Divisor;
1758
64
    return (Val >= -127 && 
Val <= 12760
);
1759
64
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemImm7ShiftedOffset<0u, 11u>() const
Line
Count
Source
1734
74
  bool isMemImm7ShiftedOffset() const {
1735
74
    if (!isGPRMem() || 
Memory.OffsetRegNum != 063
||
Memory.Alignment != 063
||
1736
74
        
!ARMMCRegisterClasses[RegClassID].contains(Memory.BaseRegNum)63
)
1737
15
      return false;
1738
59
1739
59
    // Expect an immediate offset equal to an element of the range
1740
59
    // [-127, 127], shifted left by Bits.
1741
59
1742
59
    if (!Memory.OffsetImm) 
return true25
;
1743
34
    int64_t Val = Memory.OffsetImm->getValue();
1744
34
1745
34
    // INT32_MIN is a special-case value (indicating the encoding with
1746
34
    // zero offset and the subtract bit set)
1747
34
    if (Val == INT32_MIN)
1748
34
      
return true0
;
1749
34
1750
34
    unsigned Divisor = 1U << Bits;
1751
34
1752
34
    // Check that the low bits are zero
1753
34
    if (Val % Divisor != 0)
1754
0
      return false;
1755
34
1756
34
    // Check that the remaining offset is within range.
1757
34
    Val /= Divisor;
1758
34
    return (Val >= -127 && 
Val <= 12730
);
1759
34
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemImm7ShiftedOffset<1u, 8u>() const
Line
Count
Source
1734
186
  bool isMemImm7ShiftedOffset() const {
1735
186
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0132
||
Memory.Alignment != 0132
||
1736
186
        
!ARMMCRegisterClasses[RegClassID].contains(Memory.BaseRegNum)132
)
1737
54
      return false;
1738
132
1739
132
    // Expect an immediate offset equal to an element of the range
1740
132
    // [-127, 127], shifted left by Bits.
1741
132
1742
132
    if (!Memory.OffsetImm) 
return true55
;
1743
77
    int64_t Val = Memory.OffsetImm->getValue();
1744
77
1745
77
    // INT32_MIN is a special-case value (indicating the encoding with
1746
77
    // zero offset and the subtract bit set)
1747
77
    if (Val == INT32_MIN)
1748
77
      
return true0
;
1749
77
1750
77
    unsigned Divisor = 1U << Bits;
1751
77
1752
77
    // Check that the low bits are zero
1753
77
    if (Val % Divisor != 0)
1754
0
      return false;
1755
77
1756
77
    // Check that the remaining offset is within range.
1757
77
    Val /= Divisor;
1758
77
    return (Val >= -127 && Val <= 127);
1759
77
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemImm7ShiftedOffset<1u, 11u>() const
Line
Count
Source
1734
100
  bool isMemImm7ShiftedOffset() const {
1735
100
    if (!isGPRMem() || 
Memory.OffsetRegNum != 075
||
Memory.Alignment != 075
||
1736
100
        
!ARMMCRegisterClasses[RegClassID].contains(Memory.BaseRegNum)75
)
1737
31
      return false;
1738
69
1739
69
    // Expect an immediate offset equal to an element of the range
1740
69
    // [-127, 127], shifted left by Bits.
1741
69
1742
69
    if (!Memory.OffsetImm) 
return true31
;
1743
38
    int64_t Val = Memory.OffsetImm->getValue();
1744
38
1745
38
    // INT32_MIN is a special-case value (indicating the encoding with
1746
38
    // zero offset and the subtract bit set)
1747
38
    if (Val == INT32_MIN)
1748
38
      
return true0
;
1749
38
1750
38
    unsigned Divisor = 1U << Bits;
1751
38
1752
38
    // Check that the low bits are zero
1753
38
    if (Val % Divisor != 0)
1754
0
      return false;
1755
38
1756
38
    // Check that the remaining offset is within range.
1757
38
    Val /= Divisor;
1758
38
    return (Val >= -127 && Val <= 127);
1759
38
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemImm7ShiftedOffset<2u, 8u>() const
Line
Count
Source
1734
245
  bool isMemImm7ShiftedOffset() const {
1735
245
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0102
||
Memory.Alignment != 0102
||
1736
245
        
!ARMMCRegisterClasses[RegClassID].contains(Memory.BaseRegNum)102
)
1737
143
      return false;
1738
102
1739
102
    // Expect an immediate offset equal to an element of the range
1740
102
    // [-127, 127], shifted left by Bits.
1741
102
1742
102
    if (!Memory.OffsetImm) 
return true36
;
1743
66
    int64_t Val = Memory.OffsetImm->getValue();
1744
66
1745
66
    // INT32_MIN is a special-case value (indicating the encoding with
1746
66
    // zero offset and the subtract bit set)
1747
66
    if (Val == INT32_MIN)
1748
66
      
return true0
;
1749
66
1750
66
    unsigned Divisor = 1U << Bits;
1751
66
1752
66
    // Check that the low bits are zero
1753
66
    if (Val % Divisor != 0)
1754
2
      return false;
1755
64
1756
64
    // Check that the remaining offset is within range.
1757
64
    Val /= Divisor;
1758
64
    return (Val >= -127 && Val <= 127);
1759
64
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemImm7ShiftedOffset<2u, 11u>() const
Line
Count
Source
1734
162
  bool isMemImm7ShiftedOffset() const {
1735
162
    if (!isGPRMem() || 
Memory.OffsetRegNum != 070
||
Memory.Alignment != 070
||
1736
162
        
!ARMMCRegisterClasses[RegClassID].contains(Memory.BaseRegNum)70
)
1737
104
      return false;
1738
58
1739
58
    // Expect an immediate offset equal to an element of the range
1740
58
    // [-127, 127], shifted left by Bits.
1741
58
1742
58
    if (!Memory.OffsetImm) 
return true22
;
1743
36
    int64_t Val = Memory.OffsetImm->getValue();
1744
36
1745
36
    // INT32_MIN is a special-case value (indicating the encoding with
1746
36
    // zero offset and the subtract bit set)
1747
36
    if (Val == INT32_MIN)
1748
36
      
return true0
;
1749
36
1750
36
    unsigned Divisor = 1U << Bits;
1751
36
1752
36
    // Check that the low bits are zero
1753
36
    if (Val % Divisor != 0)
1754
0
      return false;
1755
36
1756
36
    // Check that the remaining offset is within range.
1757
36
    Val /= Divisor;
1758
36
    return (Val >= -127 && Val <= 127);
1759
36
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemImm7ShiftedOffset<0u, 15u>() const
Line
Count
Source
1734
678
  bool isMemImm7ShiftedOffset() const {
1735
678
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0585
||
Memory.Alignment != 0585
||
1736
678
        
!ARMMCRegisterClasses[RegClassID].contains(Memory.BaseRegNum)585
)
1737
149
      return false;
1738
529
1739
529
    // Expect an immediate offset equal to an element of the range
1740
529
    // [-127, 127], shifted left by Bits.
1741
529
1742
529
    if (!Memory.OffsetImm) 
return true226
;
1743
303
    int64_t Val = Memory.OffsetImm->getValue();
1744
303
1745
303
    // INT32_MIN is a special-case value (indicating the encoding with
1746
303
    // zero offset and the subtract bit set)
1747
303
    if (Val == INT32_MIN)
1748
303
      
return true0
;
1749
303
1750
303
    unsigned Divisor = 1U << Bits;
1751
303
1752
303
    // Check that the low bits are zero
1753
303
    if (Val % Divisor != 0)
1754
0
      return false;
1755
303
1756
303
    // Check that the remaining offset is within range.
1757
303
    Val /= Divisor;
1758
303
    return (Val >= -127 && 
Val <= 127291
);
1759
303
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemImm7ShiftedOffset<1u, 15u>() const
Line
Count
Source
1734
266
  bool isMemImm7ShiftedOffset() const {
1735
266
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0223
||
Memory.Alignment != 0223
||
1736
266
        
!ARMMCRegisterClasses[RegClassID].contains(Memory.BaseRegNum)223
)
1737
63
      return false;
1738
203
1739
203
    // Expect an immediate offset equal to an element of the range
1740
203
    // [-127, 127], shifted left by Bits.
1741
203
1742
203
    if (!Memory.OffsetImm) 
return true73
;
1743
130
    int64_t Val = Memory.OffsetImm->getValue();
1744
130
1745
130
    // INT32_MIN is a special-case value (indicating the encoding with
1746
130
    // zero offset and the subtract bit set)
1747
130
    if (Val == INT32_MIN)
1748
130
      
return true0
;
1749
130
1750
130
    unsigned Divisor = 1U << Bits;
1751
130
1752
130
    // Check that the low bits are zero
1753
130
    if (Val % Divisor != 0)
1754
0
      return false;
1755
130
1756
130
    // Check that the remaining offset is within range.
1757
130
    Val /= Divisor;
1758
130
    return (Val >= -127 && Val <= 127);
1759
130
  }
1760
1761
1.87k
  template <int shift> bool isMemRegRQOffset() const {
1762
1.87k
    if (!isMVEMem() || Memory.OffsetImm != 0 || 
Memory.Alignment != 01.05k
)
1763
825
      return false;
1764
1.05k
1765
1.05k
    if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1766
1.05k
            Memory.BaseRegNum))
1767
124
      return false;
1768
930
    if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1769
930
            Memory.OffsetRegNum))
1770
474
      return false;
1771
456
1772
456
    if (shift == 0 && 
Memory.ShiftType != ARM_AM::no_shift306
)
1773
94
      return false;
1774
362
1775
362
    if (shift > 0 &&
1776
362
        
(150
Memory.ShiftType != ARM_AM::uxtw150
||
Memory.ShiftImm != shift90
))
1777
73
      return false;
1778
289
1779
289
    return true;
1780
289
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemRegRQOffset<0>() const
Line
Count
Source
1761
1.26k
  template <int shift> bool isMemRegRQOffset() const {
1762
1.26k
    if (!isMVEMem() || Memory.OffsetImm != 0 || 
Memory.Alignment != 0716
)
1763
550
      return false;
1764
716
1765
716
    if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1766
716
            Memory.BaseRegNum))
1767
62
      return false;
1768
654
    if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1769
654
            Memory.OffsetRegNum))
1770
348
      return false;
1771
306
1772
306
    if (shift == 0 && Memory.ShiftType != ARM_AM::no_shift)
1773
94
      return false;
1774
212
1775
212
    if (shift > 0 &&
1776
212
        
(0
Memory.ShiftType != ARM_AM::uxtw0
||
Memory.ShiftImm != shift0
))
1777
0
      return false;
1778
212
1779
212
    return true;
1780
212
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemRegRQOffset<1>() const
Line
Count
Source
1761
327
  template <int shift> bool isMemRegRQOffset() const {
1762
327
    if (!isMVEMem() || Memory.OffsetImm != 0 || 
Memory.Alignment != 0178
)
1763
149
      return false;
1764
178
1765
178
    if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1766
178
            Memory.BaseRegNum))
1767
3
      return false;
1768
175
    if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1769
175
            Memory.OffsetRegNum))
1770
104
      return false;
1771
71
1772
71
    if (shift == 0 && 
Memory.ShiftType != ARM_AM::no_shift0
)
1773
0
      return false;
1774
71
1775
71
    if (shift > 0 &&
1776
71
        (Memory.ShiftType != ARM_AM::uxtw || 
Memory.ShiftImm != shift35
))
1777
39
      return false;
1778
32
1779
32
    return true;
1780
32
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemRegRQOffset<2>() const
Line
Count
Source
1761
173
  template <int shift> bool isMemRegRQOffset() const {
1762
173
    if (!isMVEMem() || Memory.OffsetImm != 0 || 
Memory.Alignment != 088
)
1763
85
      return false;
1764
88
1765
88
    if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1766
88
            Memory.BaseRegNum))
1767
29
      return false;
1768
59
    if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1769
59
            Memory.OffsetRegNum))
1770
22
      return false;
1771
37
1772
37
    if (shift == 0 && 
Memory.ShiftType != ARM_AM::no_shift0
)
1773
0
      return false;
1774
37
1775
37
    if (shift > 0 &&
1776
37
        (Memory.ShiftType != ARM_AM::uxtw || 
Memory.ShiftImm != shift25
))
1777
14
      return false;
1778
23
1779
23
    return true;
1780
23
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemRegRQOffset<3>() const
Line
Count
Source
1761
113
  template <int shift> bool isMemRegRQOffset() const {
1762
113
    if (!isMVEMem() || Memory.OffsetImm != 0 || 
Memory.Alignment != 072
)
1763
41
      return false;
1764
72
1765
72
    if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1766
72
            Memory.BaseRegNum))
1767
30
      return false;
1768
42
    if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1769
42
            Memory.OffsetRegNum))
1770
0
      return false;
1771
42
1772
42
    if (shift == 0 && 
Memory.ShiftType != ARM_AM::no_shift0
)
1773
0
      return false;
1774
42
1775
42
    if (shift > 0 &&
1776
42
        (Memory.ShiftType != ARM_AM::uxtw || 
Memory.ShiftImm != shift30
))
1777
20
      return false;
1778
22
1779
22
    return true;
1780
22
  }
1781
1782
619
  template <int shift> bool isMemRegQOffset() const {
1783
619
    if (!isMVEMem() || Memory.OffsetRegNum != 0 || 
Memory.Alignment != 0459
)
1784
160
      return false;
1785
459
1786
459
    if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1787
459
            Memory.BaseRegNum))
1788
124
      return false;
1789
335
1790
335
    if(!Memory.OffsetImm) 
return true143
;
1791
192
    static_assert(shift < 56,
1792
192
                  "Such that we dont shift by a value higher than 62");
1793
192
    int64_t Val = Memory.OffsetImm->getValue();
1794
192
1795
192
    // The value must be a multiple of (1 << shift)
1796
192
    if ((Val & ((1U << shift) - 1)) != 0)
1797
12
      return false;
1798
180
1799
180
    // And be in the right range, depending on the amount that it is shifted
1800
180
    // by.  Shift 0, is equal to 7 unsigned bits, the sign bit is set
1801
180
    // separately.
1802
180
    int64_t Range = (1U << (7+shift)) - 1;
1803
180
    return (Val == INT32_MIN) || (Val > -Range && Val < Range);
1804
180
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemRegQOffset<2>() const
Line
Count
Source
1782
359
  template <int shift> bool isMemRegQOffset() const {
1783
359
    if (!isMVEMem() || Memory.OffsetRegNum != 0 || 
Memory.Alignment != 0284
)
1784
75
      return false;
1785
284
1786
284
    if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1787
284
            Memory.BaseRegNum))
1788
124
      return false;
1789
160
1790
160
    if(!Memory.OffsetImm) 
return true70
;
1791
90
    static_assert(shift < 56,
1792
90
                  "Such that we dont shift by a value higher than 62");
1793
90
    int64_t Val = Memory.OffsetImm->getValue();
1794
90
1795
90
    // The value must be a multiple of (1 << shift)
1796
90
    if ((Val & ((1U << shift) - 1)) != 0)
1797
4
      return false;
1798
86
1799
86
    // And be in the right range, depending on the amount that it is shifted
1800
86
    // by.  Shift 0, is equal to 7 unsigned bits, the sign bit is set
1801
86
    // separately.
1802
86
    int64_t Range = (1U << (7+shift)) - 1;
1803
86
    return (Val == INT32_MIN) || (Val > -Range && Val < Range);
1804
86
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMemRegQOffset<3>() const
Line
Count
Source
1782
260
  template <int shift> bool isMemRegQOffset() const {
1783
260
    if (!isMVEMem() || Memory.OffsetRegNum != 0 || 
Memory.Alignment != 0175
)
1784
85
      return false;
1785
175
1786
175
    if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1787
175
            Memory.BaseRegNum))
1788
0
      return false;
1789
175
1790
175
    if(!Memory.OffsetImm) 
return true73
;
1791
102
    static_assert(shift < 56,
1792
102
                  "Such that we dont shift by a value higher than 62");
1793
102
    int64_t Val = Memory.OffsetImm->getValue();
1794
102
1795
102
    // The value must be a multiple of (1 << shift)
1796
102
    if ((Val & ((1U << shift) - 1)) != 0)
1797
8
      return false;
1798
94
1799
94
    // And be in the right range, depending on the amount that it is shifted
1800
94
    // by.  Shift 0, is equal to 7 unsigned bits, the sign bit is set
1801
94
    // separately.
1802
94
    int64_t Range = (1U << (7+shift)) - 1;
1803
94
    return (Val == INT32_MIN) || (Val > -Range && Val < Range);
1804
94
  }
1805
1806
74
  bool isMemPosImm8Offset() const {
1807
74
    if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1808
0
      return false;
1809
74
    // Immediate offset in range [0, 255].
1810
74
    if (!Memory.OffsetImm) 
return true44
;
1811
30
    int64_t Val = Memory.OffsetImm->getValue();
1812
30
    return Val >= 0 && Val < 256;
1813
30
  }
1814
1815
1.17k
  bool isMemNegImm8Offset() const {
1816
1.17k
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0664
||
Memory.Alignment != 0513
)
1817
661
      return false;
1818
513
    // Base reg of PC isn't allowed for these encodings.
1819
513
    if (Memory.BaseRegNum == ARM::PC) 
return false60
;
1820
453
    // Immediate offset in range [-255, -1].
1821
453
    if (!Memory.OffsetImm) 
return false150
;
1822
303
    int64_t Val = Memory.OffsetImm->getValue();
1823
303
    return (Val == std::numeric_limits<int32_t>::min()) ||
1824
303
           
(294
Val > -256294
&&
Val < 0294
);
1825
303
  }
1826
1827
1.44k
  bool isMemUImm12Offset() const {
1828
1.44k
    if (!isGPRMem() || 
Memory.OffsetRegNum != 01.09k
||
Memory.Alignment != 0724
)
1829
725
      return false;
1830
724
    // Immediate offset in range [0, 4095].
1831
724
    if (!Memory.OffsetImm) 
return true271
;
1832
453
    int64_t Val = Memory.OffsetImm->getValue();
1833
453
    return (Val >= 0 && 
Val < 4096308
);
1834
453
  }
1835
1836
993
  bool isMemImm12Offset() const {
1837
993
    // If we have an immediate that's not a constant, treat it as a label
1838
993
    // reference needing a fixup. If it is a constant, it's something else
1839
993
    // and we reject it.
1840
993
1841
993
    if (isImm() && 
!isa<MCConstantExpr>(getImm())14
)
1842
14
      return true;
1843
979
1844
979
    if (!isGPRMem() || 
Memory.OffsetRegNum != 0546
||
Memory.Alignment != 0431
)
1845
548
      return false;
1846
431
    // Immediate offset in range [-4095, 4095].
1847
431
    if (!Memory.OffsetImm) 
return true161
;
1848
270
    int64_t Val = Memory.OffsetImm->getValue();
1849
270
    return (Val > -4096 && 
Val < 4096258
) ||
1850
270
           
(Val == std::numeric_limits<int32_t>::min())12
;
1851
270
  }
1852
1853
1.29k
  bool isConstPoolAsmImm() const {
1854
1.29k
    // Delay processing of Constant Pool Immediate, this will turn into
1855
1.29k
    // a constant. Match no other operand
1856
1.29k
    return (isConstantPoolImm());
1857
1.29k
  }
1858
1859
19
  bool isPostIdxImm8() const {
1860
19
    if (!isImm()) 
return false3
;
1861
16
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1862
16
    if (!CE) 
return false0
;
1863
16
    int64_t Val = CE->getValue();
1864
16
    return (Val > -256 && 
Val < 25614
) ||
1865
16
           
(Val == std::numeric_limits<int32_t>::min())2
;
1866
16
  }
1867
1868
352
  bool isPostIdxImm8s4() const {
1869
352
    if (!isImm()) 
return false0
;
1870
352
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1871
352
    if (!CE) 
return false0
;
1872
352
    int64_t Val = CE->getValue();
1873
352
    return ((Val & 3) == 0 && Val >= -1020 && 
Val <= 1020224
) ||
1874
352
           
(Val == std::numeric_limits<int32_t>::min())128
;
1875
352
  }
1876
1877
625
  bool isMSRMask() const { return Kind == k_MSRMask; }
1878
670
  bool isBankedReg() const { return Kind == k_BankedReg; }
1879
154
  bool isProcIFlags() const { return Kind == k_ProcIFlags; }
1880
1881
  // NEON operands.
1882
52.4k
  bool isSingleSpacedVectorList() const {
1883
52.4k
    return Kind == k_VectorList && 
!VectorList.isDoubleSpaced33.1k
;
1884
52.4k
  }
1885
1886
8.31k
  bool isDoubleSpacedVectorList() const {
1887
8.31k
    return Kind == k_VectorList && 
VectorList.isDoubleSpaced3.34k
;
1888
8.31k
  }
1889
1890
8.19k
  bool isVecListOneD() const {
1891
8.19k
    if (!isSingleSpacedVectorList()) 
return false2.47k
;
1892
5.71k
    return VectorList.Count == 1;
1893
5.71k
  }
1894
1895
171
  bool isVecListTwoMQ() const {
1896
171
    return isSingleSpacedVectorList() && 
VectorList.Count == 2165
&&
1897
171
           ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1898
153
               VectorList.RegNum);
1899
171
  }
1900
1901
12.7k
  bool isVecListDPair() const {
1902
12.7k
    if (!isSingleSpacedVectorList()) 
return false5.24k
;
1903
7.50k
    return (ARMMCRegisterClasses[ARM::DPairRegClassID]
1904
7.50k
              .contains(VectorList.RegNum));
1905
7.50k
  }
1906
1907
12.5k
  bool isVecListThreeD() const {
1908
12.5k
    if (!isSingleSpacedVectorList()) 
return false6.05k
;
1909
6.52k
    return VectorList.Count == 3;
1910
6.52k
  }
1911
1912
16.6k
  bool isVecListFourD() const {
1913
16.6k
    if (!isSingleSpacedVectorList()) 
return false8.61k
;
1914
7.99k
    return VectorList.Count == 4;
1915
7.99k
  }
1916
1917
4.02k
  bool isVecListDPairSpaced() const {
1918
4.02k
    if (Kind != k_VectorList) 
return false2.03k
;
1919
1.99k
    if (isSingleSpacedVectorList()) 
return false1.34k
;
1920
651
    return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
1921
651
              .contains(VectorList.RegNum));
1922
651
  }
1923
1924
4.38k
  bool isVecListThreeQ() const {
1925
4.38k
    if (!isDoubleSpacedVectorList()) 
return false3.39k
;
1926
990
    return VectorList.Count == 3;
1927
990
  }
1928
1929
3.93k
  bool isVecListFourQ() const {
1930
3.93k
    if (!isDoubleSpacedVectorList()) 
return false3.08k
;
1931
846
    return VectorList.Count == 4;
1932
846
  }
1933
1934
147
  bool isVecListFourMQ() const {
1935
147
    return isSingleSpacedVectorList() && 
VectorList.Count == 4141
&&
1936
147
           ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1937
123
               VectorList.RegNum);
1938
147
  }
1939
1940
15.8k
  bool isSingleSpacedVectorAllLanes() const {
1941
15.8k
    return Kind == k_VectorListAllLanes && 
!VectorList.isDoubleSpaced4.51k
;
1942
15.8k
  }
1943
1944
7.77k
  bool isDoubleSpacedVectorAllLanes() const {
1945
7.77k
    return Kind == k_VectorListAllLanes && 
VectorList.isDoubleSpaced2.65k
;
1946
7.77k
  }
1947
1948
3.75k
  bool isVecListOneDAllLanes() const {
1949
3.75k
    if (!isSingleSpacedVectorAllLanes()) 
return false2.89k
;
1950
858
    return VectorList.Count == 1;
1951
858
  }
1952
1953
6.76k
  bool isVecListDPairAllLanes() const {
1954
6.76k
    if (!isSingleSpacedVectorAllLanes()) 
return false5.45k
;
1955
1.31k
    return (ARMMCRegisterClasses[ARM::DPairRegClassID]
1956
1.31k
              .contains(VectorList.RegNum));
1957
1.31k
  }
1958
1959
2.74k
  bool isVecListDPairSpacedAllLanes() const {
1960
2.74k
    if (!isDoubleSpacedVectorAllLanes()) 
return false2.31k
;
1961
429
    return VectorList.Count == 2;
1962
429
  }
1963
1964
2.81k
  bool isVecListThreeDAllLanes() const {
1965
2.81k
    if (!isSingleSpacedVectorAllLanes()) 
return false2.31k
;
1966
495
    return VectorList.Count == 3;
1967
495
  }
1968
1969
2.70k
  bool isVecListThreeQAllLanes() const {
1970
2.70k
    if (!isDoubleSpacedVectorAllLanes()) 
return false2.20k
;
1971
495
    return VectorList.Count == 3;
1972
495
  }
1973
1974
2.50k
  bool isVecListFourDAllLanes() const {
1975
2.50k
    if (!isSingleSpacedVectorAllLanes()) 
return false2.06k
;
1976
447
    return VectorList.Count == 4;
1977
447
  }
1978
1979
2.32k
  bool isVecListFourQAllLanes() const {
1980
2.32k
    if (!isDoubleSpacedVectorAllLanes()) 
return false1.88k
;
1981
447
    return VectorList.Count == 4;
1982
447
  }
1983
1984
18.5k
  bool isSingleSpacedVectorIndexed() const {
1985
18.5k
    return Kind == k_VectorListIndexed && 
!VectorList.isDoubleSpaced5.61k
;
1986
18.5k
  }
1987
1988
8.44k
  bool isDoubleSpacedVectorIndexed() const {
1989
8.44k
    return Kind == k_VectorListIndexed && 
VectorList.isDoubleSpaced3.07k
;
1990
8.44k
  }
1991
1992
1.75k
  bool isVecListOneDByteIndexed() const {
1993
1.75k
    if (!isSingleSpacedVectorIndexed()) 
return false1.44k
;
1994
313
    return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
1995
313
  }
1996
1997
2.29k
  bool isVecListOneDHWordIndexed() const {
1998
2.29k
    if (!isSingleSpacedVectorIndexed()) 
return false1.91k
;
1999
374
    return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2000
374
  }
2001
2002
2.10k
  bool isVecListOneDWordIndexed() const {
2003
2.10k
    if (!isSingleSpacedVectorIndexed()) 
return false1.75k
;
2004
346
    return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2005
346
  }
2006
2007
1.07k
  bool isVecListTwoDByteIndexed() const {
2008
1.07k
    if (!isSingleSpacedVectorIndexed()) 
return false847
;
2009
232
    return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2010
232
  }
2011
2012
1.46k
  bool isVecListTwoDHWordIndexed() const {
2013
1.46k
    if (!isSingleSpacedVectorIndexed()) 
return false1.19k
;
2014
274
    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2015
274
  }
2016
2017
1.25k
  bool isVecListTwoQWordIndexed() const {
2018
1.25k
    if (!isDoubleSpacedVectorIndexed()) 
return false1.10k
;
2019
150
    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2020
150
  }
2021
2022
1.45k
  bool isVecListTwoQHWordIndexed() const {
2023
1.45k
    if (!isDoubleSpacedVectorIndexed()) 
return false1.27k
;
2024
172
    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2025
172
  }
2026
2027
1.28k
  bool isVecListTwoDWordIndexed() const {
2028
1.28k
    if (!isSingleSpacedVectorIndexed()) 
return false1.02k
;
2029
258
    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2030
258
  }
2031
2032
1.36k
  bool isVecListThreeDByteIndexed() const {
2033
1.36k
    if (!isSingleSpacedVectorIndexed()) 
return false1.05k
;
2034
312
    return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2035
312
  }
2036
2037
1.63k
  bool isVecListThreeDHWordIndexed() const {
2038
1.63k
    if (!isSingleSpacedVectorIndexed()) 
return false1.27k
;
2039
356
    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2040
356
  }
2041
2042
1.43k
  bool isVecListThreeQWordIndexed() const {
2043
1.43k
    if (!isDoubleSpacedVectorIndexed()) 
return false1.21k
;
2044
214
    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2045
214
  }
2046
2047
1.56k
  bool isVecListThreeQHWordIndexed() const {
2048
1.56k
    if (!isDoubleSpacedVectorIndexed()) 
return false1.32k
;
2049
236
    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2050
236
  }
2051
2052
1.50k
  bool isVecListThreeDWordIndexed() const {
2053
1.50k
    if (!isSingleSpacedVectorIndexed()) 
return false1.16k
;
2054
334
    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2055
334
  }
2056
2057
1.13k
  bool isVecListFourDByteIndexed() const {
2058
1.13k
    if (!isSingleSpacedVectorIndexed()) 
return false846
;
2059
288
    return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2060
288
  }
2061
2062
1.59k
  bool isVecListFourDHWordIndexed() const {
2063
1.59k
    if (!isSingleSpacedVectorIndexed()) 
return false1.22k
;
2064
374
    return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2065
374
  }
2066
2067
1.25k
  bool isVecListFourQWordIndexed() const {
2068
1.25k
    if (!isDoubleSpacedVectorIndexed()) 
return false1.02k
;
2069
233
    return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2070
233
  }
2071
2072
1.49k
  bool isVecListFourQHWordIndexed() const {
2073
1.49k
    if (!isDoubleSpacedVectorIndexed()) 
return false1.22k
;
2074
270
    return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2075
270
  }
2076
2077
1.38k
  bool isVecListFourDWordIndexed() const {
2078
1.38k
    if (!isSingleSpacedVectorIndexed()) 
return false1.04k
;
2079
337
    return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2080
337
  }
2081
2082
26.9k
  bool isVectorIndex() const { return Kind == k_VectorIndex; }
2083
2084
  template <unsigned NumLanes>
2085
1.54k
  bool isVectorIndexInRange() const {
2086
1.54k
    if (Kind != k_VectorIndex) 
return false364
;
2087
1.17k
    return VectorIndex.Val < NumLanes;
2088
1.17k
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isVectorIndexInRange<2u>() const
Line
Count
Source
2085
575
  bool isVectorIndexInRange() const {
2086
575
    if (Kind != k_VectorIndex) 
return false139
;
2087
436
    return VectorIndex.Val < NumLanes;
2088
436
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isVectorIndexInRange<1u>() const
Line
Count
Source
2085
154
  bool isVectorIndexInRange() const {
2086
154
    if (Kind != k_VectorIndex) 
return false50
;
2087
104
    return VectorIndex.Val < NumLanes;
2088
104
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isVectorIndexInRange<4u>() const
Line
Count
Source
2085
532
  bool isVectorIndexInRange() const {
2086
532
    if (Kind != k_VectorIndex) 
return false140
;
2087
392
    return VectorIndex.Val < NumLanes;
2088
392
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isVectorIndexInRange<8u>() const
Line
Count
Source
2085
199
  bool isVectorIndexInRange() const {
2086
199
    if (Kind != k_VectorIndex) 
return false26
;
2087
173
    return VectorIndex.Val < NumLanes;
2088
173
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isVectorIndexInRange<16u>() const
Line
Count
Source
2085
83
  bool isVectorIndexInRange() const {
2086
83
    if (Kind != k_VectorIndex) 
return false9
;
2087
74
    return VectorIndex.Val < NumLanes;
2088
74
  }
2089
2090
107
  bool isVectorIndex8()  const { return isVectorIndexInRange<8>(); }
2091
424
  bool isVectorIndex16() const { return isVectorIndexInRange<4>(); }
2092
575
  bool isVectorIndex32() const { return isVectorIndexInRange<2>(); }
2093
154
  bool isVectorIndex64() const { return isVectorIndexInRange<1>(); }
2094
2095
  template<int PermittedValue, int OtherPermittedValue>
2096
136
  bool isMVEPairVectorIndex() const {
2097
136
    if (Kind != k_VectorIndex) 
return false101
;
2098
35
    return VectorIndex.Val == PermittedValue ||
2099
35
           
VectorIndex.Val == OtherPermittedValue22
;
2100
35
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMVEPairVectorIndex<0, 1>() const
Line
Count
Source
2096
12
  bool isMVEPairVectorIndex() const {
2097
12
    if (Kind != k_VectorIndex) 
return false0
;
2098
12
    return VectorIndex.Val == PermittedValue ||
2099
12
           
VectorIndex.Val == OtherPermittedValue8
;
2100
12
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isMVEPairVectorIndex<2, 3>() const
Line
Count
Source
2096
124
  bool isMVEPairVectorIndex() const {
2097
124
    if (Kind != k_VectorIndex) 
return false101
;
2098
23
    return VectorIndex.Val == PermittedValue ||
2099
23
           
VectorIndex.Val == OtherPermittedValue14
;
2100
23
  }
2101
2102
101
  bool isNEONi8splat() const {
2103
101
    if (!isImm()) 
return false80
;
2104
21
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2105
21
    // Must be a constant.
2106
21
    if (!CE) 
return false0
;
2107
21
    int64_t Value = CE->getValue();
2108
21
    // i8 value splatted across 8 bytes. The immediate is just the 8 byte
2109
21
    // value.
2110
21
    return Value >= 0 && 
Value < 25620
;
2111
21
  }
2112
2113
337
  bool isNEONi16splat() const {
2114
337
    if (isNEONByteReplicate(2))
2115
78
      return false; // Leave that for bytes replication and forbid by default.
2116
259
    if (!isImm())
2117
151
      return false;
2118
108
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2119
108
    // Must be a constant.
2120
108
    if (!CE) 
return false0
;
2121
108
    unsigned Value = CE->getValue();
2122
108
    return ARM_AM::isNEONi16splat(Value);
2123
108
  }
2124
2125
64
  bool isNEONi16splatNot() const {
2126
64
    if (!isImm())
2127
42
      return false;
2128
22
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2129
22
    // Must be a constant.
2130
22
    if (!CE) 
return false0
;
2131
22
    unsigned Value = CE->getValue();
2132
22
    return ARM_AM::isNEONi16splat(~Value & 0xffff);
2133
22
  }
2134
2135
97
  bool isNEONi32splat() const {
2136
97
    if (isNEONByteReplicate(4))
2137
16
      return false; // Leave that for bytes replication and forbid by default.
2138
81
    if (!isImm())
2139
46
      return false;
2140
35
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2141
35
    // Must be a constant.
2142
35
    if (!CE) 
return false0
;
2143
35
    unsigned Value = CE->getValue();
2144
35
    return ARM_AM::isNEONi32splat(Value);
2145
35
  }
2146
2147
70
  bool isNEONi32splatNot() const {
2148
70
    if (!isImm())
2149
42
      return false;
2150
28
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2151
28
    // Must be a constant.
2152
28
    if (!CE) 
return false0
;
2153
28
    unsigned Value = CE->getValue();
2154
28
    return ARM_AM::isNEONi32splat(~Value);
2155
28
  }
2156
2157
350
  static bool isValidNEONi32vmovImm(int64_t Value) {
2158
350
    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
2159
350
    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
2160
350
    return ((Value & 0xffffffffffffff00) == 0) ||
2161
350
           
((Value & 0xffffffffffff00ff) == 0)305
||
2162
350
           
((Value & 0xffffffffff00ffff) == 0)287
||
2163
350
           
((Value & 0xffffffff00ffffff) == 0)273
||
2164
350
           
((Value & 0xffffffffffff00ff) == 0xff)237
||
2165
350
           
((Value & 0xffffffffff00ffff) == 0xffff)221
;
2166
350
  }
2167
2168
1.82k
  bool isNEONReplicate(unsigned Width, unsigned NumElems, bool Inv) const {
2169
1.82k
    assert((Width == 8 || Width == 16 || Width == 32) &&
2170
1.82k
           "Invalid element width");
2171
1.82k
    assert(NumElems * Width <= 64 && "Invalid result width");
2172
1.82k
2173
1.82k
    if (!isImm())
2174
811
      return false;
2175
1.01k
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2176
1.01k
    // Must be a constant.
2177
1.01k
    if (!CE)
2178
0
      return false;
2179
1.01k
    int64_t Value = CE->getValue();
2180
1.01k
    if (!Value)
2181
4
      return false; // Don't bother with zero.
2182
1.01k
    if (Inv)
2183
129
      Value = ~Value;
2184
1.01k
2185
1.01k
    uint64_t Mask = (1ull << Width) - 1;
2186
1.01k
    uint64_t Elem = Value & Mask;
2187
1.01k
    if (Width == 16 && 
(Elem & 0x00ff) != 0175
&&
(Elem & 0xff00) != 0122
)
2188
72
      return false;
2189
940
    if (Width == 32 && 
!isValidNEONi32vmovImm(Elem)35
)
2190
16
      return false;
2191
924
2192
1.61k
    
for (unsigned i = 1; 924
i < NumElems;
++i694
) {
2193
1.37k
      Value >>= Width;
2194
1.37k
      if ((Value & Mask) != Elem)
2195
681
        return false;
2196
1.37k
    }
2197
924
    
return true243
;
2198
924
  }
2199
2200
840
  bool isNEONByteReplicate(unsigned NumBytes) const {
2201
840
    return isNEONReplicate(8, NumBytes, false);
2202
840
  }
2203
2204
1.02k
  static void checkNeonReplicateArgs(unsigned FromW, unsigned ToW) {
2205
1.02k
    assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2206
1.02k
           "Invalid source width");
2207
1.02k
    assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2208
1.02k
           "Invalid destination width");
2209
1.02k
    assert(FromW < ToW && "ToW is not less than FromW");
2210
1.02k
  }
2211
2212
  template<unsigned FromW, unsigned ToW>
2213
836
  bool isNEONmovReplicate() const {
2214
836
    checkNeonReplicateArgs(FromW, ToW);
2215
836
    if (ToW == 64 && 
isNEONi64splat()332
)
2216
41
      return false;
2217
795
    return isNEONReplicate(FromW, ToW / FromW, false);
2218
795
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isNEONmovReplicate<8u, 16u>() const
Line
Count
Source
2213
163
  bool isNEONmovReplicate() const {
2214
163
    checkNeonReplicateArgs(FromW, ToW);
2215
163
    if (ToW == 64 && 
isNEONi64splat()0
)
2216
0
      return false;
2217
163
    return isNEONReplicate(FromW, ToW / FromW, false);
2218
163
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isNEONmovReplicate<8u, 32u>() const
Line
Count
Source
2213
136
  bool isNEONmovReplicate() const {
2214
136
    checkNeonReplicateArgs(FromW, ToW);
2215
136
    if (ToW == 64 && 
isNEONi64splat()0
)
2216
0
      return false;
2217
136
    return isNEONReplicate(FromW, ToW / FromW, false);
2218
136
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isNEONmovReplicate<8u, 64u>() const
Line
Count
Source
2213
88
  bool isNEONmovReplicate() const {
2214
88
    checkNeonReplicateArgs(FromW, ToW);
2215
88
    if (ToW == 64 && isNEONi64splat())
2216
13
      return false;
2217
75
    return isNEONReplicate(FromW, ToW / FromW, false);
2218
75
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isNEONmovReplicate<16u, 32u>() const
Line
Count
Source
2213
205
  bool isNEONmovReplicate() const {
2214
205
    checkNeonReplicateArgs(FromW, ToW);
2215
205
    if (ToW == 64 && 
isNEONi64splat()0
)
2216
0
      return false;
2217
205
    return isNEONReplicate(FromW, ToW / FromW, false);
2218
205
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isNEONmovReplicate<16u, 64u>() const
Line
Count
Source
2213
126
  bool isNEONmovReplicate() const {
2214
126
    checkNeonReplicateArgs(FromW, ToW);
2215
126
    if (ToW == 64 && isNEONi64splat())
2216
14
      return false;
2217
112
    return isNEONReplicate(FromW, ToW / FromW, false);
2218
112
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isNEONmovReplicate<32u, 64u>() const
Line
Count
Source
2213
118
  bool isNEONmovReplicate() const {
2214
118
    checkNeonReplicateArgs(FromW, ToW);
2215
118
    if (ToW == 64 && isNEONi64splat())
2216
14
      return false;
2217
104
    return isNEONReplicate(FromW, ToW / FromW, false);
2218
104
  }
2219
2220
  template<unsigned FromW, unsigned ToW>
2221
192
  bool isNEONinvReplicate() const {
2222
192
    checkNeonReplicateArgs(FromW, ToW);
2223
192
    return isNEONReplicate(FromW, ToW / FromW, true);
2224
192
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isNEONinvReplicate<8u, 16u>() const
Line
Count
Source
2221
71
  bool isNEONinvReplicate() const {
2222
71
    checkNeonReplicateArgs(FromW, ToW);
2223
71
    return isNEONReplicate(FromW, ToW / FromW, true);
2224
71
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isNEONinvReplicate<8u, 32u>() const
Line
Count
Source
2221
77
  bool isNEONinvReplicate() const {
2222
77
    checkNeonReplicateArgs(FromW, ToW);
2223
77
    return isNEONReplicate(FromW, ToW / FromW, true);
2224
77
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isNEONinvReplicate<8u, 64u>() const
Line
Count
Source
2221
44
  bool isNEONinvReplicate() const {
2222
44
    checkNeonReplicateArgs(FromW, ToW);
2223
44
    return isNEONReplicate(FromW, ToW / FromW, true);
2224
44
  }
2225
2226
406
  bool isNEONi32vmov() const {
2227
406
    if (isNEONByteReplicate(4))
2228
23
      return false; // Let it to be classified as byte-replicate case.
2229
383
    if (!isImm())
2230
156
      return false;
2231
227
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2232
227
    // Must be a constant.
2233
227
    if (!CE)
2234
0
      return false;
2235
227
    return isValidNEONi32vmovImm(CE->getValue());
2236
227
  }
2237
2238
161
  bool isNEONi32vmovNeg() const {
2239
161
    if (!isImm()) 
return false73
;
2240
88
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2241
88
    // Must be a constant.
2242
88
    if (!CE) 
return false0
;
2243
88
    return isValidNEONi32vmovImm(~CE->getValue());
2244
88
  }
2245
2246
418
  bool isNEONi64splat() const {
2247
418
    if (!isImm()) 
return false234
;
2248
184
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2249
184
    // Must be a constant.
2250
184
    if (!CE) 
return false0
;
2251
184
    uint64_t Value = CE->getValue();
2252
184
    // i64 value with each byte being either 0 or 0xff.
2253
746
    for (unsigned i = 0; i < 8; 
++i, Value >>= 8562
)
2254
691
      if ((Value & 0xff) != 0 && 
(Value & 0xff) != 0xff453
)
return false129
;
2255
184
    
return true55
;
2256
184
  }
2257
2258
  template<int64_t Angle, int64_t Remainder>
2259
931
  bool isComplexRotation() const {
2260
931
    if (!isImm()) 
return false192
;
2261
739
2262
739
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2263
739
    if (!CE) 
return false0
;
2264
739
    uint64_t Value = CE->getValue();
2265
739
2266
739
    return (Value % Angle == Remainder && 
Value <= 270511
);
2267
739
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isComplexRotation<90ll, 0ll>() const
Line
Count
Source
2259
598
  bool isComplexRotation() const {
2260
598
    if (!isImm()) 
return false192
;
2261
406
2262
406
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2263
406
    if (!CE) 
return false0
;
2264
406
    uint64_t Value = CE->getValue();
2265
406
2266
406
    return (Value % Angle == Remainder && 
Value <= 270326
);
2267
406
  }
ARMAsmParser.cpp:bool (anonymous namespace)::ARMOperand::isComplexRotation<180ll, 90ll>() const
Line
Count
Source
2259
333
  bool isComplexRotation() const {
2260
333
    if (!isImm()) 
return false0
;
2261
333
2262
333
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2263
333
    if (!CE) 
return false0
;
2264
333
    uint64_t Value = CE->getValue();
2265
333
2266
333
    return (Value % Angle == Remainder && 
Value <= 270185
);
2267
333
  }
2268
2269
63
  bool isMVELongShift() const {
2270
63
    if (!isImm()) 
return false14
;
2271
49
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2272
49
    // Must be a constant.
2273
49
    if (!CE) 
return false0
;
2274
49
    uint64_t Value = CE->getValue();
2275
49
    return Value >= 1 && Value <= 32;
2276
49
  }
2277
2278
12
  bool isMveSaturateOp() const {
2279
12
    if (!isImm()) 
return false0
;
2280
12
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2281
12
    if (!CE) 
return false0
;
2282
12
    uint64_t Value = CE->getValue();
2283
12
    return Value == 48 || 
Value == 649
;
2284
12
  }
2285
2286
116
  bool isITCondCodeNoAL() const {
2287
116
    if (!isITCondCode()) 
return false9
;
2288
107
    ARMCC::CondCodes CC = getCondCode();
2289
107
    return CC != ARMCC::AL;
2290
107
  }
2291
2292
587
  bool isITCondCodeRestrictedI() const {
2293
587
    if (!isITCondCode())
2294
0
      return false;
2295
587
    ARMCC::CondCodes CC = getCondCode();
2296
587
    return CC == ARMCC::EQ || 
CC == ARMCC::NE408
;
2297
587
  }
2298
2299
910
  bool isITCondCodeRestrictedS() const {
2300
910
    if (!isITCondCode())
2301
0
      return false;
2302
910
    ARMCC::CondCodes CC = getCondCode();
2303
910
    return CC == ARMCC::LT || 
CC == ARMCC::GT820
||
CC == ARMCC::LE748
||
2304
910
           
CC == ARMCC::GE672
;
2305
910
  }
2306
2307
774
  bool isITCondCodeRestrictedU() const {
2308
774
    if (!isITCondCode())
2309
0
      return false;
2310
774
    ARMCC::CondCodes CC = getCondCode();
2311
774
    return CC == ARMCC::HS || 
CC == ARMCC::HI696
;
2312
774
  }
2313
2314
373
  bool isITCondCodeRestrictedFP() const {
2315
373
    if (!isITCondCode())
2316
12
      return false;
2317
361
    ARMCC::CondCodes CC = getCondCode();
2318
361
    return CC == ARMCC::EQ || 
CC == ARMCC::NE275
||
CC == ARMCC::LT226
||
2319
361
           
CC == ARMCC::GT188
||
CC == ARMCC::LE160
||
CC == ARMCC::GE140
;
2320
361
  }
2321
2322
9.75k
  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
2323
9.75k
    // Add as immediates when possible.  Null MCExpr = 0.
2324
9.75k
    if (!Expr)
2325
0
      Inst.addOperand(MCOperand::createImm(0));
2326
9.75k
    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2327
6.99k
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
2328
2.75k
    else
2329
2.75k
      Inst.addOperand(MCOperand::createExpr(Expr));
2330
9.75k
  }
2331
2332
1.21k
  void addARMBranchTargetOperands(MCInst &Inst, unsigned N) const {
2333
1.21k
    assert(N == 1 && "Invalid number of operands!");
2334
1.21k
    addExpr(Inst, getImm());
2335
1.21k
  }
2336
2337
331
  void addThumbBranchTargetOperands(MCInst &Inst, unsigned N) const {
2338
331
    assert(N == 1 && "Invalid number of operands!");
2339
331
    addExpr(Inst, getImm());
2340
331
  }
2341
2342
34.6k
  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
2343
34.6k
    assert(N == 2 && "Invalid number of operands!");
2344
34.6k
    Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
2345
34.6k
    unsigned RegNum = getCondCode() == ARMCC::AL ? 
026.7k
:
ARM::CPSR7.88k
;
2346
34.6k
    Inst.addOperand(MCOperand::createReg(RegNum));
2347
34.6k
  }
2348
2349
1.91k
  void addVPTPredNOperands(MCInst &Inst, unsigned N) const {
2350
1.91k
    assert(N == 2 && "Invalid number of operands!");
2351
1.91k
    Inst.addOperand(MCOperand::createImm(unsigned(getVPTPred())));
2352
1.91k
    unsigned RegNum = getVPTPred() == ARMVCC::None ? 
01.76k
:
ARM::P0149
;
2353
1.91k
    Inst.addOperand(MCOperand::createReg(RegNum));
2354
1.91k
  }
2355
2356
813
  void addVPTPredROperands(MCInst &Inst, unsigned N) const {
2357
813
    assert(N == 3 && "Invalid number of operands!");
2358
813
    addVPTPredNOperands(Inst, N-1);
2359
813
    unsigned RegNum;
2360
813
    if (getVPTPred() == ARMVCC::None) {
2361
738
      RegNum = 0;
2362
738
    } else {
2363
75
      unsigned NextOpIndex = Inst.getNumOperands();
2364
75
      const MCInstrDesc &MCID = ARMInsts[Inst.getOpcode()];
2365
75
      int TiedOp = MCID.getOperandConstraint(NextOpIndex, MCOI::TIED_TO);
2366
75
      assert(TiedOp >= 0 &&
2367
75
             "Inactive register in vpred_r is not tied to an output!");
2368
75
      RegNum = Inst.getOperand(TiedOp).getReg();
2369
75
    }
2370
813
    Inst.addOperand(MCOperand::createReg(RegNum));
2371
813
  }
2372
2373
1.53k
  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
2374
1.53k
    assert(N == 1 && "Invalid number of operands!");
2375
1.53k
    Inst.addOperand(MCOperand::createImm(getCoproc()));
2376
1.53k
  }
2377
2378
1.77k
  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
2379
1.77k
    assert(N == 1 && "Invalid number of operands!");
2380
1.77k
    Inst.addOperand(MCOperand::createImm(getCoproc()));
2381
1.77k
  }
2382
2383
142
  void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
2384
142
    assert(N == 1 && "Invalid number of operands!");
2385
142
    Inst.addOperand(MCOperand::createImm(CoprocOption.Val));
2386
142
  }
2387
2388
7.66k
  void addITMaskOperands(MCInst &Inst, unsigned N) const {
2389
7.66k
    assert(N == 1 && "Invalid number of operands!");
2390
7.66k
    Inst.addOperand(MCOperand::createImm(ITMask.Mask));
2391
7.66k
  }
2392
2393
7.79k
  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
2394
7.79k
    assert(N == 1 && "Invalid number of operands!");
2395
7.79k
    Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
2396
7.79k
  }
2397
2398
26
  void addITCondCodeInvOperands(MCInst &Inst, unsigned N) const {
2399
26
    assert(N == 1 && "Invalid number of operands!");
2400
26
    Inst.addOperand(MCOperand::createImm(unsigned(ARMCC::getOppositeCondition(getCondCode()))));
2401
26
  }
2402
2403
7.30k
  void addCCOutOperands(MCInst &Inst, unsigned N) const {
2404
7.30k
    assert(N == 1 && "Invalid number of operands!");
2405
7.30k
    Inst.addOperand(MCOperand::createReg(getReg()));
2406
7.30k
  }
2407
2408
57.2k
  void addRegOperands(MCInst &Inst, unsigned N) const {
2409
57.2k
    assert(N == 1 && "Invalid number of operands!");
2410
57.2k
    Inst.addOperand(MCOperand::createReg(getReg()));
2411
57.2k
  }
2412
2413
241
  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
2414
241
    assert(N == 3 && "Invalid number of operands!");
2415
241
    assert(isRegShiftedReg() &&
2416
241
           "addRegShiftedRegOperands() on non-RegShiftedReg!");
2417
241
    Inst.addOperand(MCOperand::createReg(RegShiftedReg.SrcReg));
2418
241
    Inst.addOperand(MCOperand::createReg(RegShiftedReg.ShiftReg));
2419
241
    Inst.addOperand(MCOperand::createImm(
2420
241
      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
2421
241
  }
2422
2423
2.30k
  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
2424
2.30k
    assert(N == 2 && "Invalid number of operands!");
2425
2.30k
    assert(isRegShiftedImm() &&
2426
2.30k
           "addRegShiftedImmOperands() on non-RegShiftedImm!");
2427
2.30k
    Inst.addOperand(MCOperand::createReg(RegShiftedImm.SrcReg));
2428
2.30k
    // Shift of #32 is encoded as 0 where permitted
2429
2.30k
    unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 
084
:
RegShiftedImm.ShiftImm2.22k
);
2430
2.30k
    Inst.addOperand(MCOperand::createImm(
2431
2.30k
      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm)));
2432
2.30k
  }
2433
2434
44
  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
2435
44
    assert(N == 1 && "Invalid number of operands!");
2436
44
    Inst.addOperand(MCOperand::createImm((ShifterImm.isASR << 5) |
2437
44
                                         ShifterImm.Imm));
2438
44
  }
2439
2440
1.59k
  void addRegListOperands(MCInst &Inst, unsigned N) const {
2441
1.59k
    assert(N == 1 && "Invalid number of operands!");
2442
1.59k
    const SmallVectorImpl<unsigned> &RegList = getRegList();
2443
1.59k
    for (SmallVectorImpl<unsigned>::const_iterator
2444
8.36k
           I = RegList.begin(), E = RegList.end(); I != E; 
++I6.77k
)
2445
6.77k
      Inst.addOperand(MCOperand::createReg(*I));
2446
1.59k
  }
2447
2448
8
  void addRegListWithAPSROperands(MCInst &Inst, unsigned N) const {
2449
8
    assert(N == 1 && "Invalid number of operands!");
2450
8
    const SmallVectorImpl<unsigned> &RegList = getRegList();
2451
8
    for (SmallVectorImpl<unsigned>::const_iterator
2452
56
           I = RegList.begin(), E = RegList.end(); I != E; 
++I48
)
2453
48
      Inst.addOperand(MCOperand::createReg(*I));
2454
8
  }
2455
2456
159
  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
2457
159
    addRegListOperands(Inst, N);
2458
159
  }
2459
2460
72
  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
2461
72
    addRegListOperands(Inst, N);
2462
72
  }
2463
2464
10
  void addFPSRegListWithVPROperands(MCInst &Inst, unsigned N) const {
2465
10
    addRegListOperands(Inst, N);
2466
10
  }
2467
2468
4
  void addFPDRegListWithVPROperands(MCInst &Inst, unsigned N) const {
2469
4
    addRegListOperands(Inst, N);
2470
4
  }
2471
2472
330
  void addRotImmOperands(MCInst &Inst, unsigned N) const {
2473
330
    assert(N == 1 && "Invalid number of operands!");
2474
330
    // Encoded as val>>3. The printer handles display as 8, 16, 24.
2475
330
    Inst.addOperand(MCOperand::createImm(RotImm.Imm >> 3));
2476
330
  }
2477
2478
1.11k
  void addModImmOperands(MCInst &Inst, unsigned N) const {
2479
1.11k
    assert(N == 1 && "Invalid number of operands!");
2480
1.11k
2481
1.11k
    // Support for fixups (MCFixup)
2482
1.11k
    if (isImm())
2483
11
      return addImmOperands(Inst, N);
2484
1.10k
2485
1.10k
    Inst.addOperand(MCOperand::createImm(ModImm.Bits | (ModImm.Rot << 7)));
2486
1.10k
  }
2487
2488
49
  void addModImmNotOperands(MCInst &Inst, unsigned N) const {
2489
49
    assert(N == 1 && "Invalid number of operands!");
2490
49
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2491
49
    uint32_t Enc = ARM_AM::getSOImmVal(~CE->getValue());
2492
49
    Inst.addOperand(MCOperand::createImm(Enc));
2493
49
  }
2494
2495
36
  void addModImmNegOperands(MCInst &Inst, unsigned N) const {
2496
36
    assert(N == 1 && "Invalid number of operands!");
2497
36
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2498
36
    uint32_t Enc = ARM_AM::getSOImmVal(-CE->getValue());
2499
36
    Inst.addOperand(MCOperand::createImm(Enc));
2500
36
  }
2501
2502
4
  void addThumbModImmNeg8_255Operands(MCInst &Inst, unsigned N) const {
2503
4
    assert(N == 1 && "Invalid number of operands!");
2504
4
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2505
4
    uint32_t Val = -CE->getValue();
2506
4
    Inst.addOperand(MCOperand::createImm(Val));
2507
4
  }
2508
2509
4
  void addThumbModImmNeg1_7Operands(MCInst &Inst, unsigned N) const {
2510
4
    assert(N == 1 && "Invalid number of operands!");
2511
4
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2512
4
    uint32_t Val = -CE->getValue();
2513
4
    Inst.addOperand(MCOperand::createImm(Val));
2514
4
  }
2515
2516
45
  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
2517
45
    assert(N == 1 && "Invalid number of operands!");
2518
45
    // Munge the lsb/width into a bitfield mask.
2519
45
    unsigned lsb = Bitfield.LSB;
2520
45
    unsigned width = Bitfield.Width;
2521
45
    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
2522
45
    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
2523
45
                      (32 - (lsb + width)));
2524
45
    Inst.addOperand(MCOperand::createImm(Mask));
2525
45
  }
2526
2527
7.64k
  void addImmOperands(MCInst &Inst, unsigned N) const {
2528
7.64k
    assert(N == 1 && "Invalid number of operands!");
2529
7.64k
    addExpr(Inst, getImm());
2530
7.64k
  }
2531
2532
36
  void addFBits16Operands(MCInst &Inst, unsigned N) const {
2533
36
    assert(N == 1 && "Invalid number of operands!");
2534
36
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2535
36
    Inst.addOperand(MCOperand::createImm(16 - CE->getValue()));
2536
36
  }
2537
2538
36
  void addFBits32Operands(MCInst &Inst, unsigned N) const {
2539
36
    assert(N == 1 && "Invalid number of operands!");
2540
36
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2541
36
    Inst.addOperand(MCOperand::createImm(32 - CE->getValue()));
2542
36
  }
2543
2544
45
  void addFPImmOperands(MCInst &Inst, unsigned N) const {
2545
45
    assert(N == 1 && "Invalid number of operands!");
2546
45
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2547
45
    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
2548
45
    Inst.addOperand(MCOperand::createImm(Val));
2549
45
  }
2550
2551
0
  void addImm8s4Operands(MCInst &Inst, unsigned N) const {
2552
0
    assert(N == 1 && "Invalid number of operands!");
2553
0
    // FIXME: We really want to scale the value here, but the LDRD/STRD
2554
0
    // instruction don't encode operands that way yet.
2555
0
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2556
0
    Inst.addOperand(MCOperand::createImm(CE->getValue()));
2557
0
  }
2558
2559
90
  void addImm7s4Operands(MCInst &Inst, unsigned N) const {
2560
90
    assert(N == 1 && "Invalid number of operands!");
2561
90
    // FIXME: We really want to scale the value here, but the VSTR/VLDR_VSYSR
2562
90
    // instruction don't encode operands that way yet.
2563
90
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2564
90
    Inst.addOperand(MCOperand::createImm(CE->getValue()));
2565
90
  }
2566
2567
16
  void addImm7Shift0Operands(MCInst &Inst, unsigned N) const {
2568
16
    assert(N == 1 && "Invalid number of operands!");
2569
16
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2570
16
    assert(CE != nullptr && "Invalid operand type!");
2571
16
    Inst.addOperand(MCOperand::createImm(CE->getValue()));
2572
16
  }
2573
2574
12
  void addImm7Shift1Operands(MCInst &Inst, unsigned N) const {
2575
12
    assert(N == 1 && "Invalid number of operands!");
2576
12
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2577
12
    assert(CE != nullptr && "Invalid operand type!");
2578
12
    Inst.addOperand(MCOperand::createImm(CE->getValue()));
2579
12
  }
2580
2581
4
  void addImm7Shift2Operands(MCInst &Inst, unsigned N) const {
2582
4
    assert(N == 1 && "Invalid number of operands!");
2583
4
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2584
4
    assert(CE != nullptr && "Invalid operand type!");
2585
4
    Inst.addOperand(MCOperand::createImm(CE->getValue()));
2586
4
  }
2587
2588
0
  void addImm7Operands(MCInst &Inst, unsigned N) const {
2589
0
    assert(N == 1 && "Invalid number of operands!");
2590
0
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2591
0
    assert(CE != nullptr && "Invalid operand type!");
2592
0
    Inst.addOperand(MCOperand::createImm(CE->getValue()));
2593
0
  }
2594
2595
41
  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
2596
41
    assert(N == 1 && "Invalid number of operands!");
2597
41
    // The immediate is scaled by four in the encoding and is stored
2598
41
    // in the MCInst as such. Lop off the low two bits here.
2599
41
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2600
41
    Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
2601
41
  }
2602
2603
6
  void addImm0_508s4NegOperands(MCInst &Inst, unsigned N) const {
2604
6
    assert(N == 1 && "Invalid number of operands!");
2605
6
    // The immediate is scaled by four in the encoding and is stored
2606
6
    // in the MCInst as such. Lop off the low two bits here.
2607
6
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2608
6
    Inst.addOperand(MCOperand::createImm(-(CE->getValue() / 4)));
2609
6
  }
2610
2611
51
  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
2612
51
    assert(N == 1 && "Invalid number of operands!");
2613
51
    // The immediate is scaled by four in the encoding and is stored
2614
51
    // in the MCInst as such. Lop off the low two bits here.
2615
51
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2616
51
    Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
2617
51
  }
2618
2619
18
  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
2620
18
    assert(N == 1 && "Invalid number of operands!");
2621
18
    // The constant encodes as the immediate-1, and we store in the instruction
2622
18
    // the bits as encoded, so subtract off one here.
2623
18
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2624
18
    Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
2625
18
  }
2626
2627
156
  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
2628
156
    assert(N == 1 && "Invalid number of operands!");
2629
156
    // The constant encodes as the immediate-1, and we store in the instruction
2630
156
    // the bits as encoded, so subtract off one here.
2631
156
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2632
156
    Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
2633
156
  }
2634
2635
0
  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
2636
0
    assert(N == 1 && "Invalid number of operands!");
2637
0
    // The constant encodes as the immediate, except for 32, which encodes as
2638
0
    // zero.
2639
0
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2640
0
    unsigned Imm = CE->getValue();
2641
0
    Inst.addOperand(MCOperand::createImm((Imm == 32 ? 0 : Imm)));
2642
0
  }
2643
2644
12
  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
2645
12
    assert(N == 1 && "Invalid number of operands!");
2646
12
    // An ASR value of 32 encodes as 0, so that's how we want to add it to
2647
12
    // the instruction as well.
2648
12
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2649
12
    int Val = CE->getValue();
2650
12
    Inst.addOperand(MCOperand::createImm(Val == 32 ? 
00
: Val));
2651
12
  }
2652
2653
69
  void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
2654
69
    assert(N == 1 && "Invalid number of operands!");
2655
69
    // The operand is actually a t2_so_imm, but we have its bitwise
2656
69
    // negation in the assembly source, so twiddle it here.
2657
69
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2658
69
    Inst.addOperand(MCOperand::createImm(~(uint32_t)CE->getValue()));
2659
69
  }
2660
2661
67
  void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
2662
67
    assert(N == 1 && "Invalid number of operands!");
2663
67
    // The operand is actually a t2_so_imm, but we have its
2664
67
    // negation in the assembly source, so twiddle it here.
2665
67
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2666
67
    Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
2667
67
  }
2668
2669
18
  void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const {
2670
18
    assert(N == 1 && "Invalid number of operands!");
2671
18
    // The operand is actually an imm0_4095, but we have its
2672
18
    // negation in the assembly source, so twiddle it here.
2673
18
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2674
18
    Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
2675
18
  }
2676
2677
31
  void addUnsignedOffset_b8s2Operands(MCInst &Inst, unsigned N) const {
2678
31
    if(const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
2679
10
      Inst.addOperand(MCOperand::createImm(CE->getValue() >> 2));
2680
10
      return;
2681
10
    }
2682
21
2683
21
    const MCSymbolRefExpr *SR = dyn_cast<MCSymbolRefExpr>(Imm.Val);
2684
21
    assert(SR && "Unknown value type!");
2685
21
    Inst.addOperand(MCOperand::createExpr(SR));
2686
21
  }
2687
2688
50
  void addThumbMemPCOperands(MCInst &Inst, unsigned N) const {
2689
50
    assert(N == 1 && "Invalid number of operands!");
2690
50
    if (isImm()) {
2691
38
      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2692
38
      if (CE) {
2693
6
        Inst.addOperand(MCOperand::createImm(CE->getValue()));
2694
6
        return;
2695
6
      }
2696
32
2697
32
      const MCSymbolRefExpr *SR = dyn_cast<MCSymbolRefExpr>(Imm.Val);
2698
32
2699
32
      assert(SR && "Unknown value type!");
2700
32
      Inst.addOperand(MCOperand::createExpr(SR));
2701
32
      return;
2702
32
    }
2703
12
2704
12
    assert(isGPRMem()  && "Unknown value type!");
2705
12
    assert(isa<MCConstantExpr>(Memory.OffsetImm) && "Unknown value type!");
2706
12
    Inst.addOperand(MCOperand::createImm(Memory.OffsetImm->getValue()));
2707
12
  }
2708
2709
256
  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
2710
256
    assert(N == 1 && "Invalid number of operands!");
2711
256
    Inst.addOperand(MCOperand::createImm(unsigned(getMemBarrierOpt())));
2712
256
  }
2713
2714
18
  void addInstSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
2715
18
    assert(N == 1 && "Invalid number of operands!");
2716
18
    Inst.addOperand(MCOperand::createImm(unsigned(getInstSyncBarrierOpt())));
2717
18
  }
2718
2719
2
  void addTraceSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
2720
2
    assert(N == 1 && "Invalid number of operands!");
2721
2
    Inst.addOperand(MCOperand::createImm(unsigned(getTraceSyncBarrierOpt())));
2722
2
  }
2723
2724
1.26k
  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
2725
1.26k
    assert(N == 1 && "Invalid number of operands!");
2726
1.26k
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2727
1.26k
  }
2728
2729
131
  void addMemNoOffsetT2Operands(MCInst &Inst, unsigned N) const {
2730
131
    assert(N == 1 && "Invalid number of operands!");
2731
131
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2732
131
  }
2733
2734
40
  void addMemNoOffsetT2NoSpOperands(MCInst &Inst, unsigned N) const {
2735
40
    assert(N == 1 && "Invalid number of operands!");
2736
40
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2737
40
  }
2738
2739
18
  void addMemNoOffsetTOperands(MCInst &Inst, unsigned N) const {
2740
18
    assert(N == 1 && "Invalid number of operands!");
2741
18
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2742
18
  }
2743
2744
53
  void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
2745
53
    assert(N == 1 && "Invalid number of operands!");
2746
53
    int32_t Imm = Memory.OffsetImm->getValue();
2747
53
    Inst.addOperand(MCOperand::createImm(Imm));
2748
53
  }
2749
2750
26
  void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
2751
26
    assert(N == 1 && "Invalid number of operands!");
2752
26
    assert(isImm() && "Not an immediate!");
2753
26
2754
26
    // If we have an immediate that's not a constant, treat it as a label
2755
26
    // reference needing a fixup.
2756
26
    if (!isa<MCConstantExpr>(getImm())) {
2757
12
      Inst.addOperand(MCOperand::createExpr(getImm()));
2758
12
      return;
2759
12
    }
2760
14
2761
14
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2762
14
    int Val = CE->getValue();
2763
14
    Inst.addOperand(MCOperand::createImm(Val));
2764
14
  }
2765
2766
1.38k
  void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
2767
1.38k
    assert(N == 2 && "Invalid number of operands!");
2768
1.38k
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2769
1.38k
    Inst.addOperand(MCOperand::createImm(Memory.Alignment));
2770
1.38k
  }
2771
2772
48
  void addDupAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
2773
48
    addAlignedMemoryOperands(Inst, N);
2774
48
  }
2775
2776
80
  void addAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
2777
80
    addAlignedMemoryOperands(Inst, N);
2778
80
  }
2779
2780
38
  void addAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
2781
38
    addAlignedMemoryOperands(Inst, N);
2782
38
  }
2783
2784
24
  void addDupAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
2785
24
    addAlignedMemoryOperands(Inst, N);
2786
24
  }
2787
2788
66
  void addAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
2789
66
    addAlignedMemoryOperands(Inst, N);
2790
66
  }
2791
2792
42
  void addDupAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
2793
42
    addAlignedMemoryOperands(Inst, N);
2794
42
  }
2795
2796
346
  void addAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
2797
346
    addAlignedMemoryOperands(Inst, N);
2798
346
  }
2799
2800
36
  void addDupAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
2801
36
    addAlignedMemoryOperands(Inst, N);
2802
36
  }
2803
2804
290
  void addAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
2805
290
    addAlignedMemoryOperands(Inst, N);
2806
290
  }
2807
2808
24
  void addDupAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
2809
24
    addAlignedMemoryOperands(Inst, N);
2810
24
  }
2811
2812
393
  void addAlignedMemory64or128or256Operands(MCInst &Inst, unsigned N) const {
2813
393
    addAlignedMemoryOperands(Inst, N);
2814
393
  }
2815
2816
0
  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
2817
0
    assert(N == 3 && "Invalid number of operands!");
2818
0
    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
2819
0
    if (!Memory.OffsetRegNum) {
2820
0
      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
2821
0
      // Special case for #-0
2822
0
      if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2823
0
      if (Val < 0) Val = -Val;
2824
0
      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
2825
0
    } else {
2826
0
      // For register offset, we encode the shift type and negation flag
2827
0
      // here.
2828
0
      Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
2829
0
                              Memory.ShiftImm, Memory.ShiftType);
2830
0
    }
2831
0
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2832
0
    Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
2833
0
    Inst.addOperand(MCOperand::createImm(Val));
2834
0
  }
2835
2836
43
  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
2837
43
    assert(N == 2 && "Invalid number of operands!");
2838
43
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2839
43
    assert(CE && "non-constant AM2OffsetImm operand!");
2840
43
    int32_t Val = CE->getValue();
2841
43
    ARM_AM::AddrOpc AddSub = Val < 0 ? 
ARM_AM::sub12
:
ARM_AM::add31
;
2842
43
    // Special case for #-0
2843
43
    if (Val == std::numeric_limits<int32_t>::min()) 
Val = 02
;
2844
43
    if (Val < 0) 
Val = -Val10
;
2845
43
    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
2846
43
    Inst.addOperand(MCOperand::createReg(0));
2847
43
    Inst.addOperand(MCOperand::createImm(Val));
2848
43
  }
2849
2850
147
  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
2851
147
    assert(N == 3 && "Invalid number of operands!");
2852
147
    // If we have an immediate that's not a constant, treat it as a label
2853
147
    // reference needing a fixup. If it is a constant, it's something else
2854
147
    // and we reject it.
2855
147
    if (isImm()) {
2856
2
      Inst.addOperand(MCOperand::createExpr(getImm()));
2857
2
      Inst.addOperand(MCOperand::createReg(0));
2858
2
      Inst.addOperand(MCOperand::createImm(0));
2859
2
      return;
2860
2
    }
2861
145
2862
145
    int32_t Val = Memory.OffsetImm ? 
Memory.OffsetImm->getValue()82
:
063
;
2863
145
    if (!Memory.OffsetRegNum) {
2864
110
      ARM_AM::AddrOpc AddSub = Val < 0 ? 
ARM_AM::sub15
:
ARM_AM::add95
;
2865
110
      // Special case for #-0
2866
110
      if (Val == std::numeric_limits<int32_t>::min()) 
Val = 03
;
2867
110
      if (Val < 0) 
Val = -Val12
;
2868
110
      Val = ARM_AM::getAM3Opc(AddSub, Val);
2869
110
    } else {
2870
35
      // For register offset, we encode the shift type and negation flag
2871
35
      // here.
2872
35
      Val = ARM_AM::getAM3Opc(Memory.isNegative ? 
ARM_AM::sub7
:
ARM_AM::add28
, 0);
2873
35
    }
2874
145
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2875
145
    Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
2876
145
    Inst.addOperand(MCOperand::createImm(Val));
2877
145
  }
2878
2879
78
  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
2880
78
    assert(N == 2 && "Invalid number of operands!");
2881
78
    if (Kind == k_PostIndexRegister) {
2882
23
      int32_t Val =
2883
23
        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? 
ARM_AM::add17
:
ARM_AM::sub6
, 0);
2884
23
      Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
2885
23
      Inst.addOperand(MCOperand::createImm(Val));
2886
23
      return;
2887
23
    }
2888
55
2889
55
    // Constant offset.
2890
55
    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
2891
55
    int32_t Val = CE->getValue();
2892
55
    ARM_AM::AddrOpc AddSub = Val < 0 ? 
ARM_AM::sub9
:
ARM_AM::add46
;
2893
55
    // Special case for #-0
2894
55
    if (Val == std::numeric_limits<int32_t>::min()) 
Val = 02
;
2895
55
    if (Val < 0) 
Val = -Val7
;
2896
55
    Val = ARM_AM::getAM3Opc(AddSub, Val);
2897
55
    Inst.addOperand(MCOperand::createReg(0));
2898
55
    Inst.addOperand(MCOperand::createImm(Val));
2899
55
  }
2900
2901
785
  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
2902
785
    assert(N == 2 && "Invalid number of operands!");
2903
785
    // If we have an immediate that's not a constant, treat it as a label
2904
785
    // reference needing a fixup. If it is a constant, it's something else
2905
785
    // and we reject it.
2906
785
    if (isImm()) {
2907
1
      Inst.addOperand(MCOperand::createExpr(getImm()));
2908
1
      Inst.addOperand(MCOperand::createImm(0));
2909
1
      return;
2910
1
    }
2911
784
2912
784
    // The lower two bits are always zero and as such are not encoded.
2913
784
    int32_t Val = Memory.OffsetImm ? 
Memory.OffsetImm->getValue() / 4554
:
0230
;
2914
784
    ARM_AM::AddrOpc AddSub = Val < 0 ? 
ARM_AM::sub362
:
ARM_AM::add422
;
2915
784
    // Special case for #-0
2916
784
    if (Val == std::numeric_limits<int32_t>::min()) 
Val = 00
;
2917
784
    if (Val < 0) 
Val = -Val362
;
2918
784
    Val = ARM_AM::getAM5Opc(AddSub, Val);
2919
784
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2920
784
    Inst.addOperand(MCOperand::createImm(Val));
2921
784
  }
2922
2923
86
  void addAddrMode5FP16Operands(MCInst &Inst, unsigned N) const {
2924
86
    assert(N == 2 && "Invalid number of operands!");
2925
86
    // If we have an immediate that's not a constant, treat it as a label
2926
86
    // reference needing a fixup. If it is a constant, it's something else
2927
86
    // and we reject it.
2928
86
    if (isImm()) {
2929
2
      Inst.addOperand(MCOperand::createExpr(getImm()));
2930
2
      Inst.addOperand(MCOperand::createImm(0));
2931
2
      return;
2932
2
    }
2933
84
2934
84
    // The lower bit is always zero and as such is not encoded.
2935
84
    int32_t Val = Memory.OffsetImm ? 
Memory.OffsetImm->getValue() / 264
:
020
;
2936
84
    ARM_AM::AddrOpc AddSub = Val < 0 ? 
ARM_AM::sub32
:
ARM_AM::add52
;
2937
84
    // Special case for #-0
2938
84
    if (Val == std::numeric_limits<int32_t>::min()) 
Val = 00
;
2939
84
    if (Val < 0) 
Val = -Val32
;
2940
84
    Val = ARM_AM::getAM5FP16Opc(AddSub, Val);
2941
84
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2942
84
    Inst.addOperand(MCOperand::createImm(Val));
2943
84
  }
2944
2945
145
  void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
2946
145
    assert(N == 2 && "Invalid number of operands!");
2947
145
    // If we have an immediate that's not a constant, treat it as a label
2948
145
    // reference needing a fixup. If it is a constant, it's something else
2949
145
    // and we reject it.
2950
145
    if (isImm()) {
2951
2
      Inst.addOperand(MCOperand::createExpr(getImm()));
2952
2
      Inst.addOperand(MCOperand::createImm(0));
2953
2
      return;
2954
2
    }
2955
143
2956
143
    int64_t Val = Memory.OffsetImm ? 
Memory.OffsetImm->getValue()104
:
039
;
2957
143
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2958
143
    Inst.addOperand(MCOperand::createImm(Val));
2959
143
  }
2960
2961
180
  void addMemImm7s4OffsetOperands(MCInst &Inst, unsigned N) const {
2962
180
    assert(N == 2 && "Invalid number of operands!");
2963
180
    // If we have an immediate that's not a constant, treat it as a label
2964
180
    // reference needing a fixup. If it is a constant, it's something else
2965
180
    // and we reject it.
2966
180
    if (isImm()) {
2967
0
      Inst.addOperand(MCOperand::createExpr(getImm()));
2968
0
      Inst.addOperand(MCOperand::createImm(0));
2969
0
      return;
2970
0
    }
2971
180
2972
180
    int64_t Val = Memory.OffsetImm ? 
Memory.OffsetImm->getValue()144
:
036
;
2973
180
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2974
180
    Inst.addOperand(MCOperand::createImm(Val));
2975
180
  }
2976
2977
364
  void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
2978
364
    assert(N == 2 && "Invalid number of operands!");
2979
364
    // The lower two bits are always zero and as such are not encoded.
2980
364
    int32_t Val = Memory.OffsetImm ? 
Memory.OffsetImm->getValue() / 414
:
0350
;
2981
364
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2982
364
    Inst.addOperand(MCOperand::createImm(Val));
2983
364
  }
2984
2985
566
  void addMemImmOffsetOperands(MCInst &Inst, unsigned N) const {
2986
566
    assert(N == 2 && "Invalid number of operands!");
2987
566
    int64_t Val = Memory.OffsetImm ? 
Memory.OffsetImm->getValue()427
:
0139
;
2988
566
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2989
566
    Inst.addOperand(MCOperand::createImm(Val));
2990
566
  }
2991
2992
107
  void addMemRegRQOffsetOperands(MCInst &Inst, unsigned N) const {
2993
107
    assert(N == 2 && "Invalid number of operands!");
2994
107
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2995
107
    Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
2996
107
  }
2997
2998
340
  void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
2999
340
    assert(N == 2 && "Invalid number of operands!");
3000
340
    // If this is an immediate, it's a label reference.
3001
340
    if (isImm()) {
3002
0
      addExpr(Inst, getImm());
3003
0
      Inst.addOperand(MCOperand::createImm(0));
3004
0
      return;
3005
0
    }
3006
340
3007
340
    // Otherwise, it's a normal memory reg+offset.
3008
340
    int64_t Val = Memory.OffsetImm ? 
Memory.OffsetImm->getValue()206
:
0134
;
3009
340
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3010
340
    Inst.addOperand(MCOperand::createImm(Val));
3011
340
  }
3012
3013
230
  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
3014
230
    assert(N == 2 && "Invalid number of operands!");
3015
230
    // If this is an immediate, it's a label reference.
3016
230
    if (isImm()) {
3017
14
      addExpr(Inst, getImm());
3018
14
      Inst.addOperand(MCOperand::createImm(0));
3019
14
      return;
3020
14
    }
3021
216
3022
216
    // Otherwise, it's a normal memory reg+offset.
3023
216
    int64_t Val = Memory.OffsetImm ? 
Memory.OffsetImm->getValue()199
:
017
;
3024
216
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3025
216
    Inst.addOperand(MCOperand::createImm(Val));
3026
216
  }
3027
3028
549
  void addConstPoolAsmImmOperands(MCInst &Inst, unsigned N) const {
3029
549
    assert(N == 1 && "Invalid number of operands!");
3030
549
    // This is container for the immediate that we will create the constant
3031
549
    // pool from
3032
549
    addExpr(Inst, getConstantPoolImm());
3033
549
    return;
3034
549
  }
3035
3036
7
  void addMemTBBOperands(MCInst &Inst, unsigned N) const {
3037
7
    assert(N == 2 && "Invalid number of operands!");
3038
7
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3039
7
    Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3040
7
  }
3041
3042
7
  void addMemTBHOperands(MCInst &Inst, unsigned N) const {
3043
7
    assert(N == 2 && "Invalid number of operands!");
3044
7
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3045
7
    Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3046
7
  }
3047
3048
90
  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3049
90
    assert(N == 3 && "Invalid number of operands!");
3050
90
    unsigned Val =
3051
90
      ARM_AM::getAM2Opc(Memory.isNegative ? 
ARM_AM::sub12
:
ARM_AM::add78
,
3052
90
                        Memory.ShiftImm, Memory.ShiftType);
3053
90
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3054
90
    Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3055
90
    Inst.addOperand(MCOperand::createImm(Val));
3056
90
  }
3057
3058
321
  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3059
321
    assert(N == 3 && "Invalid number of operands!");
3060
321
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3061
321
    Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3062
321
    Inst.addOperand(MCOperand::createImm(Memory.ShiftImm));
3063
321
  }
3064
3065
39
  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
3066
39
    assert(N == 2 && "Invalid number of operands!");
3067
39
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3068
39
    Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3069
39
  }
3070
3071
84
  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
3072
84
    assert(N == 2 && "Invalid number of operands!");
3073
84
    int64_t Val = Memory.OffsetImm ? 
(Memory.OffsetImm->getValue() / 4)25
:
059
;
3074
84
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3075
84
    Inst.addOperand(MCOperand::createImm(Val));
3076
84
  }
3077
3078
30
  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
3079
30
    assert(N == 2 && "Invalid number of operands!");
3080
30
    int64_t Val = Memory.OffsetImm ? 
(Memory.OffsetImm->getValue() / 2)20
:
010
;
3081
30
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3082
30
    Inst.addOperand(MCOperand::createImm(Val));
3083
30
  }
3084
3085
27
  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
3086
27
    assert(N == 2 && "Invalid number of operands!");
3087
27
    int64_t Val = Memory.OffsetImm ? 
(Memory.OffsetImm->getValue())15
:
012
;
3088
27
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3089
27
    Inst.addOperand(MCOperand::createImm(Val));
3090
27
  }
3091
3092
47
  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
3093
47
    assert(N == 2 && "Invalid number of operands!");
3094
47
    int64_t Val = Memory.OffsetImm ? 
(Memory.OffsetImm->getValue() / 4)28
:
019
;
3095
47
    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3096
47
    Inst.addOperand(MCOperand::createImm(Val));
3097
47
  }
3098
3099
16
  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
3100
16
    assert(N == 1 && "Invalid number of operands!");
3101
16
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3102
16
    assert(CE && "non-constant post-idx-imm8 operand!");
3103
16
    int Imm = CE->getValue();
3104
16
    bool isAdd = Imm >= 0;
3105
16
    if (Imm == std::numeric_limits<int32_t>::min()) 
Imm = 02
;
3106
16
    Imm = (Imm < 0 ? 
-Imm4
:
Imm12
) | (int)isAdd << 8;
3107
16
    Inst.addOperand(MCOperand::createImm(Imm));
3108
16
  }
3109
3110
352
  void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
3111
352
    assert(N == 1 && "Invalid number of operands!");
3112
352
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3113
352
    assert(CE && "non-constant post-idx-imm8s4 operand!");
3114
352
    int Imm = CE->getValue();
3115
352
    bool isAdd = Imm >= 0;
3116
352
    if (Imm == std::numeric_limits<int32_t>::min()) 
Imm = 0128
;
3117
352
    // Immediate is scaled by 4.
3118
352
    Imm = ((Imm < 0 ? 
-Imm48
:
Imm304
) / 4) | (int)isAdd << 8;
3119
352
    Inst.addOperand(MCOperand::createImm(Imm));
3120
352
  }
3121
3122
12
  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
3123
12
    assert(N == 2 && "Invalid number of operands!");
3124
12
    Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3125
12
    Inst.addOperand(MCOperand::createImm(PostIdxReg.isAdd));
3126
12
  }
3127
3128
36
  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
3129
36
    assert(N == 2 && "Invalid number of operands!");
3130
36
    Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3131
36
    // The sign, shift type, and shift amount are encoded in a single operand
3132
36
    // using the AM2 encoding helpers.
3133
36
    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? 
ARM_AM::add30
:
ARM_AM::sub6
;
3134
36
    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
3135
36
                                     PostIdxReg.ShiftTy);
3136
36
    Inst.addOperand(MCOperand::createImm(Imm));
3137
36
  }
3138
3139
24
  void addPowerTwoOperands(MCInst &Inst, unsigned N) const {
3140
24
    assert(N == 1 && "Invalid number of operands!");
3141
24
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3142
24
    Inst.addOperand(MCOperand::createImm(CE->getValue()));
3143
24
  }
3144
3145
342
  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
3146
342
    assert(N == 1 && "Invalid number of operands!");
3147
342
    Inst.addOperand(MCOperand::createImm(unsigned(getMSRMask())));
3148
342
  }
3149
3150
198
  void addBankedRegOperands(MCInst &Inst, unsigned N) const {
3151
198
    assert(N == 1 && "Invalid number of operands!");
3152
198
    Inst.addOperand(MCOperand::createImm(unsigned(getBankedReg())));
3153
198
  }
3154
3155
71
  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
3156
71
    assert(N == 1 && "Invalid number of operands!");
3157
71
    Inst.addOperand(MCOperand::createImm(unsigned(getProcIFlags())));
3158
71
  }
3159
3160
1.07k
  void addVecListOperands(MCInst &Inst, unsigned N) const {
3161
1.07k
    assert(N == 1 && "Invalid number of operands!");
3162
1.07k
    Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3163
1.07k
  }
3164
3165
67
  void addMVEVecListOperands(MCInst &Inst, unsigned N) const {
3166
67
    assert(N == 1 && "Invalid number of operands!");
3167
67
3168
67
    // When we come here, the VectorList field will identify a range
3169
67
    // of q-registers by its base register and length, and it will
3170
67
    // have already been error-checked to be the expected length of
3171
67
    // range and contain only q-regs in the range q0-q7. So we can
3172
67
    // count on the base register being in the range q0-q6 (for 2
3173
67
    // regs) or q0-q4 (for 4)
3174
67
    //
3175
67
    // The MVE instructions taking a register range of this kind will
3176
67
    // need an operand in the QQPR or QQQQPR class, representing the
3177
67
    // entire range as a unit. So we must translate into that class,
3178
67
    // by finding the index of the base register in the MQPR reg
3179
67
    // class, and returning the super-register at the corresponding
3180
67
    // index in the target class.
3181
67
3182
67
    const MCRegisterClass *RC_in = &ARMMCRegisterClasses[ARM::MQPRRegClassID];
3183
67
    const MCRegisterClass *RC_out = (VectorList.Count == 2) ?
3184
37
      &ARMMCRegisterClasses[ARM::QQPRRegClassID] :
3185
67
      
&ARMMCRegisterClasses[ARM::QQQQPRRegClassID]30
;
3186
67
3187
67
    unsigned I, E = RC_out->getNumRegs();
3188
148
    for (I = 0; I < E; 
I++81
)
3189
148
      if (RC_in->getRegister(I) == VectorList.RegNum)
3190
67
        break;
3191
67
    assert(I < E && "Invalid vector list start register!");
3192
67
3193
67
    Inst.addOperand(MCOperand::createReg(RC_out->getRegister(I)));
3194
67
  }
3195
3196
327
  void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
3197
327
    assert(N == 2 && "Invalid number of operands!");
3198
327
    Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3199
327
    Inst.addOperand(MCOperand::createImm(VectorList.LaneIndex));
3200
327
  }
3201
3202
22
  void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
3203
22
    assert(N == 1 && "Invalid number of operands!");
3204
22
    Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3205
22
  }
3206
3207
134
  void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
3208
134
    assert(N == 1 && "Invalid number of operands!");
3209
134
    Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3210
134
  }
3211
3212
196
  void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
3213
196
    assert(N == 1 && "Invalid number of operands!");
3214
196
    Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3215
196
  }
3216
3217
40
  void addVectorIndex64Operands(MCInst &Inst, unsigned N) const {
3218
40
    assert(N == 1 && "Invalid number of operands!");
3219
40
    Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3220
40
  }
3221
3222
19
  void addMVEVectorIndexOperands(MCInst &Inst, unsigned N) const {
3223
19
    assert(N == 1 && "Invalid number of operands!");
3224
19
    Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3225
19
  }
3226
3227
24
  void addMVEPairVectorIndexOperands(MCInst &Inst, unsigned N) const {
3228
24
    assert(N == 1 && "Invalid number of operands!");
3229
24
    Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3230
24
  }
3231
3232
5
  void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
3233
5
    assert(N == 1 && "Invalid number of operands!");
3234
5
    // The immediate encodes the type of constant as well as the value.
3235
5
    // Mask in that this is an i8 splat.
3236
5
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3237
5
    Inst.addOperand(MCOperand::createImm(CE->getValue() | 0xe00));
3238
5
  }
3239
3240
17
  void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
3241
17
    assert(N == 1 && "Invalid number of operands!");
3242
17
    // The immediate encodes the type of constant as well as the value.
3243
17
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3244
17
    unsigned Value = CE->getValue();
3245
17
    Value = ARM_AM::encodeNEONi16splat(Value);
3246
17
    Inst.addOperand(MCOperand::createImm(Value));
3247
17
  }
3248
3249
4
  void addNEONi16splatNotOperands(MCInst &Inst, unsigned N) const {
3250
4
    assert(N == 1 && "Invalid number of operands!");
3251
4
    // The immediate encodes the type of constant as well as the value.
3252
4
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3253
4
    unsigned Value = CE->getValue();
3254
4
    Value = ARM_AM::encodeNEONi16splat(~Value & 0xffff);
3255
4
    Inst.addOperand(MCOperand::createImm(Value));
3256
4
  }
3257
3258
11
  void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
3259
11
    assert(N == 1 && "Invalid number of operands!");
3260
11
    // The immediate encodes the type of constant as well as the value.
3261
11
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3262
11
    unsigned Value = CE->getValue();
3263
11
    Value = ARM_AM::encodeNEONi32splat(Value);
3264
11
    Inst.addOperand(MCOperand::createImm(Value));
3265
11
  }
3266
3267
8
  void addNEONi32splatNotOperands(MCInst &Inst, unsigned N) const {
3268
8
    assert(N == 1 && "Invalid number of operands!");
3269
8
    // The immediate encodes the type of constant as well as the value.
3270
8
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3271
8
    unsigned Value = CE->getValue();
3272
8
    Value = ARM_AM::encodeNEONi32splat(~Value);
3273
8
    Inst.addOperand(MCOperand::createImm(Value));
3274
8
  }
3275
3276
18
  void addNEONi8ReplicateOperands(MCInst &Inst, bool Inv) const {
3277
18
    // The immediate encodes the type of constant as well as the value.
3278
18
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3279
18
    assert((Inst.getOpcode() == ARM::VMOVv8i8 ||
3280
18
            Inst.getOpcode() == ARM::VMOVv16i8) &&
3281
18
          "All instructions that wants to replicate non-zero byte "
3282
18
          "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3283
18
    unsigned Value = CE->getValue();
3284
18
    if (Inv)
3285
10
      Value = ~Value;
3286
18
    unsigned B = Value & 0xff;
3287
18
    B |= 0xe00; // cmode = 0b1110
3288
18
    Inst.addOperand(MCOperand::createImm(B));
3289
18
  }
3290
3291
10
  void addNEONinvi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3292
10
    assert(N == 1 && "Invalid number of operands!");
3293
10
    addNEONi8ReplicateOperands(Inst, true);
3294
10
  }
3295
3296
47
  static unsigned encodeNeonVMOVImmediate(unsigned Value) {
3297
47
    if (Value >= 256 && 
Value <= 0xffff36
)
3298
13
      Value = (Value >> 8) | ((Value & 0xff) ? 
0xc007
:
0x2006
);
3299
34
    else if (Value > 0xffff && 
Value <= 0xffffff23
)
3300
16
      Value = (Value >> 16) | ((Value & 0xff) ? 
0xd0010
:
0x4006
);
3301
18
    else if (Value > 0xffffff)
3302
7
      Value = (Value >> 24) | 0x600;
3303
47
    return Value;
3304
47
  }
3305
3306
39
  void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
3307
39
    assert(N == 1 && "Invalid number of operands!");
3308
39
    // The immediate encodes the type of constant as well as the value.
3309
39
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3310
39
    unsigned Value = encodeNeonVMOVImmediate(CE->getValue());
3311
39
    Inst.addOperand(MCOperand::createImm(Value));
3312
39
  }
3313
3314
8
  void addNEONvmovi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3315
8
    assert(N == 1 && "Invalid number of operands!");
3316
8
    addNEONi8ReplicateOperands(Inst, false);
3317
8
  }
3318
3319
16
  void addNEONvmovi16ReplicateOperands(MCInst &Inst, unsigned N) const {
3320
16
    assert(N == 1 && "Invalid number of operands!");
3321
16
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3322
16
    assert((Inst.getOpcode() == ARM::VMOVv4i16 ||
3323
16
            Inst.getOpcode() == ARM::VMOVv8i16 ||
3324
16
            Inst.getOpcode() == ARM::VMVNv4i16 ||
3325
16
            Inst.getOpcode() == ARM::VMVNv8i16) &&
3326
16
          "All instructions that want to replicate non-zero half-word "
3327
16
          "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3328
16
    uint64_t Value = CE->getValue();
3329
16
    unsigned Elem = Value & 0xffff;
3330
16
    if (Elem >= 256)
3331
8
      Elem = (Elem >> 8) | 0x200;
3332
16
    Inst.addOperand(MCOperand::createImm(Elem));
3333
16
  }
3334
3335
0
  void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
3336
0
    assert(N == 1 && "Invalid number of operands!");
3337
0
    // The immediate encodes the type of constant as well as the value.
3338
0
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3339
0
    unsigned Value = encodeNeonVMOVImmediate(~CE->getValue());
3340
0
    Inst.addOperand(MCOperand::createImm(Value));
3341
0
  }
3342
3343
8
  void addNEONvmovi32ReplicateOperands(MCInst &Inst, unsigned N) const {
3344
8
    assert(N == 1 && "Invalid number of operands!");
3345
8
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3346
8
    assert((Inst.getOpcode() == ARM::VMOVv2i32 ||
3347
8
            Inst.getOpcode() == ARM::VMOVv4i32 ||
3348
8
            Inst.getOpcode() == ARM::VMVNv2i32 ||
3349
8
            Inst.getOpcode() == ARM::VMVNv4i32) &&
3350
8
          "All instructions that want to replicate non-zero word "
3351
8
          "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3352
8
    uint64_t Value = CE->getValue();
3353
8
    unsigned Elem = encodeNeonVMOVImmediate(Value & 0xffffffff);
3354
8
    Inst.addOperand(MCOperand::createImm(Elem));
3355
8
  }
3356
3357
9
  void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
3358
9
    assert(N == 1 && "Invalid number of operands!");
3359
9
    // The immediate encodes the type of constant as well as the value.
3360
9
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3361
9
    uint64_t Value = CE->getValue();
3362
9
    unsigned Imm = 0;
3363
81
    for (unsigned i = 0; i < 8; 
++i, Value >>= 872
) {
3364
72
      Imm |= (Value & 1) << i;
3365
72
    }
3366
9
    Inst.addOperand(MCOperand::createImm(Imm | 0x1e00));
3367
9
  }
3368
3369
164
  void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const {
3370
164
    assert(N == 1 && "Invalid number of operands!");
3371
164
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3372
164
    Inst.addOperand(MCOperand::createImm(CE->getValue() / 90));
3373
164
  }
3374
3375
75
  void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const {
3376
75
    assert(N == 1 && "Invalid number of operands!");
3377
75
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3378
75
    Inst.addOperand(MCOperand::createImm((CE->getValue() - 90) / 180));
3379
75
  }
3380
3381
6
  void addMveSaturateOperands(MCInst &Inst, unsigned N) const {
3382
6
    assert(N == 1 && "Invalid number of operands!");
3383
6
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3384
6
    unsigned Imm = CE->getValue();
3385
6
    assert((Imm == 48 || Imm == 64) && "Invalid saturate operand");
3386
6
    Inst.addOperand(MCOperand::createImm(Imm == 48 ? 
13
:
03
));
3387
6
  }
3388
3389
  void print(raw_ostream &OS) const override;
3390
3391
3.89k
  static std::unique_ptr<ARMOperand> CreateITMask(unsigned Mask, SMLoc S) {
3392
3.89k
    auto Op = make_unique<ARMOperand>(k_ITCondMask);
3393
3.89k
    Op->ITMask.Mask = Mask;
3394
3.89k
    Op->StartLoc = S;
3395
3.89k
    Op->EndLoc = S;
3396
3.89k
    return Op;
3397
3.89k
  }
3398
3399
  static std::unique_ptr<ARMOperand> CreateCondCode(ARMCC::CondCodes CC,
3400
36.7k
                                                    SMLoc S) {
3401
36.7k
    auto Op = make_unique<ARMOperand>(k_CondCode);
3402
36.7k
    Op->CC.Val = CC;
3403
36.7k
    Op->StartLoc = S;
3404
36.7k
    Op->EndLoc = S;
3405
36.7k
    return Op;
3406
36.7k
  }
3407
3408
  static std::unique_ptr<ARMOperand> CreateVPTPred(ARMVCC::VPTCodes CC,
3409
2.27k
                                                   SMLoc S) {
3410
2.27k
    auto Op = make_unique<ARMOperand>(k_VPTPred);
3411
2.27k
    Op->VCC.Val = CC;
3412
2.27k
    Op->StartLoc = S;
3413
2.27k
    Op->EndLoc = S;
3414
2.27k
    return Op;
3415
2.27k
  }
3416
3417
984
  static std::unique_ptr<ARMOperand> CreateCoprocNum(unsigned CopVal, SMLoc S) {
3418
984
    auto Op = make_unique<ARMOperand>(k_CoprocNum);
3419
984
    Op->Cop.Val = CopVal;
3420
984
    Op->StartLoc = S;
3421
984
    Op->EndLoc = S;
3422
984
    return Op;
3423
984
  }
3424
3425
1.27k
  static std::unique_ptr<ARMOperand> CreateCoprocReg(unsigned CopVal, SMLoc S) {
3426
1.27k
    auto Op = make_unique<ARMOperand>(k_CoprocReg);
3427
1.27k
    Op->Cop.Val = CopVal;
3428
1.27k
    Op->StartLoc = S;
3429
1.27k
    Op->EndLoc = S;
3430
1.27k
    return Op;
3431
1.27k
  }
3432
3433
  static std::unique_ptr<ARMOperand> CreateCoprocOption(unsigned Val, SMLoc S,
3434
78
                                                        SMLoc E) {
3435
78
    auto Op = make_unique<ARMOperand>(k_CoprocOption);
3436
78
    Op->Cop.Val = Val;
3437
78
    Op->StartLoc = S;
3438
78
    Op->EndLoc = E;
3439
78
    return Op;
3440
78
  }
3441
3442
6.79k
  static std::unique_ptr<ARMOperand> CreateCCOut(unsigned RegNum, SMLoc S) {
3443
6.79k
    auto Op = make_unique<ARMOperand>(k_CCOut);
3444
6.79k
    Op->Reg.RegNum = RegNum;
3445
6.79k
    Op->StartLoc = S;
3446
6.79k
    Op->EndLoc = S;
3447
6.79k
    return Op;
3448
6.79k
  }
3449
3450
57.4k
  static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S) {
3451
57.4k
    auto Op = make_unique<ARMOperand>(k_Token);
3452
57.4k
    Op->Tok.Data = Str.data();
3453
57.4k
    Op->Tok.Length = Str.size();
3454
57.4k
    Op->StartLoc = S;
3455
57.4k
    Op->EndLoc = S;
3456
57.4k
    return Op;
3457
57.4k
  }
3458
3459
  static std::unique_ptr<ARMOperand> CreateReg(unsigned RegNum, SMLoc S,
3460
56.3k
                                               SMLoc E) {
3461
56.3k
    auto Op = make_unique<ARMOperand>(k_Register);
3462
56.3k
    Op->Reg.RegNum = RegNum;
3463
56.3k
    Op->StartLoc = S;
3464
56.3k
    Op->EndLoc = E;
3465
56.3k
    return Op;
3466
56.3k
  }
3467
3468
  static std::unique_ptr<ARMOperand>
3469
  CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, unsigned SrcReg,
3470
                        unsigned ShiftReg, unsigned ShiftImm, SMLoc S,
3471
247
                        SMLoc E) {
3472
247
    auto Op = make_unique<ARMOperand>(k_ShiftedRegister);
3473
247
    Op->RegShiftedReg.ShiftTy = ShTy;
3474
247
    Op->RegShiftedReg.SrcReg = SrcReg;
3475
247
    Op->RegShiftedReg.ShiftReg = ShiftReg;
3476
247
    Op->RegShiftedReg.ShiftImm = ShiftImm;
3477
247
    Op->StartLoc = S;
3478
247
    Op->EndLoc = E;
3479
247
    return Op;
3480
247
  }
3481
3482
  static std::unique_ptr<ARMOperand>
3483
  CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, unsigned SrcReg,
3484
2.02k
                         unsigned ShiftImm, SMLoc S, SMLoc E) {
3485
2.02k
    auto Op = make_unique<ARMOperand>(k_ShiftedImmediate);
3486
2.02k
    Op->RegShiftedImm.ShiftTy = ShTy;
3487
2.02k
    Op->RegShiftedImm.SrcReg = SrcReg;
3488
2.02k
    Op->RegShiftedImm.ShiftImm = ShiftImm;
3489
2.02k
    Op->StartLoc = S;
3490
2.02k
    Op->EndLoc = E;
3491
2.02k
    return Op;
3492
2.02k
  }
3493
3494
  static std::unique_ptr<ARMOperand> CreateShifterImm(bool isASR, unsigned Imm,
3495
32
                                                      SMLoc S, SMLoc E) {
3496
32
    auto Op = make_unique<ARMOperand>(k_ShifterImmediate);
3497
32
    Op->ShifterImm.isASR = isASR;
3498
32
    Op->ShifterImm.Imm = Imm;
3499
32
    Op->StartLoc = S;
3500
32
    Op->EndLoc = E;
3501
32
    return Op;
3502
32
  }
3503
3504
  static std::unique_ptr<ARMOperand> CreateRotImm(unsigned Imm, SMLoc S,
3505
218
                                                  SMLoc E) {
3506
218
    auto Op = make_unique<ARMOperand>(k_RotateImmediate);
3507
218
    Op->RotImm.Imm = Imm;
3508
218
    Op->StartLoc = S;
3509
218
    Op->EndLoc = E;
3510
218
    return Op;
3511
218
  }
3512
3513
  static std::unique_ptr<ARMOperand> CreateModImm(unsigned Bits, unsigned Rot,
3514
1.10k
                                                  SMLoc S, SMLoc E) {
3515
1.10k
    auto Op = make_unique<ARMOperand>(k_ModifiedImmediate);
3516
1.10k
    Op->ModImm.Bits = Bits;
3517
1.10k
    Op->ModImm.Rot = Rot;
3518
1.10k
    Op->StartLoc = S;
3519
1.10k
    Op->EndLoc = E;
3520
1.10k
    return Op;
3521
1.10k
  }
3522
3523
  static std::unique_ptr<ARMOperand>
3524
388
  CreateConstantPoolImm(const MCExpr *Val, SMLoc S, SMLoc E) {
3525
388
    auto Op = make_unique<ARMOperand>(k_ConstantPoolImmediate);
3526
388
    Op->Imm.Val = Val;
3527
388
    Op->StartLoc = S;
3528
388
    Op->EndLoc = E;
3529
388
    return Op;
3530
388
  }
3531
3532
  static std::unique_ptr<ARMOperand>
3533
34
  CreateBitfield(unsigned LSB, unsigned Width, SMLoc S, SMLoc E) {
3534
34
    auto Op = make_unique<ARMOperand>(k_BitfieldDescriptor);
3535
34
    Op->Bitfield.LSB = LSB;
3536
34
    Op->Bitfield.Width = Width;
3537
34
    Op->StartLoc = S;
3538
34
    Op->EndLoc = E;
3539
34
    return Op;
3540
34
  }
3541
3542
  static std::unique_ptr<ARMOperand>
3543
  CreateRegList(SmallVectorImpl<std::pair<unsigned, unsigned>> &Regs,
3544
1.33k
                SMLoc StartLoc, SMLoc EndLoc) {
3545
1.33k
    assert(Regs.size() > 0 && "RegList contains no registers?");
3546
1.33k
    KindTy Kind = k_RegisterList;
3547
1.33k
3548
1.33k
    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(
3549
1.33k
            Regs.front().second)) {
3550
180
      if (Regs.back().second == ARM::VPR)
3551
4
        Kind = k_FPDRegisterListWithVPR;
3552
176
      else
3553
176
        Kind = k_DPRRegisterList;
3554
1.15k
    } else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(
3555
1.15k
                   Regs.front().second)) {
3556
96
      if (Regs.back().second == ARM::VPR)
3557
10
        Kind = k_FPSRegisterListWithVPR;
3558
86
      else
3559
86
        Kind = k_SPRRegisterList;
3560
96
    }
3561
1.33k
3562
1.33k
    // Sort based on the register encoding values.
3563
1.33k
    array_pod_sort(Regs.begin(), Regs.end());
3564
1.33k
3565
1.33k
    if (Kind == k_RegisterList && 
Regs.back().second == ARM::APSR1.05k
)
3566
3
      Kind = k_RegisterListWithAPSR;
3567
1.33k
3568
1.33k
    auto Op = make_unique<ARMOperand>(Kind);
3569
1.33k
    for (SmallVectorImpl<std::pair<unsigned, unsigned>>::const_iterator
3570
7.34k
           I = Regs.begin(), E = Regs.end(); I != E; 
++I6.01k
)
3571
6.01k
      Op->Registers.push_back(I->second);
3572
1.33k
3573
1.33k
    Op->StartLoc = StartLoc;
3574
1.33k
    Op->EndLoc = EndLoc;
3575
1.33k
    return Op;
3576
1.33k
  }
3577
3578
  static std::unique_ptr<ARMOperand> CreateVectorList(unsigned RegNum,
3579
                                                      unsigned Count,
3580
                                                      bool isDoubleSpaced,
3581
1.62k
                                                      SMLoc S, SMLoc E) {
3582
1.62k
    auto Op = make_unique<ARMOperand>(k_VectorList);
3583
1.62k
    Op->VectorList.RegNum = RegNum;
3584
1.62k
    Op->VectorList.Count = Count;
3585
1.62k
    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3586
1.62k
    Op->StartLoc = S;
3587
1.62k
    Op->EndLoc = E;
3588
1.62k
    return Op;
3589
1.62k
  }
3590
3591
  static std::unique_ptr<ARMOperand>
3592
  CreateVectorListAllLanes(unsigned RegNum, unsigned Count, bool isDoubleSpaced,
3593
480
                           SMLoc S, SMLoc E) {
3594
480
    auto Op = make_unique<ARMOperand>(k_VectorListAllLanes);
3595
480
    Op->VectorList.RegNum = RegNum;
3596
480
    Op->VectorList.Count = Count;
3597
480
    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3598
480
    Op->StartLoc = S;
3599
480
    Op->EndLoc = E;
3600
480
    return Op;
3601
480
  }
3602
3603
  static std::unique_ptr<ARMOperand>
3604
  CreateVectorListIndexed(unsigned RegNum, unsigned Count, unsigned Index,
3605
786
                          bool isDoubleSpaced, SMLoc S, SMLoc E) {
3606
786
    auto Op = make_unique<ARMOperand>(k_VectorListIndexed);
3607
786
    Op->VectorList.RegNum = RegNum;
3608
786
    Op->VectorList.Count = Count;
3609
786
    Op->VectorList.LaneIndex = Index;
3610
786
    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3611
786
    Op->StartLoc = S;
3612
786
    Op->EndLoc = E;
3613
786
    return Op;
3614
786
  }
3615
3616
  static std::unique_ptr<ARMOperand>
3617
533
  CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) {
3618
533
    auto Op = make_unique<ARMOperand>(k_VectorIndex);
3619
533
    Op->VectorIndex.Val = Idx;
3620
533
    Op->StartLoc = S;
3621
533
    Op->EndLoc = E;
3622
533
    return Op;
3623
533
  }
3624
3625
  static std::unique_ptr<ARMOperand> CreateImm(const MCExpr *Val, SMLoc S,
3626
10.0k
                                               SMLoc E) {
3627
10.0k
    auto Op = make_unique<ARMOperand>(k_Immediate);
3628
10.0k
    Op->Imm.Val = Val;
3629
10.0k
    Op->StartLoc = S;
3630
10.0k
    Op->EndLoc = E;
3631
10.0k
    return Op;
3632
10.0k
  }
3633
3634
  static std::unique_ptr<ARMOperand>
3635
  CreateMem(unsigned BaseRegNum, const MCConstantExpr *OffsetImm,
3636
            unsigned OffsetRegNum, ARM_AM::ShiftOpc ShiftType,
3637
            unsigned ShiftImm, unsigned Alignment, bool isNegative, SMLoc S,
3638
7.64k
            SMLoc E, SMLoc AlignmentLoc = SMLoc()) {
3639
7.64k
    auto Op = make_unique<ARMOperand>(k_Memory);
3640
7.64k
    Op->Memory.BaseRegNum = BaseRegNum;
3641
7.64k
    Op->Memory.OffsetImm = OffsetImm;
3642
7.64k
    Op->Memory.OffsetRegNum = OffsetRegNum;
3643
7.64k
    Op->Memory.ShiftType = ShiftType;
3644
7.64k
    Op->Memory.ShiftImm = ShiftImm;
3645
7.64k
    Op->Memory.Alignment = Alignment;
3646
7.64k
    Op->Memory.isNegative = isNegative;
3647
7.64k
    Op->StartLoc = S;
3648
7.64k
    Op->EndLoc = E;
3649
7.64k
    Op->AlignmentLoc = AlignmentLoc;
3650
7.64k
    return Op;
3651
7.64k
  }
3652
3653
  static std::unique_ptr<ARMOperand>
3654
  CreatePostIdxReg(unsigned RegNum, bool isAdd, ARM_AM::ShiftOpc ShiftTy,
3655
76
                   unsigned ShiftImm, SMLoc S, SMLoc E) {
3656
76
    auto Op = make_unique<ARMOperand>(k_PostIndexRegister);
3657
76
    Op->PostIdxReg.RegNum = RegNum;
3658
76
    Op->PostIdxReg.isAdd = isAdd;
3659
76
    Op->PostIdxReg.ShiftTy = ShiftTy;
3660
76
    Op->PostIdxReg.ShiftImm = ShiftImm;
3661
76
    Op->StartLoc = S;
3662
76
    Op->EndLoc = E;
3663
76
    return Op;
3664
76
  }
3665
3666
  static std::unique_ptr<ARMOperand> CreateMemBarrierOpt(ARM_MB::MemBOpt Opt,
3667
256
                                                         SMLoc S) {
3668
256
    auto Op = make_unique<ARMOperand>(k_MemBarrierOpt);
3669
256
    Op->MBOpt.Val = Opt;
3670
256
    Op->StartLoc = S;
3671
256
    Op->EndLoc = S;
3672
256
    return Op;
3673
256
  }
3674
3675
  static std::unique_ptr<ARMOperand>
3676
18
  CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt, SMLoc S) {
3677
18
    auto Op = make_unique<ARMOperand>(k_InstSyncBarrierOpt);
3678
18
    Op->ISBOpt.Val = Opt;
3679
18
    Op->StartLoc = S;
3680
18
    Op->EndLoc = S;
3681
18
    return Op;
3682
18
  }
3683
3684
  static std::unique_ptr<ARMOperand>
3685
2
  CreateTraceSyncBarrierOpt(ARM_TSB::TraceSyncBOpt Opt, SMLoc S) {
3686
2
    auto Op = make_unique<ARMOperand>(k_TraceSyncBarrierOpt);
3687
2
    Op->TSBOpt.Val = Opt;
3688
2
    Op->StartLoc = S;
3689
2
    Op->EndLoc = S;
3690
2
    return Op;
3691
2
  }
3692
3693
  static std::unique_ptr<ARMOperand> CreateProcIFlags(ARM_PROC::IFlags IFlags,
3694
44
                                                      SMLoc S) {
3695
44
    auto Op = make_unique<ARMOperand>(k_ProcIFlags);
3696
44
    Op->IFlags.Val = IFlags;
3697
44
    Op->StartLoc = S;
3698
44
    Op->EndLoc = S;
3699
44
    return Op;
3700
44
  }
3701
3702
227
  static std::unique_ptr<ARMOperand> CreateMSRMask(unsigned MMask, SMLoc S) {
3703
227
    auto Op = make_unique<ARMOperand>(k_MSRMask);
3704
227
    Op->MMask.Val = MMask;
3705
227
    Op->StartLoc = S;
3706
227
    Op->EndLoc = S;
3707
227
    return Op;
3708
227
  }
3709
3710
132
  static std::unique_ptr<ARMOperand> CreateBankedReg(unsigned Reg, SMLoc S) {
3711
132
    auto Op = make_unique<ARMOperand>(k_BankedReg);
3712
132
    Op->BankedReg.Val = Reg;
3713
132
    Op->StartLoc = S;
3714
132
    Op->EndLoc = S;
3715
132
    return Op;
3716
132
  }
3717
};
3718
3719
} // end anonymous namespace.
3720
3721
0
void ARMOperand::print(raw_ostream &OS) const {
3722
0
  auto RegName = [](unsigned Reg) {
3723
0
    if (Reg)
3724
0
      return ARMInstPrinter::getRegisterName(Reg);
3725
0
    else
3726
0
      return "noreg";
3727
0
  };
3728
0
3729
0
  switch (Kind) {
3730
0
  case k_CondCode:
3731
0
    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
3732
0
    break;
3733
0
  case k_VPTPred:
3734
0
    OS << "<ARMVCC::" << ARMVPTPredToString(getVPTPred()) << ">";
3735
0
    break;
3736
0
  case k_CCOut:
3737
0
    OS << "<ccout " << RegName(getReg()) << ">";
3738
0
    break;
3739
0
  case k_ITCondMask: {
3740
0
    static const char *const MaskStr[] = {
3741
0
      "(invalid)", "(tttt)", "(ttt)", "(ttte)",
3742
0
      "(tt)",      "(ttet)", "(tte)", "(ttee)",
3743
0
      "(t)",       "(tett)", "(tet)", "(tete)",
3744
0
      "(te)",      "(teet)", "(tee)", "(teee)",
3745
0
    };
3746
0
    assert((ITMask.Mask & 0xf) == ITMask.Mask);
3747
0
    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
3748
0
    break;
3749
0
  }
3750
0
  case k_CoprocNum:
3751
0
    OS << "<coprocessor number: " << getCoproc() << ">";
3752
0
    break;
3753
0
  case k_CoprocReg:
3754
0
    OS << "<coprocessor register: " << getCoproc() << ">";
3755
0
    break;
3756
0
  case k_CoprocOption:
3757
0
    OS << "<coprocessor option: " << CoprocOption.Val << ">";
3758
0
    break;
3759
0
  case k_MSRMask:
3760
0
    OS << "<mask: " << getMSRMask() << ">";
3761
0
    break;
3762
0
  case k_BankedReg:
3763
0
    OS << "<banked reg: " << getBankedReg() << ">";
3764
0
    break;
3765
0
  case k_Immediate:
3766
0
    OS << *getImm();
3767
0
    break;
3768
0
  case k_MemBarrierOpt:
3769
0
    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt(), false) << ">";
3770
0
    break;
3771
0
  case k_InstSyncBarrierOpt:
3772
0
    OS << "<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) << ">";
3773
0
    break;
3774
0
  case k_TraceSyncBarrierOpt:
3775
0
    OS << "<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) << ">";
3776
0
    break;
3777
0
  case k_Memory:
3778
0
    OS << "<memory";
3779
0
    if (Memory.BaseRegNum)
3780
0
      OS << " base:" << RegName(Memory.BaseRegNum);
3781
0
    if (Memory.OffsetImm)
3782
0
      OS << " offset-imm:" << *Memory.OffsetImm;
3783
0
    if (Memory.OffsetRegNum)
3784
0
      OS << " offset-reg:" << (Memory.isNegative ? "-" : "")
3785
0
         << RegName(Memory.OffsetRegNum);
3786
0
    if (Memory.ShiftType != ARM_AM::no_shift) {
3787
0
      OS << " shift-type:" << ARM_AM::getShiftOpcStr(Memory.ShiftType);
3788
0
      OS << " shift-imm:" << Memory.ShiftImm;
3789
0
    }
3790
0
    if (Memory.Alignment)
3791
0
      OS << " alignment:" << Memory.Alignment;
3792
0
    OS << ">";
3793
0
    break;
3794
0
  case k_PostIndexRegister:
3795
0
    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
3796
0
       << RegName(PostIdxReg.RegNum);
3797
0
    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
3798
0
      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
3799
0
         << PostIdxReg.ShiftImm;
3800
0
    OS << ">";
3801
0
    break;
3802
0
  case k_ProcIFlags: {
3803
0
    OS << "<ARM_PROC::";
3804
0
    unsigned IFlags = getProcIFlags();
3805
0
    for (int i=2; i >= 0; --i)
3806
0
      if (IFlags & (1 << i))
3807
0
        OS << ARM_PROC::IFlagsToString(1 << i);
3808
0
    OS << ">";
3809
0
    break;
3810
0
  }
3811
0
  case k_Register:
3812
0
    OS << "<register " << RegName(getReg()) << ">";
3813
0
    break;
3814
0
  case k_ShifterImmediate:
3815
0
    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
3816
0
       << " #" << ShifterImm.Imm << ">";
3817
0
    break;
3818
0
  case k_ShiftedRegister:
3819
0
    OS << "<so_reg_reg " << RegName(RegShiftedReg.SrcReg) << " "
3820
0
       << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy) << " "
3821
0
       << RegName(RegShiftedReg.ShiftReg) << ">";
3822
0
    break;
3823
0
  case k_ShiftedImmediate:
3824
0
    OS << "<so_reg_imm " << RegName(RegShiftedImm.SrcReg) << " "
3825
0
       << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy) << " #"
3826
0
       << RegShiftedImm.ShiftImm << ">";
3827
0
    break;
3828
0
  case k_RotateImmediate:
3829
0
    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
3830
0
    break;
3831
0
  case k_ModifiedImmediate:
3832
0
    OS << "<mod_imm #" << ModImm.Bits << ", #"
3833
0
       <<  ModImm.Rot << ")>";
3834
0
    break;
3835
0
  case k_ConstantPoolImmediate:
3836
0
    OS << "<constant_pool_imm #" << *getConstantPoolImm();
3837
0
    break;
3838
0
  case k_BitfieldDescriptor:
3839
0
    OS << "<bitfield " << "lsb: " << Bitfield.LSB
3840
0
       << ", width: " << Bitfield.Width << ">";
3841
0
    break;
3842
0
  case k_RegisterList:
3843
0
  case k_RegisterListWithAPSR:
3844
0
  case k_DPRRegisterList:
3845
0
  case k_SPRRegisterList:
3846
0
  case k_FPSRegisterListWithVPR:
3847
0
  case k_FPDRegisterListWithVPR: {
3848
0
    OS << "<register_list ";
3849
0
3850
0
    const SmallVectorImpl<unsigned> &RegList = getRegList();
3851
0
    for (SmallVectorImpl<unsigned>::const_iterator
3852
0
           I = RegList.begin(), E = RegList.end(); I != E; ) {
3853
0
      OS << RegName(*I);
3854
0
      if (++I < E) OS << ", ";
3855
0
    }
3856
0
3857
0
    OS << ">";
3858
0
    break;
3859
0
  }
3860
0
  case k_VectorList:
3861
0
    OS << "<vector_list " << VectorList.Count << " * "
3862
0
       << RegName(VectorList.RegNum) << ">";
3863
0
    break;
3864
0
  case k_VectorListAllLanes:
3865
0
    OS << "<vector_list(all lanes) " << VectorList.Count << " * "
3866
0
       << RegName(VectorList.RegNum) << ">";
3867
0
    break;
3868
0
  case k_VectorListIndexed:
3869
0
    OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
3870
0
       << VectorList.Count << " * " << RegName(VectorList.RegNum) << ">";
3871
0
    break;
3872
0
  case k_Token:
3873
0
    OS << "'" << getToken() << "'";
3874
0
    break;
3875
0
  case k_VectorIndex:
3876
0
    OS << "<vectorindex " << getVectorIndex() << ">";
3877
0
    break;
3878
0
  }
3879
0
}
3880
3881
/// @name Auto-generated Match Functions
3882
/// {
3883
3884
static unsigned MatchRegisterName(StringRef Name);
3885
3886
/// }
3887
3888
bool ARMAsmParser::ParseRegister(unsigned &RegNo,
3889
45
                                 SMLoc &StartLoc, SMLoc &EndLoc) {
3890
45
  const AsmToken &Tok = getParser().getTok();
3891
45
  StartLoc = Tok.getLoc();
3892
45
  EndLoc = Tok.getEndLoc();
3893
45
  RegNo = tryParseRegister();
3894
45
3895
45
  return (RegNo == (unsigned)-1);
3896
45
}
3897
3898
/// Try to parse a register name.  The token must be an Identifier when called,
3899
/// and if it is a register name the token is eaten and the register number is
3900
/// returned.  Otherwise return -1.
3901
79.7k
int ARMAsmParser::tryParseRegister() {
3902
79.7k
  MCAsmParser &Parser = getParser();
3903
79.7k
  const AsmToken &Tok = Parser.getTok();
3904
79.7k
  if (Tok.isNot(AsmToken::Identifier)) 
return -149
;
3905
79.6k
3906
79.6k
  std::string lowerCase = Tok.getString().lower();
3907
79.6k
  unsigned RegNum = MatchRegisterName(lowerCase);
3908
79.6k
  if (!RegNum) {
3909
3.41k
    RegNum = StringSwitch<unsigned>(lowerCase)
3910
3.41k
      .Case("r13", ARM::SP)
3911
3.41k
      .Case("r14", ARM::LR)
3912
3.41k
      .Case("r15", ARM::PC)
3913
3.41k
      .Case("ip", ARM::R12)
3914
3.41k
      // Additional register name aliases for 'gas' compatibility.
3915
3.41k
      .Case("a1", ARM::R0)
3916
3.41k
      .Case("a2", ARM::R1)
3917
3.41k
      .Case("a3", ARM::R2)
3918
3.41k
      .Case("a4", ARM::R3)
3919
3.41k
      .Case("v1", ARM::R4)
3920
3.41k
      .Case("v2", ARM::R5)
3921
3.41k
      .Case("v3", ARM::R6)
3922
3.41k
      .Case("v4", ARM::R7)
3923
3.41k
      .Case("v5", ARM::R8)
3924
3.41k
      .Case("v6", ARM::R9)
3925
3.41k
      .Case("v7", ARM::R10)
3926
3.41k
      .Case("v8", ARM::R11)
3927
3.41k
      .Case("sb", ARM::R9)
3928
3.41k
      .Case("sl", ARM::R10)
3929
3.41k
      .Case("fp", ARM::R11)
3930
3.41k
      .Default(0);
3931
3.41k
  }
3932
79.6k
  if (!RegNum) {
3933
2.69k
    // Check for aliases registered via .req. Canonicalize to lower case.
3934
2.69k
    // That's more consistent since register names are case insensitive, and
3935
2.69k
    // it's how the original entry was passed in from MC/MCParser/AsmParser.
3936
2.69k
    StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase);
3937
2.69k
    // If no match, return failure.
3938
2.69k
    if (Entry == RegisterReqs.end())
3939
2.69k
      return -1;
3940
5
    Parser.Lex(); // Eat identifier token.
3941
5
    return Entry->getValue();
3942
5
  }
3943
76.9k
3944
76.9k
  // Some FPUs only have 16 D registers, so D16-D31 are invalid
3945
76.9k
  if (!hasD32() && 
RegNum >= ARM::D1619.7k
&&
RegNum <= ARM::D3117.2k
)
3946
24
    return -1;
3947
76.9k
3948
76.9k
  Parser.Lex(); // Eat identifier token.
3949
76.9k
3950
76.9k
  return RegNum;
3951
76.9k
}
3952
3953
// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
3954
// If a recoverable error occurs, return 1. If an irrecoverable error
3955
// occurs, return -1. An irrecoverable error is one where tokens have been
3956
// consumed in the process of trying to parse the shifter (i.e., when it is
3957
// indeed a shifter operand, but malformed).
3958
2.71k
int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) {
3959
2.71k
  MCAsmParser &Parser = getParser();
3960
2.71k
  SMLoc S = Parser.getTok().getLoc();
3961
2.71k
  const AsmToken &Tok = Parser.getTok();
3962
2.71k
  if (Tok.isNot(AsmToken::Identifier))
3963
3
    return -1;
3964
2.71k
3965
2.71k
  std::string lowerCase = Tok.getString().lower();
3966
2.71k
  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
3967
2.71k
      .Case("asl", ARM_AM::lsl)
3968
2.71k
      .Case("lsl", ARM_AM::lsl)
3969
2.71k
      .Case("lsr", ARM_AM::lsr)
3970
2.71k
      .Case("asr", ARM_AM::asr)
3971
2.71k
      .Case("ror", ARM_AM::ror)
3972
2.71k
      .Case("rrx", ARM_AM::rrx)
3973
2.71k
      .Default(ARM_AM::no_shift);
3974
2.71k
3975
2.71k
  if (ShiftTy == ARM_AM::no_shift)
3976
431
    return 1;
3977
2.28k
3978
2.28k
  Parser.Lex(); // Eat the operator.
3979
2.28k
3980
2.28k
  // The source register for the shift has already been added to the
3981
2.28k
  // operand list, so we need to pop it off and combine it into the shifted
3982
2.28k
  // register operand instead.
3983
2.28k
  std::unique_ptr<ARMOperand> PrevOp(
3984
2.28k
      (ARMOperand *)Operands.pop_back_val().release());
3985
2.28k
  if (!PrevOp->isReg())
3986
0
    return Error(PrevOp->getStartLoc(), "shift must be of a register");
3987
2.28k
  int SrcReg = PrevOp->getReg();
3988
2.28k
3989
2.28k
  SMLoc EndLoc;
3990
2.28k
  int64_t Imm = 0;
3991
2.28k
  int ShiftReg = 0;
3992
2.28k
  if (ShiftTy == ARM_AM::rrx) {
3993
50
    // RRX Doesn't have an explicit shift amount. The encoder expects
3994
50
    // the shift register to be the same as the source register. Seems odd,
3995
50
    // but OK.
3996
50
    ShiftReg = SrcReg;
3997
2.23k
  } else {
3998
2.23k
    // Figure out if this is shifted by a constant or a register (for non-RRX).
3999
2.23k
    if (Parser.getTok().is(AsmToken::Hash) ||
4000
2.23k
        
Parser.getTok().is(AsmToken::Dollar)247
) {
4001
1.98k
      Parser.Lex(); // Eat hash.
4002
1.98k
      SMLoc ImmLoc = Parser.getTok().getLoc();
4003
1.98k
      const MCExpr *ShiftExpr = nullptr;
4004
1.98k
      if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4005
0
        Error(ImmLoc, "invalid immediate shift value");
4006
0
        return -1;
4007
0
      }
4008
1.98k
      // The expression must be evaluatable as an immediate.
4009
1.98k
      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
4010
1.98k
      if (!CE) {
4011
2
        Error(ImmLoc, "invalid immediate shift value");
4012
2
        return -1;
4013
2
      }
4014
1.98k
      // Range check the immediate.
4015
1.98k
      // lsl, ror: 0 <= imm <= 31
4016
1.98k
      // lsr, asr: 0 <= imm <= 32