1 //==- AArch64AsmParser.cpp - Parse AArch64 assembly to MCInst instructions -==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "MCTargetDesc/AArch64AddressingModes.h"
11 #include "MCTargetDesc/AArch64MCExpr.h"
12 #include "MCTargetDesc/AArch64TargetStreamer.h"
13 #include "Utils/AArch64BaseInfo.h"
14 #include "llvm/ADT/APInt.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/ADT/Twine.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCObjectFileInfo.h"
24 #include "llvm/MC/MCParser/MCAsmLexer.h"
25 #include "llvm/MC/MCParser/MCAsmParser.h"
26 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
27 #include "llvm/MC/MCRegisterInfo.h"
28 #include "llvm/MC/MCStreamer.h"
29 #include "llvm/MC/MCSubtargetInfo.h"
30 #include "llvm/MC/MCSymbol.h"
31 #include "llvm/MC/MCTargetAsmParser.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/SourceMgr.h"
34 #include "llvm/Support/TargetRegistry.h"
35 #include "llvm/Support/raw_ostream.h"
36 #include <cstdio>
37 using namespace llvm;
38
39 namespace {
40
41 class AArch64Operand;
42
43 class AArch64AsmParser : public MCTargetAsmParser {
44 private:
45 StringRef Mnemonic; ///< Instruction mnemonic.
46 MCSubtargetInfo &STI;
47
48 // Map of register aliases registers via the .req directive.
49 StringMap<std::pair<bool, unsigned> > RegisterReqs;
50
getTargetStreamer()51 AArch64TargetStreamer &getTargetStreamer() {
52 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
53 return static_cast<AArch64TargetStreamer &>(TS);
54 }
55
getLoc() const56 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
57
58 bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
59 AArch64CC::CondCode parseCondCodeString(StringRef Cond);
60 bool parseCondCode(OperandVector &Operands, bool invertCondCode);
61 unsigned matchRegisterNameAlias(StringRef Name, bool isVector);
62 int tryParseRegister();
63 int tryMatchVectorRegister(StringRef &Kind, bool expected);
64 bool parseRegister(OperandVector &Operands);
65 bool parseSymbolicImmVal(const MCExpr *&ImmVal);
66 bool parseVectorList(OperandVector &Operands);
67 bool parseOperand(OperandVector &Operands, bool isCondCode,
68 bool invertCondCode);
69
Warning(SMLoc L,const Twine & Msg)70 void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); }
Error(SMLoc L,const Twine & Msg)71 bool Error(SMLoc L, const Twine &Msg) { return getParser().Error(L, Msg); }
72 bool showMatchError(SMLoc Loc, unsigned ErrCode);
73
74 bool parseDirectiveWord(unsigned Size, SMLoc L);
75 bool parseDirectiveInst(SMLoc L);
76
77 bool parseDirectiveTLSDescCall(SMLoc L);
78
79 bool parseDirectiveLOH(StringRef LOH, SMLoc L);
80 bool parseDirectiveLtorg(SMLoc L);
81
82 bool parseDirectiveReq(StringRef Name, SMLoc L);
83 bool parseDirectiveUnreq(SMLoc L);
84
85 bool validateInstruction(MCInst &Inst, SmallVectorImpl<SMLoc> &Loc);
86 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
87 OperandVector &Operands, MCStreamer &Out,
88 uint64_t &ErrorInfo,
89 bool MatchingInlineAsm) override;
90 /// @name Auto-generated Match Functions
91 /// {
92
93 #define GET_ASSEMBLER_HEADER
94 #include "AArch64GenAsmMatcher.inc"
95
96 /// }
97
98 OperandMatchResultTy tryParseOptionalShiftExtend(OperandVector &Operands);
99 OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands);
100 OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands);
101 OperandMatchResultTy tryParseSysReg(OperandVector &Operands);
102 OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands);
103 OperandMatchResultTy tryParsePrefetch(OperandVector &Operands);
104 OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands);
105 OperandMatchResultTy tryParseAdrLabel(OperandVector &Operands);
106 OperandMatchResultTy tryParseFPImm(OperandVector &Operands);
107 OperandMatchResultTy tryParseAddSubImm(OperandVector &Operands);
108 OperandMatchResultTy tryParseGPR64sp0Operand(OperandVector &Operands);
109 bool tryParseVectorRegister(OperandVector &Operands);
110 OperandMatchResultTy tryParseGPRSeqPair(OperandVector &Operands);
111
112 public:
113 enum AArch64MatchResultTy {
114 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
115 #define GET_OPERAND_DIAGNOSTIC_TYPES
116 #include "AArch64GenAsmMatcher.inc"
117 };
AArch64AsmParser(MCSubtargetInfo & STI,MCAsmParser & Parser,const MCInstrInfo & MII,const MCTargetOptions & Options)118 AArch64AsmParser(MCSubtargetInfo &STI, MCAsmParser &Parser,
119 const MCInstrInfo &MII, const MCTargetOptions &Options)
120 : MCTargetAsmParser(), STI(STI) {
121 MCAsmParserExtension::Initialize(Parser);
122 MCStreamer &S = getParser().getStreamer();
123 if (S.getTargetStreamer() == nullptr)
124 new AArch64TargetStreamer(S);
125
126 // Initialize the set of available features.
127 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
128 }
129
130 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
131 SMLoc NameLoc, OperandVector &Operands) override;
132 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
133 bool ParseDirective(AsmToken DirectiveID) override;
134 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
135 unsigned Kind) override;
136
137 static bool classifySymbolRef(const MCExpr *Expr,
138 AArch64MCExpr::VariantKind &ELFRefKind,
139 MCSymbolRefExpr::VariantKind &DarwinRefKind,
140 int64_t &Addend);
141 };
142 } // end anonymous namespace
143
144 namespace {
145
146 /// AArch64Operand - Instances of this class represent a parsed AArch64 machine
147 /// instruction.
148 class AArch64Operand : public MCParsedAsmOperand {
149 private:
150 enum KindTy {
151 k_Immediate,
152 k_ShiftedImm,
153 k_CondCode,
154 k_Register,
155 k_VectorList,
156 k_VectorIndex,
157 k_Token,
158 k_SysReg,
159 k_SysCR,
160 k_Prefetch,
161 k_ShiftExtend,
162 k_FPImm,
163 k_Barrier
164 } Kind;
165
166 SMLoc StartLoc, EndLoc;
167
168 struct TokOp {
169 const char *Data;
170 unsigned Length;
171 bool IsSuffix; // Is the operand actually a suffix on the mnemonic.
172 };
173
174 struct RegOp {
175 unsigned RegNum;
176 bool isVector;
177 };
178
179 struct VectorListOp {
180 unsigned RegNum;
181 unsigned Count;
182 unsigned NumElements;
183 unsigned ElementKind;
184 };
185
186 struct VectorIndexOp {
187 unsigned Val;
188 };
189
190 struct ImmOp {
191 const MCExpr *Val;
192 };
193
194 struct ShiftedImmOp {
195 const MCExpr *Val;
196 unsigned ShiftAmount;
197 };
198
199 struct CondCodeOp {
200 AArch64CC::CondCode Code;
201 };
202
203 struct FPImmOp {
204 unsigned Val; // Encoded 8-bit representation.
205 };
206
207 struct BarrierOp {
208 unsigned Val; // Not the enum since not all values have names.
209 const char *Data;
210 unsigned Length;
211 };
212
213 struct SysRegOp {
214 const char *Data;
215 unsigned Length;
216 uint32_t MRSReg;
217 uint32_t MSRReg;
218 uint32_t PStateField;
219 };
220
221 struct SysCRImmOp {
222 unsigned Val;
223 };
224
225 struct PrefetchOp {
226 unsigned Val;
227 const char *Data;
228 unsigned Length;
229 };
230
231 struct ShiftExtendOp {
232 AArch64_AM::ShiftExtendType Type;
233 unsigned Amount;
234 bool HasExplicitAmount;
235 };
236
237 struct ExtendOp {
238 unsigned Val;
239 };
240
241 union {
242 struct TokOp Tok;
243 struct RegOp Reg;
244 struct VectorListOp VectorList;
245 struct VectorIndexOp VectorIndex;
246 struct ImmOp Imm;
247 struct ShiftedImmOp ShiftedImm;
248 struct CondCodeOp CondCode;
249 struct FPImmOp FPImm;
250 struct BarrierOp Barrier;
251 struct SysRegOp SysReg;
252 struct SysCRImmOp SysCRImm;
253 struct PrefetchOp Prefetch;
254 struct ShiftExtendOp ShiftExtend;
255 };
256
257 // Keep the MCContext around as the MCExprs may need manipulated during
258 // the add<>Operands() calls.
259 MCContext &Ctx;
260
261 public:
AArch64Operand(KindTy K,MCContext & Ctx)262 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(K), Ctx(Ctx) {}
263
AArch64Operand(const AArch64Operand & o)264 AArch64Operand(const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(o.Ctx) {
265 Kind = o.Kind;
266 StartLoc = o.StartLoc;
267 EndLoc = o.EndLoc;
268 switch (Kind) {
269 case k_Token:
270 Tok = o.Tok;
271 break;
272 case k_Immediate:
273 Imm = o.Imm;
274 break;
275 case k_ShiftedImm:
276 ShiftedImm = o.ShiftedImm;
277 break;
278 case k_CondCode:
279 CondCode = o.CondCode;
280 break;
281 case k_FPImm:
282 FPImm = o.FPImm;
283 break;
284 case k_Barrier:
285 Barrier = o.Barrier;
286 break;
287 case k_Register:
288 Reg = o.Reg;
289 break;
290 case k_VectorList:
291 VectorList = o.VectorList;
292 break;
293 case k_VectorIndex:
294 VectorIndex = o.VectorIndex;
295 break;
296 case k_SysReg:
297 SysReg = o.SysReg;
298 break;
299 case k_SysCR:
300 SysCRImm = o.SysCRImm;
301 break;
302 case k_Prefetch:
303 Prefetch = o.Prefetch;
304 break;
305 case k_ShiftExtend:
306 ShiftExtend = o.ShiftExtend;
307 break;
308 }
309 }
310
311 /// getStartLoc - Get the location of the first token of this operand.
getStartLoc() const312 SMLoc getStartLoc() const override { return StartLoc; }
313 /// getEndLoc - Get the location of the last token of this operand.
getEndLoc() const314 SMLoc getEndLoc() const override { return EndLoc; }
315
getToken() const316 StringRef getToken() const {
317 assert(Kind == k_Token && "Invalid access!");
318 return StringRef(Tok.Data, Tok.Length);
319 }
320
isTokenSuffix() const321 bool isTokenSuffix() const {
322 assert(Kind == k_Token && "Invalid access!");
323 return Tok.IsSuffix;
324 }
325
getImm() const326 const MCExpr *getImm() const {
327 assert(Kind == k_Immediate && "Invalid access!");
328 return Imm.Val;
329 }
330
getShiftedImmVal() const331 const MCExpr *getShiftedImmVal() const {
332 assert(Kind == k_ShiftedImm && "Invalid access!");
333 return ShiftedImm.Val;
334 }
335
getShiftedImmShift() const336 unsigned getShiftedImmShift() const {
337 assert(Kind == k_ShiftedImm && "Invalid access!");
338 return ShiftedImm.ShiftAmount;
339 }
340
getCondCode() const341 AArch64CC::CondCode getCondCode() const {
342 assert(Kind == k_CondCode && "Invalid access!");
343 return CondCode.Code;
344 }
345
getFPImm() const346 unsigned getFPImm() const {
347 assert(Kind == k_FPImm && "Invalid access!");
348 return FPImm.Val;
349 }
350
getBarrier() const351 unsigned getBarrier() const {
352 assert(Kind == k_Barrier && "Invalid access!");
353 return Barrier.Val;
354 }
355
getBarrierName() const356 StringRef getBarrierName() const {
357 assert(Kind == k_Barrier && "Invalid access!");
358 return StringRef(Barrier.Data, Barrier.Length);
359 }
360
getReg() const361 unsigned getReg() const override {
362 assert(Kind == k_Register && "Invalid access!");
363 return Reg.RegNum;
364 }
365
getVectorListStart() const366 unsigned getVectorListStart() const {
367 assert(Kind == k_VectorList && "Invalid access!");
368 return VectorList.RegNum;
369 }
370
getVectorListCount() const371 unsigned getVectorListCount() const {
372 assert(Kind == k_VectorList && "Invalid access!");
373 return VectorList.Count;
374 }
375
getVectorIndex() const376 unsigned getVectorIndex() const {
377 assert(Kind == k_VectorIndex && "Invalid access!");
378 return VectorIndex.Val;
379 }
380
getSysReg() const381 StringRef getSysReg() const {
382 assert(Kind == k_SysReg && "Invalid access!");
383 return StringRef(SysReg.Data, SysReg.Length);
384 }
385
getSysCR() const386 unsigned getSysCR() const {
387 assert(Kind == k_SysCR && "Invalid access!");
388 return SysCRImm.Val;
389 }
390
getPrefetch() const391 unsigned getPrefetch() const {
392 assert(Kind == k_Prefetch && "Invalid access!");
393 return Prefetch.Val;
394 }
395
getPrefetchName() const396 StringRef getPrefetchName() const {
397 assert(Kind == k_Prefetch && "Invalid access!");
398 return StringRef(Prefetch.Data, Prefetch.Length);
399 }
400
getShiftExtendType() const401 AArch64_AM::ShiftExtendType getShiftExtendType() const {
402 assert(Kind == k_ShiftExtend && "Invalid access!");
403 return ShiftExtend.Type;
404 }
405
getShiftExtendAmount() const406 unsigned getShiftExtendAmount() const {
407 assert(Kind == k_ShiftExtend && "Invalid access!");
408 return ShiftExtend.Amount;
409 }
410
hasShiftExtendAmount() const411 bool hasShiftExtendAmount() const {
412 assert(Kind == k_ShiftExtend && "Invalid access!");
413 return ShiftExtend.HasExplicitAmount;
414 }
415
isImm() const416 bool isImm() const override { return Kind == k_Immediate; }
isMem() const417 bool isMem() const override { return false; }
isSImm9() const418 bool isSImm9() const {
419 if (!isImm())
420 return false;
421 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
422 if (!MCE)
423 return false;
424 int64_t Val = MCE->getValue();
425 return (Val >= -256 && Val < 256);
426 }
isSImm7s4() const427 bool isSImm7s4() const {
428 if (!isImm())
429 return false;
430 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
431 if (!MCE)
432 return false;
433 int64_t Val = MCE->getValue();
434 return (Val >= -256 && Val <= 252 && (Val & 3) == 0);
435 }
isSImm7s8() const436 bool isSImm7s8() const {
437 if (!isImm())
438 return false;
439 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
440 if (!MCE)
441 return false;
442 int64_t Val = MCE->getValue();
443 return (Val >= -512 && Val <= 504 && (Val & 7) == 0);
444 }
isSImm7s16() const445 bool isSImm7s16() const {
446 if (!isImm())
447 return false;
448 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
449 if (!MCE)
450 return false;
451 int64_t Val = MCE->getValue();
452 return (Val >= -1024 && Val <= 1008 && (Val & 15) == 0);
453 }
454
isSymbolicUImm12Offset(const MCExpr * Expr,unsigned Scale) const455 bool isSymbolicUImm12Offset(const MCExpr *Expr, unsigned Scale) const {
456 AArch64MCExpr::VariantKind ELFRefKind;
457 MCSymbolRefExpr::VariantKind DarwinRefKind;
458 int64_t Addend;
459 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
460 Addend)) {
461 // If we don't understand the expression, assume the best and
462 // let the fixup and relocation code deal with it.
463 return true;
464 }
465
466 if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
467 ELFRefKind == AArch64MCExpr::VK_LO12 ||
468 ELFRefKind == AArch64MCExpr::VK_GOT_LO12 ||
469 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
470 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
471 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
472 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
473 ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC ||
474 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) {
475 // Note that we don't range-check the addend. It's adjusted modulo page
476 // size when converted, so there is no "out of range" condition when using
477 // @pageoff.
478 return Addend >= 0 && (Addend % Scale) == 0;
479 } else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF ||
480 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) {
481 // @gotpageoff/@tlvppageoff can only be used directly, not with an addend.
482 return Addend == 0;
483 }
484
485 return false;
486 }
487
isUImm12Offset() const488 template <int Scale> bool isUImm12Offset() const {
489 if (!isImm())
490 return false;
491
492 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
493 if (!MCE)
494 return isSymbolicUImm12Offset(getImm(), Scale);
495
496 int64_t Val = MCE->getValue();
497 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
498 }
499
isImm0_7() const500 bool isImm0_7() const {
501 if (!isImm())
502 return false;
503 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
504 if (!MCE)
505 return false;
506 int64_t Val = MCE->getValue();
507 return (Val >= 0 && Val < 8);
508 }
isImm1_8() const509 bool isImm1_8() const {
510 if (!isImm())
511 return false;
512 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
513 if (!MCE)
514 return false;
515 int64_t Val = MCE->getValue();
516 return (Val > 0 && Val < 9);
517 }
isImm0_15() const518 bool isImm0_15() const {
519 if (!isImm())
520 return false;
521 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
522 if (!MCE)
523 return false;
524 int64_t Val = MCE->getValue();
525 return (Val >= 0 && Val < 16);
526 }
isImm1_16() const527 bool isImm1_16() const {
528 if (!isImm())
529 return false;
530 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
531 if (!MCE)
532 return false;
533 int64_t Val = MCE->getValue();
534 return (Val > 0 && Val < 17);
535 }
isImm0_31() const536 bool isImm0_31() const {
537 if (!isImm())
538 return false;
539 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
540 if (!MCE)
541 return false;
542 int64_t Val = MCE->getValue();
543 return (Val >= 0 && Val < 32);
544 }
isImm1_31() const545 bool isImm1_31() const {
546 if (!isImm())
547 return false;
548 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
549 if (!MCE)
550 return false;
551 int64_t Val = MCE->getValue();
552 return (Val >= 1 && Val < 32);
553 }
isImm1_32() const554 bool isImm1_32() const {
555 if (!isImm())
556 return false;
557 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
558 if (!MCE)
559 return false;
560 int64_t Val = MCE->getValue();
561 return (Val >= 1 && Val < 33);
562 }
isImm0_63() const563 bool isImm0_63() const {
564 if (!isImm())
565 return false;
566 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
567 if (!MCE)
568 return false;
569 int64_t Val = MCE->getValue();
570 return (Val >= 0 && Val < 64);
571 }
isImm1_63() const572 bool isImm1_63() const {
573 if (!isImm())
574 return false;
575 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
576 if (!MCE)
577 return false;
578 int64_t Val = MCE->getValue();
579 return (Val >= 1 && Val < 64);
580 }
isImm1_64() const581 bool isImm1_64() const {
582 if (!isImm())
583 return false;
584 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
585 if (!MCE)
586 return false;
587 int64_t Val = MCE->getValue();
588 return (Val >= 1 && Val < 65);
589 }
isImm0_127() const590 bool isImm0_127() const {
591 if (!isImm())
592 return false;
593 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
594 if (!MCE)
595 return false;
596 int64_t Val = MCE->getValue();
597 return (Val >= 0 && Val < 128);
598 }
isImm0_255() const599 bool isImm0_255() const {
600 if (!isImm())
601 return false;
602 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
603 if (!MCE)
604 return false;
605 int64_t Val = MCE->getValue();
606 return (Val >= 0 && Val < 256);
607 }
isImm0_65535() const608 bool isImm0_65535() const {
609 if (!isImm())
610 return false;
611 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
612 if (!MCE)
613 return false;
614 int64_t Val = MCE->getValue();
615 return (Val >= 0 && Val < 65536);
616 }
isImm32_63() const617 bool isImm32_63() const {
618 if (!isImm())
619 return false;
620 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
621 if (!MCE)
622 return false;
623 int64_t Val = MCE->getValue();
624 return (Val >= 32 && Val < 64);
625 }
isLogicalImm32() const626 bool isLogicalImm32() const {
627 if (!isImm())
628 return false;
629 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
630 if (!MCE)
631 return false;
632 int64_t Val = MCE->getValue();
633 if (Val >> 32 != 0 && Val >> 32 != ~0LL)
634 return false;
635 Val &= 0xFFFFFFFF;
636 return AArch64_AM::isLogicalImmediate(Val, 32);
637 }
isLogicalImm64() const638 bool isLogicalImm64() const {
639 if (!isImm())
640 return false;
641 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
642 if (!MCE)
643 return false;
644 return AArch64_AM::isLogicalImmediate(MCE->getValue(), 64);
645 }
isLogicalImm32Not() const646 bool isLogicalImm32Not() const {
647 if (!isImm())
648 return false;
649 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
650 if (!MCE)
651 return false;
652 int64_t Val = ~MCE->getValue() & 0xFFFFFFFF;
653 return AArch64_AM::isLogicalImmediate(Val, 32);
654 }
isLogicalImm64Not() const655 bool isLogicalImm64Not() const {
656 if (!isImm())
657 return false;
658 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
659 if (!MCE)
660 return false;
661 return AArch64_AM::isLogicalImmediate(~MCE->getValue(), 64);
662 }
isShiftedImm() const663 bool isShiftedImm() const { return Kind == k_ShiftedImm; }
isAddSubImm() const664 bool isAddSubImm() const {
665 if (!isShiftedImm() && !isImm())
666 return false;
667
668 const MCExpr *Expr;
669
670 // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'.
671 if (isShiftedImm()) {
672 unsigned Shift = ShiftedImm.ShiftAmount;
673 Expr = ShiftedImm.Val;
674 if (Shift != 0 && Shift != 12)
675 return false;
676 } else {
677 Expr = getImm();
678 }
679
680 AArch64MCExpr::VariantKind ELFRefKind;
681 MCSymbolRefExpr::VariantKind DarwinRefKind;
682 int64_t Addend;
683 if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
684 DarwinRefKind, Addend)) {
685 return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF
686 || DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF
687 || (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0)
688 || ELFRefKind == AArch64MCExpr::VK_LO12
689 || ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12
690 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12
691 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC
692 || ELFRefKind == AArch64MCExpr::VK_TPREL_HI12
693 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12
694 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC
695 || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12;
696 }
697
698 // Otherwise it should be a real immediate in range:
699 const MCConstantExpr *CE = cast<MCConstantExpr>(Expr);
700 return CE->getValue() >= 0 && CE->getValue() <= 0xfff;
701 }
isAddSubImmNeg() const702 bool isAddSubImmNeg() const {
703 if (!isShiftedImm() && !isImm())
704 return false;
705
706 const MCExpr *Expr;
707
708 // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'.
709 if (isShiftedImm()) {
710 unsigned Shift = ShiftedImm.ShiftAmount;
711 Expr = ShiftedImm.Val;
712 if (Shift != 0 && Shift != 12)
713 return false;
714 } else
715 Expr = getImm();
716
717 // Otherwise it should be a real negative immediate in range:
718 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
719 return CE != nullptr && CE->getValue() < 0 && -CE->getValue() <= 0xfff;
720 }
isCondCode() const721 bool isCondCode() const { return Kind == k_CondCode; }
isSIMDImmType10() const722 bool isSIMDImmType10() const {
723 if (!isImm())
724 return false;
725 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
726 if (!MCE)
727 return false;
728 return AArch64_AM::isAdvSIMDModImmType10(MCE->getValue());
729 }
isBranchTarget26() const730 bool isBranchTarget26() const {
731 if (!isImm())
732 return false;
733 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
734 if (!MCE)
735 return true;
736 int64_t Val = MCE->getValue();
737 if (Val & 0x3)
738 return false;
739 return (Val >= -(0x2000000 << 2) && Val <= (0x1ffffff << 2));
740 }
isPCRelLabel19() const741 bool isPCRelLabel19() const {
742 if (!isImm())
743 return false;
744 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
745 if (!MCE)
746 return true;
747 int64_t Val = MCE->getValue();
748 if (Val & 0x3)
749 return false;
750 return (Val >= -(0x40000 << 2) && Val <= (0x3ffff << 2));
751 }
isBranchTarget14() const752 bool isBranchTarget14() const {
753 if (!isImm())
754 return false;
755 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
756 if (!MCE)
757 return true;
758 int64_t Val = MCE->getValue();
759 if (Val & 0x3)
760 return false;
761 return (Val >= -(0x2000 << 2) && Val <= (0x1fff << 2));
762 }
763
764 bool
isMovWSymbol(ArrayRef<AArch64MCExpr::VariantKind> AllowedModifiers) const765 isMovWSymbol(ArrayRef<AArch64MCExpr::VariantKind> AllowedModifiers) const {
766 if (!isImm())
767 return false;
768
769 AArch64MCExpr::VariantKind ELFRefKind;
770 MCSymbolRefExpr::VariantKind DarwinRefKind;
771 int64_t Addend;
772 if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
773 DarwinRefKind, Addend)) {
774 return false;
775 }
776 if (DarwinRefKind != MCSymbolRefExpr::VK_None)
777 return false;
778
779 for (unsigned i = 0; i != AllowedModifiers.size(); ++i) {
780 if (ELFRefKind == AllowedModifiers[i])
781 return Addend == 0;
782 }
783
784 return false;
785 }
786
isMovZSymbolG3() const787 bool isMovZSymbolG3() const {
788 return isMovWSymbol(AArch64MCExpr::VK_ABS_G3);
789 }
790
isMovZSymbolG2() const791 bool isMovZSymbolG2() const {
792 return isMovWSymbol({AArch64MCExpr::VK_ABS_G2, AArch64MCExpr::VK_ABS_G2_S,
793 AArch64MCExpr::VK_TPREL_G2,
794 AArch64MCExpr::VK_DTPREL_G2});
795 }
796
isMovZSymbolG1() const797 bool isMovZSymbolG1() const {
798 return isMovWSymbol({
799 AArch64MCExpr::VK_ABS_G1, AArch64MCExpr::VK_ABS_G1_S,
800 AArch64MCExpr::VK_GOTTPREL_G1, AArch64MCExpr::VK_TPREL_G1,
801 AArch64MCExpr::VK_DTPREL_G1,
802 });
803 }
804
isMovZSymbolG0() const805 bool isMovZSymbolG0() const {
806 return isMovWSymbol({AArch64MCExpr::VK_ABS_G0, AArch64MCExpr::VK_ABS_G0_S,
807 AArch64MCExpr::VK_TPREL_G0,
808 AArch64MCExpr::VK_DTPREL_G0});
809 }
810
isMovKSymbolG3() const811 bool isMovKSymbolG3() const {
812 return isMovWSymbol(AArch64MCExpr::VK_ABS_G3);
813 }
814
isMovKSymbolG2() const815 bool isMovKSymbolG2() const {
816 return isMovWSymbol(AArch64MCExpr::VK_ABS_G2_NC);
817 }
818
isMovKSymbolG1() const819 bool isMovKSymbolG1() const {
820 return isMovWSymbol({AArch64MCExpr::VK_ABS_G1_NC,
821 AArch64MCExpr::VK_TPREL_G1_NC,
822 AArch64MCExpr::VK_DTPREL_G1_NC});
823 }
824
isMovKSymbolG0() const825 bool isMovKSymbolG0() const {
826 return isMovWSymbol(
827 {AArch64MCExpr::VK_ABS_G0_NC, AArch64MCExpr::VK_GOTTPREL_G0_NC,
828 AArch64MCExpr::VK_TPREL_G0_NC, AArch64MCExpr::VK_DTPREL_G0_NC});
829 }
830
831 template<int RegWidth, int Shift>
isMOVZMovAlias() const832 bool isMOVZMovAlias() const {
833 if (!isImm()) return false;
834
835 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
836 if (!CE) return false;
837 uint64_t Value = CE->getValue();
838
839 if (RegWidth == 32)
840 Value &= 0xffffffffULL;
841
842 // "lsl #0" takes precedence: in practice this only affects "#0, lsl #0".
843 if (Value == 0 && Shift != 0)
844 return false;
845
846 return (Value & ~(0xffffULL << Shift)) == 0;
847 }
848
849 template<int RegWidth, int Shift>
isMOVNMovAlias() const850 bool isMOVNMovAlias() const {
851 if (!isImm()) return false;
852
853 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
854 if (!CE) return false;
855 uint64_t Value = CE->getValue();
856
857 // MOVZ takes precedence over MOVN.
858 for (int MOVZShift = 0; MOVZShift <= 48; MOVZShift += 16)
859 if ((Value & ~(0xffffULL << MOVZShift)) == 0)
860 return false;
861
862 Value = ~Value;
863 if (RegWidth == 32)
864 Value &= 0xffffffffULL;
865
866 return (Value & ~(0xffffULL << Shift)) == 0;
867 }
868
isFPImm() const869 bool isFPImm() const { return Kind == k_FPImm; }
isBarrier() const870 bool isBarrier() const { return Kind == k_Barrier; }
isSysReg() const871 bool isSysReg() const { return Kind == k_SysReg; }
isMRSSystemRegister() const872 bool isMRSSystemRegister() const {
873 if (!isSysReg()) return false;
874
875 return SysReg.MRSReg != -1U;
876 }
isMSRSystemRegister() const877 bool isMSRSystemRegister() const {
878 if (!isSysReg()) return false;
879
880 return SysReg.MSRReg != -1U;
881 }
isSystemPStateField() const882 bool isSystemPStateField() const {
883 if (!isSysReg()) return false;
884
885 return SysReg.PStateField != -1U;
886 }
isReg() const887 bool isReg() const override { return Kind == k_Register && !Reg.isVector; }
isVectorReg() const888 bool isVectorReg() const { return Kind == k_Register && Reg.isVector; }
isVectorRegLo() const889 bool isVectorRegLo() const {
890 return Kind == k_Register && Reg.isVector &&
891 AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
892 Reg.RegNum);
893 }
isGPR32as64() const894 bool isGPR32as64() const {
895 return Kind == k_Register && !Reg.isVector &&
896 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(Reg.RegNum);
897 }
isWSeqPair() const898 bool isWSeqPair() const {
899 return Kind == k_Register && !Reg.isVector &&
900 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
901 Reg.RegNum);
902 }
isXSeqPair() const903 bool isXSeqPair() const {
904 return Kind == k_Register && !Reg.isVector &&
905 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
906 Reg.RegNum);
907 }
908
isGPR64sp0() const909 bool isGPR64sp0() const {
910 return Kind == k_Register && !Reg.isVector &&
911 AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].contains(Reg.RegNum);
912 }
913
914 /// Is this a vector list with the type implicit (presumably attached to the
915 /// instruction itself)?
isImplicitlyTypedVectorList() const916 template <unsigned NumRegs> bool isImplicitlyTypedVectorList() const {
917 return Kind == k_VectorList && VectorList.Count == NumRegs &&
918 !VectorList.ElementKind;
919 }
920
921 template <unsigned NumRegs, unsigned NumElements, char ElementKind>
isTypedVectorList() const922 bool isTypedVectorList() const {
923 if (Kind != k_VectorList)
924 return false;
925 if (VectorList.Count != NumRegs)
926 return false;
927 if (VectorList.ElementKind != ElementKind)
928 return false;
929 return VectorList.NumElements == NumElements;
930 }
931
isVectorIndex1() const932 bool isVectorIndex1() const {
933 return Kind == k_VectorIndex && VectorIndex.Val == 1;
934 }
isVectorIndexB() const935 bool isVectorIndexB() const {
936 return Kind == k_VectorIndex && VectorIndex.Val < 16;
937 }
isVectorIndexH() const938 bool isVectorIndexH() const {
939 return Kind == k_VectorIndex && VectorIndex.Val < 8;
940 }
isVectorIndexS() const941 bool isVectorIndexS() const {
942 return Kind == k_VectorIndex && VectorIndex.Val < 4;
943 }
isVectorIndexD() const944 bool isVectorIndexD() const {
945 return Kind == k_VectorIndex && VectorIndex.Val < 2;
946 }
isToken() const947 bool isToken() const override { return Kind == k_Token; }
isTokenEqual(StringRef Str) const948 bool isTokenEqual(StringRef Str) const {
949 return Kind == k_Token && getToken() == Str;
950 }
isSysCR() const951 bool isSysCR() const { return Kind == k_SysCR; }
isPrefetch() const952 bool isPrefetch() const { return Kind == k_Prefetch; }
isShiftExtend() const953 bool isShiftExtend() const { return Kind == k_ShiftExtend; }
isShifter() const954 bool isShifter() const {
955 if (!isShiftExtend())
956 return false;
957
958 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
959 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
960 ST == AArch64_AM::ASR || ST == AArch64_AM::ROR ||
961 ST == AArch64_AM::MSL);
962 }
isExtend() const963 bool isExtend() const {
964 if (!isShiftExtend())
965 return false;
966
967 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
968 return (ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB ||
969 ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH ||
970 ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW ||
971 ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
972 ET == AArch64_AM::LSL) &&
973 getShiftExtendAmount() <= 4;
974 }
975
isExtend64() const976 bool isExtend64() const {
977 if (!isExtend())
978 return false;
979 // UXTX and SXTX require a 64-bit source register (the ExtendLSL64 class).
980 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
981 return ET != AArch64_AM::UXTX && ET != AArch64_AM::SXTX;
982 }
isExtendLSL64() const983 bool isExtendLSL64() const {
984 if (!isExtend())
985 return false;
986 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
987 return (ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
988 ET == AArch64_AM::LSL) &&
989 getShiftExtendAmount() <= 4;
990 }
991
isMemXExtend() const992 template<int Width> bool isMemXExtend() const {
993 if (!isExtend())
994 return false;
995 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
996 return (ET == AArch64_AM::LSL || ET == AArch64_AM::SXTX) &&
997 (getShiftExtendAmount() == Log2_32(Width / 8) ||
998 getShiftExtendAmount() == 0);
999 }
1000
isMemWExtend() const1001 template<int Width> bool isMemWExtend() const {
1002 if (!isExtend())
1003 return false;
1004 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1005 return (ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW) &&
1006 (getShiftExtendAmount() == Log2_32(Width / 8) ||
1007 getShiftExtendAmount() == 0);
1008 }
1009
1010 template <unsigned width>
isArithmeticShifter() const1011 bool isArithmeticShifter() const {
1012 if (!isShifter())
1013 return false;
1014
1015 // An arithmetic shifter is LSL, LSR, or ASR.
1016 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1017 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
1018 ST == AArch64_AM::ASR) && getShiftExtendAmount() < width;
1019 }
1020
1021 template <unsigned width>
isLogicalShifter() const1022 bool isLogicalShifter() const {
1023 if (!isShifter())
1024 return false;
1025
1026 // A logical shifter is LSL, LSR, ASR or ROR.
1027 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1028 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
1029 ST == AArch64_AM::ASR || ST == AArch64_AM::ROR) &&
1030 getShiftExtendAmount() < width;
1031 }
1032
isMovImm32Shifter() const1033 bool isMovImm32Shifter() const {
1034 if (!isShifter())
1035 return false;
1036
1037 // A MOVi shifter is LSL of 0, 16, 32, or 48.
1038 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1039 if (ST != AArch64_AM::LSL)
1040 return false;
1041 uint64_t Val = getShiftExtendAmount();
1042 return (Val == 0 || Val == 16);
1043 }
1044
isMovImm64Shifter() const1045 bool isMovImm64Shifter() const {
1046 if (!isShifter())
1047 return false;
1048
1049 // A MOVi shifter is LSL of 0 or 16.
1050 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1051 if (ST != AArch64_AM::LSL)
1052 return false;
1053 uint64_t Val = getShiftExtendAmount();
1054 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1055 }
1056
isLogicalVecShifter() const1057 bool isLogicalVecShifter() const {
1058 if (!isShifter())
1059 return false;
1060
1061 // A logical vector shifter is a left shift by 0, 8, 16, or 24.
1062 unsigned Shift = getShiftExtendAmount();
1063 return getShiftExtendType() == AArch64_AM::LSL &&
1064 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1065 }
1066
isLogicalVecHalfWordShifter() const1067 bool isLogicalVecHalfWordShifter() const {
1068 if (!isLogicalVecShifter())
1069 return false;
1070
1071 // A logical vector shifter is a left shift by 0 or 8.
1072 unsigned Shift = getShiftExtendAmount();
1073 return getShiftExtendType() == AArch64_AM::LSL &&
1074 (Shift == 0 || Shift == 8);
1075 }
1076
isMoveVecShifter() const1077 bool isMoveVecShifter() const {
1078 if (!isShiftExtend())
1079 return false;
1080
1081 // A logical vector shifter is a left shift by 8 or 16.
1082 unsigned Shift = getShiftExtendAmount();
1083 return getShiftExtendType() == AArch64_AM::MSL &&
1084 (Shift == 8 || Shift == 16);
1085 }
1086
1087 // Fallback unscaled operands are for aliases of LDR/STR that fall back
1088 // to LDUR/STUR when the offset is not legal for the former but is for
1089 // the latter. As such, in addition to checking for being a legal unscaled
1090 // address, also check that it is not a legal scaled address. This avoids
1091 // ambiguity in the matcher.
1092 template<int Width>
isSImm9OffsetFB() const1093 bool isSImm9OffsetFB() const {
1094 return isSImm9() && !isUImm12Offset<Width / 8>();
1095 }
1096
isAdrpLabel() const1097 bool isAdrpLabel() const {
1098 // Validation was handled during parsing, so we just sanity check that
1099 // something didn't go haywire.
1100 if (!isImm())
1101 return false;
1102
1103 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1104 int64_t Val = CE->getValue();
1105 int64_t Min = - (4096 * (1LL << (21 - 1)));
1106 int64_t Max = 4096 * ((1LL << (21 - 1)) - 1);
1107 return (Val % 4096) == 0 && Val >= Min && Val <= Max;
1108 }
1109
1110 return true;
1111 }
1112
isAdrLabel() const1113 bool isAdrLabel() const {
1114 // Validation was handled during parsing, so we just sanity check that
1115 // something didn't go haywire.
1116 if (!isImm())
1117 return false;
1118
1119 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1120 int64_t Val = CE->getValue();
1121 int64_t Min = - (1LL << (21 - 1));
1122 int64_t Max = ((1LL << (21 - 1)) - 1);
1123 return Val >= Min && Val <= Max;
1124 }
1125
1126 return true;
1127 }
1128
addExpr(MCInst & Inst,const MCExpr * Expr) const1129 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1130 // Add as immediates when possible. Null MCExpr = 0.
1131 if (!Expr)
1132 Inst.addOperand(MCOperand::createImm(0));
1133 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1134 Inst.addOperand(MCOperand::createImm(CE->getValue()));
1135 else
1136 Inst.addOperand(MCOperand::createExpr(Expr));
1137 }
1138
addRegOperands(MCInst & Inst,unsigned N) const1139 void addRegOperands(MCInst &Inst, unsigned N) const {
1140 assert(N == 1 && "Invalid number of operands!");
1141 Inst.addOperand(MCOperand::createReg(getReg()));
1142 }
1143
addGPR32as64Operands(MCInst & Inst,unsigned N) const1144 void addGPR32as64Operands(MCInst &Inst, unsigned N) const {
1145 assert(N == 1 && "Invalid number of operands!");
1146 assert(
1147 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(getReg()));
1148
1149 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1150 uint32_t Reg = RI->getRegClass(AArch64::GPR32RegClassID).getRegister(
1151 RI->getEncodingValue(getReg()));
1152
1153 Inst.addOperand(MCOperand::createReg(Reg));
1154 }
1155
addVectorReg64Operands(MCInst & Inst,unsigned N) const1156 void addVectorReg64Operands(MCInst &Inst, unsigned N) const {
1157 assert(N == 1 && "Invalid number of operands!");
1158 assert(
1159 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()));
1160 Inst.addOperand(MCOperand::createReg(AArch64::D0 + getReg() - AArch64::Q0));
1161 }
1162
addVectorReg128Operands(MCInst & Inst,unsigned N) const1163 void addVectorReg128Operands(MCInst &Inst, unsigned N) const {
1164 assert(N == 1 && "Invalid number of operands!");
1165 assert(
1166 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()));
1167 Inst.addOperand(MCOperand::createReg(getReg()));
1168 }
1169
addVectorRegLoOperands(MCInst & Inst,unsigned N) const1170 void addVectorRegLoOperands(MCInst &Inst, unsigned N) const {
1171 assert(N == 1 && "Invalid number of operands!");
1172 Inst.addOperand(MCOperand::createReg(getReg()));
1173 }
1174
1175 template <unsigned NumRegs>
addVectorList64Operands(MCInst & Inst,unsigned N) const1176 void addVectorList64Operands(MCInst &Inst, unsigned N) const {
1177 assert(N == 1 && "Invalid number of operands!");
1178 static unsigned FirstRegs[] = { AArch64::D0, AArch64::D0_D1,
1179 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 };
1180 unsigned FirstReg = FirstRegs[NumRegs - 1];
1181
1182 Inst.addOperand(
1183 MCOperand::createReg(FirstReg + getVectorListStart() - AArch64::Q0));
1184 }
1185
1186 template <unsigned NumRegs>
addVectorList128Operands(MCInst & Inst,unsigned N) const1187 void addVectorList128Operands(MCInst &Inst, unsigned N) const {
1188 assert(N == 1 && "Invalid number of operands!");
1189 static unsigned FirstRegs[] = { AArch64::Q0, AArch64::Q0_Q1,
1190 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 };
1191 unsigned FirstReg = FirstRegs[NumRegs - 1];
1192
1193 Inst.addOperand(
1194 MCOperand::createReg(FirstReg + getVectorListStart() - AArch64::Q0));
1195 }
1196
addVectorIndex1Operands(MCInst & Inst,unsigned N) const1197 void addVectorIndex1Operands(MCInst &Inst, unsigned N) const {
1198 assert(N == 1 && "Invalid number of operands!");
1199 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1200 }
1201
addVectorIndexBOperands(MCInst & Inst,unsigned N) const1202 void addVectorIndexBOperands(MCInst &Inst, unsigned N) const {
1203 assert(N == 1 && "Invalid number of operands!");
1204 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1205 }
1206
addVectorIndexHOperands(MCInst & Inst,unsigned N) const1207 void addVectorIndexHOperands(MCInst &Inst, unsigned N) const {
1208 assert(N == 1 && "Invalid number of operands!");
1209 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1210 }
1211
addVectorIndexSOperands(MCInst & Inst,unsigned N) const1212 void addVectorIndexSOperands(MCInst &Inst, unsigned N) const {
1213 assert(N == 1 && "Invalid number of operands!");
1214 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1215 }
1216
addVectorIndexDOperands(MCInst & Inst,unsigned N) const1217 void addVectorIndexDOperands(MCInst &Inst, unsigned N) const {
1218 assert(N == 1 && "Invalid number of operands!");
1219 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1220 }
1221
addImmOperands(MCInst & Inst,unsigned N) const1222 void addImmOperands(MCInst &Inst, unsigned N) const {
1223 assert(N == 1 && "Invalid number of operands!");
1224 // If this is a pageoff symrefexpr with an addend, adjust the addend
1225 // to be only the page-offset portion. Otherwise, just add the expr
1226 // as-is.
1227 addExpr(Inst, getImm());
1228 }
1229
addAddSubImmOperands(MCInst & Inst,unsigned N) const1230 void addAddSubImmOperands(MCInst &Inst, unsigned N) const {
1231 assert(N == 2 && "Invalid number of operands!");
1232 if (isShiftedImm()) {
1233 addExpr(Inst, getShiftedImmVal());
1234 Inst.addOperand(MCOperand::createImm(getShiftedImmShift()));
1235 } else {
1236 addExpr(Inst, getImm());
1237 Inst.addOperand(MCOperand::createImm(0));
1238 }
1239 }
1240
addAddSubImmNegOperands(MCInst & Inst,unsigned N) const1241 void addAddSubImmNegOperands(MCInst &Inst, unsigned N) const {
1242 assert(N == 2 && "Invalid number of operands!");
1243
1244 const MCExpr *MCE = isShiftedImm() ? getShiftedImmVal() : getImm();
1245 const MCConstantExpr *CE = cast<MCConstantExpr>(MCE);
1246 int64_t Val = -CE->getValue();
1247 unsigned ShiftAmt = isShiftedImm() ? ShiftedImm.ShiftAmount : 0;
1248
1249 Inst.addOperand(MCOperand::createImm(Val));
1250 Inst.addOperand(MCOperand::createImm(ShiftAmt));
1251 }
1252
addCondCodeOperands(MCInst & Inst,unsigned N) const1253 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1254 assert(N == 1 && "Invalid number of operands!");
1255 Inst.addOperand(MCOperand::createImm(getCondCode()));
1256 }
1257
addAdrpLabelOperands(MCInst & Inst,unsigned N) const1258 void addAdrpLabelOperands(MCInst &Inst, unsigned N) const {
1259 assert(N == 1 && "Invalid number of operands!");
1260 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1261 if (!MCE)
1262 addExpr(Inst, getImm());
1263 else
1264 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 12));
1265 }
1266
addAdrLabelOperands(MCInst & Inst,unsigned N) const1267 void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
1268 addImmOperands(Inst, N);
1269 }
1270
1271 template<int Scale>
addUImm12OffsetOperands(MCInst & Inst,unsigned N) const1272 void addUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1273 assert(N == 1 && "Invalid number of operands!");
1274 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1275
1276 if (!MCE) {
1277 Inst.addOperand(MCOperand::createExpr(getImm()));
1278 return;
1279 }
1280 Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale));
1281 }
1282
addSImm9Operands(MCInst & Inst,unsigned N) const1283 void addSImm9Operands(MCInst &Inst, unsigned N) const {
1284 assert(N == 1 && "Invalid number of operands!");
1285 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1286 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1287 }
1288
addSImm7s4Operands(MCInst & Inst,unsigned N) const1289 void addSImm7s4Operands(MCInst &Inst, unsigned N) const {
1290 assert(N == 1 && "Invalid number of operands!");
1291 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1292 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 4));
1293 }
1294
addSImm7s8Operands(MCInst & Inst,unsigned N) const1295 void addSImm7s8Operands(MCInst &Inst, unsigned N) const {
1296 assert(N == 1 && "Invalid number of operands!");
1297 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1298 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 8));
1299 }
1300
addSImm7s16Operands(MCInst & Inst,unsigned N) const1301 void addSImm7s16Operands(MCInst &Inst, unsigned N) const {
1302 assert(N == 1 && "Invalid number of operands!");
1303 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1304 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 16));
1305 }
1306
addImm0_7Operands(MCInst & Inst,unsigned N) const1307 void addImm0_7Operands(MCInst &Inst, unsigned N) const {
1308 assert(N == 1 && "Invalid number of operands!");
1309 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1310 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1311 }
1312
addImm1_8Operands(MCInst & Inst,unsigned N) const1313 void addImm1_8Operands(MCInst &Inst, unsigned N) const {
1314 assert(N == 1 && "Invalid number of operands!");
1315 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1316 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1317 }
1318
addImm0_15Operands(MCInst & Inst,unsigned N) const1319 void addImm0_15Operands(MCInst &Inst, unsigned N) const {
1320 assert(N == 1 && "Invalid number of operands!");
1321 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1322 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1323 }
1324
addImm1_16Operands(MCInst & Inst,unsigned N) const1325 void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1326 assert(N == 1 && "Invalid number of operands!");
1327 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1328 assert(MCE && "Invalid constant immediate operand!");
1329 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1330 }
1331
addImm0_31Operands(MCInst & Inst,unsigned N) const1332 void addImm0_31Operands(MCInst &Inst, unsigned N) const {
1333 assert(N == 1 && "Invalid number of operands!");
1334 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1335 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1336 }
1337
addImm1_31Operands(MCInst & Inst,unsigned N) const1338 void addImm1_31Operands(MCInst &Inst, unsigned N) const {
1339 assert(N == 1 && "Invalid number of operands!");
1340 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1341 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1342 }
1343
addImm1_32Operands(MCInst & Inst,unsigned N) const1344 void addImm1_32Operands(MCInst &Inst, unsigned N) const {
1345 assert(N == 1 && "Invalid number of operands!");
1346 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1347 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1348 }
1349
addImm0_63Operands(MCInst & Inst,unsigned N) const1350 void addImm0_63Operands(MCInst &Inst, unsigned N) const {
1351 assert(N == 1 && "Invalid number of operands!");
1352 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1353 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1354 }
1355
addImm1_63Operands(MCInst & Inst,unsigned N) const1356 void addImm1_63Operands(MCInst &Inst, unsigned N) const {
1357 assert(N == 1 && "Invalid number of operands!");
1358 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1359 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1360 }
1361
addImm1_64Operands(MCInst & Inst,unsigned N) const1362 void addImm1_64Operands(MCInst &Inst, unsigned N) const {
1363 assert(N == 1 && "Invalid number of operands!");
1364 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1365 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1366 }
1367
addImm0_127Operands(MCInst & Inst,unsigned N) const1368 void addImm0_127Operands(MCInst &Inst, unsigned N) const {
1369 assert(N == 1 && "Invalid number of operands!");
1370 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1371 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1372 }
1373
addImm0_255Operands(MCInst & Inst,unsigned N) const1374 void addImm0_255Operands(MCInst &Inst, unsigned N) const {
1375 assert(N == 1 && "Invalid number of operands!");
1376 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1377 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1378 }
1379
addImm0_65535Operands(MCInst & Inst,unsigned N) const1380 void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
1381 assert(N == 1 && "Invalid number of operands!");
1382 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1383 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1384 }
1385
addImm32_63Operands(MCInst & Inst,unsigned N) const1386 void addImm32_63Operands(MCInst &Inst, unsigned N) const {
1387 assert(N == 1 && "Invalid number of operands!");
1388 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1389 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1390 }
1391
addLogicalImm32Operands(MCInst & Inst,unsigned N) const1392 void addLogicalImm32Operands(MCInst &Inst, unsigned N) const {
1393 assert(N == 1 && "Invalid number of operands!");
1394 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1395 uint64_t encoding =
1396 AArch64_AM::encodeLogicalImmediate(MCE->getValue() & 0xFFFFFFFF, 32);
1397 Inst.addOperand(MCOperand::createImm(encoding));
1398 }
1399
addLogicalImm64Operands(MCInst & Inst,unsigned N) const1400 void addLogicalImm64Operands(MCInst &Inst, unsigned N) const {
1401 assert(N == 1 && "Invalid number of operands!");
1402 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1403 uint64_t encoding = AArch64_AM::encodeLogicalImmediate(MCE->getValue(), 64);
1404 Inst.addOperand(MCOperand::createImm(encoding));
1405 }
1406
addLogicalImm32NotOperands(MCInst & Inst,unsigned N) const1407 void addLogicalImm32NotOperands(MCInst &Inst, unsigned N) const {
1408 assert(N == 1 && "Invalid number of operands!");
1409 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1410 int64_t Val = ~MCE->getValue() & 0xFFFFFFFF;
1411 uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, 32);
1412 Inst.addOperand(MCOperand::createImm(encoding));
1413 }
1414
addLogicalImm64NotOperands(MCInst & Inst,unsigned N) const1415 void addLogicalImm64NotOperands(MCInst &Inst, unsigned N) const {
1416 assert(N == 1 && "Invalid number of operands!");
1417 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1418 uint64_t encoding =
1419 AArch64_AM::encodeLogicalImmediate(~MCE->getValue(), 64);
1420 Inst.addOperand(MCOperand::createImm(encoding));
1421 }
1422
addSIMDImmType10Operands(MCInst & Inst,unsigned N) const1423 void addSIMDImmType10Operands(MCInst &Inst, unsigned N) const {
1424 assert(N == 1 && "Invalid number of operands!");
1425 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1426 uint64_t encoding = AArch64_AM::encodeAdvSIMDModImmType10(MCE->getValue());
1427 Inst.addOperand(MCOperand::createImm(encoding));
1428 }
1429
addBranchTarget26Operands(MCInst & Inst,unsigned N) const1430 void addBranchTarget26Operands(MCInst &Inst, unsigned N) const {
1431 // Branch operands don't encode the low bits, so shift them off
1432 // here. If it's a label, however, just put it on directly as there's
1433 // not enough information now to do anything.
1434 assert(N == 1 && "Invalid number of operands!");
1435 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1436 if (!MCE) {
1437 addExpr(Inst, getImm());
1438 return;
1439 }
1440 assert(MCE && "Invalid constant immediate operand!");
1441 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1442 }
1443
addPCRelLabel19Operands(MCInst & Inst,unsigned N) const1444 void addPCRelLabel19Operands(MCInst &Inst, unsigned N) const {
1445 // Branch operands don't encode the low bits, so shift them off
1446 // here. If it's a label, however, just put it on directly as there's
1447 // not enough information now to do anything.
1448 assert(N == 1 && "Invalid number of operands!");
1449 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1450 if (!MCE) {
1451 addExpr(Inst, getImm());
1452 return;
1453 }
1454 assert(MCE && "Invalid constant immediate operand!");
1455 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1456 }
1457
addBranchTarget14Operands(MCInst & Inst,unsigned N) const1458 void addBranchTarget14Operands(MCInst &Inst, unsigned N) const {
1459 // Branch operands don't encode the low bits, so shift them off
1460 // here. If it's a label, however, just put it on directly as there's
1461 // not enough information now to do anything.
1462 assert(N == 1 && "Invalid number of operands!");
1463 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1464 if (!MCE) {
1465 addExpr(Inst, getImm());
1466 return;
1467 }
1468 assert(MCE && "Invalid constant immediate operand!");
1469 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1470 }
1471
addFPImmOperands(MCInst & Inst,unsigned N) const1472 void addFPImmOperands(MCInst &Inst, unsigned N) const {
1473 assert(N == 1 && "Invalid number of operands!");
1474 Inst.addOperand(MCOperand::createImm(getFPImm()));
1475 }
1476
addBarrierOperands(MCInst & Inst,unsigned N) const1477 void addBarrierOperands(MCInst &Inst, unsigned N) const {
1478 assert(N == 1 && "Invalid number of operands!");
1479 Inst.addOperand(MCOperand::createImm(getBarrier()));
1480 }
1481
addMRSSystemRegisterOperands(MCInst & Inst,unsigned N) const1482 void addMRSSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1483 assert(N == 1 && "Invalid number of operands!");
1484
1485 Inst.addOperand(MCOperand::createImm(SysReg.MRSReg));
1486 }
1487
addMSRSystemRegisterOperands(MCInst & Inst,unsigned N) const1488 void addMSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1489 assert(N == 1 && "Invalid number of operands!");
1490
1491 Inst.addOperand(MCOperand::createImm(SysReg.MSRReg));
1492 }
1493
addSystemPStateFieldOperands(MCInst & Inst,unsigned N) const1494 void addSystemPStateFieldOperands(MCInst &Inst, unsigned N) const {
1495 assert(N == 1 && "Invalid number of operands!");
1496
1497 Inst.addOperand(MCOperand::createImm(SysReg.PStateField));
1498 }
1499
addSysCROperands(MCInst & Inst,unsigned N) const1500 void addSysCROperands(MCInst &Inst, unsigned N) const {
1501 assert(N == 1 && "Invalid number of operands!");
1502 Inst.addOperand(MCOperand::createImm(getSysCR()));
1503 }
1504
addPrefetchOperands(MCInst & Inst,unsigned N) const1505 void addPrefetchOperands(MCInst &Inst, unsigned N) const {
1506 assert(N == 1 && "Invalid number of operands!");
1507 Inst.addOperand(MCOperand::createImm(getPrefetch()));
1508 }
1509
addShifterOperands(MCInst & Inst,unsigned N) const1510 void addShifterOperands(MCInst &Inst, unsigned N) const {
1511 assert(N == 1 && "Invalid number of operands!");
1512 unsigned Imm =
1513 AArch64_AM::getShifterImm(getShiftExtendType(), getShiftExtendAmount());
1514 Inst.addOperand(MCOperand::createImm(Imm));
1515 }
1516
addExtendOperands(MCInst & Inst,unsigned N) const1517 void addExtendOperands(MCInst &Inst, unsigned N) const {
1518 assert(N == 1 && "Invalid number of operands!");
1519 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1520 if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTW;
1521 unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
1522 Inst.addOperand(MCOperand::createImm(Imm));
1523 }
1524
addExtend64Operands(MCInst & Inst,unsigned N) const1525 void addExtend64Operands(MCInst &Inst, unsigned N) const {
1526 assert(N == 1 && "Invalid number of operands!");
1527 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1528 if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTX;
1529 unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
1530 Inst.addOperand(MCOperand::createImm(Imm));
1531 }
1532
addMemExtendOperands(MCInst & Inst,unsigned N) const1533 void addMemExtendOperands(MCInst &Inst, unsigned N) const {
1534 assert(N == 2 && "Invalid number of operands!");
1535 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1536 bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
1537 Inst.addOperand(MCOperand::createImm(IsSigned));
1538 Inst.addOperand(MCOperand::createImm(getShiftExtendAmount() != 0));
1539 }
1540
1541 // For 8-bit load/store instructions with a register offset, both the
1542 // "DoShift" and "NoShift" variants have a shift of 0. Because of this,
1543 // they're disambiguated by whether the shift was explicit or implicit rather
1544 // than its size.
addMemExtend8Operands(MCInst & Inst,unsigned N) const1545 void addMemExtend8Operands(MCInst &Inst, unsigned N) const {
1546 assert(N == 2 && "Invalid number of operands!");
1547 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1548 bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
1549 Inst.addOperand(MCOperand::createImm(IsSigned));
1550 Inst.addOperand(MCOperand::createImm(hasShiftExtendAmount()));
1551 }
1552
1553 template<int Shift>
addMOVZMovAliasOperands(MCInst & Inst,unsigned N) const1554 void addMOVZMovAliasOperands(MCInst &Inst, unsigned N) const {
1555 assert(N == 1 && "Invalid number of operands!");
1556
1557 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
1558 uint64_t Value = CE->getValue();
1559 Inst.addOperand(MCOperand::createImm((Value >> Shift) & 0xffff));
1560 }
1561
1562 template<int Shift>
addMOVNMovAliasOperands(MCInst & Inst,unsigned N) const1563 void addMOVNMovAliasOperands(MCInst &Inst, unsigned N) const {
1564 assert(N == 1 && "Invalid number of operands!");
1565
1566 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
1567 uint64_t Value = CE->getValue();
1568 Inst.addOperand(MCOperand::createImm((~Value >> Shift) & 0xffff));
1569 }
1570
1571 void print(raw_ostream &OS) const override;
1572
1573 static std::unique_ptr<AArch64Operand>
CreateToken(StringRef Str,bool IsSuffix,SMLoc S,MCContext & Ctx)1574 CreateToken(StringRef Str, bool IsSuffix, SMLoc S, MCContext &Ctx) {
1575 auto Op = make_unique<AArch64Operand>(k_Token, Ctx);
1576 Op->Tok.Data = Str.data();
1577 Op->Tok.Length = Str.size();
1578 Op->Tok.IsSuffix = IsSuffix;
1579 Op->StartLoc = S;
1580 Op->EndLoc = S;
1581 return Op;
1582 }
1583
1584 static std::unique_ptr<AArch64Operand>
CreateReg(unsigned RegNum,bool isVector,SMLoc S,SMLoc E,MCContext & Ctx)1585 CreateReg(unsigned RegNum, bool isVector, SMLoc S, SMLoc E, MCContext &Ctx) {
1586 auto Op = make_unique<AArch64Operand>(k_Register, Ctx);
1587 Op->Reg.RegNum = RegNum;
1588 Op->Reg.isVector = isVector;
1589 Op->StartLoc = S;
1590 Op->EndLoc = E;
1591 return Op;
1592 }
1593
1594 static std::unique_ptr<AArch64Operand>
CreateVectorList(unsigned RegNum,unsigned Count,unsigned NumElements,char ElementKind,SMLoc S,SMLoc E,MCContext & Ctx)1595 CreateVectorList(unsigned RegNum, unsigned Count, unsigned NumElements,
1596 char ElementKind, SMLoc S, SMLoc E, MCContext &Ctx) {
1597 auto Op = make_unique<AArch64Operand>(k_VectorList, Ctx);
1598 Op->VectorList.RegNum = RegNum;
1599 Op->VectorList.Count = Count;
1600 Op->VectorList.NumElements = NumElements;
1601 Op->VectorList.ElementKind = ElementKind;
1602 Op->StartLoc = S;
1603 Op->EndLoc = E;
1604 return Op;
1605 }
1606
1607 static std::unique_ptr<AArch64Operand>
CreateVectorIndex(unsigned Idx,SMLoc S,SMLoc E,MCContext & Ctx)1608 CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) {
1609 auto Op = make_unique<AArch64Operand>(k_VectorIndex, Ctx);
1610 Op->VectorIndex.Val = Idx;
1611 Op->StartLoc = S;
1612 Op->EndLoc = E;
1613 return Op;
1614 }
1615
CreateImm(const MCExpr * Val,SMLoc S,SMLoc E,MCContext & Ctx)1616 static std::unique_ptr<AArch64Operand> CreateImm(const MCExpr *Val, SMLoc S,
1617 SMLoc E, MCContext &Ctx) {
1618 auto Op = make_unique<AArch64Operand>(k_Immediate, Ctx);
1619 Op->Imm.Val = Val;
1620 Op->StartLoc = S;
1621 Op->EndLoc = E;
1622 return Op;
1623 }
1624
CreateShiftedImm(const MCExpr * Val,unsigned ShiftAmount,SMLoc S,SMLoc E,MCContext & Ctx)1625 static std::unique_ptr<AArch64Operand> CreateShiftedImm(const MCExpr *Val,
1626 unsigned ShiftAmount,
1627 SMLoc S, SMLoc E,
1628 MCContext &Ctx) {
1629 auto Op = make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
1630 Op->ShiftedImm .Val = Val;
1631 Op->ShiftedImm.ShiftAmount = ShiftAmount;
1632 Op->StartLoc = S;
1633 Op->EndLoc = E;
1634 return Op;
1635 }
1636
1637 static std::unique_ptr<AArch64Operand>
CreateCondCode(AArch64CC::CondCode Code,SMLoc S,SMLoc E,MCContext & Ctx)1638 CreateCondCode(AArch64CC::CondCode Code, SMLoc S, SMLoc E, MCContext &Ctx) {
1639 auto Op = make_unique<AArch64Operand>(k_CondCode, Ctx);
1640 Op->CondCode.Code = Code;
1641 Op->StartLoc = S;
1642 Op->EndLoc = E;
1643 return Op;
1644 }
1645
CreateFPImm(unsigned Val,SMLoc S,MCContext & Ctx)1646 static std::unique_ptr<AArch64Operand> CreateFPImm(unsigned Val, SMLoc S,
1647 MCContext &Ctx) {
1648 auto Op = make_unique<AArch64Operand>(k_FPImm, Ctx);
1649 Op->FPImm.Val = Val;
1650 Op->StartLoc = S;
1651 Op->EndLoc = S;
1652 return Op;
1653 }
1654
CreateBarrier(unsigned Val,StringRef Str,SMLoc S,MCContext & Ctx)1655 static std::unique_ptr<AArch64Operand> CreateBarrier(unsigned Val,
1656 StringRef Str,
1657 SMLoc S,
1658 MCContext &Ctx) {
1659 auto Op = make_unique<AArch64Operand>(k_Barrier, Ctx);
1660 Op->Barrier.Val = Val;
1661 Op->Barrier.Data = Str.data();
1662 Op->Barrier.Length = Str.size();
1663 Op->StartLoc = S;
1664 Op->EndLoc = S;
1665 return Op;
1666 }
1667
CreateSysReg(StringRef Str,SMLoc S,uint32_t MRSReg,uint32_t MSRReg,uint32_t PStateField,MCContext & Ctx)1668 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
1669 uint32_t MRSReg,
1670 uint32_t MSRReg,
1671 uint32_t PStateField,
1672 MCContext &Ctx) {
1673 auto Op = make_unique<AArch64Operand>(k_SysReg, Ctx);
1674 Op->SysReg.Data = Str.data();
1675 Op->SysReg.Length = Str.size();
1676 Op->SysReg.MRSReg = MRSReg;
1677 Op->SysReg.MSRReg = MSRReg;
1678 Op->SysReg.PStateField = PStateField;
1679 Op->StartLoc = S;
1680 Op->EndLoc = S;
1681 return Op;
1682 }
1683
CreateSysCR(unsigned Val,SMLoc S,SMLoc E,MCContext & Ctx)1684 static std::unique_ptr<AArch64Operand> CreateSysCR(unsigned Val, SMLoc S,
1685 SMLoc E, MCContext &Ctx) {
1686 auto Op = make_unique<AArch64Operand>(k_SysCR, Ctx);
1687 Op->SysCRImm.Val = Val;
1688 Op->StartLoc = S;
1689 Op->EndLoc = E;
1690 return Op;
1691 }
1692
CreatePrefetch(unsigned Val,StringRef Str,SMLoc S,MCContext & Ctx)1693 static std::unique_ptr<AArch64Operand> CreatePrefetch(unsigned Val,
1694 StringRef Str,
1695 SMLoc S,
1696 MCContext &Ctx) {
1697 auto Op = make_unique<AArch64Operand>(k_Prefetch, Ctx);
1698 Op->Prefetch.Val = Val;
1699 Op->Barrier.Data = Str.data();
1700 Op->Barrier.Length = Str.size();
1701 Op->StartLoc = S;
1702 Op->EndLoc = S;
1703 return Op;
1704 }
1705
1706 static std::unique_ptr<AArch64Operand>
CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp,unsigned Val,bool HasExplicitAmount,SMLoc S,SMLoc E,MCContext & Ctx)1707 CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val,
1708 bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) {
1709 auto Op = make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
1710 Op->ShiftExtend.Type = ShOp;
1711 Op->ShiftExtend.Amount = Val;
1712 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
1713 Op->StartLoc = S;
1714 Op->EndLoc = E;
1715 return Op;
1716 }
1717 };
1718
1719 } // end anonymous namespace.
1720
print(raw_ostream & OS) const1721 void AArch64Operand::print(raw_ostream &OS) const {
1722 switch (Kind) {
1723 case k_FPImm:
1724 OS << "<fpimm " << getFPImm() << "("
1725 << AArch64_AM::getFPImmFloat(getFPImm()) << ") >";
1726 break;
1727 case k_Barrier: {
1728 StringRef Name = getBarrierName();
1729 if (!Name.empty())
1730 OS << "<barrier " << Name << ">";
1731 else
1732 OS << "<barrier invalid #" << getBarrier() << ">";
1733 break;
1734 }
1735 case k_Immediate:
1736 OS << *getImm();
1737 break;
1738 case k_ShiftedImm: {
1739 unsigned Shift = getShiftedImmShift();
1740 OS << "<shiftedimm ";
1741 OS << *getShiftedImmVal();
1742 OS << ", lsl #" << AArch64_AM::getShiftValue(Shift) << ">";
1743 break;
1744 }
1745 case k_CondCode:
1746 OS << "<condcode " << getCondCode() << ">";
1747 break;
1748 case k_Register:
1749 OS << "<register " << getReg() << ">";
1750 break;
1751 case k_VectorList: {
1752 OS << "<vectorlist ";
1753 unsigned Reg = getVectorListStart();
1754 for (unsigned i = 0, e = getVectorListCount(); i != e; ++i)
1755 OS << Reg + i << " ";
1756 OS << ">";
1757 break;
1758 }
1759 case k_VectorIndex:
1760 OS << "<vectorindex " << getVectorIndex() << ">";
1761 break;
1762 case k_SysReg:
1763 OS << "<sysreg: " << getSysReg() << '>';
1764 break;
1765 case k_Token:
1766 OS << "'" << getToken() << "'";
1767 break;
1768 case k_SysCR:
1769 OS << "c" << getSysCR();
1770 break;
1771 case k_Prefetch: {
1772 StringRef Name = getPrefetchName();
1773 if (!Name.empty())
1774 OS << "<prfop " << Name << ">";
1775 else
1776 OS << "<prfop invalid #" << getPrefetch() << ">";
1777 break;
1778 }
1779 case k_ShiftExtend: {
1780 OS << "<" << AArch64_AM::getShiftExtendName(getShiftExtendType()) << " #"
1781 << getShiftExtendAmount();
1782 if (!hasShiftExtendAmount())
1783 OS << "<imp>";
1784 OS << '>';
1785 break;
1786 }
1787 }
1788 }
1789
1790 /// @name Auto-generated Match Functions
1791 /// {
1792
1793 static unsigned MatchRegisterName(StringRef Name);
1794
1795 /// }
1796
matchVectorRegName(StringRef Name)1797 static unsigned matchVectorRegName(StringRef Name) {
1798 return StringSwitch<unsigned>(Name.lower())
1799 .Case("v0", AArch64::Q0)
1800 .Case("v1", AArch64::Q1)
1801 .Case("v2", AArch64::Q2)
1802 .Case("v3", AArch64::Q3)
1803 .Case("v4", AArch64::Q4)
1804 .Case("v5", AArch64::Q5)
1805 .Case("v6", AArch64::Q6)
1806 .Case("v7", AArch64::Q7)
1807 .Case("v8", AArch64::Q8)
1808 .Case("v9", AArch64::Q9)
1809 .Case("v10", AArch64::Q10)
1810 .Case("v11", AArch64::Q11)
1811 .Case("v12", AArch64::Q12)
1812 .Case("v13", AArch64::Q13)
1813 .Case("v14", AArch64::Q14)
1814 .Case("v15", AArch64::Q15)
1815 .Case("v16", AArch64::Q16)
1816 .Case("v17", AArch64::Q17)
1817 .Case("v18", AArch64::Q18)
1818 .Case("v19", AArch64::Q19)
1819 .Case("v20", AArch64::Q20)
1820 .Case("v21", AArch64::Q21)
1821 .Case("v22", AArch64::Q22)
1822 .Case("v23", AArch64::Q23)
1823 .Case("v24", AArch64::Q24)
1824 .Case("v25", AArch64::Q25)
1825 .Case("v26", AArch64::Q26)
1826 .Case("v27", AArch64::Q27)
1827 .Case("v28", AArch64::Q28)
1828 .Case("v29", AArch64::Q29)
1829 .Case("v30", AArch64::Q30)
1830 .Case("v31", AArch64::Q31)
1831 .Default(0);
1832 }
1833
isValidVectorKind(StringRef Name)1834 static bool isValidVectorKind(StringRef Name) {
1835 return StringSwitch<bool>(Name.lower())
1836 .Case(".8b", true)
1837 .Case(".16b", true)
1838 .Case(".4h", true)
1839 .Case(".8h", true)
1840 .Case(".2s", true)
1841 .Case(".4s", true)
1842 .Case(".1d", true)
1843 .Case(".2d", true)
1844 .Case(".1q", true)
1845 // Accept the width neutral ones, too, for verbose syntax. If those
1846 // aren't used in the right places, the token operand won't match so
1847 // all will work out.
1848 .Case(".b", true)
1849 .Case(".h", true)
1850 .Case(".s", true)
1851 .Case(".d", true)
1852 .Default(false);
1853 }
1854
parseValidVectorKind(StringRef Name,unsigned & NumElements,char & ElementKind)1855 static void parseValidVectorKind(StringRef Name, unsigned &NumElements,
1856 char &ElementKind) {
1857 assert(isValidVectorKind(Name));
1858
1859 ElementKind = Name.lower()[Name.size() - 1];
1860 NumElements = 0;
1861
1862 if (Name.size() == 2)
1863 return;
1864
1865 // Parse the lane count
1866 Name = Name.drop_front();
1867 while (isdigit(Name.front())) {
1868 NumElements = 10 * NumElements + (Name.front() - '0');
1869 Name = Name.drop_front();
1870 }
1871 }
1872
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)1873 bool AArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1874 SMLoc &EndLoc) {
1875 StartLoc = getLoc();
1876 RegNo = tryParseRegister();
1877 EndLoc = SMLoc::getFromPointer(getLoc().getPointer() - 1);
1878 return (RegNo == (unsigned)-1);
1879 }
1880
1881 // Matches a register name or register alias previously defined by '.req'
matchRegisterNameAlias(StringRef Name,bool isVector)1882 unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
1883 bool isVector) {
1884 unsigned RegNum = isVector ? matchVectorRegName(Name)
1885 : MatchRegisterName(Name);
1886
1887 if (RegNum == 0) {
1888 // Check for aliases registered via .req. Canonicalize to lower case.
1889 // That's more consistent since register names are case insensitive, and
1890 // it's how the original entry was passed in from MC/MCParser/AsmParser.
1891 auto Entry = RegisterReqs.find(Name.lower());
1892 if (Entry == RegisterReqs.end())
1893 return 0;
1894 // set RegNum if the match is the right kind of register
1895 if (isVector == Entry->getValue().first)
1896 RegNum = Entry->getValue().second;
1897 }
1898 return RegNum;
1899 }
1900
1901 /// tryParseRegister - Try to parse a register name. The token must be an
1902 /// Identifier when called, and if it is a register name the token is eaten and
1903 /// the register is added to the operand list.
tryParseRegister()1904 int AArch64AsmParser::tryParseRegister() {
1905 MCAsmParser &Parser = getParser();
1906 const AsmToken &Tok = Parser.getTok();
1907 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1908
1909 std::string lowerCase = Tok.getString().lower();
1910 unsigned RegNum = matchRegisterNameAlias(lowerCase, false);
1911 // Also handle a few aliases of registers.
1912 if (RegNum == 0)
1913 RegNum = StringSwitch<unsigned>(lowerCase)
1914 .Case("fp", AArch64::FP)
1915 .Case("lr", AArch64::LR)
1916 .Case("x31", AArch64::XZR)
1917 .Case("w31", AArch64::WZR)
1918 .Default(0);
1919
1920 if (RegNum == 0)
1921 return -1;
1922
1923 Parser.Lex(); // Eat identifier token.
1924 return RegNum;
1925 }
1926
1927 /// tryMatchVectorRegister - Try to parse a vector register name with optional
1928 /// kind specifier. If it is a register specifier, eat the token and return it.
tryMatchVectorRegister(StringRef & Kind,bool expected)1929 int AArch64AsmParser::tryMatchVectorRegister(StringRef &Kind, bool expected) {
1930 MCAsmParser &Parser = getParser();
1931 if (Parser.getTok().isNot(AsmToken::Identifier)) {
1932 TokError("vector register expected");
1933 return -1;
1934 }
1935
1936 StringRef Name = Parser.getTok().getString();
1937 // If there is a kind specifier, it's separated from the register name by
1938 // a '.'.
1939 size_t Start = 0, Next = Name.find('.');
1940 StringRef Head = Name.slice(Start, Next);
1941 unsigned RegNum = matchRegisterNameAlias(Head, true);
1942
1943 if (RegNum) {
1944 if (Next != StringRef::npos) {
1945 Kind = Name.slice(Next, StringRef::npos);
1946 if (!isValidVectorKind(Kind)) {
1947 TokError("invalid vector kind qualifier");
1948 return -1;
1949 }
1950 }
1951 Parser.Lex(); // Eat the register token.
1952 return RegNum;
1953 }
1954
1955 if (expected)
1956 TokError("vector register expected");
1957 return -1;
1958 }
1959
1960 /// tryParseSysCROperand - Try to parse a system instruction CR operand name.
1961 AArch64AsmParser::OperandMatchResultTy
tryParseSysCROperand(OperandVector & Operands)1962 AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) {
1963 MCAsmParser &Parser = getParser();
1964 SMLoc S = getLoc();
1965
1966 if (Parser.getTok().isNot(AsmToken::Identifier)) {
1967 Error(S, "Expected cN operand where 0 <= N <= 15");
1968 return MatchOperand_ParseFail;
1969 }
1970
1971 StringRef Tok = Parser.getTok().getIdentifier();
1972 if (Tok[0] != 'c' && Tok[0] != 'C') {
1973 Error(S, "Expected cN operand where 0 <= N <= 15");
1974 return MatchOperand_ParseFail;
1975 }
1976
1977 uint32_t CRNum;
1978 bool BadNum = Tok.drop_front().getAsInteger(10, CRNum);
1979 if (BadNum || CRNum > 15) {
1980 Error(S, "Expected cN operand where 0 <= N <= 15");
1981 return MatchOperand_ParseFail;
1982 }
1983
1984 Parser.Lex(); // Eat identifier token.
1985 Operands.push_back(
1986 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
1987 return MatchOperand_Success;
1988 }
1989
1990 /// tryParsePrefetch - Try to parse a prefetch operand.
1991 AArch64AsmParser::OperandMatchResultTy
tryParsePrefetch(OperandVector & Operands)1992 AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
1993 MCAsmParser &Parser = getParser();
1994 SMLoc S = getLoc();
1995 const AsmToken &Tok = Parser.getTok();
1996 // Either an identifier for named values or a 5-bit immediate.
1997 bool Hash = Tok.is(AsmToken::Hash);
1998 if (Hash || Tok.is(AsmToken::Integer)) {
1999 if (Hash)
2000 Parser.Lex(); // Eat hash token.
2001 const MCExpr *ImmVal;
2002 if (getParser().parseExpression(ImmVal))
2003 return MatchOperand_ParseFail;
2004
2005 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2006 if (!MCE) {
2007 TokError("immediate value expected for prefetch operand");
2008 return MatchOperand_ParseFail;
2009 }
2010 unsigned prfop = MCE->getValue();
2011 if (prfop > 31) {
2012 TokError("prefetch operand out of range, [0,31] expected");
2013 return MatchOperand_ParseFail;
2014 }
2015
2016 bool Valid;
2017 auto Mapper = AArch64PRFM::PRFMMapper();
2018 StringRef Name =
2019 Mapper.toString(MCE->getValue(), STI.getFeatureBits(), Valid);
2020 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, Name,
2021 S, getContext()));
2022 return MatchOperand_Success;
2023 }
2024
2025 if (Tok.isNot(AsmToken::Identifier)) {
2026 TokError("pre-fetch hint expected");
2027 return MatchOperand_ParseFail;
2028 }
2029
2030 bool Valid;
2031 auto Mapper = AArch64PRFM::PRFMMapper();
2032 unsigned prfop =
2033 Mapper.fromString(Tok.getString(), STI.getFeatureBits(), Valid);
2034 if (!Valid) {
2035 TokError("pre-fetch hint expected");
2036 return MatchOperand_ParseFail;
2037 }
2038
2039 Parser.Lex(); // Eat identifier token.
2040 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, Tok.getString(),
2041 S, getContext()));
2042 return MatchOperand_Success;
2043 }
2044
2045 /// tryParseAdrpLabel - Parse and validate a source label for the ADRP
2046 /// instruction.
2047 AArch64AsmParser::OperandMatchResultTy
tryParseAdrpLabel(OperandVector & Operands)2048 AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
2049 MCAsmParser &Parser = getParser();
2050 SMLoc S = getLoc();
2051 const MCExpr *Expr;
2052
2053 if (Parser.getTok().is(AsmToken::Hash)) {
2054 Parser.Lex(); // Eat hash token.
2055 }
2056
2057 if (parseSymbolicImmVal(Expr))
2058 return MatchOperand_ParseFail;
2059
2060 AArch64MCExpr::VariantKind ELFRefKind;
2061 MCSymbolRefExpr::VariantKind DarwinRefKind;
2062 int64_t Addend;
2063 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
2064 if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
2065 ELFRefKind == AArch64MCExpr::VK_INVALID) {
2066 // No modifier was specified at all; this is the syntax for an ELF basic
2067 // ADRP relocation (unfortunately).
2068 Expr =
2069 AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_PAGE, getContext());
2070 } else if ((DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGE ||
2071 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGE) &&
2072 Addend != 0) {
2073 Error(S, "gotpage label reference not allowed an addend");
2074 return MatchOperand_ParseFail;
2075 } else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE &&
2076 DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE &&
2077 DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
2078 ELFRefKind != AArch64MCExpr::VK_GOT_PAGE &&
2079 ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
2080 ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
2081 // The operand must be an @page or @gotpage qualified symbolref.
2082 Error(S, "page or gotpage label reference expected");
2083 return MatchOperand_ParseFail;
2084 }
2085 }
2086
2087 // We have either a label reference possibly with addend or an immediate. The
2088 // addend is a raw value here. The linker will adjust it to only reference the
2089 // page.
2090 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2091 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2092
2093 return MatchOperand_Success;
2094 }
2095
2096 /// tryParseAdrLabel - Parse and validate a source label for the ADR
2097 /// instruction.
2098 AArch64AsmParser::OperandMatchResultTy
tryParseAdrLabel(OperandVector & Operands)2099 AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
2100 MCAsmParser &Parser = getParser();
2101 SMLoc S = getLoc();
2102 const MCExpr *Expr;
2103
2104 if (Parser.getTok().is(AsmToken::Hash)) {
2105 Parser.Lex(); // Eat hash token.
2106 }
2107
2108 if (getParser().parseExpression(Expr))
2109 return MatchOperand_ParseFail;
2110
2111 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2112 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2113
2114 return MatchOperand_Success;
2115 }
2116
2117 /// tryParseFPImm - A floating point immediate expression operand.
2118 AArch64AsmParser::OperandMatchResultTy
tryParseFPImm(OperandVector & Operands)2119 AArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
2120 MCAsmParser &Parser = getParser();
2121 SMLoc S = getLoc();
2122
2123 bool Hash = false;
2124 if (Parser.getTok().is(AsmToken::Hash)) {
2125 Parser.Lex(); // Eat '#'
2126 Hash = true;
2127 }
2128
2129 // Handle negation, as that still comes through as a separate token.
2130 bool isNegative = false;
2131 if (Parser.getTok().is(AsmToken::Minus)) {
2132 isNegative = true;
2133 Parser.Lex();
2134 }
2135 const AsmToken &Tok = Parser.getTok();
2136 if (Tok.is(AsmToken::Real)) {
2137 APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
2138 if (isNegative)
2139 RealVal.changeSign();
2140
2141 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
2142 int Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
2143 Parser.Lex(); // Eat the token.
2144 // Check for out of range values. As an exception, we let Zero through,
2145 // as we handle that special case in post-processing before matching in
2146 // order to use the zero register for it.
2147 if (Val == -1 && !RealVal.isPosZero()) {
2148 TokError("expected compatible register or floating-point constant");
2149 return MatchOperand_ParseFail;
2150 }
2151 Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
2152 return MatchOperand_Success;
2153 }
2154 if (Tok.is(AsmToken::Integer)) {
2155 int64_t Val;
2156 if (!isNegative && Tok.getString().startswith("0x")) {
2157 Val = Tok.getIntVal();
2158 if (Val > 255 || Val < 0) {
2159 TokError("encoded floating point value out of range");
2160 return MatchOperand_ParseFail;
2161 }
2162 } else {
2163 APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
2164 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
2165 // If we had a '-' in front, toggle the sign bit.
2166 IntVal ^= (uint64_t)isNegative << 63;
2167 Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
2168 }
2169 Parser.Lex(); // Eat the token.
2170 Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
2171 return MatchOperand_Success;
2172 }
2173
2174 if (!Hash)
2175 return MatchOperand_NoMatch;
2176
2177 TokError("invalid floating point immediate");
2178 return MatchOperand_ParseFail;
2179 }
2180
2181 /// tryParseAddSubImm - Parse ADD/SUB shifted immediate operand
2182 AArch64AsmParser::OperandMatchResultTy
tryParseAddSubImm(OperandVector & Operands)2183 AArch64AsmParser::tryParseAddSubImm(OperandVector &Operands) {
2184 MCAsmParser &Parser = getParser();
2185 SMLoc S = getLoc();
2186
2187 if (Parser.getTok().is(AsmToken::Hash))
2188 Parser.Lex(); // Eat '#'
2189 else if (Parser.getTok().isNot(AsmToken::Integer))
2190 // Operand should start from # or should be integer, emit error otherwise.
2191 return MatchOperand_NoMatch;
2192
2193 const MCExpr *Imm;
2194 if (parseSymbolicImmVal(Imm))
2195 return MatchOperand_ParseFail;
2196 else if (Parser.getTok().isNot(AsmToken::Comma)) {
2197 uint64_t ShiftAmount = 0;
2198 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm);
2199 if (MCE) {
2200 int64_t Val = MCE->getValue();
2201 if (Val > 0xfff && (Val & 0xfff) == 0) {
2202 Imm = MCConstantExpr::create(Val >> 12, getContext());
2203 ShiftAmount = 12;
2204 }
2205 }
2206 SMLoc E = Parser.getTok().getLoc();
2207 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S, E,
2208 getContext()));
2209 return MatchOperand_Success;
2210 }
2211
2212 // Eat ','
2213 Parser.Lex();
2214
2215 // The optional operand must be "lsl #N" where N is non-negative.
2216 if (!Parser.getTok().is(AsmToken::Identifier) ||
2217 !Parser.getTok().getIdentifier().equals_lower("lsl")) {
2218 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
2219 return MatchOperand_ParseFail;
2220 }
2221
2222 // Eat 'lsl'
2223 Parser.Lex();
2224
2225 if (Parser.getTok().is(AsmToken::Hash)) {
2226 Parser.Lex();
2227 }
2228
2229 if (Parser.getTok().isNot(AsmToken::Integer)) {
2230 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
2231 return MatchOperand_ParseFail;
2232 }
2233
2234 int64_t ShiftAmount = Parser.getTok().getIntVal();
2235
2236 if (ShiftAmount < 0) {
2237 Error(Parser.getTok().getLoc(), "positive shift amount required");
2238 return MatchOperand_ParseFail;
2239 }
2240 Parser.Lex(); // Eat the number
2241
2242 SMLoc E = Parser.getTok().getLoc();
2243 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount,
2244 S, E, getContext()));
2245 return MatchOperand_Success;
2246 }
2247
2248 /// parseCondCodeString - Parse a Condition Code string.
parseCondCodeString(StringRef Cond)2249 AArch64CC::CondCode AArch64AsmParser::parseCondCodeString(StringRef Cond) {
2250 AArch64CC::CondCode CC = StringSwitch<AArch64CC::CondCode>(Cond.lower())
2251 .Case("eq", AArch64CC::EQ)
2252 .Case("ne", AArch64CC::NE)
2253 .Case("cs", AArch64CC::HS)
2254 .Case("hs", AArch64CC::HS)
2255 .Case("cc", AArch64CC::LO)
2256 .Case("lo", AArch64CC::LO)
2257 .Case("mi", AArch64CC::MI)
2258 .Case("pl", AArch64CC::PL)
2259 .Case("vs", AArch64CC::VS)
2260 .Case("vc", AArch64CC::VC)
2261 .Case("hi", AArch64CC::HI)
2262 .Case("ls", AArch64CC::LS)
2263 .Case("ge", AArch64CC::GE)
2264 .Case("lt", AArch64CC::LT)
2265 .Case("gt", AArch64CC::GT)
2266 .Case("le", AArch64CC::LE)
2267 .Case("al", AArch64CC::AL)
2268 .Case("nv", AArch64CC::NV)
2269 .Default(AArch64CC::Invalid);
2270 return CC;
2271 }
2272
2273 /// parseCondCode - Parse a Condition Code operand.
parseCondCode(OperandVector & Operands,bool invertCondCode)2274 bool AArch64AsmParser::parseCondCode(OperandVector &Operands,
2275 bool invertCondCode) {
2276 MCAsmParser &Parser = getParser();
2277 SMLoc S = getLoc();
2278 const AsmToken &Tok = Parser.getTok();
2279 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2280
2281 StringRef Cond = Tok.getString();
2282 AArch64CC::CondCode CC = parseCondCodeString(Cond);
2283 if (CC == AArch64CC::Invalid)
2284 return TokError("invalid condition code");
2285 Parser.Lex(); // Eat identifier token.
2286
2287 if (invertCondCode) {
2288 if (CC == AArch64CC::AL || CC == AArch64CC::NV)
2289 return TokError("condition codes AL and NV are invalid for this instruction");
2290 CC = AArch64CC::getInvertedCondCode(AArch64CC::CondCode(CC));
2291 }
2292
2293 Operands.push_back(
2294 AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext()));
2295 return false;
2296 }
2297
2298 /// tryParseOptionalShift - Some operands take an optional shift argument. Parse
2299 /// them if present.
2300 AArch64AsmParser::OperandMatchResultTy
tryParseOptionalShiftExtend(OperandVector & Operands)2301 AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) {
2302 MCAsmParser &Parser = getParser();
2303 const AsmToken &Tok = Parser.getTok();
2304 std::string LowerID = Tok.getString().lower();
2305 AArch64_AM::ShiftExtendType ShOp =
2306 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
2307 .Case("lsl", AArch64_AM::LSL)
2308 .Case("lsr", AArch64_AM::LSR)
2309 .Case("asr", AArch64_AM::ASR)
2310 .Case("ror", AArch64_AM::ROR)
2311 .Case("msl", AArch64_AM::MSL)
2312 .Case("uxtb", AArch64_AM::UXTB)
2313 .Case("uxth", AArch64_AM::UXTH)
2314 .Case("uxtw", AArch64_AM::UXTW)
2315 .Case("uxtx", AArch64_AM::UXTX)
2316 .Case("sxtb", AArch64_AM::SXTB)
2317 .Case("sxth", AArch64_AM::SXTH)
2318 .Case("sxtw", AArch64_AM::SXTW)
2319 .Case("sxtx", AArch64_AM::SXTX)
2320 .Default(AArch64_AM::InvalidShiftExtend);
2321
2322 if (ShOp == AArch64_AM::InvalidShiftExtend)
2323 return MatchOperand_NoMatch;
2324
2325 SMLoc S = Tok.getLoc();
2326 Parser.Lex();
2327
2328 bool Hash = getLexer().is(AsmToken::Hash);
2329 if (!Hash && getLexer().isNot(AsmToken::Integer)) {
2330 if (ShOp == AArch64_AM::LSL || ShOp == AArch64_AM::LSR ||
2331 ShOp == AArch64_AM::ASR || ShOp == AArch64_AM::ROR ||
2332 ShOp == AArch64_AM::MSL) {
2333 // We expect a number here.
2334 TokError("expected #imm after shift specifier");
2335 return MatchOperand_ParseFail;
2336 }
2337
2338 // "extend" type operatoins don't need an immediate, #0 is implicit.
2339 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2340 Operands.push_back(
2341 AArch64Operand::CreateShiftExtend(ShOp, 0, false, S, E, getContext()));
2342 return MatchOperand_Success;
2343 }
2344
2345 if (Hash)
2346 Parser.Lex(); // Eat the '#'.
2347
2348 // Make sure we do actually have a number or a parenthesized expression.
2349 SMLoc E = Parser.getTok().getLoc();
2350 if (!Parser.getTok().is(AsmToken::Integer) &&
2351 !Parser.getTok().is(AsmToken::LParen)) {
2352 Error(E, "expected integer shift amount");
2353 return MatchOperand_ParseFail;
2354 }
2355
2356 const MCExpr *ImmVal;
2357 if (getParser().parseExpression(ImmVal))
2358 return MatchOperand_ParseFail;
2359
2360 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2361 if (!MCE) {
2362 Error(E, "expected constant '#imm' after shift specifier");
2363 return MatchOperand_ParseFail;
2364 }
2365
2366 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2367 Operands.push_back(AArch64Operand::CreateShiftExtend(
2368 ShOp, MCE->getValue(), true, S, E, getContext()));
2369 return MatchOperand_Success;
2370 }
2371
2372 /// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for
2373 /// the SYS instruction. Parse them specially so that we create a SYS MCInst.
parseSysAlias(StringRef Name,SMLoc NameLoc,OperandVector & Operands)2374 bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
2375 OperandVector &Operands) {
2376 if (Name.find('.') != StringRef::npos)
2377 return TokError("invalid operand");
2378
2379 Mnemonic = Name;
2380 Operands.push_back(
2381 AArch64Operand::CreateToken("sys", false, NameLoc, getContext()));
2382
2383 MCAsmParser &Parser = getParser();
2384 const AsmToken &Tok = Parser.getTok();
2385 StringRef Op = Tok.getString();
2386 SMLoc S = Tok.getLoc();
2387
2388 const MCExpr *Expr = nullptr;
2389
2390 #define SYS_ALIAS(op1, Cn, Cm, op2) \
2391 do { \
2392 Expr = MCConstantExpr::create(op1, getContext()); \
2393 Operands.push_back( \
2394 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); \
2395 Operands.push_back( \
2396 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext())); \
2397 Operands.push_back( \
2398 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext())); \
2399 Expr = MCConstantExpr::create(op2, getContext()); \
2400 Operands.push_back( \
2401 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); \
2402 } while (0)
2403
2404 if (Mnemonic == "ic") {
2405 if (!Op.compare_lower("ialluis")) {
2406 // SYS #0, C7, C1, #0
2407 SYS_ALIAS(0, 7, 1, 0);
2408 } else if (!Op.compare_lower("iallu")) {
2409 // SYS #0, C7, C5, #0
2410 SYS_ALIAS(0, 7, 5, 0);
2411 } else if (!Op.compare_lower("ivau")) {
2412 // SYS #3, C7, C5, #1
2413 SYS_ALIAS(3, 7, 5, 1);
2414 } else {
2415 return TokError("invalid operand for IC instruction");
2416 }
2417 } else if (Mnemonic == "dc") {
2418 if (!Op.compare_lower("zva")) {
2419 // SYS #3, C7, C4, #1
2420 SYS_ALIAS(3, 7, 4, 1);
2421 } else if (!Op.compare_lower("ivac")) {
2422 // SYS #3, C7, C6, #1
2423 SYS_ALIAS(0, 7, 6, 1);
2424 } else if (!Op.compare_lower("isw")) {
2425 // SYS #0, C7, C6, #2
2426 SYS_ALIAS(0, 7, 6, 2);
2427 } else if (!Op.compare_lower("cvac")) {
2428 // SYS #3, C7, C10, #1
2429 SYS_ALIAS(3, 7, 10, 1);
2430 } else if (!Op.compare_lower("csw")) {
2431 // SYS #0, C7, C10, #2
2432 SYS_ALIAS(0, 7, 10, 2);
2433 } else if (!Op.compare_lower("cvau")) {
2434 // SYS #3, C7, C11, #1
2435 SYS_ALIAS(3, 7, 11, 1);
2436 } else if (!Op.compare_lower("civac")) {
2437 // SYS #3, C7, C14, #1
2438 SYS_ALIAS(3, 7, 14, 1);
2439 } else if (!Op.compare_lower("cisw")) {
2440 // SYS #0, C7, C14, #2
2441 SYS_ALIAS(0, 7, 14, 2);
2442 } else {
2443 return TokError("invalid operand for DC instruction");
2444 }
2445 } else if (Mnemonic == "at") {
2446 if (!Op.compare_lower("s1e1r")) {
2447 // SYS #0, C7, C8, #0
2448 SYS_ALIAS(0, 7, 8, 0);
2449 } else if (!Op.compare_lower("s1e2r")) {
2450 // SYS #4, C7, C8, #0
2451 SYS_ALIAS(4, 7, 8, 0);
2452 } else if (!Op.compare_lower("s1e3r")) {
2453 // SYS #6, C7, C8, #0
2454 SYS_ALIAS(6, 7, 8, 0);
2455 } else if (!Op.compare_lower("s1e1w")) {
2456 // SYS #0, C7, C8, #1
2457 SYS_ALIAS(0, 7, 8, 1);
2458 } else if (!Op.compare_lower("s1e2w")) {
2459 // SYS #4, C7, C8, #1
2460 SYS_ALIAS(4, 7, 8, 1);
2461 } else if (!Op.compare_lower("s1e3w")) {
2462 // SYS #6, C7, C8, #1
2463 SYS_ALIAS(6, 7, 8, 1);
2464 } else if (!Op.compare_lower("s1e0r")) {
2465 // SYS #0, C7, C8, #3
2466 SYS_ALIAS(0, 7, 8, 2);
2467 } else if (!Op.compare_lower("s1e0w")) {
2468 // SYS #0, C7, C8, #3
2469 SYS_ALIAS(0, 7, 8, 3);
2470 } else if (!Op.compare_lower("s12e1r")) {
2471 // SYS #4, C7, C8, #4
2472 SYS_ALIAS(4, 7, 8, 4);
2473 } else if (!Op.compare_lower("s12e1w")) {
2474 // SYS #4, C7, C8, #5
2475 SYS_ALIAS(4, 7, 8, 5);
2476 } else if (!Op.compare_lower("s12e0r")) {
2477 // SYS #4, C7, C8, #6
2478 SYS_ALIAS(4, 7, 8, 6);
2479 } else if (!Op.compare_lower("s12e0w")) {
2480 // SYS #4, C7, C8, #7
2481 SYS_ALIAS(4, 7, 8, 7);
2482 } else {
2483 return TokError("invalid operand for AT instruction");
2484 }
2485 } else if (Mnemonic == "tlbi") {
2486 if (!Op.compare_lower("vmalle1is")) {
2487 // SYS #0, C8, C3, #0
2488 SYS_ALIAS(0, 8, 3, 0);
2489 } else if (!Op.compare_lower("alle2is")) {
2490 // SYS #4, C8, C3, #0
2491 SYS_ALIAS(4, 8, 3, 0);
2492 } else if (!Op.compare_lower("alle3is")) {
2493 // SYS #6, C8, C3, #0
2494 SYS_ALIAS(6, 8, 3, 0);
2495 } else if (!Op.compare_lower("vae1is")) {
2496 // SYS #0, C8, C3, #1
2497 SYS_ALIAS(0, 8, 3, 1);
2498 } else if (!Op.compare_lower("vae2is")) {
2499 // SYS #4, C8, C3, #1
2500 SYS_ALIAS(4, 8, 3, 1);
2501 } else if (!Op.compare_lower("vae3is")) {
2502 // SYS #6, C8, C3, #1
2503 SYS_ALIAS(6, 8, 3, 1);
2504 } else if (!Op.compare_lower("aside1is")) {
2505 // SYS #0, C8, C3, #2
2506 SYS_ALIAS(0, 8, 3, 2);
2507 } else if (!Op.compare_lower("vaae1is")) {
2508 // SYS #0, C8, C3, #3
2509 SYS_ALIAS(0, 8, 3, 3);
2510 } else if (!Op.compare_lower("alle1is")) {
2511 // SYS #4, C8, C3, #4
2512 SYS_ALIAS(4, 8, 3, 4);
2513 } else if (!Op.compare_lower("vale1is")) {
2514 // SYS #0, C8, C3, #5
2515 SYS_ALIAS(0, 8, 3, 5);
2516 } else if (!Op.compare_lower("vaale1is")) {
2517 // SYS #0, C8, C3, #7
2518 SYS_ALIAS(0, 8, 3, 7);
2519 } else if (!Op.compare_lower("vmalle1")) {
2520 // SYS #0, C8, C7, #0
2521 SYS_ALIAS(0, 8, 7, 0);
2522 } else if (!Op.compare_lower("alle2")) {
2523 // SYS #4, C8, C7, #0
2524 SYS_ALIAS(4, 8, 7, 0);
2525 } else if (!Op.compare_lower("vale2is")) {
2526 // SYS #4, C8, C3, #5
2527 SYS_ALIAS(4, 8, 3, 5);
2528 } else if (!Op.compare_lower("vale3is")) {
2529 // SYS #6, C8, C3, #5
2530 SYS_ALIAS(6, 8, 3, 5);
2531 } else if (!Op.compare_lower("alle3")) {
2532 // SYS #6, C8, C7, #0
2533 SYS_ALIAS(6, 8, 7, 0);
2534 } else if (!Op.compare_lower("vae1")) {
2535 // SYS #0, C8, C7, #1
2536 SYS_ALIAS(0, 8, 7, 1);
2537 } else if (!Op.compare_lower("vae2")) {
2538 // SYS #4, C8, C7, #1
2539 SYS_ALIAS(4, 8, 7, 1);
2540 } else if (!Op.compare_lower("vae3")) {
2541 // SYS #6, C8, C7, #1
2542 SYS_ALIAS(6, 8, 7, 1);
2543 } else if (!Op.compare_lower("aside1")) {
2544 // SYS #0, C8, C7, #2
2545 SYS_ALIAS(0, 8, 7, 2);
2546 } else if (!Op.compare_lower("vaae1")) {
2547 // SYS #0, C8, C7, #3
2548 SYS_ALIAS(0, 8, 7, 3);
2549 } else if (!Op.compare_lower("alle1")) {
2550 // SYS #4, C8, C7, #4
2551 SYS_ALIAS(4, 8, 7, 4);
2552 } else if (!Op.compare_lower("vale1")) {
2553 // SYS #0, C8, C7, #5
2554 SYS_ALIAS(0, 8, 7, 5);
2555 } else if (!Op.compare_lower("vale2")) {
2556 // SYS #4, C8, C7, #5
2557 SYS_ALIAS(4, 8, 7, 5);
2558 } else if (!Op.compare_lower("vale3")) {
2559 // SYS #6, C8, C7, #5
2560 SYS_ALIAS(6, 8, 7, 5);
2561 } else if (!Op.compare_lower("vaale1")) {
2562 // SYS #0, C8, C7, #7
2563 SYS_ALIAS(0, 8, 7, 7);
2564 } else if (!Op.compare_lower("ipas2e1")) {
2565 // SYS #4, C8, C4, #1
2566 SYS_ALIAS(4, 8, 4, 1);
2567 } else if (!Op.compare_lower("ipas2le1")) {
2568 // SYS #4, C8, C4, #5
2569 SYS_ALIAS(4, 8, 4, 5);
2570 } else if (!Op.compare_lower("ipas2e1is")) {
2571 // SYS #4, C8, C4, #1
2572 SYS_ALIAS(4, 8, 0, 1);
2573 } else if (!Op.compare_lower("ipas2le1is")) {
2574 // SYS #4, C8, C4, #5
2575 SYS_ALIAS(4, 8, 0, 5);
2576 } else if (!Op.compare_lower("vmalls12e1")) {
2577 // SYS #4, C8, C7, #6
2578 SYS_ALIAS(4, 8, 7, 6);
2579 } else if (!Op.compare_lower("vmalls12e1is")) {
2580 // SYS #4, C8, C3, #6
2581 SYS_ALIAS(4, 8, 3, 6);
2582 } else {
2583 return TokError("invalid operand for TLBI instruction");
2584 }
2585 }
2586
2587 #undef SYS_ALIAS
2588
2589 Parser.Lex(); // Eat operand.
2590
2591 bool ExpectRegister = (Op.lower().find("all") == StringRef::npos);
2592 bool HasRegister = false;
2593
2594 // Check for the optional register operand.
2595 if (getLexer().is(AsmToken::Comma)) {
2596 Parser.Lex(); // Eat comma.
2597
2598 if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands))
2599 return TokError("expected register operand");
2600
2601 HasRegister = true;
2602 }
2603
2604 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2605 Parser.eatToEndOfStatement();
2606 return TokError("unexpected token in argument list");
2607 }
2608
2609 if (ExpectRegister && !HasRegister) {
2610 return TokError("specified " + Mnemonic + " op requires a register");
2611 }
2612 else if (!ExpectRegister && HasRegister) {
2613 return TokError("specified " + Mnemonic + " op does not use a register");
2614 }
2615
2616 Parser.Lex(); // Consume the EndOfStatement
2617 return false;
2618 }
2619
2620 AArch64AsmParser::OperandMatchResultTy
tryParseBarrierOperand(OperandVector & Operands)2621 AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
2622 MCAsmParser &Parser = getParser();
2623 const AsmToken &Tok = Parser.getTok();
2624
2625 // Can be either a #imm style literal or an option name
2626 bool Hash = Tok.is(AsmToken::Hash);
2627 if (Hash || Tok.is(AsmToken::Integer)) {
2628 // Immediate operand.
2629 if (Hash)
2630 Parser.Lex(); // Eat the '#'
2631 const MCExpr *ImmVal;
2632 SMLoc ExprLoc = getLoc();
2633 if (getParser().parseExpression(ImmVal))
2634 return MatchOperand_ParseFail;
2635 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2636 if (!MCE) {
2637 Error(ExprLoc, "immediate value expected for barrier operand");
2638 return MatchOperand_ParseFail;
2639 }
2640 if (MCE->getValue() < 0 || MCE->getValue() > 15) {
2641 Error(ExprLoc, "barrier operand out of range");
2642 return MatchOperand_ParseFail;
2643 }
2644 bool Valid;
2645 auto Mapper = AArch64DB::DBarrierMapper();
2646 StringRef Name =
2647 Mapper.toString(MCE->getValue(), STI.getFeatureBits(), Valid);
2648 Operands.push_back( AArch64Operand::CreateBarrier(MCE->getValue(), Name,
2649 ExprLoc, getContext()));
2650 return MatchOperand_Success;
2651 }
2652
2653 if (Tok.isNot(AsmToken::Identifier)) {
2654 TokError("invalid operand for instruction");
2655 return MatchOperand_ParseFail;
2656 }
2657
2658 bool Valid;
2659 auto Mapper = AArch64DB::DBarrierMapper();
2660 unsigned Opt =
2661 Mapper.fromString(Tok.getString(), STI.getFeatureBits(), Valid);
2662 if (!Valid) {
2663 TokError("invalid barrier option name");
2664 return MatchOperand_ParseFail;
2665 }
2666
2667 // The only valid named option for ISB is 'sy'
2668 if (Mnemonic == "isb" && Opt != AArch64DB::SY) {
2669 TokError("'sy' or #imm operand expected");
2670 return MatchOperand_ParseFail;
2671 }
2672
2673 Operands.push_back( AArch64Operand::CreateBarrier(Opt, Tok.getString(),
2674 getLoc(), getContext()));
2675 Parser.Lex(); // Consume the option
2676
2677 return MatchOperand_Success;
2678 }
2679
2680 AArch64AsmParser::OperandMatchResultTy
tryParseSysReg(OperandVector & Operands)2681 AArch64AsmParser::tryParseSysReg(OperandVector &Operands) {
2682 MCAsmParser &Parser = getParser();
2683 const AsmToken &Tok = Parser.getTok();
2684
2685 if (Tok.isNot(AsmToken::Identifier))
2686 return MatchOperand_NoMatch;
2687
2688 bool IsKnown;
2689 auto MRSMapper = AArch64SysReg::MRSMapper();
2690 uint32_t MRSReg = MRSMapper.fromString(Tok.getString(), STI.getFeatureBits(),
2691 IsKnown);
2692 assert(IsKnown == (MRSReg != -1U) &&
2693 "register should be -1 if and only if it's unknown");
2694
2695 auto MSRMapper = AArch64SysReg::MSRMapper();
2696 uint32_t MSRReg = MSRMapper.fromString(Tok.getString(), STI.getFeatureBits(),
2697 IsKnown);
2698 assert(IsKnown == (MSRReg != -1U) &&
2699 "register should be -1 if and only if it's unknown");
2700
2701 auto PStateMapper = AArch64PState::PStateMapper();
2702 uint32_t PStateField =
2703 PStateMapper.fromString(Tok.getString(), STI.getFeatureBits(), IsKnown);
2704 assert(IsKnown == (PStateField != -1U) &&
2705 "register should be -1 if and only if it's unknown");
2706
2707 Operands.push_back(AArch64Operand::CreateSysReg(
2708 Tok.getString(), getLoc(), MRSReg, MSRReg, PStateField, getContext()));
2709 Parser.Lex(); // Eat identifier
2710
2711 return MatchOperand_Success;
2712 }
2713
2714 /// tryParseVectorRegister - Parse a vector register operand.
tryParseVectorRegister(OperandVector & Operands)2715 bool AArch64AsmParser::tryParseVectorRegister(OperandVector &Operands) {
2716 MCAsmParser &Parser = getParser();
2717 if (Parser.getTok().isNot(AsmToken::Identifier))
2718 return true;
2719
2720 SMLoc S = getLoc();
2721 // Check for a vector register specifier first.
2722 StringRef Kind;
2723 int64_t Reg = tryMatchVectorRegister(Kind, false);
2724 if (Reg == -1)
2725 return true;
2726 Operands.push_back(
2727 AArch64Operand::CreateReg(Reg, true, S, getLoc(), getContext()));
2728 // If there was an explicit qualifier, that goes on as a literal text
2729 // operand.
2730 if (!Kind.empty())
2731 Operands.push_back(
2732 AArch64Operand::CreateToken(Kind, false, S, getContext()));
2733
2734 // If there is an index specifier following the register, parse that too.
2735 if (Parser.getTok().is(AsmToken::LBrac)) {
2736 SMLoc SIdx = getLoc();
2737 Parser.Lex(); // Eat left bracket token.
2738
2739 const MCExpr *ImmVal;
2740 if (getParser().parseExpression(ImmVal))
2741 return false;
2742 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2743 if (!MCE) {
2744 TokError("immediate value expected for vector index");
2745 return false;
2746 }
2747
2748 SMLoc E = getLoc();
2749 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2750 Error(E, "']' expected");
2751 return false;
2752 }
2753
2754 Parser.Lex(); // Eat right bracket token.
2755
2756 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
2757 E, getContext()));
2758 }
2759
2760 return false;
2761 }
2762
2763 /// parseRegister - Parse a non-vector register operand.
parseRegister(OperandVector & Operands)2764 bool AArch64AsmParser::parseRegister(OperandVector &Operands) {
2765 MCAsmParser &Parser = getParser();
2766 SMLoc S = getLoc();
2767 // Try for a vector register.
2768 if (!tryParseVectorRegister(Operands))
2769 return false;
2770
2771 // Try for a scalar register.
2772 int64_t Reg = tryParseRegister();
2773 if (Reg == -1)
2774 return true;
2775 Operands.push_back(
2776 AArch64Operand::CreateReg(Reg, false, S, getLoc(), getContext()));
2777
2778 // A small number of instructions (FMOVXDhighr, for example) have "[1]"
2779 // as a string token in the instruction itself.
2780 if (getLexer().getKind() == AsmToken::LBrac) {
2781 SMLoc LBracS = getLoc();
2782 Parser.Lex();
2783 const AsmToken &Tok = Parser.getTok();
2784 if (Tok.is(AsmToken::Integer)) {
2785 SMLoc IntS = getLoc();
2786 int64_t Val = Tok.getIntVal();
2787 if (Val == 1) {
2788 Parser.Lex();
2789 if (getLexer().getKind() == AsmToken::RBrac) {
2790 SMLoc RBracS = getLoc();
2791 Parser.Lex();
2792 Operands.push_back(
2793 AArch64Operand::CreateToken("[", false, LBracS, getContext()));
2794 Operands.push_back(
2795 AArch64Operand::CreateToken("1", false, IntS, getContext()));
2796 Operands.push_back(
2797 AArch64Operand::CreateToken("]", false, RBracS, getContext()));
2798 return false;
2799 }
2800 }
2801 }
2802 }
2803
2804 return false;
2805 }
2806
parseSymbolicImmVal(const MCExpr * & ImmVal)2807 bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
2808 MCAsmParser &Parser = getParser();
2809 bool HasELFModifier = false;
2810 AArch64MCExpr::VariantKind RefKind;
2811
2812 if (Parser.getTok().is(AsmToken::Colon)) {
2813 Parser.Lex(); // Eat ':"
2814 HasELFModifier = true;
2815
2816 if (Parser.getTok().isNot(AsmToken::Identifier)) {
2817 Error(Parser.getTok().getLoc(),
2818 "expect relocation specifier in operand after ':'");
2819 return true;
2820 }
2821
2822 std::string LowerCase = Parser.getTok().getIdentifier().lower();
2823 RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
2824 .Case("lo12", AArch64MCExpr::VK_LO12)
2825 .Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
2826 .Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
2827 .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
2828 .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
2829 .Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
2830 .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
2831 .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
2832 .Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
2833 .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
2834 .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
2835 .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
2836 .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
2837 .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
2838 .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
2839 .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
2840 .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
2841 .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
2842 .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
2843 .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
2844 .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
2845 .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
2846 .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
2847 .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
2848 .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
2849 .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
2850 .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
2851 .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
2852 .Case("got", AArch64MCExpr::VK_GOT_PAGE)
2853 .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
2854 .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
2855 .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
2856 .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
2857 .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
2858 .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
2859 .Default(AArch64MCExpr::VK_INVALID);
2860
2861 if (RefKind == AArch64MCExpr::VK_INVALID) {
2862 Error(Parser.getTok().getLoc(),
2863 "expect relocation specifier in operand after ':'");
2864 return true;
2865 }
2866
2867 Parser.Lex(); // Eat identifier
2868
2869 if (Parser.getTok().isNot(AsmToken::Colon)) {
2870 Error(Parser.getTok().getLoc(), "expect ':' after relocation specifier");
2871 return true;
2872 }
2873 Parser.Lex(); // Eat ':'
2874 }
2875
2876 if (getParser().parseExpression(ImmVal))
2877 return true;
2878
2879 if (HasELFModifier)
2880 ImmVal = AArch64MCExpr::create(ImmVal, RefKind, getContext());
2881
2882 return false;
2883 }
2884
2885 /// parseVectorList - Parse a vector list operand for AdvSIMD instructions.
parseVectorList(OperandVector & Operands)2886 bool AArch64AsmParser::parseVectorList(OperandVector &Operands) {
2887 MCAsmParser &Parser = getParser();
2888 assert(Parser.getTok().is(AsmToken::LCurly) && "Token is not a Left Bracket");
2889 SMLoc S = getLoc();
2890 Parser.Lex(); // Eat left bracket token.
2891 StringRef Kind;
2892 int64_t FirstReg = tryMatchVectorRegister(Kind, true);
2893 if (FirstReg == -1)
2894 return true;
2895 int64_t PrevReg = FirstReg;
2896 unsigned Count = 1;
2897
2898 if (Parser.getTok().is(AsmToken::Minus)) {
2899 Parser.Lex(); // Eat the minus.
2900
2901 SMLoc Loc = getLoc();
2902 StringRef NextKind;
2903 int64_t Reg = tryMatchVectorRegister(NextKind, true);
2904 if (Reg == -1)
2905 return true;
2906 // Any Kind suffices must match on all regs in the list.
2907 if (Kind != NextKind)
2908 return Error(Loc, "mismatched register size suffix");
2909
2910 unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg);
2911
2912 if (Space == 0 || Space > 3) {
2913 return Error(Loc, "invalid number of vectors");
2914 }
2915
2916 Count += Space;
2917 }
2918 else {
2919 while (Parser.getTok().is(AsmToken::Comma)) {
2920 Parser.Lex(); // Eat the comma token.
2921
2922 SMLoc Loc = getLoc();
2923 StringRef NextKind;
2924 int64_t Reg = tryMatchVectorRegister(NextKind, true);
2925 if (Reg == -1)
2926 return true;
2927 // Any Kind suffices must match on all regs in the list.
2928 if (Kind != NextKind)
2929 return Error(Loc, "mismatched register size suffix");
2930
2931 // Registers must be incremental (with wraparound at 31)
2932 if (getContext().getRegisterInfo()->getEncodingValue(Reg) !=
2933 (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32)
2934 return Error(Loc, "registers must be sequential");
2935
2936 PrevReg = Reg;
2937 ++Count;
2938 }
2939 }
2940
2941 if (Parser.getTok().isNot(AsmToken::RCurly))
2942 return Error(getLoc(), "'}' expected");
2943 Parser.Lex(); // Eat the '}' token.
2944
2945 if (Count > 4)
2946 return Error(S, "invalid number of vectors");
2947
2948 unsigned NumElements = 0;
2949 char ElementKind = 0;
2950 if (!Kind.empty())
2951 parseValidVectorKind(Kind, NumElements, ElementKind);
2952
2953 Operands.push_back(AArch64Operand::CreateVectorList(
2954 FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext()));
2955
2956 // If there is an index specifier following the list, parse that too.
2957 if (Parser.getTok().is(AsmToken::LBrac)) {
2958 SMLoc SIdx = getLoc();
2959 Parser.Lex(); // Eat left bracket token.
2960
2961 const MCExpr *ImmVal;
2962 if (getParser().parseExpression(ImmVal))
2963 return false;
2964 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2965 if (!MCE) {
2966 TokError("immediate value expected for vector index");
2967 return false;
2968 }
2969
2970 SMLoc E = getLoc();
2971 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2972 Error(E, "']' expected");
2973 return false;
2974 }
2975
2976 Parser.Lex(); // Eat right bracket token.
2977
2978 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
2979 E, getContext()));
2980 }
2981 return false;
2982 }
2983
2984 AArch64AsmParser::OperandMatchResultTy
tryParseGPR64sp0Operand(OperandVector & Operands)2985 AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
2986 MCAsmParser &Parser = getParser();
2987 const AsmToken &Tok = Parser.getTok();
2988 if (!Tok.is(AsmToken::Identifier))
2989 return MatchOperand_NoMatch;
2990
2991 unsigned RegNum = matchRegisterNameAlias(Tok.getString().lower(), false);
2992
2993 MCContext &Ctx = getContext();
2994 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2995 if (!RI->getRegClass(AArch64::GPR64spRegClassID).contains(RegNum))
2996 return MatchOperand_NoMatch;
2997
2998 SMLoc S = getLoc();
2999 Parser.Lex(); // Eat register
3000
3001 if (Parser.getTok().isNot(AsmToken::Comma)) {
3002 Operands.push_back(
3003 AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
3004 return MatchOperand_Success;
3005 }
3006 Parser.Lex(); // Eat comma.
3007
3008 if (Parser.getTok().is(AsmToken::Hash))
3009 Parser.Lex(); // Eat hash
3010
3011 if (Parser.getTok().isNot(AsmToken::Integer)) {
3012 Error(getLoc(), "index must be absent or #0");
3013 return MatchOperand_ParseFail;
3014 }
3015
3016 const MCExpr *ImmVal;
3017 if (Parser.parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
3018 cast<MCConstantExpr>(ImmVal)->getValue() != 0) {
3019 Error(getLoc(), "index must be absent or #0");
3020 return MatchOperand_ParseFail;
3021 }
3022
3023 Operands.push_back(
3024 AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
3025 return MatchOperand_Success;
3026 }
3027
3028 /// parseOperand - Parse a arm instruction operand. For now this parses the
3029 /// operand regardless of the mnemonic.
parseOperand(OperandVector & Operands,bool isCondCode,bool invertCondCode)3030 bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
3031 bool invertCondCode) {
3032 MCAsmParser &Parser = getParser();
3033 // Check if the current operand has a custom associated parser, if so, try to
3034 // custom parse the operand, or fallback to the general approach.
3035 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3036 if (ResTy == MatchOperand_Success)
3037 return false;
3038 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3039 // there was a match, but an error occurred, in which case, just return that
3040 // the operand parsing failed.
3041 if (ResTy == MatchOperand_ParseFail)
3042 return true;
3043
3044 // Nothing custom, so do general case parsing.
3045 SMLoc S, E;
3046 switch (getLexer().getKind()) {
3047 default: {
3048 SMLoc S = getLoc();
3049 const MCExpr *Expr;
3050 if (parseSymbolicImmVal(Expr))
3051 return Error(S, "invalid operand");
3052
3053 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3054 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
3055 return false;
3056 }
3057 case AsmToken::LBrac: {
3058 SMLoc Loc = Parser.getTok().getLoc();
3059 Operands.push_back(AArch64Operand::CreateToken("[", false, Loc,
3060 getContext()));
3061 Parser.Lex(); // Eat '['
3062
3063 // There's no comma after a '[', so we can parse the next operand
3064 // immediately.
3065 return parseOperand(Operands, false, false);
3066 }
3067 case AsmToken::LCurly:
3068 return parseVectorList(Operands);
3069 case AsmToken::Identifier: {
3070 // If we're expecting a Condition Code operand, then just parse that.
3071 if (isCondCode)
3072 return parseCondCode(Operands, invertCondCode);
3073
3074 // If it's a register name, parse it.
3075 if (!parseRegister(Operands))
3076 return false;
3077
3078 // This could be an optional "shift" or "extend" operand.
3079 OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands);
3080 // We can only continue if no tokens were eaten.
3081 if (GotShift != MatchOperand_NoMatch)
3082 return GotShift;
3083
3084 // This was not a register so parse other operands that start with an
3085 // identifier (like labels) as expressions and create them as immediates.
3086 const MCExpr *IdVal;
3087 S = getLoc();
3088 if (getParser().parseExpression(IdVal))
3089 return true;
3090
3091 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3092 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
3093 return false;
3094 }
3095 case AsmToken::Integer:
3096 case AsmToken::Real:
3097 case AsmToken::Hash: {
3098 // #42 -> immediate.
3099 S = getLoc();
3100 if (getLexer().is(AsmToken::Hash))
3101 Parser.Lex();
3102
3103 // Parse a negative sign
3104 bool isNegative = false;
3105 if (Parser.getTok().is(AsmToken::Minus)) {
3106 isNegative = true;
3107 // We need to consume this token only when we have a Real, otherwise
3108 // we let parseSymbolicImmVal take care of it
3109 if (Parser.getLexer().peekTok().is(AsmToken::Real))
3110 Parser.Lex();
3111 }
3112
3113 // The only Real that should come through here is a literal #0.0 for
3114 // the fcmp[e] r, #0.0 instructions. They expect raw token operands,
3115 // so convert the value.
3116 const AsmToken &Tok = Parser.getTok();
3117 if (Tok.is(AsmToken::Real)) {
3118 APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
3119 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
3120 if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" &&
3121 Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" &&
3122 Mnemonic != "fcmlt")
3123 return TokError("unexpected floating point literal");
3124 else if (IntVal != 0 || isNegative)
3125 return TokError("expected floating-point constant #0.0");
3126 Parser.Lex(); // Eat the token.
3127
3128 Operands.push_back(
3129 AArch64Operand::CreateToken("#0", false, S, getContext()));
3130 Operands.push_back(
3131 AArch64Operand::CreateToken(".0", false, S, getContext()));
3132 return false;
3133 }
3134
3135 const MCExpr *ImmVal;
3136 if (parseSymbolicImmVal(ImmVal))
3137 return true;
3138
3139 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3140 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
3141 return false;
3142 }
3143 case AsmToken::Equal: {
3144 SMLoc Loc = Parser.getTok().getLoc();
3145 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
3146 return Error(Loc, "unexpected token in operand");
3147 Parser.Lex(); // Eat '='
3148 const MCExpr *SubExprVal;
3149 if (getParser().parseExpression(SubExprVal))
3150 return true;
3151
3152 if (Operands.size() < 2 ||
3153 !static_cast<AArch64Operand &>(*Operands[1]).isReg())
3154 return true;
3155
3156 bool IsXReg =
3157 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3158 Operands[1]->getReg());
3159
3160 MCContext& Ctx = getContext();
3161 E = SMLoc::getFromPointer(Loc.getPointer() - 1);
3162 // If the op is an imm and can be fit into a mov, then replace ldr with mov.
3163 if (isa<MCConstantExpr>(SubExprVal)) {
3164 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
3165 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
3166 while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) {
3167 ShiftAmt += 16;
3168 Imm >>= 16;
3169 }
3170 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
3171 Operands[0] = AArch64Operand::CreateToken("movz", false, Loc, Ctx);
3172 Operands.push_back(AArch64Operand::CreateImm(
3173 MCConstantExpr::create(Imm, Ctx), S, E, Ctx));
3174 if (ShiftAmt)
3175 Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL,
3176 ShiftAmt, true, S, E, Ctx));
3177 return false;
3178 }
3179 APInt Simm = APInt(64, Imm << ShiftAmt);
3180 // check if the immediate is an unsigned or signed 32-bit int for W regs
3181 if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32)))
3182 return Error(Loc, "Immediate too large for register");
3183 }
3184 // If it is a label or an imm that cannot fit in a movz, put it into CP.
3185 const MCExpr *CPLoc =
3186 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4);
3187 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
3188 return false;
3189 }
3190 }
3191 }
3192
3193 /// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its
3194 /// operands.
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)3195 bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
3196 StringRef Name, SMLoc NameLoc,
3197 OperandVector &Operands) {
3198 MCAsmParser &Parser = getParser();
3199 Name = StringSwitch<StringRef>(Name.lower())
3200 .Case("beq", "b.eq")
3201 .Case("bne", "b.ne")
3202 .Case("bhs", "b.hs")
3203 .Case("bcs", "b.cs")
3204 .Case("blo", "b.lo")
3205 .Case("bcc", "b.cc")
3206 .Case("bmi", "b.mi")
3207 .Case("bpl", "b.pl")
3208 .Case("bvs", "b.vs")
3209 .Case("bvc", "b.vc")
3210 .Case("bhi", "b.hi")
3211 .Case("bls", "b.ls")
3212 .Case("bge", "b.ge")
3213 .Case("blt", "b.lt")
3214 .Case("bgt", "b.gt")
3215 .Case("ble", "b.le")
3216 .Case("bal", "b.al")
3217 .Case("bnv", "b.nv")
3218 .Default(Name);
3219
3220 // First check for the AArch64-specific .req directive.
3221 if (Parser.getTok().is(AsmToken::Identifier) &&
3222 Parser.getTok().getIdentifier() == ".req") {
3223 parseDirectiveReq(Name, NameLoc);
3224 // We always return 'error' for this, as we're done with this
3225 // statement and don't need to match the 'instruction."
3226 return true;
3227 }
3228
3229 // Create the leading tokens for the mnemonic, split by '.' characters.
3230 size_t Start = 0, Next = Name.find('.');
3231 StringRef Head = Name.slice(Start, Next);
3232
3233 // IC, DC, AT, and TLBI instructions are aliases for the SYS instruction.
3234 if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi") {
3235 bool IsError = parseSysAlias(Head, NameLoc, Operands);
3236 if (IsError && getLexer().isNot(AsmToken::EndOfStatement))
3237 Parser.eatToEndOfStatement();
3238 return IsError;
3239 }
3240
3241 Operands.push_back(
3242 AArch64Operand::CreateToken(Head, false, NameLoc, getContext()));
3243 Mnemonic = Head;
3244
3245 // Handle condition codes for a branch mnemonic
3246 if (Head == "b" && Next != StringRef::npos) {
3247 Start = Next;
3248 Next = Name.find('.', Start + 1);
3249 Head = Name.slice(Start + 1, Next);
3250
3251 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3252 (Head.data() - Name.data()));
3253 AArch64CC::CondCode CC = parseCondCodeString(Head);
3254 if (CC == AArch64CC::Invalid)
3255 return Error(SuffixLoc, "invalid condition code");
3256 Operands.push_back(
3257 AArch64Operand::CreateToken(".", true, SuffixLoc, getContext()));
3258 Operands.push_back(
3259 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
3260 }
3261
3262 // Add the remaining tokens in the mnemonic.
3263 while (Next != StringRef::npos) {
3264 Start = Next;
3265 Next = Name.find('.', Start + 1);
3266 Head = Name.slice(Start, Next);
3267 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3268 (Head.data() - Name.data()) + 1);
3269 Operands.push_back(
3270 AArch64Operand::CreateToken(Head, true, SuffixLoc, getContext()));
3271 }
3272
3273 // Conditional compare instructions have a Condition Code operand, which needs
3274 // to be parsed and an immediate operand created.
3275 bool condCodeFourthOperand =
3276 (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" ||
3277 Head == "fccmpe" || Head == "fcsel" || Head == "csel" ||
3278 Head == "csinc" || Head == "csinv" || Head == "csneg");
3279
3280 // These instructions are aliases to some of the conditional select
3281 // instructions. However, the condition code is inverted in the aliased
3282 // instruction.
3283 //
3284 // FIXME: Is this the correct way to handle these? Or should the parser
3285 // generate the aliased instructions directly?
3286 bool condCodeSecondOperand = (Head == "cset" || Head == "csetm");
3287 bool condCodeThirdOperand =
3288 (Head == "cinc" || Head == "cinv" || Head == "cneg");
3289
3290 // Read the remaining operands.
3291 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3292 // Read the first operand.
3293 if (parseOperand(Operands, false, false)) {
3294 Parser.eatToEndOfStatement();
3295 return true;
3296 }
3297
3298 unsigned N = 2;
3299 while (getLexer().is(AsmToken::Comma)) {
3300 Parser.Lex(); // Eat the comma.
3301
3302 // Parse and remember the operand.
3303 if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
3304 (N == 3 && condCodeThirdOperand) ||
3305 (N == 2 && condCodeSecondOperand),
3306 condCodeSecondOperand || condCodeThirdOperand)) {
3307 Parser.eatToEndOfStatement();
3308 return true;
3309 }
3310
3311 // After successfully parsing some operands there are two special cases to
3312 // consider (i.e. notional operands not separated by commas). Both are due
3313 // to memory specifiers:
3314 // + An RBrac will end an address for load/store/prefetch
3315 // + An '!' will indicate a pre-indexed operation.
3316 //
3317 // It's someone else's responsibility to make sure these tokens are sane
3318 // in the given context!
3319 if (Parser.getTok().is(AsmToken::RBrac)) {
3320 SMLoc Loc = Parser.getTok().getLoc();
3321 Operands.push_back(AArch64Operand::CreateToken("]", false, Loc,
3322 getContext()));
3323 Parser.Lex();
3324 }
3325
3326 if (Parser.getTok().is(AsmToken::Exclaim)) {
3327 SMLoc Loc = Parser.getTok().getLoc();
3328 Operands.push_back(AArch64Operand::CreateToken("!", false, Loc,
3329 getContext()));
3330 Parser.Lex();
3331 }
3332
3333 ++N;
3334 }
3335 }
3336
3337 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3338 SMLoc Loc = Parser.getTok().getLoc();
3339 Parser.eatToEndOfStatement();
3340 return Error(Loc, "unexpected token in argument list");
3341 }
3342
3343 Parser.Lex(); // Consume the EndOfStatement
3344 return false;
3345 }
3346
3347 // FIXME: This entire function is a giant hack to provide us with decent
3348 // operand range validation/diagnostics until TableGen/MC can be extended
3349 // to support autogeneration of this kind of validation.
validateInstruction(MCInst & Inst,SmallVectorImpl<SMLoc> & Loc)3350 bool AArch64AsmParser::validateInstruction(MCInst &Inst,
3351 SmallVectorImpl<SMLoc> &Loc) {
3352 const MCRegisterInfo *RI = getContext().getRegisterInfo();
3353 // Check for indexed addressing modes w/ the base register being the
3354 // same as a destination/source register or pair load where
3355 // the Rt == Rt2. All of those are undefined behaviour.
3356 switch (Inst.getOpcode()) {
3357 case AArch64::LDPSWpre:
3358 case AArch64::LDPWpost:
3359 case AArch64::LDPWpre:
3360 case AArch64::LDPXpost:
3361 case AArch64::LDPXpre: {
3362 unsigned Rt = Inst.getOperand(1).getReg();
3363 unsigned Rt2 = Inst.getOperand(2).getReg();
3364 unsigned Rn = Inst.getOperand(3).getReg();
3365 if (RI->isSubRegisterEq(Rn, Rt))
3366 return Error(Loc[0], "unpredictable LDP instruction, writeback base "
3367 "is also a destination");
3368 if (RI->isSubRegisterEq(Rn, Rt2))
3369 return Error(Loc[1], "unpredictable LDP instruction, writeback base "
3370 "is also a destination");
3371 // FALLTHROUGH
3372 }
3373 case AArch64::LDPDi:
3374 case AArch64::LDPQi:
3375 case AArch64::LDPSi:
3376 case AArch64::LDPSWi:
3377 case AArch64::LDPWi:
3378 case AArch64::LDPXi: {
3379 unsigned Rt = Inst.getOperand(0).getReg();
3380 unsigned Rt2 = Inst.getOperand(1).getReg();
3381 if (Rt == Rt2)
3382 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3383 break;
3384 }
3385 case AArch64::LDPDpost:
3386 case AArch64::LDPDpre:
3387 case AArch64::LDPQpost:
3388 case AArch64::LDPQpre:
3389 case AArch64::LDPSpost:
3390 case AArch64::LDPSpre:
3391 case AArch64::LDPSWpost: {
3392 unsigned Rt = Inst.getOperand(1).getReg();
3393 unsigned Rt2 = Inst.getOperand(2).getReg();
3394 if (Rt == Rt2)
3395 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3396 break;
3397 }
3398 case AArch64::STPDpost:
3399 case AArch64::STPDpre:
3400 case AArch64::STPQpost:
3401 case AArch64::STPQpre:
3402 case AArch64::STPSpost:
3403 case AArch64::STPSpre:
3404 case AArch64::STPWpost:
3405 case AArch64::STPWpre:
3406 case AArch64::STPXpost:
3407 case AArch64::STPXpre: {
3408 unsigned Rt = Inst.getOperand(1).getReg();
3409 unsigned Rt2 = Inst.getOperand(2).getReg();
3410 unsigned Rn = Inst.getOperand(3).getReg();
3411 if (RI->isSubRegisterEq(Rn, Rt))
3412 return Error(Loc[0], "unpredictable STP instruction, writeback base "
3413 "is also a source");
3414 if (RI->isSubRegisterEq(Rn, Rt2))
3415 return Error(Loc[1], "unpredictable STP instruction, writeback base "
3416 "is also a source");
3417 break;
3418 }
3419 case AArch64::LDRBBpre:
3420 case AArch64::LDRBpre:
3421 case AArch64::LDRHHpre:
3422 case AArch64::LDRHpre:
3423 case AArch64::LDRSBWpre:
3424 case AArch64::LDRSBXpre:
3425 case AArch64::LDRSHWpre:
3426 case AArch64::LDRSHXpre:
3427 case AArch64::LDRSWpre:
3428 case AArch64::LDRWpre:
3429 case AArch64::LDRXpre:
3430 case AArch64::LDRBBpost:
3431 case AArch64::LDRBpost:
3432 case AArch64::LDRHHpost:
3433 case AArch64::LDRHpost:
3434 case AArch64::LDRSBWpost:
3435 case AArch64::LDRSBXpost:
3436 case AArch64::LDRSHWpost:
3437 case AArch64::LDRSHXpost:
3438 case AArch64::LDRSWpost:
3439 case AArch64::LDRWpost:
3440 case AArch64::LDRXpost: {
3441 unsigned Rt = Inst.getOperand(1).getReg();
3442 unsigned Rn = Inst.getOperand(2).getReg();
3443 if (RI->isSubRegisterEq(Rn, Rt))
3444 return Error(Loc[0], "unpredictable LDR instruction, writeback base "
3445 "is also a source");
3446 break;
3447 }
3448 case AArch64::STRBBpost:
3449 case AArch64::STRBpost:
3450 case AArch64::STRHHpost:
3451 case AArch64::STRHpost:
3452 case AArch64::STRWpost:
3453 case AArch64::STRXpost:
3454 case AArch64::STRBBpre:
3455 case AArch64::STRBpre:
3456 case AArch64::STRHHpre:
3457 case AArch64::STRHpre:
3458 case AArch64::STRWpre:
3459 case AArch64::STRXpre: {
3460 unsigned Rt = Inst.getOperand(1).getReg();
3461 unsigned Rn = Inst.getOperand(2).getReg();
3462 if (RI->isSubRegisterEq(Rn, Rt))
3463 return Error(Loc[0], "unpredictable STR instruction, writeback base "
3464 "is also a source");
3465 break;
3466 }
3467 }
3468
3469 // Now check immediate ranges. Separate from the above as there is overlap
3470 // in the instructions being checked and this keeps the nested conditionals
3471 // to a minimum.
3472 switch (Inst.getOpcode()) {
3473 case AArch64::ADDSWri:
3474 case AArch64::ADDSXri:
3475 case AArch64::ADDWri:
3476 case AArch64::ADDXri:
3477 case AArch64::SUBSWri:
3478 case AArch64::SUBSXri:
3479 case AArch64::SUBWri:
3480 case AArch64::SUBXri: {
3481 // Annoyingly we can't do this in the isAddSubImm predicate, so there is
3482 // some slight duplication here.
3483 if (Inst.getOperand(2).isExpr()) {
3484 const MCExpr *Expr = Inst.getOperand(2).getExpr();
3485 AArch64MCExpr::VariantKind ELFRefKind;
3486 MCSymbolRefExpr::VariantKind DarwinRefKind;
3487 int64_t Addend;
3488 if (!classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3489 return Error(Loc[2], "invalid immediate expression");
3490 }
3491
3492 // Only allow these with ADDXri.
3493 if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
3494 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) &&
3495 Inst.getOpcode() == AArch64::ADDXri)
3496 return false;
3497
3498 // Only allow these with ADDXri/ADDWri
3499 if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
3500 ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
3501 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
3502 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
3503 ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
3504 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
3505 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
3506 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) &&
3507 (Inst.getOpcode() == AArch64::ADDXri ||
3508 Inst.getOpcode() == AArch64::ADDWri))
3509 return false;
3510
3511 // Don't allow expressions in the immediate field otherwise
3512 return Error(Loc[2], "invalid immediate expression");
3513 }
3514 return false;
3515 }
3516 default:
3517 return false;
3518 }
3519 }
3520
showMatchError(SMLoc Loc,unsigned ErrCode)3521 bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
3522 switch (ErrCode) {
3523 case Match_MissingFeature:
3524 return Error(Loc,
3525 "instruction requires a CPU feature not currently enabled");
3526 case Match_InvalidOperand:
3527 return Error(Loc, "invalid operand for instruction");
3528 case Match_InvalidSuffix:
3529 return Error(Loc, "invalid type suffix for instruction");
3530 case Match_InvalidCondCode:
3531 return Error(Loc, "expected AArch64 condition code");
3532 case Match_AddSubRegExtendSmall:
3533 return Error(Loc,
3534 "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]");
3535 case Match_AddSubRegExtendLarge:
3536 return Error(Loc,
3537 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
3538 case Match_AddSubSecondSource:
3539 return Error(Loc,
3540 "expected compatible register, symbol or integer in range [0, 4095]");
3541 case Match_LogicalSecondSource:
3542 return Error(Loc, "expected compatible register or logical immediate");
3543 case Match_InvalidMovImm32Shift:
3544 return Error(Loc, "expected 'lsl' with optional integer 0 or 16");
3545 case Match_InvalidMovImm64Shift:
3546 return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48");
3547 case Match_AddSubRegShift32:
3548 return Error(Loc,
3549 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
3550 case Match_AddSubRegShift64:
3551 return Error(Loc,
3552 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
3553 case Match_InvalidFPImm:
3554 return Error(Loc,
3555 "expected compatible register or floating-point constant");
3556 case Match_InvalidMemoryIndexedSImm9:
3557 return Error(Loc, "index must be an integer in range [-256, 255].");
3558 case Match_InvalidMemoryIndexed4SImm7:
3559 return Error(Loc, "index must be a multiple of 4 in range [-256, 252].");
3560 case Match_InvalidMemoryIndexed8SImm7:
3561 return Error(Loc, "index must be a multiple of 8 in range [-512, 504].");
3562 case Match_InvalidMemoryIndexed16SImm7:
3563 return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008].");
3564 case Match_InvalidMemoryWExtend8:
3565 return Error(Loc,
3566 "expected 'uxtw' or 'sxtw' with optional shift of #0");
3567 case Match_InvalidMemoryWExtend16:
3568 return Error(Loc,
3569 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
3570 case Match_InvalidMemoryWExtend32:
3571 return Error(Loc,
3572 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
3573 case Match_InvalidMemoryWExtend64:
3574 return Error(Loc,
3575 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
3576 case Match_InvalidMemoryWExtend128:
3577 return Error(Loc,
3578 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
3579 case Match_InvalidMemoryXExtend8:
3580 return Error(Loc,
3581 "expected 'lsl' or 'sxtx' with optional shift of #0");
3582 case Match_InvalidMemoryXExtend16:
3583 return Error(Loc,
3584 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
3585 case Match_InvalidMemoryXExtend32:
3586 return Error(Loc,
3587 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
3588 case Match_InvalidMemoryXExtend64:
3589 return Error(Loc,
3590 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
3591 case Match_InvalidMemoryXExtend128:
3592 return Error(Loc,
3593 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
3594 case Match_InvalidMemoryIndexed1:
3595 return Error(Loc, "index must be an integer in range [0, 4095].");
3596 case Match_InvalidMemoryIndexed2:
3597 return Error(Loc, "index must be a multiple of 2 in range [0, 8190].");
3598 case Match_InvalidMemoryIndexed4:
3599 return Error(Loc, "index must be a multiple of 4 in range [0, 16380].");
3600 case Match_InvalidMemoryIndexed8:
3601 return Error(Loc, "index must be a multiple of 8 in range [0, 32760].");
3602 case Match_InvalidMemoryIndexed16:
3603 return Error(Loc, "index must be a multiple of 16 in range [0, 65520].");
3604 case Match_InvalidImm0_7:
3605 return Error(Loc, "immediate must be an integer in range [0, 7].");
3606 case Match_InvalidImm0_15:
3607 return Error(Loc, "immediate must be an integer in range [0, 15].");
3608 case Match_InvalidImm0_31:
3609 return Error(Loc, "immediate must be an integer in range [0, 31].");
3610 case Match_InvalidImm0_63:
3611 return Error(Loc, "immediate must be an integer in range [0, 63].");
3612 case Match_InvalidImm0_127:
3613 return Error(Loc, "immediate must be an integer in range [0, 127].");
3614 case Match_InvalidImm0_65535:
3615 return Error(Loc, "immediate must be an integer in range [0, 65535].");
3616 case Match_InvalidImm1_8:
3617 return Error(Loc, "immediate must be an integer in range [1, 8].");
3618 case Match_InvalidImm1_16:
3619 return Error(Loc, "immediate must be an integer in range [1, 16].");
3620 case Match_InvalidImm1_32:
3621 return Error(Loc, "immediate must be an integer in range [1, 32].");
3622 case Match_InvalidImm1_64:
3623 return Error(Loc, "immediate must be an integer in range [1, 64].");
3624 case Match_InvalidIndex1:
3625 return Error(Loc, "expected lane specifier '[1]'");
3626 case Match_InvalidIndexB:
3627 return Error(Loc, "vector lane must be an integer in range [0, 15].");
3628 case Match_InvalidIndexH:
3629 return Error(Loc, "vector lane must be an integer in range [0, 7].");
3630 case Match_InvalidIndexS:
3631 return Error(Loc, "vector lane must be an integer in range [0, 3].");
3632 case Match_InvalidIndexD:
3633 return Error(Loc, "vector lane must be an integer in range [0, 1].");
3634 case Match_InvalidLabel:
3635 return Error(Loc, "expected label or encodable integer pc offset");
3636 case Match_MRS:
3637 return Error(Loc, "expected readable system register");
3638 case Match_MSR:
3639 return Error(Loc, "expected writable system register or pstate");
3640 case Match_MnemonicFail:
3641 return Error(Loc, "unrecognized instruction mnemonic");
3642 default:
3643 llvm_unreachable("unexpected error code!");
3644 }
3645 }
3646
3647 static const char *getSubtargetFeatureName(uint64_t Val);
3648
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)3649 bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3650 OperandVector &Operands,
3651 MCStreamer &Out,
3652 uint64_t &ErrorInfo,
3653 bool MatchingInlineAsm) {
3654 assert(!Operands.empty() && "Unexpect empty operand list!");
3655 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]);
3656 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
3657
3658 StringRef Tok = Op.getToken();
3659 unsigned NumOperands = Operands.size();
3660
3661 if (NumOperands == 4 && Tok == "lsl") {
3662 AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
3663 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3664 if (Op2.isReg() && Op3.isImm()) {
3665 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3666 if (Op3CE) {
3667 uint64_t Op3Val = Op3CE->getValue();
3668 uint64_t NewOp3Val = 0;
3669 uint64_t NewOp4Val = 0;
3670 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
3671 Op2.getReg())) {
3672 NewOp3Val = (32 - Op3Val) & 0x1f;
3673 NewOp4Val = 31 - Op3Val;
3674 } else {
3675 NewOp3Val = (64 - Op3Val) & 0x3f;
3676 NewOp4Val = 63 - Op3Val;
3677 }
3678
3679 const MCExpr *NewOp3 = MCConstantExpr::create(NewOp3Val, getContext());
3680 const MCExpr *NewOp4 = MCConstantExpr::create(NewOp4Val, getContext());
3681
3682 Operands[0] = AArch64Operand::CreateToken(
3683 "ubfm", false, Op.getStartLoc(), getContext());
3684 Operands.push_back(AArch64Operand::CreateImm(
3685 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
3686 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
3687 Op3.getEndLoc(), getContext());
3688 }
3689 }
3690 } else if (NumOperands == 4 && Tok == "bfc") {
3691 // FIXME: Horrible hack to handle BFC->BFM alias.
3692 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3693 AArch64Operand LSBOp = static_cast<AArch64Operand &>(*Operands[2]);
3694 AArch64Operand WidthOp = static_cast<AArch64Operand &>(*Operands[3]);
3695
3696 if (Op1.isReg() && LSBOp.isImm() && WidthOp.isImm()) {
3697 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
3698 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
3699
3700 if (LSBCE && WidthCE) {
3701 uint64_t LSB = LSBCE->getValue();
3702 uint64_t Width = WidthCE->getValue();
3703
3704 uint64_t RegWidth = 0;
3705 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3706 Op1.getReg()))
3707 RegWidth = 64;
3708 else
3709 RegWidth = 32;
3710
3711 if (LSB >= RegWidth)
3712 return Error(LSBOp.getStartLoc(),
3713 "expected integer in range [0, 31]");
3714 if (Width < 1 || Width > RegWidth)
3715 return Error(WidthOp.getStartLoc(),
3716 "expected integer in range [1, 32]");
3717
3718 uint64_t ImmR = 0;
3719 if (RegWidth == 32)
3720 ImmR = (32 - LSB) & 0x1f;
3721 else
3722 ImmR = (64 - LSB) & 0x3f;
3723
3724 uint64_t ImmS = Width - 1;
3725
3726 if (ImmR != 0 && ImmS >= ImmR)
3727 return Error(WidthOp.getStartLoc(),
3728 "requested insert overflows register");
3729
3730 const MCExpr *ImmRExpr = MCConstantExpr::create(ImmR, getContext());
3731 const MCExpr *ImmSExpr = MCConstantExpr::create(ImmS, getContext());
3732 Operands[0] = AArch64Operand::CreateToken(
3733 "bfm", false, Op.getStartLoc(), getContext());
3734 Operands[2] = AArch64Operand::CreateReg(
3735 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, false, SMLoc(),
3736 SMLoc(), getContext());
3737 Operands[3] = AArch64Operand::CreateImm(
3738 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
3739 Operands.emplace_back(
3740 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
3741 WidthOp.getEndLoc(), getContext()));
3742 }
3743 }
3744 } else if (NumOperands == 5) {
3745 // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and
3746 // UBFIZ -> UBFM aliases.
3747 if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") {
3748 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3749 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3750 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
3751
3752 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3753 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3754 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
3755
3756 if (Op3CE && Op4CE) {
3757 uint64_t Op3Val = Op3CE->getValue();
3758 uint64_t Op4Val = Op4CE->getValue();
3759
3760 uint64_t RegWidth = 0;
3761 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3762 Op1.getReg()))
3763 RegWidth = 64;
3764 else
3765 RegWidth = 32;
3766
3767 if (Op3Val >= RegWidth)
3768 return Error(Op3.getStartLoc(),
3769 "expected integer in range [0, 31]");
3770 if (Op4Val < 1 || Op4Val > RegWidth)
3771 return Error(Op4.getStartLoc(),
3772 "expected integer in range [1, 32]");
3773
3774 uint64_t NewOp3Val = 0;
3775 if (RegWidth == 32)
3776 NewOp3Val = (32 - Op3Val) & 0x1f;
3777 else
3778 NewOp3Val = (64 - Op3Val) & 0x3f;
3779
3780 uint64_t NewOp4Val = Op4Val - 1;
3781
3782 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
3783 return Error(Op4.getStartLoc(),
3784 "requested insert overflows register");
3785
3786 const MCExpr *NewOp3 =
3787 MCConstantExpr::create(NewOp3Val, getContext());
3788 const MCExpr *NewOp4 =
3789 MCConstantExpr::create(NewOp4Val, getContext());
3790 Operands[3] = AArch64Operand::CreateImm(
3791 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
3792 Operands[4] = AArch64Operand::CreateImm(
3793 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3794 if (Tok == "bfi")
3795 Operands[0] = AArch64Operand::CreateToken(
3796 "bfm", false, Op.getStartLoc(), getContext());
3797 else if (Tok == "sbfiz")
3798 Operands[0] = AArch64Operand::CreateToken(
3799 "sbfm", false, Op.getStartLoc(), getContext());
3800 else if (Tok == "ubfiz")
3801 Operands[0] = AArch64Operand::CreateToken(
3802 "ubfm", false, Op.getStartLoc(), getContext());
3803 else
3804 llvm_unreachable("No valid mnemonic for alias?");
3805 }
3806 }
3807
3808 // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and
3809 // UBFX -> UBFM aliases.
3810 } else if (NumOperands == 5 &&
3811 (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) {
3812 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3813 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3814 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
3815
3816 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3817 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3818 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
3819
3820 if (Op3CE && Op4CE) {
3821 uint64_t Op3Val = Op3CE->getValue();
3822 uint64_t Op4Val = Op4CE->getValue();
3823
3824 uint64_t RegWidth = 0;
3825 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3826 Op1.getReg()))
3827 RegWidth = 64;
3828 else
3829 RegWidth = 32;
3830
3831 if (Op3Val >= RegWidth)
3832 return Error(Op3.getStartLoc(),
3833 "expected integer in range [0, 31]");
3834 if (Op4Val < 1 || Op4Val > RegWidth)
3835 return Error(Op4.getStartLoc(),
3836 "expected integer in range [1, 32]");
3837
3838 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
3839
3840 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
3841 return Error(Op4.getStartLoc(),
3842 "requested extract overflows register");
3843
3844 const MCExpr *NewOp4 =
3845 MCConstantExpr::create(NewOp4Val, getContext());
3846 Operands[4] = AArch64Operand::CreateImm(
3847 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3848 if (Tok == "bfxil")
3849 Operands[0] = AArch64Operand::CreateToken(
3850 "bfm", false, Op.getStartLoc(), getContext());
3851 else if (Tok == "sbfx")
3852 Operands[0] = AArch64Operand::CreateToken(
3853 "sbfm", false, Op.getStartLoc(), getContext());
3854 else if (Tok == "ubfx")
3855 Operands[0] = AArch64Operand::CreateToken(
3856 "ubfm", false, Op.getStartLoc(), getContext());
3857 else
3858 llvm_unreachable("No valid mnemonic for alias?");
3859 }
3860 }
3861 }
3862 }
3863 // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands.
3864 // InstAlias can't quite handle this since the reg classes aren't
3865 // subclasses.
3866 if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) {
3867 // The source register can be Wn here, but the matcher expects a
3868 // GPR64. Twiddle it here if necessary.
3869 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3870 if (Op.isReg()) {
3871 unsigned Reg = getXRegFromWReg(Op.getReg());
3872 Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3873 Op.getEndLoc(), getContext());
3874 }
3875 }
3876 // FIXME: Likewise for sxt[bh] with a Xd dst operand
3877 else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) {
3878 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3879 if (Op.isReg() &&
3880 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3881 Op.getReg())) {
3882 // The source register can be Wn here, but the matcher expects a
3883 // GPR64. Twiddle it here if necessary.
3884 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3885 if (Op.isReg()) {
3886 unsigned Reg = getXRegFromWReg(Op.getReg());
3887 Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3888 Op.getEndLoc(), getContext());
3889 }
3890 }
3891 }
3892 // FIXME: Likewise for uxt[bh] with a Xd dst operand
3893 else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) {
3894 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3895 if (Op.isReg() &&
3896 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3897 Op.getReg())) {
3898 // The source register can be Wn here, but the matcher expects a
3899 // GPR32. Twiddle it here if necessary.
3900 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3901 if (Op.isReg()) {
3902 unsigned Reg = getWRegFromXReg(Op.getReg());
3903 Operands[1] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3904 Op.getEndLoc(), getContext());
3905 }
3906 }
3907 }
3908
3909 // Yet another horrible hack to handle FMOV Rd, #0.0 using [WX]ZR.
3910 if (NumOperands == 3 && Tok == "fmov") {
3911 AArch64Operand &RegOp = static_cast<AArch64Operand &>(*Operands[1]);
3912 AArch64Operand &ImmOp = static_cast<AArch64Operand &>(*Operands[2]);
3913 if (RegOp.isReg() && ImmOp.isFPImm() && ImmOp.getFPImm() == (unsigned)-1) {
3914 unsigned zreg =
3915 AArch64MCRegisterClasses[AArch64::FPR32RegClassID].contains(
3916 RegOp.getReg())
3917 ? AArch64::WZR
3918 : AArch64::XZR;
3919 Operands[2] = AArch64Operand::CreateReg(zreg, false, Op.getStartLoc(),
3920 Op.getEndLoc(), getContext());
3921 }
3922 }
3923
3924 MCInst Inst;
3925 // First try to match against the secondary set of tables containing the
3926 // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
3927 unsigned MatchResult =
3928 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1);
3929
3930 // If that fails, try against the alternate table containing long-form NEON:
3931 // "fadd v0.2s, v1.2s, v2.2s"
3932 if (MatchResult != Match_Success)
3933 MatchResult =
3934 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0);
3935
3936 switch (MatchResult) {
3937 case Match_Success: {
3938 // Perform range checking and other semantic validations
3939 SmallVector<SMLoc, 8> OperandLocs;
3940 NumOperands = Operands.size();
3941 for (unsigned i = 1; i < NumOperands; ++i)
3942 OperandLocs.push_back(Operands[i]->getStartLoc());
3943 if (validateInstruction(Inst, OperandLocs))
3944 return true;
3945
3946 Inst.setLoc(IDLoc);
3947 Out.EmitInstruction(Inst, STI);
3948 return false;
3949 }
3950 case Match_MissingFeature: {
3951 assert(ErrorInfo && "Unknown missing feature!");
3952 // Special case the error message for the very common case where only
3953 // a single subtarget feature is missing (neon, e.g.).
3954 std::string Msg = "instruction requires:";
3955 uint64_t Mask = 1;
3956 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
3957 if (ErrorInfo & Mask) {
3958 Msg += " ";
3959 Msg += getSubtargetFeatureName(ErrorInfo & Mask);
3960 }
3961 Mask <<= 1;
3962 }
3963 return Error(IDLoc, Msg);
3964 }
3965 case Match_MnemonicFail:
3966 return showMatchError(IDLoc, MatchResult);
3967 case Match_InvalidOperand: {
3968 SMLoc ErrorLoc = IDLoc;
3969 if (ErrorInfo != ~0ULL) {
3970 if (ErrorInfo >= Operands.size())
3971 return Error(IDLoc, "too few operands for instruction");
3972
3973 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
3974 if (ErrorLoc == SMLoc())
3975 ErrorLoc = IDLoc;
3976 }
3977 // If the match failed on a suffix token operand, tweak the diagnostic
3978 // accordingly.
3979 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
3980 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
3981 MatchResult = Match_InvalidSuffix;
3982
3983 return showMatchError(ErrorLoc, MatchResult);
3984 }
3985 case Match_InvalidMemoryIndexed1:
3986 case Match_InvalidMemoryIndexed2:
3987 case Match_InvalidMemoryIndexed4:
3988 case Match_InvalidMemoryIndexed8:
3989 case Match_InvalidMemoryIndexed16:
3990 case Match_InvalidCondCode:
3991 case Match_AddSubRegExtendSmall:
3992 case Match_AddSubRegExtendLarge:
3993 case Match_AddSubSecondSource:
3994 case Match_LogicalSecondSource:
3995 case Match_AddSubRegShift32:
3996 case Match_AddSubRegShift64:
3997 case Match_InvalidMovImm32Shift:
3998 case Match_InvalidMovImm64Shift:
3999 case Match_InvalidFPImm:
4000 case Match_InvalidMemoryWExtend8:
4001 case Match_InvalidMemoryWExtend16:
4002 case Match_InvalidMemoryWExtend32:
4003 case Match_InvalidMemoryWExtend64:
4004 case Match_InvalidMemoryWExtend128:
4005 case Match_InvalidMemoryXExtend8:
4006 case Match_InvalidMemoryXExtend16:
4007 case Match_InvalidMemoryXExtend32:
4008 case Match_InvalidMemoryXExtend64:
4009 case Match_InvalidMemoryXExtend128:
4010 case Match_InvalidMemoryIndexed4SImm7:
4011 case Match_InvalidMemoryIndexed8SImm7:
4012 case Match_InvalidMemoryIndexed16SImm7:
4013 case Match_InvalidMemoryIndexedSImm9:
4014 case Match_InvalidImm0_7:
4015 case Match_InvalidImm0_15:
4016 case Match_InvalidImm0_31:
4017 case Match_InvalidImm0_63:
4018 case Match_InvalidImm0_127:
4019 case Match_InvalidImm0_65535:
4020 case Match_InvalidImm1_8:
4021 case Match_InvalidImm1_16:
4022 case Match_InvalidImm1_32:
4023 case Match_InvalidImm1_64:
4024 case Match_InvalidIndex1:
4025 case Match_InvalidIndexB:
4026 case Match_InvalidIndexH:
4027 case Match_InvalidIndexS:
4028 case Match_InvalidIndexD:
4029 case Match_InvalidLabel:
4030 case Match_MSR:
4031 case Match_MRS: {
4032 if (ErrorInfo >= Operands.size())
4033 return Error(IDLoc, "too few operands for instruction");
4034 // Any time we get here, there's nothing fancy to do. Just get the
4035 // operand SMLoc and display the diagnostic.
4036 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
4037 if (ErrorLoc == SMLoc())
4038 ErrorLoc = IDLoc;
4039 return showMatchError(ErrorLoc, MatchResult);
4040 }
4041 }
4042
4043 llvm_unreachable("Implement any new match types added!");
4044 }
4045
4046 /// ParseDirective parses the arm specific directives
ParseDirective(AsmToken DirectiveID)4047 bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
4048 const MCObjectFileInfo::Environment Format =
4049 getContext().getObjectFileInfo()->getObjectFileType();
4050 bool IsMachO = Format == MCObjectFileInfo::IsMachO;
4051 bool IsCOFF = Format == MCObjectFileInfo::IsCOFF;
4052
4053 StringRef IDVal = DirectiveID.getIdentifier();
4054 SMLoc Loc = DirectiveID.getLoc();
4055 if (IDVal == ".hword")
4056 return parseDirectiveWord(2, Loc);
4057 if (IDVal == ".word")
4058 return parseDirectiveWord(4, Loc);
4059 if (IDVal == ".xword")
4060 return parseDirectiveWord(8, Loc);
4061 if (IDVal == ".tlsdesccall")
4062 return parseDirectiveTLSDescCall(Loc);
4063 if (IDVal == ".ltorg" || IDVal == ".pool")
4064 return parseDirectiveLtorg(Loc);
4065 if (IDVal == ".unreq")
4066 return parseDirectiveUnreq(Loc);
4067
4068 if (!IsMachO && !IsCOFF) {
4069 if (IDVal == ".inst")
4070 return parseDirectiveInst(Loc);
4071 }
4072
4073 return parseDirectiveLOH(IDVal, Loc);
4074 }
4075
4076 /// parseDirectiveWord
4077 /// ::= .word [ expression (, expression)* ]
parseDirectiveWord(unsigned Size,SMLoc L)4078 bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
4079 MCAsmParser &Parser = getParser();
4080 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4081 for (;;) {
4082 const MCExpr *Value;
4083 if (getParser().parseExpression(Value))
4084 return true;
4085
4086 getParser().getStreamer().EmitValue(Value, Size);
4087
4088 if (getLexer().is(AsmToken::EndOfStatement))
4089 break;
4090
4091 // FIXME: Improve diagnostic.
4092 if (getLexer().isNot(AsmToken::Comma))
4093 return Error(L, "unexpected token in directive");
4094 Parser.Lex();
4095 }
4096 }
4097
4098 Parser.Lex();
4099 return false;
4100 }
4101
4102 /// parseDirectiveInst
4103 /// ::= .inst opcode [, ...]
parseDirectiveInst(SMLoc Loc)4104 bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
4105 MCAsmParser &Parser = getParser();
4106 if (getLexer().is(AsmToken::EndOfStatement)) {
4107 Parser.eatToEndOfStatement();
4108 Error(Loc, "expected expression following directive");
4109 return false;
4110 }
4111
4112 for (;;) {
4113 const MCExpr *Expr;
4114
4115 if (getParser().parseExpression(Expr)) {
4116 Error(Loc, "expected expression");
4117 return false;
4118 }
4119
4120 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
4121 if (!Value) {
4122 Error(Loc, "expected constant expression");
4123 return false;
4124 }
4125
4126 getTargetStreamer().emitInst(Value->getValue());
4127
4128 if (getLexer().is(AsmToken::EndOfStatement))
4129 break;
4130
4131 if (getLexer().isNot(AsmToken::Comma)) {
4132 Error(Loc, "unexpected token in directive");
4133 return false;
4134 }
4135
4136 Parser.Lex(); // Eat comma.
4137 }
4138
4139 Parser.Lex();
4140 return false;
4141 }
4142
4143 // parseDirectiveTLSDescCall:
4144 // ::= .tlsdesccall symbol
parseDirectiveTLSDescCall(SMLoc L)4145 bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
4146 StringRef Name;
4147 if (getParser().parseIdentifier(Name))
4148 return Error(L, "expected symbol after directive");
4149
4150 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4151 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
4152 Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_TLSDESC, getContext());
4153
4154 MCInst Inst;
4155 Inst.setOpcode(AArch64::TLSDESCCALL);
4156 Inst.addOperand(MCOperand::createExpr(Expr));
4157
4158 getParser().getStreamer().EmitInstruction(Inst, STI);
4159 return false;
4160 }
4161
4162 /// ::= .loh <lohName | lohId> label1, ..., labelN
4163 /// The number of arguments depends on the loh identifier.
parseDirectiveLOH(StringRef IDVal,SMLoc Loc)4164 bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
4165 if (IDVal != MCLOHDirectiveName())
4166 return true;
4167 MCLOHType Kind;
4168 if (getParser().getTok().isNot(AsmToken::Identifier)) {
4169 if (getParser().getTok().isNot(AsmToken::Integer))
4170 return TokError("expected an identifier or a number in directive");
4171 // We successfully get a numeric value for the identifier.
4172 // Check if it is valid.
4173 int64_t Id = getParser().getTok().getIntVal();
4174 if (Id <= -1U && !isValidMCLOHType(Id))
4175 return TokError("invalid numeric identifier in directive");
4176 Kind = (MCLOHType)Id;
4177 } else {
4178 StringRef Name = getTok().getIdentifier();
4179 // We successfully parse an identifier.
4180 // Check if it is a recognized one.
4181 int Id = MCLOHNameToId(Name);
4182
4183 if (Id == -1)
4184 return TokError("invalid identifier in directive");
4185 Kind = (MCLOHType)Id;
4186 }
4187 // Consume the identifier.
4188 Lex();
4189 // Get the number of arguments of this LOH.
4190 int NbArgs = MCLOHIdToNbArgs(Kind);
4191
4192 assert(NbArgs != -1 && "Invalid number of arguments");
4193
4194 SmallVector<MCSymbol *, 3> Args;
4195 for (int Idx = 0; Idx < NbArgs; ++Idx) {
4196 StringRef Name;
4197 if (getParser().parseIdentifier(Name))
4198 return TokError("expected identifier in directive");
4199 Args.push_back(getContext().getOrCreateSymbol(Name));
4200
4201 if (Idx + 1 == NbArgs)
4202 break;
4203 if (getLexer().isNot(AsmToken::Comma))
4204 return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
4205 Lex();
4206 }
4207 if (getLexer().isNot(AsmToken::EndOfStatement))
4208 return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
4209
4210 getStreamer().EmitLOHDirective((MCLOHType)Kind, Args);
4211 return false;
4212 }
4213
4214 /// parseDirectiveLtorg
4215 /// ::= .ltorg | .pool
parseDirectiveLtorg(SMLoc L)4216 bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
4217 getTargetStreamer().emitCurrentConstantPool();
4218 return false;
4219 }
4220
4221 /// parseDirectiveReq
4222 /// ::= name .req registername
parseDirectiveReq(StringRef Name,SMLoc L)4223 bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
4224 MCAsmParser &Parser = getParser();
4225 Parser.Lex(); // Eat the '.req' token.
4226 SMLoc SRegLoc = getLoc();
4227 unsigned RegNum = tryParseRegister();
4228 bool IsVector = false;
4229
4230 if (RegNum == static_cast<unsigned>(-1)) {
4231 StringRef Kind;
4232 RegNum = tryMatchVectorRegister(Kind, false);
4233 if (!Kind.empty()) {
4234 Error(SRegLoc, "vector register without type specifier expected");
4235 return false;
4236 }
4237 IsVector = true;
4238 }
4239
4240 if (RegNum == static_cast<unsigned>(-1)) {
4241 Parser.eatToEndOfStatement();
4242 Error(SRegLoc, "register name or alias expected");
4243 return false;
4244 }
4245
4246 // Shouldn't be anything else.
4247 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4248 Error(Parser.getTok().getLoc(), "unexpected input in .req directive");
4249 Parser.eatToEndOfStatement();
4250 return false;
4251 }
4252
4253 Parser.Lex(); // Consume the EndOfStatement
4254
4255 auto pair = std::make_pair(IsVector, RegNum);
4256 if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
4257 Warning(L, "ignoring redefinition of register alias '" + Name + "'");
4258
4259 return true;
4260 }
4261
4262 /// parseDirectiveUneq
4263 /// ::= .unreq registername
parseDirectiveUnreq(SMLoc L)4264 bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
4265 MCAsmParser &Parser = getParser();
4266 if (Parser.getTok().isNot(AsmToken::Identifier)) {
4267 Error(Parser.getTok().getLoc(), "unexpected input in .unreq directive.");
4268 Parser.eatToEndOfStatement();
4269 return false;
4270 }
4271 RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
4272 Parser.Lex(); // Eat the identifier.
4273 return false;
4274 }
4275
4276 bool
classifySymbolRef(const MCExpr * Expr,AArch64MCExpr::VariantKind & ELFRefKind,MCSymbolRefExpr::VariantKind & DarwinRefKind,int64_t & Addend)4277 AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
4278 AArch64MCExpr::VariantKind &ELFRefKind,
4279 MCSymbolRefExpr::VariantKind &DarwinRefKind,
4280 int64_t &Addend) {
4281 ELFRefKind = AArch64MCExpr::VK_INVALID;
4282 DarwinRefKind = MCSymbolRefExpr::VK_None;
4283 Addend = 0;
4284
4285 if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
4286 ELFRefKind = AE->getKind();
4287 Expr = AE->getSubExpr();
4288 }
4289
4290 const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr);
4291 if (SE) {
4292 // It's a simple symbol reference with no addend.
4293 DarwinRefKind = SE->getKind();
4294 return true;
4295 }
4296
4297 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
4298 if (!BE)
4299 return false;
4300
4301 SE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
4302 if (!SE)
4303 return false;
4304 DarwinRefKind = SE->getKind();
4305
4306 if (BE->getOpcode() != MCBinaryExpr::Add &&
4307 BE->getOpcode() != MCBinaryExpr::Sub)
4308 return false;
4309
4310 // See if the addend is is a constant, otherwise there's more going
4311 // on here than we can deal with.
4312 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
4313 if (!AddendExpr)
4314 return false;
4315
4316 Addend = AddendExpr->getValue();
4317 if (BE->getOpcode() == MCBinaryExpr::Sub)
4318 Addend = -Addend;
4319
4320 // It's some symbol reference + a constant addend, but really
4321 // shouldn't use both Darwin and ELF syntax.
4322 return ELFRefKind == AArch64MCExpr::VK_INVALID ||
4323 DarwinRefKind == MCSymbolRefExpr::VK_None;
4324 }
4325
4326 /// Force static initialization.
LLVMInitializeAArch64AsmParser()4327 extern "C" void LLVMInitializeAArch64AsmParser() {
4328 RegisterMCAsmParser<AArch64AsmParser> X(TheAArch64leTarget);
4329 RegisterMCAsmParser<AArch64AsmParser> Y(TheAArch64beTarget);
4330 RegisterMCAsmParser<AArch64AsmParser> Z(TheARM64Target);
4331 }
4332
4333 #define GET_REGISTER_MATCHER
4334 #define GET_SUBTARGET_FEATURE_NAME
4335 #define GET_MATCHER_IMPLEMENTATION
4336 #include "AArch64GenAsmMatcher.inc"
4337
4338 // Define this matcher function after the auto-generated include so we
4339 // have the match class enum definitions.
validateTargetOperandClass(MCParsedAsmOperand & AsmOp,unsigned Kind)4340 unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
4341 unsigned Kind) {
4342 AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp);
4343 // If the kind is a token for a literal immediate, check if our asm
4344 // operand matches. This is for InstAliases which have a fixed-value
4345 // immediate in the syntax.
4346 int64_t ExpectedVal;
4347 switch (Kind) {
4348 default:
4349 return Match_InvalidOperand;
4350 case MCK__35_0:
4351 ExpectedVal = 0;
4352 break;
4353 case MCK__35_1:
4354 ExpectedVal = 1;
4355 break;
4356 case MCK__35_12:
4357 ExpectedVal = 12;
4358 break;
4359 case MCK__35_16:
4360 ExpectedVal = 16;
4361 break;
4362 case MCK__35_2:
4363 ExpectedVal = 2;
4364 break;
4365 case MCK__35_24:
4366 ExpectedVal = 24;
4367 break;
4368 case MCK__35_3:
4369 ExpectedVal = 3;
4370 break;
4371 case MCK__35_32:
4372 ExpectedVal = 32;
4373 break;
4374 case MCK__35_4:
4375 ExpectedVal = 4;
4376 break;
4377 case MCK__35_48:
4378 ExpectedVal = 48;
4379 break;
4380 case MCK__35_6:
4381 ExpectedVal = 6;
4382 break;
4383 case MCK__35_64:
4384 ExpectedVal = 64;
4385 break;
4386 case MCK__35_8:
4387 ExpectedVal = 8;
4388 break;
4389 }
4390 if (!Op.isImm())
4391 return Match_InvalidOperand;
4392 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm());
4393 if (!CE)
4394 return Match_InvalidOperand;
4395 if (CE->getValue() == ExpectedVal)
4396 return Match_Success;
4397 return Match_InvalidOperand;
4398 }
4399
4400
4401 AArch64AsmParser::OperandMatchResultTy
tryParseGPRSeqPair(OperandVector & Operands)4402 AArch64AsmParser::tryParseGPRSeqPair(OperandVector &Operands) {
4403
4404 SMLoc S = getLoc();
4405
4406 if (getParser().getTok().isNot(AsmToken::Identifier)) {
4407 Error(S, "expected register");
4408 return MatchOperand_ParseFail;
4409 }
4410
4411 int FirstReg = tryParseRegister();
4412 if (FirstReg == -1) {
4413 return MatchOperand_ParseFail;
4414 }
4415 const MCRegisterClass &WRegClass =
4416 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
4417 const MCRegisterClass &XRegClass =
4418 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
4419
4420 bool isXReg = XRegClass.contains(FirstReg),
4421 isWReg = WRegClass.contains(FirstReg);
4422 if (!isXReg && !isWReg) {
4423 Error(S, "expected first even register of a "
4424 "consecutive same-size even/odd register pair");
4425 return MatchOperand_ParseFail;
4426 }
4427
4428 const MCRegisterInfo *RI = getContext().getRegisterInfo();
4429 unsigned FirstEncoding = RI->getEncodingValue(FirstReg);
4430
4431 if (FirstEncoding & 0x1) {
4432 Error(S, "expected first even register of a "
4433 "consecutive same-size even/odd register pair");
4434 return MatchOperand_ParseFail;
4435 }
4436
4437 SMLoc M = getLoc();
4438 if (getParser().getTok().isNot(AsmToken::Comma)) {
4439 Error(M, "expected comma");
4440 return MatchOperand_ParseFail;
4441 }
4442 // Eat the comma
4443 getParser().Lex();
4444
4445 SMLoc E = getLoc();
4446 int SecondReg = tryParseRegister();
4447 if (SecondReg ==-1) {
4448 return MatchOperand_ParseFail;
4449 }
4450
4451 if (RI->getEncodingValue(SecondReg) != FirstEncoding + 1 ||
4452 (isXReg && !XRegClass.contains(SecondReg)) ||
4453 (isWReg && !WRegClass.contains(SecondReg))) {
4454 Error(E,"expected second odd register of a "
4455 "consecutive same-size even/odd register pair");
4456 return MatchOperand_ParseFail;
4457 }
4458
4459 unsigned Pair = 0;
4460 if(isXReg) {
4461 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube64,
4462 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
4463 } else {
4464 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube32,
4465 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
4466 }
4467
4468 Operands.push_back(AArch64Operand::CreateReg(Pair, false, S, getLoc(),
4469 getContext()));
4470
4471 return MatchOperand_Success;
4472 }
4473