[ARM64] Move ARM64BaseInfo.{cpp,h} into a Utils/ subdirectory, a la AArch64. These...
[oota-llvm.git] / lib / Target / ARM64 / AsmParser / ARM64AsmParser.cpp
1 //===-- ARM64AsmParser.cpp - Parse ARM64 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/ARM64AddressingModes.h"
11 #include "MCTargetDesc/ARM64MCExpr.h"
12 #include "Utils/ARM64BaseInfo.h"
13 #include "llvm/MC/MCParser/MCAsmLexer.h"
14 #include "llvm/MC/MCParser/MCAsmParser.h"
15 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCRegisterInfo.h"
20 #include "llvm/MC/MCStreamer.h"
21 #include "llvm/MC/MCSubtargetInfo.h"
22 #include "llvm/MC/MCSymbol.h"
23 #include "llvm/MC/MCTargetAsmParser.h"
24 #include "llvm/Support/SourceMgr.h"
25 #include "llvm/Support/TargetRegistry.h"
26 #include "llvm/Support/ErrorHandling.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include "llvm/ADT/SmallString.h"
29 #include "llvm/ADT/SmallVector.h"
30 #include "llvm/ADT/STLExtras.h"
31 #include "llvm/ADT/StringSwitch.h"
32 #include "llvm/ADT/Twine.h"
33 #include <cstdio>
34 using namespace llvm;
35
36 namespace {
37
38 class ARM64Operand;
39
40 class ARM64AsmParser : public MCTargetAsmParser {
41 public:
42   typedef SmallVectorImpl<MCParsedAsmOperand *> OperandVector;
43
44 private:
45   StringRef Mnemonic; ///< Instruction mnemonic.
46   MCSubtargetInfo &STI;
47   MCAsmParser &Parser;
48
49   MCAsmParser &getParser() const { return Parser; }
50   MCAsmLexer &getLexer() const { return Parser.getLexer(); }
51
52   SMLoc getLoc() const { return Parser.getTok().getLoc(); }
53
54   bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
55   unsigned parseCondCodeString(StringRef Cond);
56   bool parseCondCode(OperandVector &Operands, bool invertCondCode);
57   int tryParseRegister();
58   int tryMatchVectorRegister(StringRef &Kind, bool expected);
59   bool parseOptionalShift(OperandVector &Operands);
60   bool parseOptionalExtend(OperandVector &Operands);
61   bool parseRegister(OperandVector &Operands);
62   bool parseMemory(OperandVector &Operands);
63   bool parseSymbolicImmVal(const MCExpr *&ImmVal);
64   bool parseVectorList(OperandVector &Operands);
65   bool parseOperand(OperandVector &Operands, bool isCondCode,
66                     bool invertCondCode);
67
68   void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
69   bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
70   bool showMatchError(SMLoc Loc, unsigned ErrCode);
71
72   bool parseDirectiveWord(unsigned Size, SMLoc L);
73   bool parseDirectiveTLSDescCall(SMLoc L);
74
75   bool parseDirectiveLOH(StringRef LOH, SMLoc L);
76
77   bool validateInstruction(MCInst &Inst, SmallVectorImpl<SMLoc> &Loc);
78   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
79                                OperandVector &Operands, MCStreamer &Out,
80                                unsigned &ErrorInfo, bool MatchingInlineAsm);
81 /// @name Auto-generated Match Functions
82 /// {
83
84 #define GET_ASSEMBLER_HEADER
85 #include "ARM64GenAsmMatcher.inc"
86
87   /// }
88
89   OperandMatchResultTy tryParseNoIndexMemory(OperandVector &Operands);
90   OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands);
91   OperandMatchResultTy tryParseSystemRegister(OperandVector &Operands);
92   OperandMatchResultTy tryParseCPSRField(OperandVector &Operands);
93   OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands);
94   OperandMatchResultTy tryParsePrefetch(OperandVector &Operands);
95   OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands);
96   OperandMatchResultTy tryParseAdrLabel(OperandVector &Operands);
97   OperandMatchResultTy tryParseFPImm(OperandVector &Operands);
98   bool tryParseVectorRegister(OperandVector &Operands);
99
100 public:
101   enum ARM64MatchResultTy {
102     Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
103 #define GET_OPERAND_DIAGNOSTIC_TYPES
104 #include "ARM64GenAsmMatcher.inc"
105   };
106   ARM64AsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser,
107                  const MCInstrInfo &MII)
108       : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
109     MCAsmParserExtension::Initialize(_Parser);
110   }
111
112   virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
113                                 SMLoc NameLoc, OperandVector &Operands);
114   virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
115   virtual bool ParseDirective(AsmToken DirectiveID);
116   unsigned validateTargetOperandClass(MCParsedAsmOperand *Op, unsigned Kind);
117
118   static bool classifySymbolRef(const MCExpr *Expr,
119                                 ARM64MCExpr::VariantKind &ELFRefKind,
120                                 MCSymbolRefExpr::VariantKind &DarwinRefKind,
121                                 const MCConstantExpr *&Addend);
122 };
123 } // end anonymous namespace
124
125 namespace {
126
127 /// ARM64Operand - Instances of this class represent a parsed ARM64 machine
128 /// instruction.
129 class ARM64Operand : public MCParsedAsmOperand {
130 public:
131   enum MemIdxKindTy {
132     ImmediateOffset, // pre-indexed, no writeback
133     RegisterOffset   // register offset, with optional extend
134   };
135
136 private:
137   enum KindTy {
138     k_Immediate,
139     k_Memory,
140     k_Register,
141     k_VectorList,
142     k_VectorIndex,
143     k_Token,
144     k_SysCR,
145     k_Prefetch,
146     k_Shifter,
147     k_Extend,
148     k_FPImm,
149     k_Barrier,
150     k_SystemRegister,
151     k_CPSRField
152   } Kind;
153
154   SMLoc StartLoc, EndLoc, OffsetLoc;
155
156   struct TokOp {
157     const char *Data;
158     unsigned Length;
159     bool IsSuffix; // Is the operand actually a suffix on the mnemonic.
160   };
161
162   struct RegOp {
163     unsigned RegNum;
164     bool isVector;
165   };
166
167   struct VectorListOp {
168     unsigned RegNum;
169     unsigned Count;
170     unsigned NumElements;
171     unsigned ElementKind;
172   };
173
174   struct VectorIndexOp {
175     unsigned Val;
176   };
177
178   struct ImmOp {
179     const MCExpr *Val;
180   };
181
182   struct FPImmOp {
183     unsigned Val; // Encoded 8-bit representation.
184   };
185
186   struct BarrierOp {
187     unsigned Val; // Not the enum since not all values have names.
188   };
189
190   struct SystemRegisterOp {
191     // 16-bit immediate, usually from the ARM64SYS::SystermRegister enum,
192     // but not limited to those values.
193     uint16_t Val;
194   };
195
196   struct CPSRFieldOp {
197     ARM64SYS::CPSRField Field;
198   };
199
200   struct SysCRImmOp {
201     unsigned Val;
202   };
203
204   struct PrefetchOp {
205     unsigned Val;
206   };
207
208   struct ShifterOp {
209     unsigned Val;
210   };
211
212   struct ExtendOp {
213     unsigned Val;
214   };
215
216   // This is for all forms of ARM64 address expressions
217   struct MemOp {
218     unsigned BaseRegNum, OffsetRegNum;
219     ARM64_AM::ExtendType ExtType;
220     unsigned ShiftVal;
221     bool ExplicitShift;
222     const MCExpr *OffsetImm;
223     MemIdxKindTy Mode;
224   };
225
226   union {
227     struct TokOp Tok;
228     struct RegOp Reg;
229     struct VectorListOp VectorList;
230     struct VectorIndexOp VectorIndex;
231     struct ImmOp Imm;
232     struct FPImmOp FPImm;
233     struct BarrierOp Barrier;
234     struct SystemRegisterOp SystemRegister;
235     struct CPSRFieldOp CPSRField;
236     struct SysCRImmOp SysCRImm;
237     struct PrefetchOp Prefetch;
238     struct ShifterOp Shifter;
239     struct ExtendOp Extend;
240     struct MemOp Mem;
241   };
242
243   // Keep the MCContext around as the MCExprs may need manipulated during
244   // the add<>Operands() calls.
245   MCContext &Ctx;
246
247   ARM64Operand(KindTy K, MCContext &_Ctx)
248       : MCParsedAsmOperand(), Kind(K), Ctx(_Ctx) {}
249
250 public:
251   ARM64Operand(const ARM64Operand &o) : MCParsedAsmOperand(), Ctx(o.Ctx) {
252     Kind = o.Kind;
253     StartLoc = o.StartLoc;
254     EndLoc = o.EndLoc;
255     switch (Kind) {
256     case k_Token:
257       Tok = o.Tok;
258       break;
259     case k_Immediate:
260       Imm = o.Imm;
261       break;
262     case k_FPImm:
263       FPImm = o.FPImm;
264       break;
265     case k_Barrier:
266       Barrier = o.Barrier;
267       break;
268     case k_SystemRegister:
269       SystemRegister = o.SystemRegister;
270       break;
271     case k_CPSRField:
272       CPSRField = o.CPSRField;
273       break;
274     case k_Register:
275       Reg = o.Reg;
276       break;
277     case k_VectorList:
278       VectorList = o.VectorList;
279       break;
280     case k_VectorIndex:
281       VectorIndex = o.VectorIndex;
282       break;
283     case k_SysCR:
284       SysCRImm = o.SysCRImm;
285       break;
286     case k_Prefetch:
287       Prefetch = o.Prefetch;
288       break;
289     case k_Memory:
290       Mem = o.Mem;
291       break;
292     case k_Shifter:
293       Shifter = o.Shifter;
294       break;
295     case k_Extend:
296       Extend = o.Extend;
297       break;
298     }
299   }
300
301   /// getStartLoc - Get the location of the first token of this operand.
302   SMLoc getStartLoc() const { return StartLoc; }
303   /// getEndLoc - Get the location of the last token of this operand.
304   SMLoc getEndLoc() const { return EndLoc; }
305   /// getOffsetLoc - Get the location of the offset of this memory operand.
306   SMLoc getOffsetLoc() const { return OffsetLoc; }
307
308   StringRef getToken() const {
309     assert(Kind == k_Token && "Invalid access!");
310     return StringRef(Tok.Data, Tok.Length);
311   }
312
313   bool isTokenSuffix() const {
314     assert(Kind == k_Token && "Invalid access!");
315     return Tok.IsSuffix;
316   }
317
318   const MCExpr *getImm() const {
319     assert(Kind == k_Immediate && "Invalid access!");
320     return Imm.Val;
321   }
322
323   unsigned getFPImm() const {
324     assert(Kind == k_FPImm && "Invalid access!");
325     return FPImm.Val;
326   }
327
328   unsigned getBarrier() const {
329     assert(Kind == k_Barrier && "Invalid access!");
330     return Barrier.Val;
331   }
332
333   uint16_t getSystemRegister() const {
334     assert(Kind == k_SystemRegister && "Invalid access!");
335     return SystemRegister.Val;
336   }
337
338   ARM64SYS::CPSRField getCPSRField() const {
339     assert(Kind == k_CPSRField && "Invalid access!");
340     return CPSRField.Field;
341   }
342
343   unsigned getReg() const {
344     assert(Kind == k_Register && "Invalid access!");
345     return Reg.RegNum;
346   }
347
348   unsigned getVectorListStart() const {
349     assert(Kind == k_VectorList && "Invalid access!");
350     return VectorList.RegNum;
351   }
352
353   unsigned getVectorListCount() const {
354     assert(Kind == k_VectorList && "Invalid access!");
355     return VectorList.Count;
356   }
357
358   unsigned getVectorIndex() const {
359     assert(Kind == k_VectorIndex && "Invalid access!");
360     return VectorIndex.Val;
361   }
362
363   unsigned getSysCR() const {
364     assert(Kind == k_SysCR && "Invalid access!");
365     return SysCRImm.Val;
366   }
367
368   unsigned getPrefetch() const {
369     assert(Kind == k_Prefetch && "Invalid access!");
370     return Prefetch.Val;
371   }
372
373   unsigned getShifter() const {
374     assert(Kind == k_Shifter && "Invalid access!");
375     return Shifter.Val;
376   }
377
378   unsigned getExtend() const {
379     assert(Kind == k_Extend && "Invalid access!");
380     return Extend.Val;
381   }
382
383   bool isImm() const { return Kind == k_Immediate; }
384   bool isSImm9() const {
385     if (!isImm())
386       return false;
387     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
388     if (!MCE)
389       return false;
390     int64_t Val = MCE->getValue();
391     return (Val >= -256 && Val < 256);
392   }
393   bool isSImm7s4() const {
394     if (!isImm())
395       return false;
396     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
397     if (!MCE)
398       return false;
399     int64_t Val = MCE->getValue();
400     return (Val >= -256 && Val <= 252 && (Val & 3) == 0);
401   }
402   bool isSImm7s8() const {
403     if (!isImm())
404       return false;
405     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
406     if (!MCE)
407       return false;
408     int64_t Val = MCE->getValue();
409     return (Val >= -512 && Val <= 504 && (Val & 7) == 0);
410   }
411   bool isSImm7s16() const {
412     if (!isImm())
413       return false;
414     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
415     if (!MCE)
416       return false;
417     int64_t Val = MCE->getValue();
418     return (Val >= -1024 && Val <= 1008 && (Val & 15) == 0);
419   }
420   bool isImm0_7() const {
421     if (!isImm())
422       return false;
423     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
424     if (!MCE)
425       return false;
426     int64_t Val = MCE->getValue();
427     return (Val >= 0 && Val < 8);
428   }
429   bool isImm1_8() const {
430     if (!isImm())
431       return false;
432     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
433     if (!MCE)
434       return false;
435     int64_t Val = MCE->getValue();
436     return (Val > 0 && Val < 9);
437   }
438   bool isImm0_15() const {
439     if (!isImm())
440       return false;
441     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
442     if (!MCE)
443       return false;
444     int64_t Val = MCE->getValue();
445     return (Val >= 0 && Val < 16);
446   }
447   bool isImm1_16() const {
448     if (!isImm())
449       return false;
450     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
451     if (!MCE)
452       return false;
453     int64_t Val = MCE->getValue();
454     return (Val > 0 && Val < 17);
455   }
456   bool isImm0_31() const {
457     if (!isImm())
458       return false;
459     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
460     if (!MCE)
461       return false;
462     int64_t Val = MCE->getValue();
463     return (Val >= 0 && Val < 32);
464   }
465   bool isImm1_31() const {
466     if (!isImm())
467       return false;
468     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
469     if (!MCE)
470       return false;
471     int64_t Val = MCE->getValue();
472     return (Val >= 1 && Val < 32);
473   }
474   bool isImm1_32() const {
475     if (!isImm())
476       return false;
477     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
478     if (!MCE)
479       return false;
480     int64_t Val = MCE->getValue();
481     return (Val >= 1 && Val < 33);
482   }
483   bool isImm0_63() const {
484     if (!isImm())
485       return false;
486     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
487     if (!MCE)
488       return false;
489     int64_t Val = MCE->getValue();
490     return (Val >= 0 && Val < 64);
491   }
492   bool isImm1_63() const {
493     if (!isImm())
494       return false;
495     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
496     if (!MCE)
497       return false;
498     int64_t Val = MCE->getValue();
499     return (Val >= 1 && Val < 64);
500   }
501   bool isImm1_64() const {
502     if (!isImm())
503       return false;
504     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
505     if (!MCE)
506       return false;
507     int64_t Val = MCE->getValue();
508     return (Val >= 1 && Val < 65);
509   }
510   bool isImm0_127() const {
511     if (!isImm())
512       return false;
513     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
514     if (!MCE)
515       return false;
516     int64_t Val = MCE->getValue();
517     return (Val >= 0 && Val < 128);
518   }
519   bool isImm0_255() const {
520     if (!isImm())
521       return false;
522     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
523     if (!MCE)
524       return false;
525     int64_t Val = MCE->getValue();
526     return (Val >= 0 && Val < 256);
527   }
528   bool isImm0_65535() const {
529     if (!isImm())
530       return false;
531     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
532     if (!MCE)
533       return false;
534     int64_t Val = MCE->getValue();
535     return (Val >= 0 && Val < 65536);
536   }
537   bool isLogicalImm32() const {
538     if (!isImm())
539       return false;
540     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
541     if (!MCE)
542       return false;
543     return ARM64_AM::isLogicalImmediate(MCE->getValue(), 32);
544   }
545   bool isLogicalImm64() const {
546     if (!isImm())
547       return false;
548     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
549     if (!MCE)
550       return false;
551     return ARM64_AM::isLogicalImmediate(MCE->getValue(), 64);
552   }
553   bool isSIMDImmType10() const {
554     if (!isImm())
555       return false;
556     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
557     if (!MCE)
558       return false;
559     return ARM64_AM::isAdvSIMDModImmType10(MCE->getValue());
560   }
561   bool isBranchTarget26() const {
562     if (!isImm())
563       return false;
564     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
565     if (!MCE)
566       return true;
567     int64_t Val = MCE->getValue();
568     if (Val & 0x3)
569       return false;
570     return (Val >= -(0x2000000 << 2) && Val <= (0x1ffffff << 2));
571   }
572   bool isBranchTarget19() const {
573     if (!isImm())
574       return false;
575     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
576     if (!MCE)
577       return true;
578     int64_t Val = MCE->getValue();
579     if (Val & 0x3)
580       return false;
581     return (Val >= -(0x40000 << 2) && Val <= (0x3ffff << 2));
582   }
583   bool isBranchTarget14() const {
584     if (!isImm())
585       return false;
586     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
587     if (!MCE)
588       return true;
589     int64_t Val = MCE->getValue();
590     if (Val & 0x3)
591       return false;
592     return (Val >= -(0x2000 << 2) && Val <= (0x1fff << 2));
593   }
594
595   bool isMovWSymbol(ArrayRef<ARM64MCExpr::VariantKind> AllowedModifiers) const {
596     if (!isImm())
597       return false;
598
599     ARM64MCExpr::VariantKind ELFRefKind;
600     MCSymbolRefExpr::VariantKind DarwinRefKind;
601     const MCConstantExpr *Addend;
602     if (!ARM64AsmParser::classifySymbolRef(getImm(), ELFRefKind, DarwinRefKind,
603                                            Addend)) {
604       return false;
605     }
606     if (DarwinRefKind != MCSymbolRefExpr::VK_None)
607       return false;
608
609     for (unsigned i = 0; i != AllowedModifiers.size(); ++i) {
610       if (ELFRefKind == AllowedModifiers[i])
611         return Addend == 0;
612     }
613
614     return false;
615   }
616
617   bool isMovZSymbolG3() const {
618     static ARM64MCExpr::VariantKind Variants[] = { ARM64MCExpr::VK_ABS_G3 };
619     return isMovWSymbol(Variants);
620   }
621
622   bool isMovZSymbolG2() const {
623     static ARM64MCExpr::VariantKind Variants[] = { ARM64MCExpr::VK_ABS_G2,
624                                                    ARM64MCExpr::VK_TPREL_G2,
625                                                    ARM64MCExpr::VK_DTPREL_G2 };
626     return isMovWSymbol(Variants);
627   }
628
629   bool isMovZSymbolG1() const {
630     static ARM64MCExpr::VariantKind Variants[] = { ARM64MCExpr::VK_ABS_G1,
631                                                    ARM64MCExpr::VK_GOTTPREL_G1,
632                                                    ARM64MCExpr::VK_TPREL_G1,
633                                                    ARM64MCExpr::VK_DTPREL_G1, };
634     return isMovWSymbol(Variants);
635   }
636
637   bool isMovZSymbolG0() const {
638     static ARM64MCExpr::VariantKind Variants[] = { ARM64MCExpr::VK_ABS_G0,
639                                                    ARM64MCExpr::VK_TPREL_G0,
640                                                    ARM64MCExpr::VK_DTPREL_G0 };
641     return isMovWSymbol(Variants);
642   }
643
644   bool isMovKSymbolG2() const {
645     static ARM64MCExpr::VariantKind Variants[] = { ARM64MCExpr::VK_ABS_G2_NC };
646     return isMovWSymbol(Variants);
647   }
648
649   bool isMovKSymbolG1() const {
650     static ARM64MCExpr::VariantKind Variants[] = {
651       ARM64MCExpr::VK_ABS_G1_NC, ARM64MCExpr::VK_TPREL_G1_NC,
652       ARM64MCExpr::VK_DTPREL_G1_NC
653     };
654     return isMovWSymbol(Variants);
655   }
656
657   bool isMovKSymbolG0() const {
658     static ARM64MCExpr::VariantKind Variants[] = {
659       ARM64MCExpr::VK_ABS_G0_NC,   ARM64MCExpr::VK_GOTTPREL_G0_NC,
660       ARM64MCExpr::VK_TPREL_G0_NC, ARM64MCExpr::VK_DTPREL_G0_NC
661     };
662     return isMovWSymbol(Variants);
663   }
664
665   bool isFPImm() const { return Kind == k_FPImm; }
666   bool isBarrier() const { return Kind == k_Barrier; }
667   bool isSystemRegister() const {
668     if (Kind == k_SystemRegister)
669       return true;
670     // SPSel is legal for both the system register and the CPSR-field
671     // variants of MSR, so special case that. Fugly.
672     return (Kind == k_CPSRField && getCPSRField() == ARM64SYS::cpsr_SPSel);
673   }
674   bool isSystemCPSRField() const { return Kind == k_CPSRField; }
675   bool isReg() const { return Kind == k_Register && !Reg.isVector; }
676   bool isVectorReg() const { return Kind == k_Register && Reg.isVector; }
677
678   /// Is this a vector list with the type implicit (presumably attached to the
679   /// instruction itself)?
680   template <unsigned NumRegs> bool isImplicitlyTypedVectorList() const {
681     return Kind == k_VectorList && VectorList.Count == NumRegs &&
682            !VectorList.ElementKind;
683   }
684
685   template <unsigned NumRegs, unsigned NumElements, char ElementKind>
686   bool isTypedVectorList() const {
687     if (Kind != k_VectorList)
688       return false;
689     if (VectorList.Count != NumRegs)
690       return false;
691     if (VectorList.ElementKind != ElementKind)
692       return false;
693     return VectorList.NumElements == NumElements;
694   }
695
696   bool isVectorIndexB() const {
697     return Kind == k_VectorIndex && VectorIndex.Val < 16;
698   }
699   bool isVectorIndexH() const {
700     return Kind == k_VectorIndex && VectorIndex.Val < 8;
701   }
702   bool isVectorIndexS() const {
703     return Kind == k_VectorIndex && VectorIndex.Val < 4;
704   }
705   bool isVectorIndexD() const {
706     return Kind == k_VectorIndex && VectorIndex.Val < 2;
707   }
708   bool isToken() const { return Kind == k_Token; }
709   bool isTokenEqual(StringRef Str) const {
710     return Kind == k_Token && getToken() == Str;
711   }
712   bool isMem() const { return Kind == k_Memory; }
713   bool isSysCR() const { return Kind == k_SysCR; }
714   bool isPrefetch() const { return Kind == k_Prefetch; }
715   bool isShifter() const { return Kind == k_Shifter; }
716   bool isExtend() const {
717     // lsl is an alias for UXTW but will be a parsed as a k_Shifter operand.
718     if (isShifter()) {
719       ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(Shifter.Val);
720       return ST == ARM64_AM::LSL;
721     }
722     return Kind == k_Extend;
723   }
724   bool isExtend64() const {
725     if (Kind != k_Extend)
726       return false;
727     // UXTX and SXTX require a 64-bit source register (the ExtendLSL64 class).
728     ARM64_AM::ExtendType ET = ARM64_AM::getArithExtendType(Extend.Val);
729     return ET != ARM64_AM::UXTX && ET != ARM64_AM::SXTX;
730   }
731   bool isExtendLSL64() const {
732     // lsl is an alias for UXTX but will be a parsed as a k_Shifter operand.
733     if (isShifter()) {
734       ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(Shifter.Val);
735       return ST == ARM64_AM::LSL;
736     }
737     if (Kind != k_Extend)
738       return false;
739     ARM64_AM::ExtendType ET = ARM64_AM::getArithExtendType(Extend.Val);
740     return ET == ARM64_AM::UXTX || ET == ARM64_AM::SXTX;
741   }
742
743   bool isArithmeticShifter() const {
744     if (!isShifter())
745       return false;
746
747     // An arithmetic shifter is LSL, LSR, or ASR.
748     ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(Shifter.Val);
749     return ST == ARM64_AM::LSL || ST == ARM64_AM::LSR || ST == ARM64_AM::ASR;
750   }
751
752   bool isMovImm32Shifter() const {
753     if (!isShifter())
754       return false;
755
756     // A MOVi shifter is LSL of 0, 16, 32, or 48.
757     ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(Shifter.Val);
758     if (ST != ARM64_AM::LSL)
759       return false;
760     uint64_t Val = ARM64_AM::getShiftValue(Shifter.Val);
761     return (Val == 0 || Val == 16);
762   }
763
764   bool isMovImm64Shifter() const {
765     if (!isShifter())
766       return false;
767
768     // A MOVi shifter is LSL of 0 or 16.
769     ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(Shifter.Val);
770     if (ST != ARM64_AM::LSL)
771       return false;
772     uint64_t Val = ARM64_AM::getShiftValue(Shifter.Val);
773     return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
774   }
775
776   bool isAddSubShifter() const {
777     if (!isShifter())
778       return false;
779
780     // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'.
781     unsigned Val = Shifter.Val;
782     return ARM64_AM::getShiftType(Val) == ARM64_AM::LSL &&
783            (ARM64_AM::getShiftValue(Val) == 0 ||
784             ARM64_AM::getShiftValue(Val) == 12);
785   }
786
787   bool isLogicalVecShifter() const {
788     if (!isShifter())
789       return false;
790
791     // A logical vector shifter is a left shift by 0, 8, 16, or 24.
792     unsigned Val = Shifter.Val;
793     unsigned Shift = ARM64_AM::getShiftValue(Val);
794     return ARM64_AM::getShiftType(Val) == ARM64_AM::LSL &&
795            (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
796   }
797
798   bool isLogicalVecHalfWordShifter() const {
799     if (!isLogicalVecShifter())
800       return false;
801
802     // A logical vector shifter is a left shift by 0 or 8.
803     unsigned Val = Shifter.Val;
804     unsigned Shift = ARM64_AM::getShiftValue(Val);
805     return ARM64_AM::getShiftType(Val) == ARM64_AM::LSL &&
806            (Shift == 0 || Shift == 8);
807   }
808
809   bool isMoveVecShifter() const {
810     if (!isShifter())
811       return false;
812
813     // A logical vector shifter is a left shift by 8 or 16.
814     unsigned Val = Shifter.Val;
815     unsigned Shift = ARM64_AM::getShiftValue(Val);
816     return ARM64_AM::getShiftType(Val) == ARM64_AM::MSL &&
817            (Shift == 8 || Shift == 16);
818   }
819
820   bool isMemoryRegisterOffset8() const {
821     return isMem() && Mem.Mode == RegisterOffset && Mem.ShiftVal == 0;
822   }
823
824   bool isMemoryRegisterOffset16() const {
825     return isMem() && Mem.Mode == RegisterOffset &&
826            (Mem.ShiftVal == 0 || Mem.ShiftVal == 1);
827   }
828
829   bool isMemoryRegisterOffset32() const {
830     return isMem() && Mem.Mode == RegisterOffset &&
831            (Mem.ShiftVal == 0 || Mem.ShiftVal == 2);
832   }
833
834   bool isMemoryRegisterOffset64() const {
835     return isMem() && Mem.Mode == RegisterOffset &&
836            (Mem.ShiftVal == 0 || Mem.ShiftVal == 3);
837   }
838
839   bool isMemoryRegisterOffset128() const {
840     return isMem() && Mem.Mode == RegisterOffset &&
841            (Mem.ShiftVal == 0 || Mem.ShiftVal == 4);
842   }
843
844   bool isMemoryUnscaled() const {
845     if (!isMem())
846       return false;
847     if (Mem.Mode != ImmediateOffset)
848       return false;
849     if (!Mem.OffsetImm)
850       return true;
851     // Make sure the immediate value is valid.
852     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.OffsetImm);
853     if (!CE)
854       return false;
855     // The offset must fit in a signed 9-bit unscaled immediate.
856     int64_t Value = CE->getValue();
857     return (Value >= -256 && Value < 256);
858   }
859   // Fallback unscaled operands are for aliases of LDR/STR that fall back
860   // to LDUR/STUR when the offset is not legal for the former but is for
861   // the latter. As such, in addition to checking for being a legal unscaled
862   // address, also check that it is not a legal scaled address. This avoids
863   // ambiguity in the matcher.
864   bool isMemoryUnscaledFB8() const {
865     return isMemoryUnscaled() && !isMemoryIndexed8();
866   }
867   bool isMemoryUnscaledFB16() const {
868     return isMemoryUnscaled() && !isMemoryIndexed16();
869   }
870   bool isMemoryUnscaledFB32() const {
871     return isMemoryUnscaled() && !isMemoryIndexed32();
872   }
873   bool isMemoryUnscaledFB64() const {
874     return isMemoryUnscaled() && !isMemoryIndexed64();
875   }
876   bool isMemoryUnscaledFB128() const {
877     return isMemoryUnscaled() && !isMemoryIndexed128();
878   }
879   bool isMemoryIndexed(unsigned Scale) const {
880     if (!isMem())
881       return false;
882     if (Mem.Mode != ImmediateOffset)
883       return false;
884     if (!Mem.OffsetImm)
885       return true;
886     // Make sure the immediate value is valid.
887     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.OffsetImm);
888
889     if (CE) {
890       // The offset must be a positive multiple of the scale and in range of
891       // encoding with a 12-bit immediate.
892       int64_t Value = CE->getValue();
893       return (Value >= 0 && (Value % Scale) == 0 && Value <= (4095 * Scale));
894     }
895
896     // If it's not a constant, check for some expressions we know.
897     const MCExpr *Expr = Mem.OffsetImm;
898     ARM64MCExpr::VariantKind ELFRefKind;
899     MCSymbolRefExpr::VariantKind DarwinRefKind;
900     const MCConstantExpr *Addend;
901     if (!ARM64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
902                                            Addend)) {
903       // If we don't understand the expression, assume the best and
904       // let the fixup and relocation code deal with it.
905       return true;
906     }
907
908     if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
909         ELFRefKind == ARM64MCExpr::VK_LO12 ||
910         ELFRefKind == ARM64MCExpr::VK_GOT_LO12 ||
911         ELFRefKind == ARM64MCExpr::VK_DTPREL_LO12 ||
912         ELFRefKind == ARM64MCExpr::VK_DTPREL_LO12_NC ||
913         ELFRefKind == ARM64MCExpr::VK_TPREL_LO12 ||
914         ELFRefKind == ARM64MCExpr::VK_TPREL_LO12_NC ||
915         ELFRefKind == ARM64MCExpr::VK_GOTTPREL_LO12_NC ||
916         ELFRefKind == ARM64MCExpr::VK_TLSDESC_LO12) {
917       // Note that we don't range-check the addend. It's adjusted modulo page
918       // size when converted, so there is no "out of range" condition when using
919       // @pageoff.
920       int64_t Value = Addend ? Addend->getValue() : 0;
921       return Value >= 0 && (Value % Scale) == 0;
922     } else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF ||
923                DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) {
924       // @gotpageoff/@tlvppageoff can only be used directly, not with an addend.
925       return Addend == 0;
926     }
927
928     return false;
929   }
930   bool isMemoryIndexed128() const { return isMemoryIndexed(16); }
931   bool isMemoryIndexed64() const { return isMemoryIndexed(8); }
932   bool isMemoryIndexed32() const { return isMemoryIndexed(4); }
933   bool isMemoryIndexed16() const { return isMemoryIndexed(2); }
934   bool isMemoryIndexed8() const { return isMemoryIndexed(1); }
935   bool isMemoryNoIndex() const {
936     if (!isMem())
937       return false;
938     if (Mem.Mode != ImmediateOffset)
939       return false;
940     if (!Mem.OffsetImm)
941       return true;
942
943     // Make sure the immediate value is valid. Only zero is allowed.
944     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.OffsetImm);
945     if (!CE || CE->getValue() != 0)
946       return false;
947     return true;
948   }
949   bool isMemorySIMDNoIndex() const {
950     if (!isMem())
951       return false;
952     if (Mem.Mode != ImmediateOffset)
953       return false;
954     return Mem.OffsetImm == 0;
955   }
956   bool isMemoryIndexedSImm9() const {
957     if (!isMem() || Mem.Mode != ImmediateOffset)
958       return false;
959     if (!Mem.OffsetImm)
960       return true;
961     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.OffsetImm);
962     assert(CE && "Non-constant pre-indexed offset!");
963     int64_t Value = CE->getValue();
964     return Value >= -256 && Value <= 255;
965   }
966   bool isMemoryIndexed32SImm7() const {
967     if (!isMem() || Mem.Mode != ImmediateOffset)
968       return false;
969     if (!Mem.OffsetImm)
970       return true;
971     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.OffsetImm);
972     assert(CE && "Non-constant pre-indexed offset!");
973     int64_t Value = CE->getValue();
974     return ((Value % 4) == 0) && Value >= -256 && Value <= 252;
975   }
976   bool isMemoryIndexed64SImm7() const {
977     if (!isMem() || Mem.Mode != ImmediateOffset)
978       return false;
979     if (!Mem.OffsetImm)
980       return true;
981     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.OffsetImm);
982     assert(CE && "Non-constant pre-indexed offset!");
983     int64_t Value = CE->getValue();
984     return ((Value % 8) == 0) && Value >= -512 && Value <= 504;
985   }
986   bool isMemoryIndexed128SImm7() const {
987     if (!isMem() || Mem.Mode != ImmediateOffset)
988       return false;
989     if (!Mem.OffsetImm)
990       return true;
991     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.OffsetImm);
992     assert(CE && "Non-constant pre-indexed offset!");
993     int64_t Value = CE->getValue();
994     return ((Value % 16) == 0) && Value >= -1024 && Value <= 1008;
995   }
996
997   bool isAdrpLabel() const {
998     // Validation was handled during parsing, so we just sanity check that
999     // something didn't go haywire.
1000     return isImm();
1001   }
1002
1003   bool isAdrLabel() const {
1004     // Validation was handled during parsing, so we just sanity check that
1005     // something didn't go haywire.
1006     return isImm();
1007   }
1008
1009   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1010     // Add as immediates when possible.  Null MCExpr = 0.
1011     if (Expr == 0)
1012       Inst.addOperand(MCOperand::CreateImm(0));
1013     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1014       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1015     else
1016       Inst.addOperand(MCOperand::CreateExpr(Expr));
1017   }
1018
1019   void addRegOperands(MCInst &Inst, unsigned N) const {
1020     assert(N == 1 && "Invalid number of operands!");
1021     Inst.addOperand(MCOperand::CreateReg(getReg()));
1022   }
1023
1024   void addVectorRegOperands(MCInst &Inst, unsigned N) const {
1025     assert(N == 1 && "Invalid number of operands!");
1026     Inst.addOperand(MCOperand::CreateReg(getReg()));
1027   }
1028
1029   template <unsigned NumRegs>
1030   void addVectorList64Operands(MCInst &Inst, unsigned N) const {
1031     assert(N == 1 && "Invalid number of operands!");
1032     static unsigned FirstRegs[] = { ARM64::D0,       ARM64::D0_D1,
1033                                     ARM64::D0_D1_D2, ARM64::D0_D1_D2_D3 };
1034     unsigned FirstReg = FirstRegs[NumRegs - 1];
1035
1036     Inst.addOperand(
1037         MCOperand::CreateReg(FirstReg + getVectorListStart() - ARM64::Q0));
1038   }
1039
1040   template <unsigned NumRegs>
1041   void addVectorList128Operands(MCInst &Inst, unsigned N) const {
1042     assert(N == 1 && "Invalid number of operands!");
1043     static unsigned FirstRegs[] = { ARM64::Q0,       ARM64::Q0_Q1,
1044                                     ARM64::Q0_Q1_Q2, ARM64::Q0_Q1_Q2_Q3 };
1045     unsigned FirstReg = FirstRegs[NumRegs - 1];
1046
1047     Inst.addOperand(
1048         MCOperand::CreateReg(FirstReg + getVectorListStart() - ARM64::Q0));
1049   }
1050
1051   void addVectorIndexBOperands(MCInst &Inst, unsigned N) const {
1052     assert(N == 1 && "Invalid number of operands!");
1053     Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1054   }
1055
1056   void addVectorIndexHOperands(MCInst &Inst, unsigned N) const {
1057     assert(N == 1 && "Invalid number of operands!");
1058     Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1059   }
1060
1061   void addVectorIndexSOperands(MCInst &Inst, unsigned N) const {
1062     assert(N == 1 && "Invalid number of operands!");
1063     Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1064   }
1065
1066   void addVectorIndexDOperands(MCInst &Inst, unsigned N) const {
1067     assert(N == 1 && "Invalid number of operands!");
1068     Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1069   }
1070
1071   void addImmOperands(MCInst &Inst, unsigned N) const {
1072     assert(N == 1 && "Invalid number of operands!");
1073     // If this is a pageoff symrefexpr with an addend, adjust the addend
1074     // to be only the page-offset portion. Otherwise, just add the expr
1075     // as-is.
1076     addExpr(Inst, getImm());
1077   }
1078
1079   void addAdrpLabelOperands(MCInst &Inst, unsigned N) const {
1080     addImmOperands(Inst, N);
1081   }
1082
1083   void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
1084     addImmOperands(Inst, N);
1085   }
1086
1087   void addSImm9Operands(MCInst &Inst, unsigned N) const {
1088     assert(N == 1 && "Invalid number of operands!");
1089     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1090     assert(MCE && "Invalid constant immediate operand!");
1091     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1092   }
1093
1094   void addSImm7s4Operands(MCInst &Inst, unsigned N) const {
1095     assert(N == 1 && "Invalid number of operands!");
1096     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1097     assert(MCE && "Invalid constant immediate operand!");
1098     Inst.addOperand(MCOperand::CreateImm(MCE->getValue() / 4));
1099   }
1100
1101   void addSImm7s8Operands(MCInst &Inst, unsigned N) const {
1102     assert(N == 1 && "Invalid number of operands!");
1103     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1104     assert(MCE && "Invalid constant immediate operand!");
1105     Inst.addOperand(MCOperand::CreateImm(MCE->getValue() / 8));
1106   }
1107
1108   void addSImm7s16Operands(MCInst &Inst, unsigned N) const {
1109     assert(N == 1 && "Invalid number of operands!");
1110     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1111     assert(MCE && "Invalid constant immediate operand!");
1112     Inst.addOperand(MCOperand::CreateImm(MCE->getValue() / 16));
1113   }
1114
1115   void addImm0_7Operands(MCInst &Inst, unsigned N) const {
1116     assert(N == 1 && "Invalid number of operands!");
1117     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1118     assert(MCE && "Invalid constant immediate operand!");
1119     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1120   }
1121
1122   void addImm1_8Operands(MCInst &Inst, unsigned N) const {
1123     assert(N == 1 && "Invalid number of operands!");
1124     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1125     assert(MCE && "Invalid constant immediate operand!");
1126     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1127   }
1128
1129   void addImm0_15Operands(MCInst &Inst, unsigned N) const {
1130     assert(N == 1 && "Invalid number of operands!");
1131     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1132     assert(MCE && "Invalid constant immediate operand!");
1133     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1134   }
1135
1136   void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1137     assert(N == 1 && "Invalid number of operands!");
1138     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1139     assert(MCE && "Invalid constant immediate operand!");
1140     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1141   }
1142
1143   void addImm0_31Operands(MCInst &Inst, unsigned N) const {
1144     assert(N == 1 && "Invalid number of operands!");
1145     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1146     assert(MCE && "Invalid constant immediate operand!");
1147     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1148   }
1149
1150   void addImm1_31Operands(MCInst &Inst, unsigned N) const {
1151     assert(N == 1 && "Invalid number of operands!");
1152     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1153     assert(MCE && "Invalid constant immediate operand!");
1154     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1155   }
1156
1157   void addImm1_32Operands(MCInst &Inst, unsigned N) const {
1158     assert(N == 1 && "Invalid number of operands!");
1159     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1160     assert(MCE && "Invalid constant immediate operand!");
1161     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1162   }
1163
1164   void addImm0_63Operands(MCInst &Inst, unsigned N) const {
1165     assert(N == 1 && "Invalid number of operands!");
1166     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1167     assert(MCE && "Invalid constant immediate operand!");
1168     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1169   }
1170
1171   void addImm1_63Operands(MCInst &Inst, unsigned N) const {
1172     assert(N == 1 && "Invalid number of operands!");
1173     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1174     assert(MCE && "Invalid constant immediate operand!");
1175     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1176   }
1177
1178   void addImm1_64Operands(MCInst &Inst, unsigned N) const {
1179     assert(N == 1 && "Invalid number of operands!");
1180     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1181     assert(MCE && "Invalid constant immediate operand!");
1182     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1183   }
1184
1185   void addImm0_127Operands(MCInst &Inst, unsigned N) const {
1186     assert(N == 1 && "Invalid number of operands!");
1187     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1188     assert(MCE && "Invalid constant immediate operand!");
1189     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1190   }
1191
1192   void addImm0_255Operands(MCInst &Inst, unsigned N) const {
1193     assert(N == 1 && "Invalid number of operands!");
1194     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1195     assert(MCE && "Invalid constant immediate operand!");
1196     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1197   }
1198
1199   void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
1200     assert(N == 1 && "Invalid number of operands!");
1201     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1202     assert(MCE && "Invalid constant immediate operand!");
1203     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1204   }
1205
1206   void addLogicalImm32Operands(MCInst &Inst, unsigned N) const {
1207     assert(N == 1 && "Invalid number of operands!");
1208     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1209     assert(MCE && "Invalid logical immediate operand!");
1210     uint64_t encoding = ARM64_AM::encodeLogicalImmediate(MCE->getValue(), 32);
1211     Inst.addOperand(MCOperand::CreateImm(encoding));
1212   }
1213
1214   void addLogicalImm64Operands(MCInst &Inst, unsigned N) const {
1215     assert(N == 1 && "Invalid number of operands!");
1216     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1217     assert(MCE && "Invalid logical immediate operand!");
1218     uint64_t encoding = ARM64_AM::encodeLogicalImmediate(MCE->getValue(), 64);
1219     Inst.addOperand(MCOperand::CreateImm(encoding));
1220   }
1221
1222   void addSIMDImmType10Operands(MCInst &Inst, unsigned N) const {
1223     assert(N == 1 && "Invalid number of operands!");
1224     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1225     assert(MCE && "Invalid immediate operand!");
1226     uint64_t encoding = ARM64_AM::encodeAdvSIMDModImmType10(MCE->getValue());
1227     Inst.addOperand(MCOperand::CreateImm(encoding));
1228   }
1229
1230   void addBranchTarget26Operands(MCInst &Inst, unsigned N) const {
1231     // Branch operands don't encode the low bits, so shift them off
1232     // here. If it's a label, however, just put it on directly as there's
1233     // not enough information now to do anything.
1234     assert(N == 1 && "Invalid number of operands!");
1235     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1236     if (!MCE) {
1237       addExpr(Inst, getImm());
1238       return;
1239     }
1240     assert(MCE && "Invalid constant immediate operand!");
1241     Inst.addOperand(MCOperand::CreateImm(MCE->getValue() >> 2));
1242   }
1243
1244   void addBranchTarget19Operands(MCInst &Inst, unsigned N) const {
1245     // Branch operands don't encode the low bits, so shift them off
1246     // here. If it's a label, however, just put it on directly as there's
1247     // not enough information now to do anything.
1248     assert(N == 1 && "Invalid number of operands!");
1249     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1250     if (!MCE) {
1251       addExpr(Inst, getImm());
1252       return;
1253     }
1254     assert(MCE && "Invalid constant immediate operand!");
1255     Inst.addOperand(MCOperand::CreateImm(MCE->getValue() >> 2));
1256   }
1257
1258   void addBranchTarget14Operands(MCInst &Inst, unsigned N) const {
1259     // Branch operands don't encode the low bits, so shift them off
1260     // here. If it's a label, however, just put it on directly as there's
1261     // not enough information now to do anything.
1262     assert(N == 1 && "Invalid number of operands!");
1263     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1264     if (!MCE) {
1265       addExpr(Inst, getImm());
1266       return;
1267     }
1268     assert(MCE && "Invalid constant immediate operand!");
1269     Inst.addOperand(MCOperand::CreateImm(MCE->getValue() >> 2));
1270   }
1271
1272   void addFPImmOperands(MCInst &Inst, unsigned N) const {
1273     assert(N == 1 && "Invalid number of operands!");
1274     Inst.addOperand(MCOperand::CreateImm(getFPImm()));
1275   }
1276
1277   void addBarrierOperands(MCInst &Inst, unsigned N) const {
1278     assert(N == 1 && "Invalid number of operands!");
1279     Inst.addOperand(MCOperand::CreateImm(getBarrier()));
1280   }
1281
1282   void addSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1283     assert(N == 1 && "Invalid number of operands!");
1284     if (Kind == k_SystemRegister)
1285       Inst.addOperand(MCOperand::CreateImm(getSystemRegister()));
1286     else {
1287       assert(Kind == k_CPSRField && getCPSRField() == ARM64SYS::cpsr_SPSel);
1288       Inst.addOperand(MCOperand::CreateImm(ARM64SYS::SPSel));
1289     }
1290   }
1291
1292   void addSystemCPSRFieldOperands(MCInst &Inst, unsigned N) const {
1293     assert(N == 1 && "Invalid number of operands!");
1294     Inst.addOperand(MCOperand::CreateImm(getCPSRField()));
1295   }
1296
1297   void addSysCROperands(MCInst &Inst, unsigned N) const {
1298     assert(N == 1 && "Invalid number of operands!");
1299     Inst.addOperand(MCOperand::CreateImm(getSysCR()));
1300   }
1301
1302   void addPrefetchOperands(MCInst &Inst, unsigned N) const {
1303     assert(N == 1 && "Invalid number of operands!");
1304     Inst.addOperand(MCOperand::CreateImm(getPrefetch()));
1305   }
1306
1307   void addShifterOperands(MCInst &Inst, unsigned N) const {
1308     assert(N == 1 && "Invalid number of operands!");
1309     Inst.addOperand(MCOperand::CreateImm(getShifter()));
1310   }
1311
1312   void addArithmeticShifterOperands(MCInst &Inst, unsigned N) const {
1313     assert(N == 1 && "Invalid number of operands!");
1314     Inst.addOperand(MCOperand::CreateImm(getShifter()));
1315   }
1316
1317   void addMovImm32ShifterOperands(MCInst &Inst, unsigned N) const {
1318     assert(N == 1 && "Invalid number of operands!");
1319     Inst.addOperand(MCOperand::CreateImm(getShifter()));
1320   }
1321
1322   void addMovImm64ShifterOperands(MCInst &Inst, unsigned N) const {
1323     assert(N == 1 && "Invalid number of operands!");
1324     Inst.addOperand(MCOperand::CreateImm(getShifter()));
1325   }
1326
1327   void addAddSubShifterOperands(MCInst &Inst, unsigned N) const {
1328     assert(N == 1 && "Invalid number of operands!");
1329     Inst.addOperand(MCOperand::CreateImm(getShifter()));
1330   }
1331
1332   void addLogicalVecShifterOperands(MCInst &Inst, unsigned N) const {
1333     assert(N == 1 && "Invalid number of operands!");
1334     Inst.addOperand(MCOperand::CreateImm(getShifter()));
1335   }
1336
1337   void addLogicalVecHalfWordShifterOperands(MCInst &Inst, unsigned N) const {
1338     assert(N == 1 && "Invalid number of operands!");
1339     Inst.addOperand(MCOperand::CreateImm(getShifter()));
1340   }
1341
1342   void addMoveVecShifterOperands(MCInst &Inst, unsigned N) const {
1343     assert(N == 1 && "Invalid number of operands!");
1344     Inst.addOperand(MCOperand::CreateImm(getShifter()));
1345   }
1346
1347   void addExtendOperands(MCInst &Inst, unsigned N) const {
1348     assert(N == 1 && "Invalid number of operands!");
1349     // lsl is an alias for UXTW but will be a parsed as a k_Shifter operand.
1350     if (isShifter()) {
1351       assert(ARM64_AM::getShiftType(getShifter()) == ARM64_AM::LSL);
1352       unsigned imm = getArithExtendImm(ARM64_AM::UXTW,
1353                                        ARM64_AM::getShiftValue(getShifter()));
1354       Inst.addOperand(MCOperand::CreateImm(imm));
1355     } else
1356       Inst.addOperand(MCOperand::CreateImm(getExtend()));
1357   }
1358
1359   void addExtend64Operands(MCInst &Inst, unsigned N) const {
1360     assert(N == 1 && "Invalid number of operands!");
1361     Inst.addOperand(MCOperand::CreateImm(getExtend()));
1362   }
1363
1364   void addExtendLSL64Operands(MCInst &Inst, unsigned N) const {
1365     assert(N == 1 && "Invalid number of operands!");
1366     // lsl is an alias for UXTX but will be a parsed as a k_Shifter operand.
1367     if (isShifter()) {
1368       assert(ARM64_AM::getShiftType(getShifter()) == ARM64_AM::LSL);
1369       unsigned imm = getArithExtendImm(ARM64_AM::UXTX,
1370                                        ARM64_AM::getShiftValue(getShifter()));
1371       Inst.addOperand(MCOperand::CreateImm(imm));
1372     } else
1373       Inst.addOperand(MCOperand::CreateImm(getExtend()));
1374   }
1375
1376   void addMemoryRegisterOffsetOperands(MCInst &Inst, unsigned N, bool DoShift) {
1377     assert(N == 3 && "Invalid number of operands!");
1378
1379     Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1380     Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
1381     unsigned ExtendImm = ARM64_AM::getMemExtendImm(Mem.ExtType, DoShift);
1382     Inst.addOperand(MCOperand::CreateImm(ExtendImm));
1383   }
1384
1385   void addMemoryRegisterOffset8Operands(MCInst &Inst, unsigned N) {
1386     addMemoryRegisterOffsetOperands(Inst, N, Mem.ExplicitShift);
1387   }
1388
1389   void addMemoryRegisterOffset16Operands(MCInst &Inst, unsigned N) {
1390     addMemoryRegisterOffsetOperands(Inst, N, Mem.ShiftVal == 1);
1391   }
1392
1393   void addMemoryRegisterOffset32Operands(MCInst &Inst, unsigned N) {
1394     addMemoryRegisterOffsetOperands(Inst, N, Mem.ShiftVal == 2);
1395   }
1396
1397   void addMemoryRegisterOffset64Operands(MCInst &Inst, unsigned N) {
1398     addMemoryRegisterOffsetOperands(Inst, N, Mem.ShiftVal == 3);
1399   }
1400
1401   void addMemoryRegisterOffset128Operands(MCInst &Inst, unsigned N) {
1402     addMemoryRegisterOffsetOperands(Inst, N, Mem.ShiftVal == 4);
1403   }
1404
1405   void addMemoryIndexedOperands(MCInst &Inst, unsigned N,
1406                                 unsigned Scale) const {
1407     // Add the base register operand.
1408     Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1409
1410     if (!Mem.OffsetImm) {
1411       // There isn't an offset.
1412       Inst.addOperand(MCOperand::CreateImm(0));
1413       return;
1414     }
1415
1416     // Add the offset operand.
1417     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.OffsetImm)) {
1418       assert(CE->getValue() % Scale == 0 &&
1419              "Offset operand must be multiple of the scale!");
1420
1421       // The MCInst offset operand doesn't include the low bits (like the
1422       // instruction encoding).
1423       Inst.addOperand(MCOperand::CreateImm(CE->getValue() / Scale));
1424     }
1425
1426     // If this is a pageoff symrefexpr with an addend, the linker will
1427     // do the scaling of the addend.
1428     //
1429     // Otherwise we don't know what this is, so just add the scaling divide to
1430     // the expression and let the MC fixup evaluation code deal with it.
1431     const MCExpr *Expr = Mem.OffsetImm;
1432     ARM64MCExpr::VariantKind ELFRefKind;
1433     MCSymbolRefExpr::VariantKind DarwinRefKind;
1434     const MCConstantExpr *Addend;
1435     if (Scale > 1 &&
1436         (!ARM64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
1437                                             Addend) ||
1438          (Addend != 0 && DarwinRefKind != MCSymbolRefExpr::VK_PAGEOFF))) {
1439       Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(Scale, Ctx),
1440                                      Ctx);
1441     }
1442
1443     Inst.addOperand(MCOperand::CreateExpr(Expr));
1444   }
1445
1446   void addMemoryUnscaledOperands(MCInst &Inst, unsigned N) const {
1447     assert(N == 2 && isMemoryUnscaled() && "Invalid number of operands!");
1448     // Add the base register operand.
1449     Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1450
1451     // Add the offset operand.
1452     if (!Mem.OffsetImm)
1453       Inst.addOperand(MCOperand::CreateImm(0));
1454     else {
1455       // Only constant offsets supported.
1456       const MCConstantExpr *CE = cast<MCConstantExpr>(Mem.OffsetImm);
1457       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1458     }
1459   }
1460
1461   void addMemoryIndexed128Operands(MCInst &Inst, unsigned N) const {
1462     assert(N == 2 && isMemoryIndexed128() && "Invalid number of operands!");
1463     addMemoryIndexedOperands(Inst, N, 16);
1464   }
1465
1466   void addMemoryIndexed64Operands(MCInst &Inst, unsigned N) const {
1467     assert(N == 2 && isMemoryIndexed64() && "Invalid number of operands!");
1468     addMemoryIndexedOperands(Inst, N, 8);
1469   }
1470
1471   void addMemoryIndexed32Operands(MCInst &Inst, unsigned N) const {
1472     assert(N == 2 && isMemoryIndexed32() && "Invalid number of operands!");
1473     addMemoryIndexedOperands(Inst, N, 4);
1474   }
1475
1476   void addMemoryIndexed16Operands(MCInst &Inst, unsigned N) const {
1477     assert(N == 2 && isMemoryIndexed16() && "Invalid number of operands!");
1478     addMemoryIndexedOperands(Inst, N, 2);
1479   }
1480
1481   void addMemoryIndexed8Operands(MCInst &Inst, unsigned N) const {
1482     assert(N == 2 && isMemoryIndexed8() && "Invalid number of operands!");
1483     addMemoryIndexedOperands(Inst, N, 1);
1484   }
1485
1486   void addMemoryNoIndexOperands(MCInst &Inst, unsigned N) const {
1487     assert(N == 1 && isMemoryNoIndex() && "Invalid number of operands!");
1488     // Add the base register operand (the offset is always zero, so ignore it).
1489     Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1490   }
1491
1492   void addMemorySIMDNoIndexOperands(MCInst &Inst, unsigned N) const {
1493     assert(N == 1 && isMemorySIMDNoIndex() && "Invalid number of operands!");
1494     // Add the base register operand (the offset is always zero, so ignore it).
1495     Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1496   }
1497
1498   void addMemoryWritebackIndexedOperands(MCInst &Inst, unsigned N,
1499                                          unsigned Scale) const {
1500     assert(N == 2 && "Invalid number of operands!");
1501
1502     // Add the base register operand.
1503     Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1504
1505     // Add the offset operand.
1506     int64_t Offset = 0;
1507     if (Mem.OffsetImm) {
1508       const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.OffsetImm);
1509       assert(CE && "Non-constant indexed offset operand!");
1510       Offset = CE->getValue();
1511     }
1512
1513     if (Scale != 1) {
1514       assert(Offset % Scale == 0 &&
1515              "Offset operand must be a multiple of the scale!");
1516       Offset /= Scale;
1517     }
1518
1519     Inst.addOperand(MCOperand::CreateImm(Offset));
1520   }
1521
1522   void addMemoryIndexedSImm9Operands(MCInst &Inst, unsigned N) const {
1523     addMemoryWritebackIndexedOperands(Inst, N, 1);
1524   }
1525
1526   void addMemoryIndexed32SImm7Operands(MCInst &Inst, unsigned N) const {
1527     addMemoryWritebackIndexedOperands(Inst, N, 4);
1528   }
1529
1530   void addMemoryIndexed64SImm7Operands(MCInst &Inst, unsigned N) const {
1531     addMemoryWritebackIndexedOperands(Inst, N, 8);
1532   }
1533
1534   void addMemoryIndexed128SImm7Operands(MCInst &Inst, unsigned N) const {
1535     addMemoryWritebackIndexedOperands(Inst, N, 16);
1536   }
1537
1538   virtual void print(raw_ostream &OS) const;
1539
1540   static ARM64Operand *CreateToken(StringRef Str, bool IsSuffix, SMLoc S,
1541                                    MCContext &Ctx) {
1542     ARM64Operand *Op = new ARM64Operand(k_Token, Ctx);
1543     Op->Tok.Data = Str.data();
1544     Op->Tok.Length = Str.size();
1545     Op->Tok.IsSuffix = IsSuffix;
1546     Op->StartLoc = S;
1547     Op->EndLoc = S;
1548     return Op;
1549   }
1550
1551   static ARM64Operand *CreateReg(unsigned RegNum, bool isVector, SMLoc S,
1552                                  SMLoc E, MCContext &Ctx) {
1553     ARM64Operand *Op = new ARM64Operand(k_Register, Ctx);
1554     Op->Reg.RegNum = RegNum;
1555     Op->Reg.isVector = isVector;
1556     Op->StartLoc = S;
1557     Op->EndLoc = E;
1558     return Op;
1559   }
1560
1561   static ARM64Operand *CreateVectorList(unsigned RegNum, unsigned Count,
1562                                         unsigned NumElements, char ElementKind,
1563                                         SMLoc S, SMLoc E, MCContext &Ctx) {
1564     ARM64Operand *Op = new ARM64Operand(k_VectorList, Ctx);
1565     Op->VectorList.RegNum = RegNum;
1566     Op->VectorList.Count = Count;
1567     Op->VectorList.NumElements = NumElements;
1568     Op->VectorList.ElementKind = ElementKind;
1569     Op->StartLoc = S;
1570     Op->EndLoc = E;
1571     return Op;
1572   }
1573
1574   static ARM64Operand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
1575                                          MCContext &Ctx) {
1576     ARM64Operand *Op = new ARM64Operand(k_VectorIndex, Ctx);
1577     Op->VectorIndex.Val = Idx;
1578     Op->StartLoc = S;
1579     Op->EndLoc = E;
1580     return Op;
1581   }
1582
1583   static ARM64Operand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E,
1584                                  MCContext &Ctx) {
1585     ARM64Operand *Op = new ARM64Operand(k_Immediate, Ctx);
1586     Op->Imm.Val = Val;
1587     Op->StartLoc = S;
1588     Op->EndLoc = E;
1589     return Op;
1590   }
1591
1592   static ARM64Operand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) {
1593     ARM64Operand *Op = new ARM64Operand(k_FPImm, Ctx);
1594     Op->FPImm.Val = Val;
1595     Op->StartLoc = S;
1596     Op->EndLoc = S;
1597     return Op;
1598   }
1599
1600   static ARM64Operand *CreateBarrier(unsigned Val, SMLoc S, MCContext &Ctx) {
1601     ARM64Operand *Op = new ARM64Operand(k_Barrier, Ctx);
1602     Op->Barrier.Val = Val;
1603     Op->StartLoc = S;
1604     Op->EndLoc = S;
1605     return Op;
1606   }
1607
1608   static ARM64Operand *CreateSystemRegister(uint16_t Val, SMLoc S,
1609                                             MCContext &Ctx) {
1610     ARM64Operand *Op = new ARM64Operand(k_SystemRegister, Ctx);
1611     Op->SystemRegister.Val = Val;
1612     Op->StartLoc = S;
1613     Op->EndLoc = S;
1614     return Op;
1615   }
1616
1617   static ARM64Operand *CreateCPSRField(ARM64SYS::CPSRField Field, SMLoc S,
1618                                        MCContext &Ctx) {
1619     ARM64Operand *Op = new ARM64Operand(k_CPSRField, Ctx);
1620     Op->CPSRField.Field = Field;
1621     Op->StartLoc = S;
1622     Op->EndLoc = S;
1623     return Op;
1624   }
1625
1626   static ARM64Operand *CreateMem(unsigned BaseRegNum, const MCExpr *Off,
1627                                  SMLoc S, SMLoc E, SMLoc OffsetLoc,
1628                                  MCContext &Ctx) {
1629     ARM64Operand *Op = new ARM64Operand(k_Memory, Ctx);
1630     Op->Mem.BaseRegNum = BaseRegNum;
1631     Op->Mem.OffsetRegNum = 0;
1632     Op->Mem.OffsetImm = Off;
1633     Op->Mem.ExtType = ARM64_AM::UXTX;
1634     Op->Mem.ShiftVal = 0;
1635     Op->Mem.ExplicitShift = false;
1636     Op->Mem.Mode = ImmediateOffset;
1637     Op->OffsetLoc = OffsetLoc;
1638     Op->StartLoc = S;
1639     Op->EndLoc = E;
1640     return Op;
1641   }
1642
1643   static ARM64Operand *CreateRegOffsetMem(unsigned BaseReg, unsigned OffsetReg,
1644                                           ARM64_AM::ExtendType ExtType,
1645                                           unsigned ShiftVal, bool ExplicitShift,
1646                                           SMLoc S, SMLoc E, MCContext &Ctx) {
1647     ARM64Operand *Op = new ARM64Operand(k_Memory, Ctx);
1648     Op->Mem.BaseRegNum = BaseReg;
1649     Op->Mem.OffsetRegNum = OffsetReg;
1650     Op->Mem.OffsetImm = 0;
1651     Op->Mem.ExtType = ExtType;
1652     Op->Mem.ShiftVal = ShiftVal;
1653     Op->Mem.ExplicitShift = ExplicitShift;
1654     Op->Mem.Mode = RegisterOffset;
1655     Op->StartLoc = S;
1656     Op->EndLoc = E;
1657     return Op;
1658   }
1659
1660   static ARM64Operand *CreateSysCR(unsigned Val, SMLoc S, SMLoc E,
1661                                    MCContext &Ctx) {
1662     ARM64Operand *Op = new ARM64Operand(k_SysCR, Ctx);
1663     Op->SysCRImm.Val = Val;
1664     Op->StartLoc = S;
1665     Op->EndLoc = E;
1666     return Op;
1667   }
1668
1669   static ARM64Operand *CreatePrefetch(unsigned Val, SMLoc S, MCContext &Ctx) {
1670     ARM64Operand *Op = new ARM64Operand(k_Prefetch, Ctx);
1671     Op->Prefetch.Val = Val;
1672     Op->StartLoc = S;
1673     Op->EndLoc = S;
1674     return Op;
1675   }
1676
1677   static ARM64Operand *CreateShifter(ARM64_AM::ShiftType ShOp, unsigned Val,
1678                                      SMLoc S, SMLoc E, MCContext &Ctx) {
1679     ARM64Operand *Op = new ARM64Operand(k_Shifter, Ctx);
1680     Op->Shifter.Val = ARM64_AM::getShifterImm(ShOp, Val);
1681     Op->StartLoc = S;
1682     Op->EndLoc = E;
1683     return Op;
1684   }
1685
1686   static ARM64Operand *CreateExtend(ARM64_AM::ExtendType ExtOp, unsigned Val,
1687                                     SMLoc S, SMLoc E, MCContext &Ctx) {
1688     ARM64Operand *Op = new ARM64Operand(k_Extend, Ctx);
1689     Op->Extend.Val = ARM64_AM::getArithExtendImm(ExtOp, Val);
1690     Op->StartLoc = S;
1691     Op->EndLoc = E;
1692     return Op;
1693   }
1694 };
1695
1696 } // end anonymous namespace.
1697
1698 void ARM64Operand::print(raw_ostream &OS) const {
1699   switch (Kind) {
1700   case k_FPImm:
1701     OS << "<fpimm " << getFPImm() << "(" << ARM64_AM::getFPImmFloat(getFPImm())
1702        << ") >";
1703     break;
1704   case k_Barrier: {
1705     const char *Name =
1706         ARM64SYS::getBarrierOptName((ARM64SYS::BarrierOption)getBarrier());
1707     OS << "<barrier ";
1708     if (Name)
1709       OS << Name;
1710     else
1711       OS << getBarrier();
1712     OS << ">";
1713     break;
1714   }
1715   case k_SystemRegister: {
1716     const char *Name = ARM64SYS::getSystemRegisterName(
1717         (ARM64SYS::SystemRegister)getSystemRegister());
1718     OS << "<systemreg ";
1719     if (Name)
1720       OS << Name;
1721     else
1722       OS << "#" << getSystemRegister();
1723     OS << ">";
1724     break;
1725   }
1726   case k_CPSRField: {
1727     const char *Name = ARM64SYS::getCPSRFieldName(getCPSRField());
1728     OS << "<cpsrfield " << Name << ">";
1729     break;
1730   }
1731   case k_Immediate:
1732     getImm()->print(OS);
1733     break;
1734   case k_Memory:
1735     OS << "<memory>";
1736     break;
1737   case k_Register:
1738     OS << "<register " << getReg() << ">";
1739     break;
1740   case k_VectorList: {
1741     OS << "<vectorlist ";
1742     unsigned Reg = getVectorListStart();
1743     for (unsigned i = 0, e = getVectorListCount(); i != e; ++i)
1744       OS << Reg + i << " ";
1745     OS << ">";
1746     break;
1747   }
1748   case k_VectorIndex:
1749     OS << "<vectorindex " << getVectorIndex() << ">";
1750     break;
1751   case k_Token:
1752     OS << "'" << getToken() << "'";
1753     break;
1754   case k_SysCR:
1755     OS << "c" << getSysCR();
1756     break;
1757   case k_Prefetch:
1758     OS << "<prfop ";
1759     if (ARM64_AM::isNamedPrefetchOp(getPrefetch()))
1760       OS << ARM64_AM::getPrefetchOpName((ARM64_AM::PrefetchOp)getPrefetch());
1761     else
1762       OS << "#" << getPrefetch();
1763     OS << ">";
1764     break;
1765   case k_Shifter: {
1766     unsigned Val = getShifter();
1767     OS << "<" << ARM64_AM::getShiftName(ARM64_AM::getShiftType(Val)) << " #"
1768        << ARM64_AM::getShiftValue(Val) << ">";
1769     break;
1770   }
1771   case k_Extend: {
1772     unsigned Val = getExtend();
1773     OS << "<" << ARM64_AM::getExtendName(ARM64_AM::getArithExtendType(Val))
1774        << " #" << ARM64_AM::getArithShiftValue(Val) << ">";
1775     break;
1776   }
1777   }
1778 }
1779
1780 /// @name Auto-generated Match Functions
1781 /// {
1782
1783 static unsigned MatchRegisterName(StringRef Name);
1784
1785 /// }
1786
1787 static unsigned matchVectorRegName(StringRef Name) {
1788   return StringSwitch<unsigned>(Name)
1789       .Case("v0", ARM64::Q0)
1790       .Case("v1", ARM64::Q1)
1791       .Case("v2", ARM64::Q2)
1792       .Case("v3", ARM64::Q3)
1793       .Case("v4", ARM64::Q4)
1794       .Case("v5", ARM64::Q5)
1795       .Case("v6", ARM64::Q6)
1796       .Case("v7", ARM64::Q7)
1797       .Case("v8", ARM64::Q8)
1798       .Case("v9", ARM64::Q9)
1799       .Case("v10", ARM64::Q10)
1800       .Case("v11", ARM64::Q11)
1801       .Case("v12", ARM64::Q12)
1802       .Case("v13", ARM64::Q13)
1803       .Case("v14", ARM64::Q14)
1804       .Case("v15", ARM64::Q15)
1805       .Case("v16", ARM64::Q16)
1806       .Case("v17", ARM64::Q17)
1807       .Case("v18", ARM64::Q18)
1808       .Case("v19", ARM64::Q19)
1809       .Case("v20", ARM64::Q20)
1810       .Case("v21", ARM64::Q21)
1811       .Case("v22", ARM64::Q22)
1812       .Case("v23", ARM64::Q23)
1813       .Case("v24", ARM64::Q24)
1814       .Case("v25", ARM64::Q25)
1815       .Case("v26", ARM64::Q26)
1816       .Case("v27", ARM64::Q27)
1817       .Case("v28", ARM64::Q28)
1818       .Case("v29", ARM64::Q29)
1819       .Case("v30", ARM64::Q30)
1820       .Case("v31", ARM64::Q31)
1821       .Default(0);
1822 }
1823
1824 static bool isValidVectorKind(StringRef Name) {
1825   return StringSwitch<bool>(Name.lower())
1826       .Case(".8b", true)
1827       .Case(".16b", true)
1828       .Case(".4h", true)
1829       .Case(".8h", true)
1830       .Case(".2s", true)
1831       .Case(".4s", true)
1832       .Case(".1d", true)
1833       .Case(".2d", true)
1834       .Case(".1q", true)
1835       // Accept the width neutral ones, too, for verbose syntax. If those
1836       // aren't used in the right places, the token operand won't match so
1837       // all will work out.
1838       .Case(".b", true)
1839       .Case(".h", true)
1840       .Case(".s", true)
1841       .Case(".d", true)
1842       .Default(false);
1843 }
1844
1845 static void parseValidVectorKind(StringRef Name, unsigned &NumElements,
1846                                  char &ElementKind) {
1847   assert(isValidVectorKind(Name));
1848
1849   ElementKind = Name.lower()[Name.size() - 1];
1850   NumElements = 0;
1851
1852   if (Name.size() == 2)
1853     return;
1854
1855   // Parse the lane count
1856   Name = Name.drop_front();
1857   while (isdigit(Name.front())) {
1858     NumElements = 10 * NumElements + (Name.front() - '0');
1859     Name = Name.drop_front();
1860   }
1861 }
1862
1863 bool ARM64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1864                                    SMLoc &EndLoc) {
1865   StartLoc = getLoc();
1866   RegNo = tryParseRegister();
1867   EndLoc = SMLoc::getFromPointer(getLoc().getPointer() - 1);
1868   return (RegNo == (unsigned)-1);
1869 }
1870
1871 /// tryParseRegister - Try to parse a register name. The token must be an
1872 /// Identifier when called, and if it is a register name the token is eaten and
1873 /// the register is added to the operand list.
1874 int ARM64AsmParser::tryParseRegister() {
1875   const AsmToken &Tok = Parser.getTok();
1876   assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1877
1878   std::string lowerCase = Tok.getString().lower();
1879   unsigned RegNum = MatchRegisterName(lowerCase);
1880   // Also handle a few aliases of registers.
1881   if (RegNum == 0)
1882     RegNum = StringSwitch<unsigned>(lowerCase)
1883                  .Case("x29", ARM64::FP)
1884                  .Case("x30", ARM64::LR)
1885                  .Case("x31", ARM64::XZR)
1886                  .Case("w31", ARM64::WZR)
1887                  .Default(0);
1888
1889   if (RegNum == 0)
1890     return -1;
1891
1892   Parser.Lex(); // Eat identifier token.
1893   return RegNum;
1894 }
1895
1896 /// tryMatchVectorRegister - Try to parse a vector register name with optional
1897 /// kind specifier. If it is a register specifier, eat the token and return it.
1898 int ARM64AsmParser::tryMatchVectorRegister(StringRef &Kind, bool expected) {
1899   if (Parser.getTok().isNot(AsmToken::Identifier)) {
1900     TokError("vector register expected");
1901     return -1;
1902   }
1903
1904   StringRef Name = Parser.getTok().getString();
1905   // If there is a kind specifier, it's separated from the register name by
1906   // a '.'.
1907   size_t Start = 0, Next = Name.find('.');
1908   StringRef Head = Name.slice(Start, Next);
1909   unsigned RegNum = matchVectorRegName(Head);
1910   if (RegNum) {
1911     if (Next != StringRef::npos) {
1912       Kind = Name.slice(Next, StringRef::npos);
1913       if (!isValidVectorKind(Kind)) {
1914         TokError("invalid vector kind qualifier");
1915         return -1;
1916       }
1917     }
1918     Parser.Lex(); // Eat the register token.
1919     return RegNum;
1920   }
1921
1922   if (expected)
1923     TokError("vector register expected");
1924   return -1;
1925 }
1926
1927 static int MatchSysCRName(StringRef Name) {
1928   // Use the same layout as the tablegen'erated register name matcher. Ugly,
1929   // but efficient.
1930   switch (Name.size()) {
1931   default:
1932     break;
1933   case 2:
1934     if (Name[0] != 'c' && Name[0] != 'C')
1935       return -1;
1936     switch (Name[1]) {
1937     default:
1938       return -1;
1939     case '0':
1940       return 0;
1941     case '1':
1942       return 1;
1943     case '2':
1944       return 2;
1945     case '3':
1946       return 3;
1947     case '4':
1948       return 4;
1949     case '5':
1950       return 5;
1951     case '6':
1952       return 6;
1953     case '7':
1954       return 7;
1955     case '8':
1956       return 8;
1957     case '9':
1958       return 9;
1959     }
1960     break;
1961   case 3:
1962     if ((Name[0] != 'c' && Name[0] != 'C') || Name[1] != '1')
1963       return -1;
1964     switch (Name[2]) {
1965     default:
1966       return -1;
1967     case '0':
1968       return 10;
1969     case '1':
1970       return 11;
1971     case '2':
1972       return 12;
1973     case '3':
1974       return 13;
1975     case '4':
1976       return 14;
1977     case '5':
1978       return 15;
1979     }
1980     break;
1981   }
1982
1983   llvm_unreachable("Unhandled SysCR operand string!");
1984   return -1;
1985 }
1986
1987 /// tryParseSysCROperand - Try to parse a system instruction CR operand name.
1988 ARM64AsmParser::OperandMatchResultTy
1989 ARM64AsmParser::tryParseSysCROperand(OperandVector &Operands) {
1990   SMLoc S = getLoc();
1991   const AsmToken &Tok = Parser.getTok();
1992   if (Tok.isNot(AsmToken::Identifier))
1993     return MatchOperand_NoMatch;
1994
1995   int Num = MatchSysCRName(Tok.getString());
1996   if (Num == -1)
1997     return MatchOperand_NoMatch;
1998
1999   Parser.Lex(); // Eat identifier token.
2000   Operands.push_back(ARM64Operand::CreateSysCR(Num, S, getLoc(), getContext()));
2001   return MatchOperand_Success;
2002 }
2003
2004 /// tryParsePrefetch - Try to parse a prefetch operand.
2005 ARM64AsmParser::OperandMatchResultTy
2006 ARM64AsmParser::tryParsePrefetch(OperandVector &Operands) {
2007   SMLoc S = getLoc();
2008   const AsmToken &Tok = Parser.getTok();
2009   // Either an identifier for named values or a 5-bit immediate.
2010   if (Tok.is(AsmToken::Hash)) {
2011     Parser.Lex(); // Eat hash token.
2012     const MCExpr *ImmVal;
2013     if (getParser().parseExpression(ImmVal))
2014       return MatchOperand_ParseFail;
2015
2016     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2017     if (!MCE) {
2018       TokError("immediate value expected for prefetch operand");
2019       return MatchOperand_ParseFail;
2020     }
2021     unsigned prfop = MCE->getValue();
2022     if (prfop > 31) {
2023       TokError("prefetch operand out of range, [0,31] expected");
2024       return MatchOperand_ParseFail;
2025     }
2026
2027     Operands.push_back(ARM64Operand::CreatePrefetch(prfop, S, getContext()));
2028     return MatchOperand_Success;
2029   }
2030
2031   if (Tok.isNot(AsmToken::Identifier)) {
2032     TokError("pre-fetch hint expected");
2033     return MatchOperand_ParseFail;
2034   }
2035
2036   unsigned prfop = StringSwitch<unsigned>(Tok.getString())
2037                        .Case("pldl1keep", ARM64_AM::PLDL1KEEP)
2038                        .Case("pldl1strm", ARM64_AM::PLDL1STRM)
2039                        .Case("pldl2keep", ARM64_AM::PLDL2KEEP)
2040                        .Case("pldl2strm", ARM64_AM::PLDL2STRM)
2041                        .Case("pldl3keep", ARM64_AM::PLDL3KEEP)
2042                        .Case("pldl3strm", ARM64_AM::PLDL3STRM)
2043                        .Case("pstl1keep", ARM64_AM::PSTL1KEEP)
2044                        .Case("pstl1strm", ARM64_AM::PSTL1STRM)
2045                        .Case("pstl2keep", ARM64_AM::PSTL2KEEP)
2046                        .Case("pstl2strm", ARM64_AM::PSTL2STRM)
2047                        .Case("pstl3keep", ARM64_AM::PSTL3KEEP)
2048                        .Case("pstl3strm", ARM64_AM::PSTL3STRM)
2049                        .Default(0xff);
2050   if (prfop == 0xff) {
2051     TokError("pre-fetch hint expected");
2052     return MatchOperand_ParseFail;
2053   }
2054
2055   Parser.Lex(); // Eat identifier token.
2056   Operands.push_back(ARM64Operand::CreatePrefetch(prfop, S, getContext()));
2057   return MatchOperand_Success;
2058 }
2059
2060 /// tryParseAdrpLabel - Parse and validate a source label for the ADRP
2061 /// instruction.
2062 ARM64AsmParser::OperandMatchResultTy
2063 ARM64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
2064   SMLoc S = getLoc();
2065   const MCExpr *Expr;
2066   if (parseSymbolicImmVal(Expr))
2067     return MatchOperand_ParseFail;
2068
2069   ARM64MCExpr::VariantKind ELFRefKind;
2070   MCSymbolRefExpr::VariantKind DarwinRefKind;
2071   const MCConstantExpr *Addend;
2072   if (!classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
2073     Error(S, "modified label reference + constant expected");
2074     return MatchOperand_ParseFail;
2075   }
2076
2077   if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
2078       ELFRefKind == ARM64MCExpr::VK_INVALID) {
2079     // No modifier was specified at all; this is the syntax for an ELF basic
2080     // ADRP relocation (unfortunately).
2081     Expr = ARM64MCExpr::Create(Expr, ARM64MCExpr::VK_ABS_PAGE, getContext());
2082   } else if ((DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGE ||
2083               DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGE) &&
2084              Addend != 0) {
2085     Error(S, "gotpage label reference not allowed an addend");
2086     return MatchOperand_ParseFail;
2087   } else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE &&
2088              DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE &&
2089              DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
2090              ELFRefKind != ARM64MCExpr::VK_GOT_PAGE &&
2091              ELFRefKind != ARM64MCExpr::VK_GOTTPREL_PAGE &&
2092              ELFRefKind != ARM64MCExpr::VK_TLSDESC_PAGE) {
2093     // The operand must be an @page or @gotpage qualified symbolref.
2094     Error(S, "page or gotpage label reference expected");
2095     return MatchOperand_ParseFail;
2096   }
2097
2098   // We have a label reference possibly with addend. The addend is a raw value
2099   // here. The linker will adjust it to only reference the page.
2100   SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2101   Operands.push_back(ARM64Operand::CreateImm(Expr, S, E, getContext()));
2102
2103   return MatchOperand_Success;
2104 }
2105
2106 /// tryParseAdrLabel - Parse and validate a source label for the ADR
2107 /// instruction.
2108 ARM64AsmParser::OperandMatchResultTy
2109 ARM64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
2110   SMLoc S = getLoc();
2111   const MCExpr *Expr;
2112   if (getParser().parseExpression(Expr))
2113     return MatchOperand_ParseFail;
2114
2115   // The operand must be an un-qualified assembler local symbolref.
2116   // FIXME: wrong for ELF.
2117   if (const MCSymbolRefExpr *SRE = dyn_cast<const MCSymbolRefExpr>(Expr)) {
2118     // FIXME: Should reference the MachineAsmInfo to get the private prefix.
2119     bool isTemporary = SRE->getSymbol().getName().startswith("L");
2120     if (!isTemporary || SRE->getKind() != MCSymbolRefExpr::VK_None) {
2121       Error(S, "unqualified, assembler-local label name expected");
2122       return MatchOperand_ParseFail;
2123     }
2124   }
2125
2126   SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2127   Operands.push_back(ARM64Operand::CreateImm(Expr, S, E, getContext()));
2128
2129   return MatchOperand_Success;
2130 }
2131
2132 /// tryParseFPImm - A floating point immediate expression operand.
2133 ARM64AsmParser::OperandMatchResultTy
2134 ARM64AsmParser::tryParseFPImm(OperandVector &Operands) {
2135   SMLoc S = getLoc();
2136
2137   if (Parser.getTok().isNot(AsmToken::Hash))
2138     return MatchOperand_NoMatch;
2139   Parser.Lex(); // Eat the '#'.
2140
2141   // Handle negation, as that still comes through as a separate token.
2142   bool isNegative = false;
2143   if (Parser.getTok().is(AsmToken::Minus)) {
2144     isNegative = true;
2145     Parser.Lex();
2146   }
2147   const AsmToken &Tok = Parser.getTok();
2148   if (Tok.is(AsmToken::Real)) {
2149     APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
2150     uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
2151     // If we had a '-' in front, toggle the sign bit.
2152     IntVal ^= (uint64_t)isNegative << 63;
2153     int Val = ARM64_AM::getFP64Imm(APInt(64, IntVal));
2154     Parser.Lex(); // Eat the token.
2155     // Check for out of range values. As an exception, we let Zero through,
2156     // as we handle that special case in post-processing before matching in
2157     // order to use the zero register for it.
2158     if (Val == -1 && !RealVal.isZero()) {
2159       TokError("floating point value out of range");
2160       return MatchOperand_ParseFail;
2161     }
2162     Operands.push_back(ARM64Operand::CreateFPImm(Val, S, getContext()));
2163     return MatchOperand_Success;
2164   }
2165   if (Tok.is(AsmToken::Integer)) {
2166     int64_t Val;
2167     if (!isNegative && Tok.getString().startswith("0x")) {
2168       Val = Tok.getIntVal();
2169       if (Val > 255 || Val < 0) {
2170         TokError("encoded floating point value out of range");
2171         return MatchOperand_ParseFail;
2172       }
2173     } else {
2174       APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
2175       uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
2176       // If we had a '-' in front, toggle the sign bit.
2177       IntVal ^= (uint64_t)isNegative << 63;
2178       Val = ARM64_AM::getFP64Imm(APInt(64, IntVal));
2179     }
2180     Parser.Lex(); // Eat the token.
2181     Operands.push_back(ARM64Operand::CreateFPImm(Val, S, getContext()));
2182     return MatchOperand_Success;
2183   }
2184
2185   TokError("invalid floating point immediate");
2186   return MatchOperand_ParseFail;
2187 }
2188
2189 /// parseCondCodeString - Parse a Condition Code string.
2190 unsigned ARM64AsmParser::parseCondCodeString(StringRef Cond) {
2191   unsigned CC = StringSwitch<unsigned>(Cond.lower())
2192                     .Case("eq", ARM64CC::EQ)
2193                     .Case("ne", ARM64CC::NE)
2194                     .Case("cs", ARM64CC::CS)
2195                     .Case("hs", ARM64CC::CS)
2196                     .Case("cc", ARM64CC::CC)
2197                     .Case("lo", ARM64CC::CC)
2198                     .Case("mi", ARM64CC::MI)
2199                     .Case("pl", ARM64CC::PL)
2200                     .Case("vs", ARM64CC::VS)
2201                     .Case("vc", ARM64CC::VC)
2202                     .Case("hi", ARM64CC::HI)
2203                     .Case("ls", ARM64CC::LS)
2204                     .Case("ge", ARM64CC::GE)
2205                     .Case("lt", ARM64CC::LT)
2206                     .Case("gt", ARM64CC::GT)
2207                     .Case("le", ARM64CC::LE)
2208                     .Case("al", ARM64CC::AL)
2209                     .Case("nv", ARM64CC::NV)
2210                     .Default(ARM64CC::Invalid);
2211   return CC;
2212 }
2213
2214 /// parseCondCode - Parse a Condition Code operand.
2215 bool ARM64AsmParser::parseCondCode(OperandVector &Operands,
2216                                    bool invertCondCode) {
2217   SMLoc S = getLoc();
2218   const AsmToken &Tok = Parser.getTok();
2219   assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2220
2221   StringRef Cond = Tok.getString();
2222   unsigned CC = parseCondCodeString(Cond);
2223   if (CC == ARM64CC::Invalid)
2224     return TokError("invalid condition code");
2225   Parser.Lex(); // Eat identifier token.
2226
2227   if (invertCondCode)
2228     CC = ARM64CC::getInvertedCondCode(ARM64CC::CondCode(CC));
2229
2230   const MCExpr *CCExpr = MCConstantExpr::Create(CC, getContext());
2231   Operands.push_back(
2232       ARM64Operand::CreateImm(CCExpr, S, getLoc(), getContext()));
2233   return false;
2234 }
2235
2236 /// ParseOptionalShift - Some operands take an optional shift argument. Parse
2237 /// them if present.
2238 bool ARM64AsmParser::parseOptionalShift(OperandVector &Operands) {
2239   const AsmToken &Tok = Parser.getTok();
2240   ARM64_AM::ShiftType ShOp = StringSwitch<ARM64_AM::ShiftType>(Tok.getString())
2241                                  .Case("lsl", ARM64_AM::LSL)
2242                                  .Case("lsr", ARM64_AM::LSR)
2243                                  .Case("asr", ARM64_AM::ASR)
2244                                  .Case("ror", ARM64_AM::ROR)
2245                                  .Case("msl", ARM64_AM::MSL)
2246                                  .Case("LSL", ARM64_AM::LSL)
2247                                  .Case("LSR", ARM64_AM::LSR)
2248                                  .Case("ASR", ARM64_AM::ASR)
2249                                  .Case("ROR", ARM64_AM::ROR)
2250                                  .Case("MSL", ARM64_AM::MSL)
2251                                  .Default(ARM64_AM::InvalidShift);
2252   if (ShOp == ARM64_AM::InvalidShift)
2253     return true;
2254
2255   SMLoc S = Tok.getLoc();
2256   Parser.Lex();
2257
2258   // We expect a number here.
2259   if (getLexer().isNot(AsmToken::Hash))
2260     return TokError("immediate value expected for shifter operand");
2261   Parser.Lex(); // Eat the '#'.
2262
2263   SMLoc ExprLoc = getLoc();
2264   const MCExpr *ImmVal;
2265   if (getParser().parseExpression(ImmVal))
2266     return true;
2267
2268   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2269   if (!MCE)
2270     return TokError("immediate value expected for shifter operand");
2271
2272   if ((MCE->getValue() & 0x3f) != MCE->getValue())
2273     return Error(ExprLoc, "immediate value too large for shifter operand");
2274
2275   SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2276   Operands.push_back(
2277       ARM64Operand::CreateShifter(ShOp, MCE->getValue(), S, E, getContext()));
2278   return false;
2279 }
2280
2281 /// parseOptionalExtend - Some operands take an optional extend argument. Parse
2282 /// them if present.
2283 bool ARM64AsmParser::parseOptionalExtend(OperandVector &Operands) {
2284   const AsmToken &Tok = Parser.getTok();
2285   ARM64_AM::ExtendType ExtOp =
2286       StringSwitch<ARM64_AM::ExtendType>(Tok.getString())
2287           .Case("uxtb", ARM64_AM::UXTB)
2288           .Case("uxth", ARM64_AM::UXTH)
2289           .Case("uxtw", ARM64_AM::UXTW)
2290           .Case("uxtx", ARM64_AM::UXTX)
2291           .Case("lsl", ARM64_AM::UXTX) // Alias for UXTX
2292           .Case("sxtb", ARM64_AM::SXTB)
2293           .Case("sxth", ARM64_AM::SXTH)
2294           .Case("sxtw", ARM64_AM::SXTW)
2295           .Case("sxtx", ARM64_AM::SXTX)
2296           .Case("UXTB", ARM64_AM::UXTB)
2297           .Case("UXTH", ARM64_AM::UXTH)
2298           .Case("UXTW", ARM64_AM::UXTW)
2299           .Case("UXTX", ARM64_AM::UXTX)
2300           .Case("LSL", ARM64_AM::UXTX) // Alias for UXTX
2301           .Case("SXTB", ARM64_AM::SXTB)
2302           .Case("SXTH", ARM64_AM::SXTH)
2303           .Case("SXTW", ARM64_AM::SXTW)
2304           .Case("SXTX", ARM64_AM::SXTX)
2305           .Default(ARM64_AM::InvalidExtend);
2306   if (ExtOp == ARM64_AM::InvalidExtend)
2307     return true;
2308
2309   SMLoc S = Tok.getLoc();
2310   Parser.Lex();
2311
2312   if (getLexer().is(AsmToken::EndOfStatement) ||
2313       getLexer().is(AsmToken::Comma)) {
2314     SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2315     Operands.push_back(
2316         ARM64Operand::CreateExtend(ExtOp, 0, S, E, getContext()));
2317     return false;
2318   }
2319
2320   if (getLexer().isNot(AsmToken::Hash)) {
2321     SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2322     Operands.push_back(
2323         ARM64Operand::CreateExtend(ExtOp, 0, S, E, getContext()));
2324     return false;
2325   }
2326
2327   Parser.Lex(); // Eat the '#'.
2328
2329   const MCExpr *ImmVal;
2330   if (getParser().parseExpression(ImmVal))
2331     return true;
2332
2333   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2334   if (!MCE)
2335     return TokError("immediate value expected for extend operand");
2336
2337   SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2338   Operands.push_back(
2339       ARM64Operand::CreateExtend(ExtOp, MCE->getValue(), S, E, getContext()));
2340   return false;
2341 }
2342
2343 /// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for
2344 /// the SYS instruction. Parse them specially so that we create a SYS MCInst.
2345 bool ARM64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
2346                                    OperandVector &Operands) {
2347   if (Name.find('.') != StringRef::npos)
2348     return TokError("invalid operand");
2349
2350   Mnemonic = Name;
2351   Operands.push_back(
2352       ARM64Operand::CreateToken("sys", false, NameLoc, getContext()));
2353
2354   const AsmToken &Tok = Parser.getTok();
2355   StringRef Op = Tok.getString();
2356   SMLoc S = Tok.getLoc();
2357
2358   const MCExpr *Expr = 0;
2359
2360 #define SYS_ALIAS(op1, Cn, Cm, op2)                                            \
2361   do {                                                                         \
2362     Expr = MCConstantExpr::Create(op1, getContext());                          \
2363     Operands.push_back(                                                        \
2364         ARM64Operand::CreateImm(Expr, S, getLoc(), getContext()));             \
2365     Operands.push_back(                                                        \
2366         ARM64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));             \
2367     Operands.push_back(                                                        \
2368         ARM64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));             \
2369     Expr = MCConstantExpr::Create(op2, getContext());                          \
2370     Operands.push_back(                                                        \
2371         ARM64Operand::CreateImm(Expr, S, getLoc(), getContext()));             \
2372   } while (0)
2373
2374   if (Mnemonic == "ic") {
2375     if (!Op.compare_lower("ialluis")) {
2376       // SYS #0, C7, C1, #0
2377       SYS_ALIAS(0, 7, 1, 0);
2378     } else if (!Op.compare_lower("iallu")) {
2379       // SYS #0, C7, C5, #0
2380       SYS_ALIAS(0, 7, 5, 0);
2381     } else if (!Op.compare_lower("ivau")) {
2382       // SYS #3, C7, C5, #1
2383       SYS_ALIAS(3, 7, 5, 1);
2384     } else {
2385       return TokError("invalid operand for IC instruction");
2386     }
2387   } else if (Mnemonic == "dc") {
2388     if (!Op.compare_lower("zva")) {
2389       // SYS #3, C7, C4, #1
2390       SYS_ALIAS(3, 7, 4, 1);
2391     } else if (!Op.compare_lower("ivac")) {
2392       // SYS #3, C7, C6, #1
2393       SYS_ALIAS(0, 7, 6, 1);
2394     } else if (!Op.compare_lower("isw")) {
2395       // SYS #0, C7, C6, #2
2396       SYS_ALIAS(0, 7, 6, 2);
2397     } else if (!Op.compare_lower("cvac")) {
2398       // SYS #3, C7, C10, #1
2399       SYS_ALIAS(3, 7, 10, 1);
2400     } else if (!Op.compare_lower("csw")) {
2401       // SYS #0, C7, C10, #2
2402       SYS_ALIAS(0, 7, 10, 2);
2403     } else if (!Op.compare_lower("cvau")) {
2404       // SYS #3, C7, C11, #1
2405       SYS_ALIAS(3, 7, 11, 1);
2406     } else if (!Op.compare_lower("civac")) {
2407       // SYS #3, C7, C14, #1
2408       SYS_ALIAS(3, 7, 14, 1);
2409     } else if (!Op.compare_lower("cisw")) {
2410       // SYS #0, C7, C14, #2
2411       SYS_ALIAS(0, 7, 14, 2);
2412     } else {
2413       return TokError("invalid operand for DC instruction");
2414     }
2415   } else if (Mnemonic == "at") {
2416     if (!Op.compare_lower("s1e1r")) {
2417       // SYS #0, C7, C8, #0
2418       SYS_ALIAS(0, 7, 8, 0);
2419     } else if (!Op.compare_lower("s1e2r")) {
2420       // SYS #4, C7, C8, #0
2421       SYS_ALIAS(4, 7, 8, 0);
2422     } else if (!Op.compare_lower("s1e3r")) {
2423       // SYS #6, C7, C8, #0
2424       SYS_ALIAS(6, 7, 8, 0);
2425     } else if (!Op.compare_lower("s1e1w")) {
2426       // SYS #0, C7, C8, #1
2427       SYS_ALIAS(0, 7, 8, 1);
2428     } else if (!Op.compare_lower("s1e2w")) {
2429       // SYS #4, C7, C8, #1
2430       SYS_ALIAS(4, 7, 8, 1);
2431     } else if (!Op.compare_lower("s1e3w")) {
2432       // SYS #6, C7, C8, #1
2433       SYS_ALIAS(6, 7, 8, 1);
2434     } else if (!Op.compare_lower("s1e0r")) {
2435       // SYS #0, C7, C8, #3
2436       SYS_ALIAS(0, 7, 8, 2);
2437     } else if (!Op.compare_lower("s1e0w")) {
2438       // SYS #0, C7, C8, #3
2439       SYS_ALIAS(0, 7, 8, 3);
2440     } else if (!Op.compare_lower("s12e1r")) {
2441       // SYS #4, C7, C8, #4
2442       SYS_ALIAS(4, 7, 8, 4);
2443     } else if (!Op.compare_lower("s12e1w")) {
2444       // SYS #4, C7, C8, #5
2445       SYS_ALIAS(4, 7, 8, 5);
2446     } else if (!Op.compare_lower("s12e0r")) {
2447       // SYS #4, C7, C8, #6
2448       SYS_ALIAS(4, 7, 8, 6);
2449     } else if (!Op.compare_lower("s12e0w")) {
2450       // SYS #4, C7, C8, #7
2451       SYS_ALIAS(4, 7, 8, 7);
2452     } else {
2453       return TokError("invalid operand for AT instruction");
2454     }
2455   } else if (Mnemonic == "tlbi") {
2456     if (!Op.compare_lower("vmalle1is")) {
2457       // SYS #0, C8, C3, #0
2458       SYS_ALIAS(0, 8, 3, 0);
2459     } else if (!Op.compare_lower("alle2is")) {
2460       // SYS #4, C8, C3, #0
2461       SYS_ALIAS(4, 8, 3, 0);
2462     } else if (!Op.compare_lower("alle3is")) {
2463       // SYS #6, C8, C3, #0
2464       SYS_ALIAS(6, 8, 3, 0);
2465     } else if (!Op.compare_lower("vae1is")) {
2466       // SYS #0, C8, C3, #1
2467       SYS_ALIAS(0, 8, 3, 1);
2468     } else if (!Op.compare_lower("vae2is")) {
2469       // SYS #4, C8, C3, #1
2470       SYS_ALIAS(4, 8, 3, 1);
2471     } else if (!Op.compare_lower("vae3is")) {
2472       // SYS #6, C8, C3, #1
2473       SYS_ALIAS(6, 8, 3, 1);
2474     } else if (!Op.compare_lower("aside1is")) {
2475       // SYS #0, C8, C3, #2
2476       SYS_ALIAS(0, 8, 3, 2);
2477     } else if (!Op.compare_lower("vaae1is")) {
2478       // SYS #0, C8, C3, #3
2479       SYS_ALIAS(0, 8, 3, 3);
2480     } else if (!Op.compare_lower("alle1is")) {
2481       // SYS #4, C8, C3, #4
2482       SYS_ALIAS(4, 8, 3, 4);
2483     } else if (!Op.compare_lower("vale1is")) {
2484       // SYS #0, C8, C3, #5
2485       SYS_ALIAS(0, 8, 3, 5);
2486     } else if (!Op.compare_lower("vaale1is")) {
2487       // SYS #0, C8, C3, #7
2488       SYS_ALIAS(0, 8, 3, 7);
2489     } else if (!Op.compare_lower("vmalle1")) {
2490       // SYS #0, C8, C7, #0
2491       SYS_ALIAS(0, 8, 7, 0);
2492     } else if (!Op.compare_lower("alle2")) {
2493       // SYS #4, C8, C7, #0
2494       SYS_ALIAS(4, 8, 7, 0);
2495     } else if (!Op.compare_lower("vale2is")) {
2496       // SYS #4, C8, C3, #5
2497       SYS_ALIAS(4, 8, 3, 5);
2498     } else if (!Op.compare_lower("vale3is")) {
2499       // SYS #6, C8, C3, #5
2500       SYS_ALIAS(6, 8, 3, 5);
2501     } else if (!Op.compare_lower("alle3")) {
2502       // SYS #6, C8, C7, #0
2503       SYS_ALIAS(6, 8, 7, 0);
2504     } else if (!Op.compare_lower("vae1")) {
2505       // SYS #0, C8, C7, #1
2506       SYS_ALIAS(0, 8, 7, 1);
2507     } else if (!Op.compare_lower("vae2")) {
2508       // SYS #4, C8, C7, #1
2509       SYS_ALIAS(4, 8, 7, 1);
2510     } else if (!Op.compare_lower("vae3")) {
2511       // SYS #6, C8, C7, #1
2512       SYS_ALIAS(6, 8, 7, 1);
2513     } else if (!Op.compare_lower("aside1")) {
2514       // SYS #0, C8, C7, #2
2515       SYS_ALIAS(0, 8, 7, 2);
2516     } else if (!Op.compare_lower("vaae1")) {
2517       // SYS #0, C8, C7, #3
2518       SYS_ALIAS(0, 8, 7, 3);
2519     } else if (!Op.compare_lower("alle1")) {
2520       // SYS #4, C8, C7, #4
2521       SYS_ALIAS(4, 8, 7, 4);
2522     } else if (!Op.compare_lower("vale1")) {
2523       // SYS #0, C8, C7, #5
2524       SYS_ALIAS(0, 8, 7, 5);
2525     } else if (!Op.compare_lower("vale2")) {
2526       // SYS #4, C8, C7, #5
2527       SYS_ALIAS(4, 8, 7, 5);
2528     } else if (!Op.compare_lower("vale3")) {
2529       // SYS #6, C8, C7, #5
2530       SYS_ALIAS(6, 8, 7, 5);
2531     } else if (!Op.compare_lower("vaale1")) {
2532       // SYS #0, C8, C7, #7
2533       SYS_ALIAS(0, 8, 7, 7);
2534     } else if (!Op.compare_lower("ipas2e1")) {
2535       // SYS #4, C8, C4, #1
2536       SYS_ALIAS(4, 8, 4, 1);
2537     } else if (!Op.compare_lower("ipas2le1")) {
2538       // SYS #4, C8, C4, #5
2539       SYS_ALIAS(4, 8, 4, 5);
2540     } else if (!Op.compare_lower("vmalls12e1")) {
2541       // SYS #4, C8, C7, #6
2542       SYS_ALIAS(4, 8, 7, 6);
2543     } else if (!Op.compare_lower("vmalls12e1is")) {
2544       // SYS #4, C8, C3, #6
2545       SYS_ALIAS(4, 8, 3, 6);
2546     } else {
2547       return TokError("invalid operand for TLBI instruction");
2548     }
2549   }
2550
2551 #undef SYS_ALIAS
2552
2553   Parser.Lex(); // Eat operand.
2554
2555   // Check for the optional register operand.
2556   if (getLexer().is(AsmToken::Comma)) {
2557     Parser.Lex(); // Eat comma.
2558
2559     if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands))
2560       return TokError("expected register operand");
2561   }
2562
2563   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2564     Parser.eatToEndOfStatement();
2565     return TokError("unexpected token in argument list");
2566   }
2567
2568   Parser.Lex(); // Consume the EndOfStatement
2569   return false;
2570 }
2571
2572 ARM64AsmParser::OperandMatchResultTy
2573 ARM64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
2574   const AsmToken &Tok = Parser.getTok();
2575
2576   // Can be either a #imm style literal or an option name
2577   if (Tok.is(AsmToken::Hash)) {
2578     // Immediate operand.
2579     Parser.Lex(); // Eat the '#'
2580     const MCExpr *ImmVal;
2581     SMLoc ExprLoc = getLoc();
2582     if (getParser().parseExpression(ImmVal))
2583       return MatchOperand_ParseFail;
2584     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2585     if (!MCE) {
2586       Error(ExprLoc, "immediate value expected for barrier operand");
2587       return MatchOperand_ParseFail;
2588     }
2589     if (MCE->getValue() < 0 || MCE->getValue() > 15) {
2590       Error(ExprLoc, "barrier operand out of range");
2591       return MatchOperand_ParseFail;
2592     }
2593     Operands.push_back(
2594         ARM64Operand::CreateBarrier(MCE->getValue(), ExprLoc, getContext()));
2595     return MatchOperand_Success;
2596   }
2597
2598   if (Tok.isNot(AsmToken::Identifier)) {
2599     TokError("invalid operand for instruction");
2600     return MatchOperand_ParseFail;
2601   }
2602
2603   unsigned Opt = StringSwitch<unsigned>(Tok.getString())
2604                      .Case("oshld", ARM64SYS::OSHLD)
2605                      .Case("oshst", ARM64SYS::OSHST)
2606                      .Case("osh", ARM64SYS::OSH)
2607                      .Case("nshld", ARM64SYS::NSHLD)
2608                      .Case("nshst", ARM64SYS::NSHST)
2609                      .Case("nsh", ARM64SYS::NSH)
2610                      .Case("ishld", ARM64SYS::ISHLD)
2611                      .Case("ishst", ARM64SYS::ISHST)
2612                      .Case("ish", ARM64SYS::ISH)
2613                      .Case("ld", ARM64SYS::LD)
2614                      .Case("st", ARM64SYS::ST)
2615                      .Case("sy", ARM64SYS::SY)
2616                      .Default(ARM64SYS::InvalidBarrier);
2617   if (Opt == ARM64SYS::InvalidBarrier) {
2618     TokError("invalid barrier option name");
2619     return MatchOperand_ParseFail;
2620   }
2621
2622   // The only valid named option for ISB is 'sy'
2623   if (Mnemonic == "isb" && Opt != ARM64SYS::SY) {
2624     TokError("'sy' or #imm operand expected");
2625     return MatchOperand_ParseFail;
2626   }
2627
2628   Operands.push_back(ARM64Operand::CreateBarrier(Opt, getLoc(), getContext()));
2629   Parser.Lex(); // Consume the option
2630
2631   return MatchOperand_Success;
2632 }
2633
2634 ARM64AsmParser::OperandMatchResultTy
2635 ARM64AsmParser::tryParseSystemRegister(OperandVector &Operands) {
2636   const AsmToken &Tok = Parser.getTok();
2637
2638   // It can be specified as a symbolic name.
2639   if (Tok.isNot(AsmToken::Identifier))
2640     return MatchOperand_NoMatch;
2641
2642   auto ID = Tok.getString().lower();
2643   ARM64SYS::SystemRegister Reg =
2644       StringSwitch<ARM64SYS::SystemRegister>(ID)
2645           .Case("spsr_el1", ARM64SYS::SPSR_svc)
2646           .Case("spsr_svc", ARM64SYS::SPSR_svc)
2647           .Case("elr_el1", ARM64SYS::ELR_EL1)
2648           .Case("sp_el0", ARM64SYS::SP_EL0)
2649           .Case("spsel", ARM64SYS::SPSel)
2650           .Case("daif", ARM64SYS::DAIF)
2651           .Case("currentel", ARM64SYS::CurrentEL)
2652           .Case("nzcv", ARM64SYS::NZCV)
2653           .Case("fpcr", ARM64SYS::FPCR)
2654           .Case("fpsr", ARM64SYS::FPSR)
2655           .Case("dspsr", ARM64SYS::DSPSR)
2656           .Case("dlr", ARM64SYS::DLR)
2657           .Case("spsr_el2", ARM64SYS::SPSR_hyp)
2658           .Case("spsr_hyp", ARM64SYS::SPSR_hyp)
2659           .Case("elr_el2", ARM64SYS::ELR_EL2)
2660           .Case("sp_el1", ARM64SYS::SP_EL1)
2661           .Case("spsr_irq", ARM64SYS::SPSR_irq)
2662           .Case("spsr_abt", ARM64SYS::SPSR_abt)
2663           .Case("spsr_und", ARM64SYS::SPSR_und)
2664           .Case("spsr_fiq", ARM64SYS::SPSR_fiq)
2665           .Case("spsr_el3", ARM64SYS::SPSR_EL3)
2666           .Case("elr_el3", ARM64SYS::ELR_EL3)
2667           .Case("sp_el2", ARM64SYS::SP_EL2)
2668           .Case("midr_el1", ARM64SYS::MIDR_EL1)
2669           .Case("ctr_el0", ARM64SYS::CTR_EL0)
2670           .Case("mpidr_el1", ARM64SYS::MPIDR_EL1)
2671           .Case("ecoidr_el1", ARM64SYS::ECOIDR_EL1)
2672           .Case("dczid_el0", ARM64SYS::DCZID_EL0)
2673           .Case("mvfr0_el1", ARM64SYS::MVFR0_EL1)
2674           .Case("mvfr1_el1", ARM64SYS::MVFR1_EL1)
2675           .Case("id_aa64pfr0_el1", ARM64SYS::ID_AA64PFR0_EL1)
2676           .Case("id_aa64pfr1_el1", ARM64SYS::ID_AA64PFR1_EL1)
2677           .Case("id_aa64dfr0_el1", ARM64SYS::ID_AA64DFR0_EL1)
2678           .Case("id_aa64dfr1_el1", ARM64SYS::ID_AA64DFR1_EL1)
2679           .Case("id_aa64isar0_el1", ARM64SYS::ID_AA64ISAR0_EL1)
2680           .Case("id_aa64isar1_el1", ARM64SYS::ID_AA64ISAR1_EL1)
2681           .Case("id_aa64mmfr0_el1", ARM64SYS::ID_AA64MMFR0_EL1)
2682           .Case("id_aa64mmfr1_el1", ARM64SYS::ID_AA64MMFR1_EL1)
2683           .Case("ccsidr_el1", ARM64SYS::CCSIDR_EL1)
2684           .Case("clidr_el1", ARM64SYS::CLIDR_EL1)
2685           .Case("aidr_el1", ARM64SYS::AIDR_EL1)
2686           .Case("csselr_el1", ARM64SYS::CSSELR_EL1)
2687           .Case("vpidr_el2", ARM64SYS::VPIDR_EL2)
2688           .Case("vmpidr_el2", ARM64SYS::VMPIDR_EL2)
2689           .Case("sctlr_el1", ARM64SYS::SCTLR_EL1)
2690           .Case("sctlr_el2", ARM64SYS::SCTLR_EL2)
2691           .Case("sctlr_el3", ARM64SYS::SCTLR_EL3)
2692           .Case("actlr_el1", ARM64SYS::ACTLR_EL1)
2693           .Case("actlr_el2", ARM64SYS::ACTLR_EL2)
2694           .Case("actlr_el3", ARM64SYS::ACTLR_EL3)
2695           .Case("cpacr_el1", ARM64SYS::CPACR_EL1)
2696           .Case("cptr_el2", ARM64SYS::CPTR_EL2)
2697           .Case("cptr_el3", ARM64SYS::CPTR_EL3)
2698           .Case("scr_el3", ARM64SYS::SCR_EL3)
2699           .Case("hcr_el2", ARM64SYS::HCR_EL2)
2700           .Case("mdcr_el2", ARM64SYS::MDCR_EL2)
2701           .Case("mdcr_el3", ARM64SYS::MDCR_EL3)
2702           .Case("hstr_el2", ARM64SYS::HSTR_EL2)
2703           .Case("hacr_el2", ARM64SYS::HACR_EL2)
2704           .Case("ttbr0_el1", ARM64SYS::TTBR0_EL1)
2705           .Case("ttbr1_el1", ARM64SYS::TTBR1_EL1)
2706           .Case("ttbr0_el2", ARM64SYS::TTBR0_EL2)
2707           .Case("ttbr0_el3", ARM64SYS::TTBR0_EL3)
2708           .Case("vttbr_el2", ARM64SYS::VTTBR_EL2)
2709           .Case("tcr_el1", ARM64SYS::TCR_EL1)
2710           .Case("tcr_el2", ARM64SYS::TCR_EL2)
2711           .Case("tcr_el3", ARM64SYS::TCR_EL3)
2712           .Case("vtcr_el2", ARM64SYS::VTCR_EL2)
2713           .Case("adfsr_el1", ARM64SYS::ADFSR_EL1)
2714           .Case("aifsr_el1", ARM64SYS::AIFSR_EL1)
2715           .Case("adfsr_el2", ARM64SYS::ADFSR_EL2)
2716           .Case("aifsr_el2", ARM64SYS::AIFSR_EL2)
2717           .Case("adfsr_el3", ARM64SYS::ADFSR_EL3)
2718           .Case("aifsr_el3", ARM64SYS::AIFSR_EL3)
2719           .Case("esr_el1", ARM64SYS::ESR_EL1)
2720           .Case("esr_el2", ARM64SYS::ESR_EL2)
2721           .Case("esr_el3", ARM64SYS::ESR_EL3)
2722           .Case("far_el1", ARM64SYS::FAR_EL1)
2723           .Case("far_el2", ARM64SYS::FAR_EL2)
2724           .Case("far_el3", ARM64SYS::FAR_EL3)
2725           .Case("hpfar_el2", ARM64SYS::HPFAR_EL2)
2726           .Case("par_el1", ARM64SYS::PAR_EL1)
2727           .Case("mair_el1", ARM64SYS::MAIR_EL1)
2728           .Case("mair_el2", ARM64SYS::MAIR_EL2)
2729           .Case("mair_el3", ARM64SYS::MAIR_EL3)
2730           .Case("amair_el1", ARM64SYS::AMAIR_EL1)
2731           .Case("amair_el2", ARM64SYS::AMAIR_EL2)
2732           .Case("amair_el3", ARM64SYS::AMAIR_EL3)
2733           .Case("vbar_el1", ARM64SYS::VBAR_EL1)
2734           .Case("vbar_el2", ARM64SYS::VBAR_EL2)
2735           .Case("vbar_el3", ARM64SYS::VBAR_EL3)
2736           .Case("rvbar_el1", ARM64SYS::RVBAR_EL1)
2737           .Case("rvbar_el2", ARM64SYS::RVBAR_EL2)
2738           .Case("rvbar_el3", ARM64SYS::RVBAR_EL3)
2739           .Case("isr_el1", ARM64SYS::ISR_EL1)
2740           .Case("contextidr_el1", ARM64SYS::CONTEXTIDR_EL1)
2741           .Case("tpidr_el0", ARM64SYS::TPIDR_EL0)
2742           .Case("tpidrro_el0", ARM64SYS::TPIDRRO_EL0)
2743           .Case("tpidr_el1", ARM64SYS::TPIDR_EL1)
2744           .Case("tpidr_el2", ARM64SYS::TPIDR_EL2)
2745           .Case("tpidr_el3", ARM64SYS::TPIDR_EL3)
2746           .Case("teecr32_el1", ARM64SYS::TEECR32_EL1)
2747           .Case("cntfrq_el0", ARM64SYS::CNTFRQ_EL0)
2748           .Case("cntpct_el0", ARM64SYS::CNTPCT_EL0)
2749           .Case("cntvct_el0", ARM64SYS::CNTVCT_EL0)
2750           .Case("cntvoff_el2", ARM64SYS::CNTVOFF_EL2)
2751           .Case("cntkctl_el1", ARM64SYS::CNTKCTL_EL1)
2752           .Case("cnthctl_el2", ARM64SYS::CNTHCTL_EL2)
2753           .Case("cntp_tval_el0", ARM64SYS::CNTP_TVAL_EL0)
2754           .Case("cntp_ctl_el0", ARM64SYS::CNTP_CTL_EL0)
2755           .Case("cntp_cval_el0", ARM64SYS::CNTP_CVAL_EL0)
2756           .Case("cntv_tval_el0", ARM64SYS::CNTV_TVAL_EL0)
2757           .Case("cntv_ctl_el0", ARM64SYS::CNTV_CTL_EL0)
2758           .Case("cntv_cval_el0", ARM64SYS::CNTV_CVAL_EL0)
2759           .Case("cnthp_tval_el2", ARM64SYS::CNTHP_TVAL_EL2)
2760           .Case("cnthp_ctl_el2", ARM64SYS::CNTHP_CTL_EL2)
2761           .Case("cnthp_cval_el2", ARM64SYS::CNTHP_CVAL_EL2)
2762           .Case("cntps_tval_el1", ARM64SYS::CNTPS_TVAL_EL1)
2763           .Case("cntps_ctl_el1", ARM64SYS::CNTPS_CTL_EL1)
2764           .Case("cntps_cval_el1", ARM64SYS::CNTPS_CVAL_EL1)
2765           .Case("dacr32_el2", ARM64SYS::DACR32_EL2)
2766           .Case("ifsr32_el2", ARM64SYS::IFSR32_EL2)
2767           .Case("teehbr32_el1", ARM64SYS::TEEHBR32_EL1)
2768           .Case("sder32_el3", ARM64SYS::SDER32_EL3)
2769           .Case("fpexc32_el2", ARM64SYS::FPEXC32_EL2)
2770           .Case("current_el", ARM64SYS::CurrentEL)
2771           .Case("pmevcntr0_el0", ARM64SYS::PMEVCNTR0_EL0)
2772           .Case("pmevcntr1_el0", ARM64SYS::PMEVCNTR1_EL0)
2773           .Case("pmevcntr2_el0", ARM64SYS::PMEVCNTR2_EL0)
2774           .Case("pmevcntr3_el0", ARM64SYS::PMEVCNTR3_EL0)
2775           .Case("pmevcntr4_el0", ARM64SYS::PMEVCNTR4_EL0)
2776           .Case("pmevcntr5_el0", ARM64SYS::PMEVCNTR5_EL0)
2777           .Case("pmevcntr6_el0", ARM64SYS::PMEVCNTR6_EL0)
2778           .Case("pmevcntr7_el0", ARM64SYS::PMEVCNTR7_EL0)
2779           .Case("pmevcntr8_el0", ARM64SYS::PMEVCNTR8_EL0)
2780           .Case("pmevcntr9_el0", ARM64SYS::PMEVCNTR9_EL0)
2781           .Case("pmevcntr10_el0", ARM64SYS::PMEVCNTR10_EL0)
2782           .Case("pmevcntr11_el0", ARM64SYS::PMEVCNTR11_EL0)
2783           .Case("pmevcntr12_el0", ARM64SYS::PMEVCNTR12_EL0)
2784           .Case("pmevcntr13_el0", ARM64SYS::PMEVCNTR13_EL0)
2785           .Case("pmevcntr14_el0", ARM64SYS::PMEVCNTR14_EL0)
2786           .Case("pmevcntr15_el0", ARM64SYS::PMEVCNTR15_EL0)
2787           .Case("pmevcntr16_el0", ARM64SYS::PMEVCNTR16_EL0)
2788           .Case("pmevcntr17_el0", ARM64SYS::PMEVCNTR17_EL0)
2789           .Case("pmevcntr18_el0", ARM64SYS::PMEVCNTR18_EL0)
2790           .Case("pmevcntr19_el0", ARM64SYS::PMEVCNTR19_EL0)
2791           .Case("pmevcntr20_el0", ARM64SYS::PMEVCNTR20_EL0)
2792           .Case("pmevcntr21_el0", ARM64SYS::PMEVCNTR21_EL0)
2793           .Case("pmevcntr22_el0", ARM64SYS::PMEVCNTR22_EL0)
2794           .Case("pmevcntr23_el0", ARM64SYS::PMEVCNTR23_EL0)
2795           .Case("pmevcntr24_el0", ARM64SYS::PMEVCNTR24_EL0)
2796           .Case("pmevcntr25_el0", ARM64SYS::PMEVCNTR25_EL0)
2797           .Case("pmevcntr26_el0", ARM64SYS::PMEVCNTR26_EL0)
2798           .Case("pmevcntr27_el0", ARM64SYS::PMEVCNTR27_EL0)
2799           .Case("pmevcntr28_el0", ARM64SYS::PMEVCNTR28_EL0)
2800           .Case("pmevcntr29_el0", ARM64SYS::PMEVCNTR29_EL0)
2801           .Case("pmevcntr30_el0", ARM64SYS::PMEVCNTR30_EL0)
2802           .Case("pmevtyper0_el0", ARM64SYS::PMEVTYPER0_EL0)
2803           .Case("pmevtyper1_el0", ARM64SYS::PMEVTYPER1_EL0)
2804           .Case("pmevtyper2_el0", ARM64SYS::PMEVTYPER2_EL0)
2805           .Case("pmevtyper3_el0", ARM64SYS::PMEVTYPER3_EL0)
2806           .Case("pmevtyper4_el0", ARM64SYS::PMEVTYPER4_EL0)
2807           .Case("pmevtyper5_el0", ARM64SYS::PMEVTYPER5_EL0)
2808           .Case("pmevtyper6_el0", ARM64SYS::PMEVTYPER6_EL0)
2809           .Case("pmevtyper7_el0", ARM64SYS::PMEVTYPER7_EL0)
2810           .Case("pmevtyper8_el0", ARM64SYS::PMEVTYPER8_EL0)
2811           .Case("pmevtyper9_el0", ARM64SYS::PMEVTYPER9_EL0)
2812           .Case("pmevtyper10_el0", ARM64SYS::PMEVTYPER10_EL0)
2813           .Case("pmevtyper11_el0", ARM64SYS::PMEVTYPER11_EL0)
2814           .Case("pmevtyper12_el0", ARM64SYS::PMEVTYPER12_EL0)
2815           .Case("pmevtyper13_el0", ARM64SYS::PMEVTYPER13_EL0)
2816           .Case("pmevtyper14_el0", ARM64SYS::PMEVTYPER14_EL0)
2817           .Case("pmevtyper15_el0", ARM64SYS::PMEVTYPER15_EL0)
2818           .Case("pmevtyper16_el0", ARM64SYS::PMEVTYPER16_EL0)
2819           .Case("pmevtyper17_el0", ARM64SYS::PMEVTYPER17_EL0)
2820           .Case("pmevtyper18_el0", ARM64SYS::PMEVTYPER18_EL0)
2821           .Case("pmevtyper19_el0", ARM64SYS::PMEVTYPER19_EL0)
2822           .Case("pmevtyper20_el0", ARM64SYS::PMEVTYPER20_EL0)
2823           .Case("pmevtyper21_el0", ARM64SYS::PMEVTYPER21_EL0)
2824           .Case("pmevtyper22_el0", ARM64SYS::PMEVTYPER22_EL0)
2825           .Case("pmevtyper23_el0", ARM64SYS::PMEVTYPER23_EL0)
2826           .Case("pmevtyper24_el0", ARM64SYS::PMEVTYPER24_EL0)
2827           .Case("pmevtyper25_el0", ARM64SYS::PMEVTYPER25_EL0)
2828           .Case("pmevtyper26_el0", ARM64SYS::PMEVTYPER26_EL0)
2829           .Case("pmevtyper27_el0", ARM64SYS::PMEVTYPER27_EL0)
2830           .Case("pmevtyper28_el0", ARM64SYS::PMEVTYPER28_EL0)
2831           .Case("pmevtyper29_el0", ARM64SYS::PMEVTYPER29_EL0)
2832           .Case("pmevtyper30_el0", ARM64SYS::PMEVTYPER30_EL0)
2833           .Case("pmccfiltr_el0", ARM64SYS::PMCCFILTR_EL0)
2834           .Case("rmr_el3", ARM64SYS::RMR_EL3)
2835           .Case("rmr_el2", ARM64SYS::RMR_EL2)
2836           .Case("rmr_el1", ARM64SYS::RMR_EL1)
2837           .Case("cpm_ioacc_ctl_el3", ARM64SYS::CPM_IOACC_CTL_EL3)
2838           .Case("mdccsr_el0", ARM64SYS::MDCCSR_EL0)
2839           .Case("mdccint_el1", ARM64SYS::MDCCINT_EL1)
2840           .Case("dbgdtr_el0", ARM64SYS::DBGDTR_EL0)
2841           .Case("dbgdtrrx_el0", ARM64SYS::DBGDTRRX_EL0)
2842           .Case("dbgdtrtx_el0", ARM64SYS::DBGDTRTX_EL0)
2843           .Case("dbgvcr32_el2", ARM64SYS::DBGVCR32_EL2)
2844           .Case("osdtrrx_el1", ARM64SYS::OSDTRRX_EL1)
2845           .Case("mdscr_el1", ARM64SYS::MDSCR_EL1)
2846           .Case("osdtrtx_el1", ARM64SYS::OSDTRTX_EL1)
2847           .Case("oseccr_el11", ARM64SYS::OSECCR_EL11)
2848           .Case("dbgbvr0_el1", ARM64SYS::DBGBVR0_EL1)
2849           .Case("dbgbvr1_el1", ARM64SYS::DBGBVR1_EL1)
2850           .Case("dbgbvr2_el1", ARM64SYS::DBGBVR2_EL1)
2851           .Case("dbgbvr3_el1", ARM64SYS::DBGBVR3_EL1)
2852           .Case("dbgbvr4_el1", ARM64SYS::DBGBVR4_EL1)
2853           .Case("dbgbvr5_el1", ARM64SYS::DBGBVR5_EL1)
2854           .Case("dbgbvr6_el1", ARM64SYS::DBGBVR6_EL1)
2855           .Case("dbgbvr7_el1", ARM64SYS::DBGBVR7_EL1)
2856           .Case("dbgbvr8_el1", ARM64SYS::DBGBVR8_EL1)
2857           .Case("dbgbvr9_el1", ARM64SYS::DBGBVR9_EL1)
2858           .Case("dbgbvr10_el1", ARM64SYS::DBGBVR10_EL1)
2859           .Case("dbgbvr11_el1", ARM64SYS::DBGBVR11_EL1)
2860           .Case("dbgbvr12_el1", ARM64SYS::DBGBVR12_EL1)
2861           .Case("dbgbvr13_el1", ARM64SYS::DBGBVR13_EL1)
2862           .Case("dbgbvr14_el1", ARM64SYS::DBGBVR14_EL1)
2863           .Case("dbgbvr15_el1", ARM64SYS::DBGBVR15_EL1)
2864           .Case("dbgbcr0_el1", ARM64SYS::DBGBCR0_EL1)
2865           .Case("dbgbcr1_el1", ARM64SYS::DBGBCR1_EL1)
2866           .Case("dbgbcr2_el1", ARM64SYS::DBGBCR2_EL1)
2867           .Case("dbgbcr3_el1", ARM64SYS::DBGBCR3_EL1)
2868           .Case("dbgbcr4_el1", ARM64SYS::DBGBCR4_EL1)
2869           .Case("dbgbcr5_el1", ARM64SYS::DBGBCR5_EL1)
2870           .Case("dbgbcr6_el1", ARM64SYS::DBGBCR6_EL1)
2871           .Case("dbgbcr7_el1", ARM64SYS::DBGBCR7_EL1)
2872           .Case("dbgbcr8_el1", ARM64SYS::DBGBCR8_EL1)
2873           .Case("dbgbcr9_el1", ARM64SYS::DBGBCR9_EL1)
2874           .Case("dbgbcr10_el1", ARM64SYS::DBGBCR10_EL1)
2875           .Case("dbgbcr11_el1", ARM64SYS::DBGBCR11_EL1)
2876           .Case("dbgbcr12_el1", ARM64SYS::DBGBCR12_EL1)
2877           .Case("dbgbcr13_el1", ARM64SYS::DBGBCR13_EL1)
2878           .Case("dbgbcr14_el1", ARM64SYS::DBGBCR14_EL1)
2879           .Case("dbgbcr15_el1", ARM64SYS::DBGBCR15_EL1)
2880           .Case("dbgwvr0_el1", ARM64SYS::DBGWVR0_EL1)
2881           .Case("dbgwvr1_el1", ARM64SYS::DBGWVR1_EL1)
2882           .Case("dbgwvr2_el1", ARM64SYS::DBGWVR2_EL1)
2883           .Case("dbgwvr3_el1", ARM64SYS::DBGWVR3_EL1)
2884           .Case("dbgwvr4_el1", ARM64SYS::DBGWVR4_EL1)
2885           .Case("dbgwvr5_el1", ARM64SYS::DBGWVR5_EL1)
2886           .Case("dbgwvr6_el1", ARM64SYS::DBGWVR6_EL1)
2887           .Case("dbgwvr7_el1", ARM64SYS::DBGWVR7_EL1)
2888           .Case("dbgwvr8_el1", ARM64SYS::DBGWVR8_EL1)
2889           .Case("dbgwvr9_el1", ARM64SYS::DBGWVR9_EL1)
2890           .Case("dbgwvr10_el1", ARM64SYS::DBGWVR10_EL1)
2891           .Case("dbgwvr11_el1", ARM64SYS::DBGWVR11_EL1)
2892           .Case("dbgwvr12_el1", ARM64SYS::DBGWVR12_EL1)
2893           .Case("dbgwvr13_el1", ARM64SYS::DBGWVR13_EL1)
2894           .Case("dbgwvr14_el1", ARM64SYS::DBGWVR14_EL1)
2895           .Case("dbgwvr15_el1", ARM64SYS::DBGWVR15_EL1)
2896           .Case("dbgwcr0_el1", ARM64SYS::DBGWCR0_EL1)
2897           .Case("dbgwcr1_el1", ARM64SYS::DBGWCR1_EL1)
2898           .Case("dbgwcr2_el1", ARM64SYS::DBGWCR2_EL1)
2899           .Case("dbgwcr3_el1", ARM64SYS::DBGWCR3_EL1)
2900           .Case("dbgwcr4_el1", ARM64SYS::DBGWCR4_EL1)
2901           .Case("dbgwcr5_el1", ARM64SYS::DBGWCR5_EL1)
2902           .Case("dbgwcr6_el1", ARM64SYS::DBGWCR6_EL1)
2903           .Case("dbgwcr7_el1", ARM64SYS::DBGWCR7_EL1)
2904           .Case("dbgwcr8_el1", ARM64SYS::DBGWCR8_EL1)
2905           .Case("dbgwcr9_el1", ARM64SYS::DBGWCR9_EL1)
2906           .Case("dbgwcr10_el1", ARM64SYS::DBGWCR10_EL1)
2907           .Case("dbgwcr11_el1", ARM64SYS::DBGWCR11_EL1)
2908           .Case("dbgwcr12_el1", ARM64SYS::DBGWCR12_EL1)
2909           .Case("dbgwcr13_el1", ARM64SYS::DBGWCR13_EL1)
2910           .Case("dbgwcr14_el1", ARM64SYS::DBGWCR14_EL1)
2911           .Case("dbgwcr15_el1", ARM64SYS::DBGWCR15_EL1)
2912           .Case("mdrar_el1", ARM64SYS::MDRAR_EL1)
2913           .Case("oslar_el1", ARM64SYS::OSLAR_EL1)
2914           .Case("oslsr_el1", ARM64SYS::OSLSR_EL1)
2915           .Case("osdlr_el1", ARM64SYS::OSDLR_EL1)
2916           .Case("dbgprcr_el1", ARM64SYS::DBGPRCR_EL1)
2917           .Case("dbgclaimset_el1", ARM64SYS::DBGCLAIMSET_EL1)
2918           .Case("dbgclaimclr_el1", ARM64SYS::DBGCLAIMCLR_EL1)
2919           .Case("dbgauthstatus_el1", ARM64SYS::DBGAUTHSTATUS_EL1)
2920           .Case("dbgdevid2", ARM64SYS::DBGDEVID2)
2921           .Case("dbgdevid1", ARM64SYS::DBGDEVID1)
2922           .Case("dbgdevid0", ARM64SYS::DBGDEVID0)
2923           .Case("id_pfr0_el1", ARM64SYS::ID_PFR0_EL1)
2924           .Case("id_pfr1_el1", ARM64SYS::ID_PFR1_EL1)
2925           .Case("id_dfr0_el1", ARM64SYS::ID_DFR0_EL1)
2926           .Case("id_afr0_el1", ARM64SYS::ID_AFR0_EL1)
2927           .Case("id_isar0_el1", ARM64SYS::ID_ISAR0_EL1)
2928           .Case("id_isar1_el1", ARM64SYS::ID_ISAR1_EL1)
2929           .Case("id_isar2_el1", ARM64SYS::ID_ISAR2_EL1)
2930           .Case("id_isar3_el1", ARM64SYS::ID_ISAR3_EL1)
2931           .Case("id_isar4_el1", ARM64SYS::ID_ISAR4_EL1)
2932           .Case("id_isar5_el1", ARM64SYS::ID_ISAR5_EL1)
2933           .Case("afsr1_el1", ARM64SYS::AFSR1_EL1)
2934           .Case("afsr0_el1", ARM64SYS::AFSR0_EL1)
2935           .Case("revidr_el1", ARM64SYS::REVIDR_EL1)
2936           .Default(ARM64SYS::InvalidSystemReg);
2937   if (Reg != ARM64SYS::InvalidSystemReg) {
2938     // We matched a reg name, so create the operand.
2939     Operands.push_back(
2940         ARM64Operand::CreateSystemRegister(Reg, getLoc(), getContext()));
2941     Parser.Lex(); // Consume the register name.
2942     return MatchOperand_Success;
2943   }
2944
2945   // Or we may have an identifier that encodes the sub-operands.
2946   // For example, s3_2_c15_c0_0.
2947   unsigned op0, op1, CRn, CRm, op2;
2948   std::string Desc = ID;
2949   if (std::sscanf(Desc.c_str(), "s%u_%u_c%u_c%u_%u", &op0, &op1, &CRn, &CRm,
2950                   &op2) != 5)
2951     return MatchOperand_NoMatch;
2952   if ((op0 != 2 && op0 != 3) || op1 > 7 || CRn > 15 || CRm > 15 || op2 > 7)
2953     return MatchOperand_NoMatch;
2954
2955   unsigned Val = op0 << 14 | op1 << 11 | CRn << 7 | CRm << 3 | op2;
2956   Operands.push_back(
2957       ARM64Operand::CreateSystemRegister(Val, getLoc(), getContext()));
2958   Parser.Lex(); // Consume the register name.
2959
2960   return MatchOperand_Success;
2961 }
2962
2963 ARM64AsmParser::OperandMatchResultTy
2964 ARM64AsmParser::tryParseCPSRField(OperandVector &Operands) {
2965   const AsmToken &Tok = Parser.getTok();
2966
2967   if (Tok.isNot(AsmToken::Identifier))
2968     return MatchOperand_NoMatch;
2969
2970   ARM64SYS::CPSRField Field =
2971       StringSwitch<ARM64SYS::CPSRField>(Tok.getString().lower())
2972           .Case("spsel", ARM64SYS::cpsr_SPSel)
2973           .Case("daifset", ARM64SYS::cpsr_DAIFSet)
2974           .Case("daifclr", ARM64SYS::cpsr_DAIFClr)
2975           .Default(ARM64SYS::InvalidCPSRField);
2976   if (Field == ARM64SYS::InvalidCPSRField)
2977     return MatchOperand_NoMatch;
2978   Operands.push_back(
2979       ARM64Operand::CreateCPSRField(Field, getLoc(), getContext()));
2980   Parser.Lex(); // Consume the register name.
2981
2982   return MatchOperand_Success;
2983 }
2984
2985 /// tryParseVectorRegister - Parse a vector register operand.
2986 bool ARM64AsmParser::tryParseVectorRegister(OperandVector &Operands) {
2987   if (Parser.getTok().isNot(AsmToken::Identifier))
2988     return true;
2989
2990   SMLoc S = getLoc();
2991   // Check for a vector register specifier first.
2992   StringRef Kind;
2993   int64_t Reg = tryMatchVectorRegister(Kind, false);
2994   if (Reg == -1)
2995     return true;
2996   Operands.push_back(
2997       ARM64Operand::CreateReg(Reg, true, S, getLoc(), getContext()));
2998   // If there was an explicit qualifier, that goes on as a literal text
2999   // operand.
3000   if (!Kind.empty())
3001     Operands.push_back(ARM64Operand::CreateToken(Kind, false, S, getContext()));
3002
3003   // If there is an index specifier following the register, parse that too.
3004   if (Parser.getTok().is(AsmToken::LBrac)) {
3005     SMLoc SIdx = getLoc();
3006     Parser.Lex(); // Eat left bracket token.
3007
3008     const MCExpr *ImmVal;
3009     if (getParser().parseExpression(ImmVal))
3010       return false;
3011     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
3012     if (!MCE) {
3013       TokError("immediate value expected for vector index");
3014       return false;
3015     }
3016
3017     SMLoc E = getLoc();
3018     if (Parser.getTok().isNot(AsmToken::RBrac)) {
3019       Error(E, "']' expected");
3020       return false;
3021     }
3022
3023     Parser.Lex(); // Eat right bracket token.
3024
3025     Operands.push_back(ARM64Operand::CreateVectorIndex(MCE->getValue(), SIdx, E,
3026                                                        getContext()));
3027   }
3028
3029   return false;
3030 }
3031
3032 /// parseRegister - Parse a non-vector register operand.
3033 bool ARM64AsmParser::parseRegister(OperandVector &Operands) {
3034   SMLoc S = getLoc();
3035   // Try for a vector register.
3036   if (!tryParseVectorRegister(Operands))
3037     return false;
3038
3039   // Try for a scalar register.
3040   int64_t Reg = tryParseRegister();
3041   if (Reg == -1)
3042     return true;
3043   Operands.push_back(
3044       ARM64Operand::CreateReg(Reg, false, S, getLoc(), getContext()));
3045
3046   // A small number of instructions (FMOVXDhighr, for example) have "[1]"
3047   // as a string token in the instruction itself.
3048   if (getLexer().getKind() == AsmToken::LBrac) {
3049     SMLoc LBracS = getLoc();
3050     Parser.Lex();
3051     const AsmToken &Tok = Parser.getTok();
3052     if (Tok.is(AsmToken::Integer)) {
3053       SMLoc IntS = getLoc();
3054       int64_t Val = Tok.getIntVal();
3055       if (Val == 1) {
3056         Parser.Lex();
3057         if (getLexer().getKind() == AsmToken::RBrac) {
3058           SMLoc RBracS = getLoc();
3059           Parser.Lex();
3060           Operands.push_back(
3061               ARM64Operand::CreateToken("[", false, LBracS, getContext()));
3062           Operands.push_back(
3063               ARM64Operand::CreateToken("1", false, IntS, getContext()));
3064           Operands.push_back(
3065               ARM64Operand::CreateToken("]", false, RBracS, getContext()));
3066           return false;
3067         }
3068       }
3069     }
3070   }
3071
3072   return false;
3073 }
3074
3075 /// tryParseNoIndexMemory - Custom parser method for memory operands that
3076 ///                         do not allow base regisrer writeback modes,
3077 ///                         or those that handle writeback separately from
3078 ///                         the memory operand (like the AdvSIMD ldX/stX
3079 ///                         instructions.
3080 ARM64AsmParser::OperandMatchResultTy
3081 ARM64AsmParser::tryParseNoIndexMemory(OperandVector &Operands) {
3082   if (Parser.getTok().isNot(AsmToken::LBrac))
3083     return MatchOperand_NoMatch;
3084   SMLoc S = getLoc();
3085   Parser.Lex(); // Eat left bracket token.
3086
3087   const AsmToken &BaseRegTok = Parser.getTok();
3088   if (BaseRegTok.isNot(AsmToken::Identifier)) {
3089     Error(BaseRegTok.getLoc(), "register expected");
3090     return MatchOperand_ParseFail;
3091   }
3092
3093   int64_t Reg = tryParseRegister();
3094   if (Reg == -1) {
3095     Error(BaseRegTok.getLoc(), "register expected");
3096     return MatchOperand_ParseFail;
3097   }
3098
3099   SMLoc E = getLoc();
3100   if (Parser.getTok().isNot(AsmToken::RBrac)) {
3101     Error(E, "']' expected");
3102     return MatchOperand_ParseFail;
3103   }
3104
3105   Parser.Lex(); // Eat right bracket token.
3106
3107   Operands.push_back(ARM64Operand::CreateMem(Reg, 0, S, E, E, getContext()));
3108   return MatchOperand_Success;
3109 }
3110
3111 /// parseMemory - Parse a memory operand for a basic load/store instruction.
3112 bool ARM64AsmParser::parseMemory(OperandVector &Operands) {
3113   assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a Left Bracket");
3114   SMLoc S = getLoc();
3115   Parser.Lex(); // Eat left bracket token.
3116
3117   const AsmToken &BaseRegTok = Parser.getTok();
3118   if (BaseRegTok.isNot(AsmToken::Identifier))
3119     return Error(BaseRegTok.getLoc(), "register expected");
3120
3121   int64_t Reg = tryParseRegister();
3122   if (Reg == -1)
3123     return Error(BaseRegTok.getLoc(), "register expected");
3124
3125   // If there is an offset expression, parse it.
3126   const MCExpr *OffsetExpr = 0;
3127   SMLoc OffsetLoc;
3128   if (Parser.getTok().is(AsmToken::Comma)) {
3129     Parser.Lex(); // Eat the comma.
3130     OffsetLoc = getLoc();
3131
3132     // Register offset
3133     const AsmToken &OffsetRegTok = Parser.getTok();
3134     int Reg2 = OffsetRegTok.is(AsmToken::Identifier) ? tryParseRegister() : -1;
3135     if (Reg2 != -1) {
3136       // Default shift is LSL, with an omitted shift.  We use the third bit of
3137       // the extend value to indicate presence/omission of the immediate offset.
3138       ARM64_AM::ExtendType ExtOp = ARM64_AM::UXTX;
3139       int64_t ShiftVal = 0;
3140       bool ExplicitShift = false;
3141
3142       if (Parser.getTok().is(AsmToken::Comma)) {
3143         // Embedded extend operand.
3144         Parser.Lex(); // Eat the comma
3145
3146         SMLoc ExtLoc = getLoc();
3147         const AsmToken &Tok = Parser.getTok();
3148         ExtOp = StringSwitch<ARM64_AM::ExtendType>(Tok.getString())
3149                     .Case("uxtw", ARM64_AM::UXTW)
3150                     .Case("lsl", ARM64_AM::UXTX) // Alias for UXTX
3151                     .Case("sxtw", ARM64_AM::SXTW)
3152                     .Case("sxtx", ARM64_AM::SXTX)
3153                     .Case("UXTW", ARM64_AM::UXTW)
3154                     .Case("LSL", ARM64_AM::UXTX) // Alias for UXTX
3155                     .Case("SXTW", ARM64_AM::SXTW)
3156                     .Case("SXTX", ARM64_AM::SXTX)
3157                     .Default(ARM64_AM::InvalidExtend);
3158         if (ExtOp == ARM64_AM::InvalidExtend)
3159           return Error(ExtLoc, "expected valid extend operation");
3160
3161         Parser.Lex(); // Eat the extend op.
3162
3163         if (getLexer().is(AsmToken::RBrac)) {
3164           // No immediate operand.
3165           if (ExtOp == ARM64_AM::UXTX)
3166             return Error(ExtLoc, "LSL extend requires immediate operand");
3167         } else if (getLexer().is(AsmToken::Hash)) {
3168           // Immediate operand.
3169           Parser.Lex(); // Eat the '#'
3170           const MCExpr *ImmVal;
3171           SMLoc ExprLoc = getLoc();
3172           if (getParser().parseExpression(ImmVal))
3173             return true;
3174           const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
3175           if (!MCE)
3176             return TokError("immediate value expected for extend operand");
3177
3178           ExplicitShift = true;
3179           ShiftVal = MCE->getValue();
3180           if (ShiftVal < 0 || ShiftVal > 4)
3181             return Error(ExprLoc, "immediate operand out of range");
3182         } else
3183           return Error(getLoc(), "expected immediate operand");
3184       }
3185
3186       if (Parser.getTok().isNot(AsmToken::RBrac))
3187         return Error(getLoc(), "']' expected");
3188
3189       Parser.Lex(); // Eat right bracket token.
3190
3191       SMLoc E = getLoc();
3192       Operands.push_back(ARM64Operand::CreateRegOffsetMem(
3193           Reg, Reg2, ExtOp, ShiftVal, ExplicitShift, S, E, getContext()));
3194       return false;
3195
3196       // Immediate expressions.
3197     } else if (Parser.getTok().is(AsmToken::Hash)) {
3198       Parser.Lex(); // Eat hash token.
3199
3200       if (parseSymbolicImmVal(OffsetExpr))
3201         return true;
3202     } else {
3203       // FIXME: We really should make sure that we're dealing with a LDR/STR
3204       // instruction that can legally have a symbolic expression here.
3205       // Symbol reference.
3206       if (Parser.getTok().isNot(AsmToken::Identifier) &&
3207           Parser.getTok().isNot(AsmToken::String))
3208         return Error(getLoc(), "identifier or immediate expression expected");
3209       if (getParser().parseExpression(OffsetExpr))
3210         return true;
3211       // If this is a plain ref, Make sure a legal variant kind was specified.
3212       // Otherwise, it's a more complicated expression and we have to just
3213       // assume it's OK and let the relocation stuff puke if it's not.
3214       ARM64MCExpr::VariantKind ELFRefKind;
3215       MCSymbolRefExpr::VariantKind DarwinRefKind;
3216       const MCConstantExpr *Addend;
3217       if (classifySymbolRef(OffsetExpr, ELFRefKind, DarwinRefKind, Addend) &&
3218           Addend == 0) {
3219         assert(ELFRefKind == ARM64MCExpr::VK_INVALID &&
3220                "ELF symbol modifiers not supported here yet");
3221
3222         switch (DarwinRefKind) {
3223         default:
3224           return Error(getLoc(), "expected @pageoff or @gotpageoff modifier");
3225         case MCSymbolRefExpr::VK_GOTPAGEOFF:
3226         case MCSymbolRefExpr::VK_PAGEOFF:
3227         case MCSymbolRefExpr::VK_TLVPPAGEOFF:
3228           // These are what we're expecting.
3229           break;
3230         }
3231       }
3232     }
3233   }
3234
3235   SMLoc E = getLoc();
3236   if (Parser.getTok().isNot(AsmToken::RBrac))
3237     return Error(E, "']' expected");
3238
3239   Parser.Lex(); // Eat right bracket token.
3240
3241   // Create the memory operand.
3242   Operands.push_back(
3243       ARM64Operand::CreateMem(Reg, OffsetExpr, S, E, OffsetLoc, getContext()));
3244
3245   // Check for a '!', indicating pre-indexed addressing with writeback.
3246   if (Parser.getTok().is(AsmToken::Exclaim)) {
3247     // There needs to have been an immediate or wback doesn't make sense.
3248     if (!OffsetExpr)
3249       return Error(E, "missing offset for pre-indexed addressing");
3250     // Pre-indexed with writeback must have a constant expression for the
3251     // offset. FIXME: Theoretically, we'd like to allow fixups so long
3252     // as they don't require a relocation.
3253     if (!isa<MCConstantExpr>(OffsetExpr))
3254       return Error(OffsetLoc, "constant immediate expression expected");
3255
3256     // Create the Token operand for the '!'.
3257     Operands.push_back(ARM64Operand::CreateToken(
3258         "!", false, Parser.getTok().getLoc(), getContext()));
3259     Parser.Lex(); // Eat the '!' token.
3260   }
3261
3262   return false;
3263 }
3264
3265 bool ARM64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
3266   bool HasELFModifier = false;
3267   ARM64MCExpr::VariantKind RefKind;
3268
3269   if (Parser.getTok().is(AsmToken::Colon)) {
3270     Parser.Lex(); // Eat ':"
3271     HasELFModifier = true;
3272
3273     if (Parser.getTok().isNot(AsmToken::Identifier)) {
3274       Error(Parser.getTok().getLoc(),
3275             "expect relocation specifier in operand after ':'");
3276       return true;
3277     }
3278
3279     std::string LowerCase = Parser.getTok().getIdentifier().lower();
3280     RefKind = StringSwitch<ARM64MCExpr::VariantKind>(LowerCase)
3281                   .Case("lo12", ARM64MCExpr::VK_LO12)
3282                   .Case("abs_g3", ARM64MCExpr::VK_ABS_G3)
3283                   .Case("abs_g2", ARM64MCExpr::VK_ABS_G2)
3284                   .Case("abs_g2_nc", ARM64MCExpr::VK_ABS_G2_NC)
3285                   .Case("abs_g1", ARM64MCExpr::VK_ABS_G1)
3286                   .Case("abs_g1_nc", ARM64MCExpr::VK_ABS_G1_NC)
3287                   .Case("abs_g0", ARM64MCExpr::VK_ABS_G0)
3288                   .Case("abs_g0_nc", ARM64MCExpr::VK_ABS_G0_NC)
3289                   .Case("dtprel_g2", ARM64MCExpr::VK_DTPREL_G2)
3290                   .Case("dtprel_g1", ARM64MCExpr::VK_DTPREL_G1)
3291                   .Case("dtprel_g1_nc", ARM64MCExpr::VK_DTPREL_G1_NC)
3292                   .Case("dtprel_g0", ARM64MCExpr::VK_DTPREL_G0)
3293                   .Case("dtprel_g0_nc", ARM64MCExpr::VK_DTPREL_G0_NC)
3294                   .Case("dtprel_lo12", ARM64MCExpr::VK_DTPREL_LO12)
3295                   .Case("dtprel_lo12_nc", ARM64MCExpr::VK_DTPREL_LO12_NC)
3296                   .Case("tprel_g2", ARM64MCExpr::VK_TPREL_G2)
3297                   .Case("tprel_g1", ARM64MCExpr::VK_TPREL_G1)
3298                   .Case("tprel_g1_nc", ARM64MCExpr::VK_TPREL_G1_NC)
3299                   .Case("tprel_g0", ARM64MCExpr::VK_TPREL_G0)
3300                   .Case("tprel_g0_nc", ARM64MCExpr::VK_TPREL_G0_NC)
3301                   .Case("tprel_lo12", ARM64MCExpr::VK_TPREL_LO12)
3302                   .Case("tprel_lo12_nc", ARM64MCExpr::VK_TPREL_LO12_NC)
3303                   .Case("tlsdesc_lo12", ARM64MCExpr::VK_TLSDESC_LO12)
3304                   .Case("got", ARM64MCExpr::VK_GOT_PAGE)
3305                   .Case("got_lo12", ARM64MCExpr::VK_GOT_LO12)
3306                   .Case("gottprel", ARM64MCExpr::VK_GOTTPREL_PAGE)
3307                   .Case("gottprel_lo12", ARM64MCExpr::VK_GOTTPREL_LO12_NC)
3308                   .Case("gottprel_g1", ARM64MCExpr::VK_GOTTPREL_G1)
3309                   .Case("gottprel_g0_nc", ARM64MCExpr::VK_GOTTPREL_G0_NC)
3310                   .Case("tlsdesc", ARM64MCExpr::VK_TLSDESC_PAGE)
3311                   .Default(ARM64MCExpr::VK_INVALID);
3312
3313     if (RefKind == ARM64MCExpr::VK_INVALID) {
3314       Error(Parser.getTok().getLoc(),
3315             "expect relocation specifier in operand after ':'");
3316       return true;
3317     }
3318
3319     Parser.Lex(); // Eat identifier
3320
3321     if (Parser.getTok().isNot(AsmToken::Colon)) {
3322       Error(Parser.getTok().getLoc(), "expect ':' after relocation specifier");
3323       return true;
3324     }
3325     Parser.Lex(); // Eat ':'
3326   }
3327
3328   if (getParser().parseExpression(ImmVal))
3329     return true;
3330
3331   if (HasELFModifier)
3332     ImmVal = ARM64MCExpr::Create(ImmVal, RefKind, getContext());
3333
3334   return false;
3335 }
3336
3337 /// parseVectorList - Parse a vector list operand for AdvSIMD instructions.
3338 bool ARM64AsmParser::parseVectorList(OperandVector &Operands) {
3339   assert(Parser.getTok().is(AsmToken::LCurly) && "Token is not a Left Bracket");
3340   SMLoc S = getLoc();
3341   Parser.Lex(); // Eat left bracket token.
3342   StringRef Kind;
3343   int64_t FirstReg = tryMatchVectorRegister(Kind, true);
3344   if (FirstReg == -1)
3345     return true;
3346   int64_t PrevReg = FirstReg;
3347   unsigned Count = 1;
3348
3349   if (Parser.getTok().is(AsmToken::Minus)) {
3350     Parser.Lex(); // Eat the minus.
3351
3352     SMLoc Loc = getLoc();
3353     StringRef NextKind;
3354     int64_t Reg = tryMatchVectorRegister(NextKind, true);
3355     if (Reg == -1)
3356       return true;
3357     // Any Kind suffices must match on all regs in the list.
3358     if (Kind != NextKind)
3359       return Error(Loc, "mismatched register size suffix");
3360
3361     unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg);
3362
3363     if (Space == 0 || Space > 3) {
3364       return Error(Loc, "invalid number of vectors");
3365     }
3366
3367     Count += Space;
3368   }
3369   else {
3370     while (Parser.getTok().is(AsmToken::Comma)) {
3371       Parser.Lex(); // Eat the comma token.
3372
3373       SMLoc Loc = getLoc();
3374       StringRef NextKind;
3375       int64_t Reg = tryMatchVectorRegister(NextKind, true);
3376       if (Reg == -1)
3377         return true;
3378       // Any Kind suffices must match on all regs in the list.
3379       if (Kind != NextKind)
3380         return Error(Loc, "mismatched register size suffix");
3381
3382       // Registers must be incremental (with wraparound at 31)
3383       if (getContext().getRegisterInfo()->getEncodingValue(Reg) !=
3384           (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32)
3385        return Error(Loc, "registers must be sequential");
3386
3387       PrevReg = Reg;
3388       ++Count;
3389     }
3390   }
3391
3392   if (Parser.getTok().is(AsmToken::EndOfStatement))
3393     Error(getLoc(), "'}' expected");
3394   Parser.Lex(); // Eat the '}' token.
3395
3396   unsigned NumElements = 0;
3397   char ElementKind = 0;
3398   if (!Kind.empty())
3399     parseValidVectorKind(Kind, NumElements, ElementKind);
3400
3401   Operands.push_back(ARM64Operand::CreateVectorList(
3402       FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext()));
3403
3404   // If there is an index specifier following the list, parse that too.
3405   if (Parser.getTok().is(AsmToken::LBrac)) {
3406     SMLoc SIdx = getLoc();
3407     Parser.Lex(); // Eat left bracket token.
3408
3409     const MCExpr *ImmVal;
3410     if (getParser().parseExpression(ImmVal))
3411       return false;
3412     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
3413     if (!MCE) {
3414       TokError("immediate value expected for vector index");
3415       return false;
3416     }
3417
3418     SMLoc E = getLoc();
3419     if (Parser.getTok().isNot(AsmToken::RBrac)) {
3420       Error(E, "']' expected");
3421       return false;
3422     }
3423
3424     Parser.Lex(); // Eat right bracket token.
3425
3426     Operands.push_back(ARM64Operand::CreateVectorIndex(MCE->getValue(), SIdx, E,
3427                                                        getContext()));
3428   }
3429   return false;
3430 }
3431
3432 /// parseOperand - Parse a arm instruction operand.  For now this parses the
3433 /// operand regardless of the mnemonic.
3434 bool ARM64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
3435                                   bool invertCondCode) {
3436   // Check if the current operand has a custom associated parser, if so, try to
3437   // custom parse the operand, or fallback to the general approach.
3438   OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3439   if (ResTy == MatchOperand_Success)
3440     return false;
3441   // If there wasn't a custom match, try the generic matcher below. Otherwise,
3442   // there was a match, but an error occurred, in which case, just return that
3443   // the operand parsing failed.
3444   if (ResTy == MatchOperand_ParseFail)
3445     return true;
3446
3447   // Nothing custom, so do general case parsing.
3448   SMLoc S, E;
3449   switch (getLexer().getKind()) {
3450   default: {
3451     SMLoc S = getLoc();
3452     const MCExpr *Expr;
3453     if (parseSymbolicImmVal(Expr))
3454       return Error(S, "invalid operand");
3455
3456     SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3457     Operands.push_back(ARM64Operand::CreateImm(Expr, S, E, getContext()));
3458     return false;
3459   }
3460   case AsmToken::LBrac:
3461     return parseMemory(Operands);
3462   case AsmToken::LCurly:
3463     return parseVectorList(Operands);
3464   case AsmToken::Identifier: {
3465     // If we're expecting a Condition Code operand, then just parse that.
3466     if (isCondCode)
3467       return parseCondCode(Operands, invertCondCode);
3468
3469     // If it's a register name, parse it.
3470     if (!parseRegister(Operands))
3471       return false;
3472
3473     // This could be an optional "shift" operand.
3474     if (!parseOptionalShift(Operands))
3475       return false;
3476
3477     // Or maybe it could be an optional "extend" operand.
3478     if (!parseOptionalExtend(Operands))
3479       return false;
3480
3481     // This was not a register so parse other operands that start with an
3482     // identifier (like labels) as expressions and create them as immediates.
3483     const MCExpr *IdVal;
3484     S = getLoc();
3485     if (getParser().parseExpression(IdVal))
3486       return true;
3487
3488     E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3489     Operands.push_back(ARM64Operand::CreateImm(IdVal, S, E, getContext()));
3490     return false;
3491   }
3492   case AsmToken::Hash: {
3493     // #42 -> immediate.
3494     S = getLoc();
3495     Parser.Lex();
3496
3497     // The only Real that should come through here is a literal #0.0 for
3498     // the fcmp[e] r, #0.0 instructions. They expect raw token operands,
3499     // so convert the value.
3500     const AsmToken &Tok = Parser.getTok();
3501     if (Tok.is(AsmToken::Real)) {
3502       APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
3503       uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
3504       if (IntVal != 0 || (Mnemonic != "fcmp" && Mnemonic != "fcmpe"))
3505         return TokError("unexpected floating point literal");
3506       Parser.Lex(); // Eat the token.
3507
3508       Operands.push_back(
3509           ARM64Operand::CreateToken("#0", false, S, getContext()));
3510       Operands.push_back(
3511           ARM64Operand::CreateToken(".0", false, S, getContext()));
3512       return false;
3513     }
3514
3515     const MCExpr *ImmVal;
3516     if (parseSymbolicImmVal(ImmVal))
3517       return true;
3518
3519     E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3520     Operands.push_back(ARM64Operand::CreateImm(ImmVal, S, E, getContext()));
3521     return false;
3522   }
3523   }
3524 }
3525
3526 /// ParseInstruction - Parse an ARM64 instruction mnemonic followed by its
3527 /// operands.
3528 bool ARM64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
3529                                       StringRef Name, SMLoc NameLoc,
3530                                       OperandVector &Operands) {
3531   // Create the leading tokens for the mnemonic, split by '.' characters.
3532   size_t Start = 0, Next = Name.find('.');
3533   StringRef Head = Name.slice(Start, Next);
3534
3535   // IC, DC, AT, and TLBI instructions are aliases for the SYS instruction.
3536   if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi")
3537     return parseSysAlias(Head, NameLoc, Operands);
3538
3539   Operands.push_back(
3540       ARM64Operand::CreateToken(Head, false, NameLoc, getContext()));
3541   Mnemonic = Head;
3542
3543   // Handle condition codes for a branch mnemonic
3544   if (Head == "b" && Next != StringRef::npos) {
3545     Start = Next;
3546     Next = Name.find('.', Start + 1);
3547     Head = Name.slice(Start + 1, Next);
3548
3549     SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3550                                             (Head.data() - Name.data()));
3551     unsigned CC = parseCondCodeString(Head);
3552     if (CC == ARM64CC::Invalid)
3553       return Error(SuffixLoc, "invalid condition code");
3554     const MCExpr *CCExpr = MCConstantExpr::Create(CC, getContext());
3555     Operands.push_back(
3556         ARM64Operand::CreateImm(CCExpr, NameLoc, NameLoc, getContext()));
3557   }
3558
3559   // Add the remaining tokens in the mnemonic.
3560   while (Next != StringRef::npos) {
3561     Start = Next;
3562     Next = Name.find('.', Start + 1);
3563     Head = Name.slice(Start, Next);
3564     SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3565                                             (Head.data() - Name.data()) + 1);
3566     Operands.push_back(
3567         ARM64Operand::CreateToken(Head, true, SuffixLoc, getContext()));
3568   }
3569
3570   // Conditional compare instructions have a Condition Code operand, which needs
3571   // to be parsed and an immediate operand created.
3572   bool condCodeFourthOperand =
3573       (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" ||
3574        Head == "fccmpe" || Head == "fcsel" || Head == "csel" ||
3575        Head == "csinc" || Head == "csinv" || Head == "csneg");
3576
3577   // These instructions are aliases to some of the conditional select
3578   // instructions. However, the condition code is inverted in the aliased
3579   // instruction.
3580   //
3581   // FIXME: Is this the correct way to handle these? Or should the parser
3582   //        generate the aliased instructions directly?
3583   bool condCodeSecondOperand = (Head == "cset" || Head == "csetm");
3584   bool condCodeThirdOperand =
3585       (Head == "cinc" || Head == "cinv" || Head == "cneg");
3586
3587   // Read the remaining operands.
3588   if (getLexer().isNot(AsmToken::EndOfStatement)) {
3589     // Read the first operand.
3590     if (parseOperand(Operands, false, false)) {
3591       Parser.eatToEndOfStatement();
3592       return true;
3593     }
3594
3595     unsigned N = 2;
3596     while (getLexer().is(AsmToken::Comma)) {
3597       Parser.Lex(); // Eat the comma.
3598
3599       // Parse and remember the operand.
3600       if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
3601                                      (N == 3 && condCodeThirdOperand) ||
3602                                      (N == 2 && condCodeSecondOperand),
3603                        condCodeSecondOperand || condCodeThirdOperand)) {
3604         Parser.eatToEndOfStatement();
3605         return true;
3606       }
3607
3608       ++N;
3609     }
3610   }
3611
3612   if (getLexer().isNot(AsmToken::EndOfStatement)) {
3613     SMLoc Loc = Parser.getTok().getLoc();
3614     Parser.eatToEndOfStatement();
3615     return Error(Loc, "unexpected token in argument list");
3616   }
3617
3618   Parser.Lex(); // Consume the EndOfStatement
3619   return false;
3620 }
3621
3622 /// isFPR32Register - Check if a register is in the FPR32 register class.
3623 /// (The parser does not have the target register info to check the register
3624 /// class directly.)
3625 static bool isFPR32Register(unsigned Reg) {
3626   using namespace ARM64;
3627   switch (Reg) {
3628   default:
3629     break;
3630   case S0:  case S1:  case S2:  case S3:  case S4:  case S5:  case S6:
3631   case S7:  case S8:  case S9:  case S10:  case S11:  case S12:  case S13:
3632   case S14:  case S15:  case S16:  case S17:  case S18:  case S19:  case S20:
3633   case S21:  case S22:  case S23:  case S24:  case S25:  case S26:  case S27:
3634   case S28:  case S29:  case S30:  case S31:
3635     return true;
3636   }
3637   return false;
3638 }
3639
3640 /// isGPR32Register - Check if a register is in the GPR32sp register class.
3641 /// (The parser does not have the target register info to check the register
3642 /// class directly.)
3643 static bool isGPR32Register(unsigned Reg) {
3644   using namespace ARM64;
3645   switch (Reg) {
3646   default:
3647     break;
3648   case W0:  case W1:  case W2:  case W3:  case W4:  case W5:  case W6:
3649   case W7:  case W8:  case W9:  case W10:  case W11:  case W12:  case W13:
3650   case W14:  case W15:  case W16:  case W17:  case W18:  case W19:  case W20:
3651   case W21:  case W22:  case W23:  case W24:  case W25:  case W26:  case W27:
3652   case W28:  case W29:  case W30:  case WSP:
3653     return true;
3654   }
3655   return false;
3656 }
3657
3658 static bool isGPR64Reg(unsigned Reg) {
3659   using namespace ARM64;
3660   switch (Reg) {
3661   case X0:  case X1:  case X2:  case X3:  case X4:  case X5:  case X6:
3662   case X7:  case X8:  case X9:  case X10:  case X11:  case X12:  case X13:
3663   case X14:  case X15:  case X16:  case X17:  case X18:  case X19:  case X20:
3664   case X21:  case X22:  case X23:  case X24:  case X25:  case X26:  case X27:
3665   case X28:  case FP:  case LR:  case SP:  case XZR:
3666     return true;
3667   default:
3668     return false;
3669   }
3670 }
3671
3672
3673 // FIXME: This entire function is a giant hack to provide us with decent
3674 // operand range validation/diagnostics until TableGen/MC can be extended
3675 // to support autogeneration of this kind of validation.
3676 bool ARM64AsmParser::validateInstruction(MCInst &Inst,
3677                                          SmallVectorImpl<SMLoc> &Loc) {
3678   const MCRegisterInfo *RI = getContext().getRegisterInfo();
3679   // Check for indexed addressing modes w/ the base register being the
3680   // same as a destination/source register or pair load where
3681   // the Rt == Rt2. All of those are undefined behaviour.
3682   switch (Inst.getOpcode()) {
3683   case ARM64::LDPSWpre:
3684   case ARM64::LDPWpost:
3685   case ARM64::LDPWpre:
3686   case ARM64::LDPXpost:
3687   case ARM64::LDPXpre: {
3688     unsigned Rt = Inst.getOperand(0).getReg();
3689     unsigned Rt2 = Inst.getOperand(1).getReg();
3690     unsigned Rn = Inst.getOperand(2).getReg();
3691     if (RI->isSubRegisterEq(Rn, Rt))
3692       return Error(Loc[0], "unpredictable LDP instruction, writeback base "
3693                            "is also a destination");
3694     if (RI->isSubRegisterEq(Rn, Rt2))
3695       return Error(Loc[1], "unpredictable LDP instruction, writeback base "
3696                            "is also a destination");
3697     // FALLTHROUGH
3698   }
3699   case ARM64::LDPDpost:
3700   case ARM64::LDPDpre:
3701   case ARM64::LDPQpost:
3702   case ARM64::LDPQpre:
3703   case ARM64::LDPSpost:
3704   case ARM64::LDPSpre:
3705   case ARM64::LDPSWpost:
3706   case ARM64::LDPDi:
3707   case ARM64::LDPQi:
3708   case ARM64::LDPSi:
3709   case ARM64::LDPSWi:
3710   case ARM64::LDPWi:
3711   case ARM64::LDPXi: {
3712     unsigned Rt = Inst.getOperand(0).getReg();
3713     unsigned Rt2 = Inst.getOperand(1).getReg();
3714     if (Rt == Rt2)
3715       return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3716     break;
3717   }
3718   case ARM64::STPDpost:
3719   case ARM64::STPDpre:
3720   case ARM64::STPQpost:
3721   case ARM64::STPQpre:
3722   case ARM64::STPSpost:
3723   case ARM64::STPSpre:
3724   case ARM64::STPWpost:
3725   case ARM64::STPWpre:
3726   case ARM64::STPXpost:
3727   case ARM64::STPXpre: {
3728     unsigned Rt = Inst.getOperand(0).getReg();
3729     unsigned Rt2 = Inst.getOperand(1).getReg();
3730     unsigned Rn = Inst.getOperand(2).getReg();
3731     if (RI->isSubRegisterEq(Rn, Rt))
3732       return Error(Loc[0], "unpredictable STP instruction, writeback base "
3733                            "is also a source");
3734     if (RI->isSubRegisterEq(Rn, Rt2))
3735       return Error(Loc[1], "unpredictable STP instruction, writeback base "
3736                            "is also a source");
3737     break;
3738   }
3739   case ARM64::LDRBBpre:
3740   case ARM64::LDRBpre:
3741   case ARM64::LDRHHpre:
3742   case ARM64::LDRHpre:
3743   case ARM64::LDRSBWpre:
3744   case ARM64::LDRSBXpre:
3745   case ARM64::LDRSHWpre:
3746   case ARM64::LDRSHXpre:
3747   case ARM64::LDRSWpre:
3748   case ARM64::LDRWpre:
3749   case ARM64::LDRXpre:
3750   case ARM64::LDRBBpost:
3751   case ARM64::LDRBpost:
3752   case ARM64::LDRHHpost:
3753   case ARM64::LDRHpost:
3754   case ARM64::LDRSBWpost:
3755   case ARM64::LDRSBXpost:
3756   case ARM64::LDRSHWpost:
3757   case ARM64::LDRSHXpost:
3758   case ARM64::LDRSWpost:
3759   case ARM64::LDRWpost:
3760   case ARM64::LDRXpost: {
3761     unsigned Rt = Inst.getOperand(0).getReg();
3762     unsigned Rn = Inst.getOperand(1).getReg();
3763     if (RI->isSubRegisterEq(Rn, Rt))
3764       return Error(Loc[0], "unpredictable LDR instruction, writeback base "
3765                            "is also a source");
3766     break;
3767   }
3768   case ARM64::STRBBpost:
3769   case ARM64::STRBpost:
3770   case ARM64::STRHHpost:
3771   case ARM64::STRHpost:
3772   case ARM64::STRWpost:
3773   case ARM64::STRXpost:
3774   case ARM64::STRBBpre:
3775   case ARM64::STRBpre:
3776   case ARM64::STRHHpre:
3777   case ARM64::STRHpre:
3778   case ARM64::STRWpre:
3779   case ARM64::STRXpre: {
3780     unsigned Rt = Inst.getOperand(0).getReg();
3781     unsigned Rn = Inst.getOperand(1).getReg();
3782     if (RI->isSubRegisterEq(Rn, Rt))
3783       return Error(Loc[0], "unpredictable STR instruction, writeback base "
3784                            "is also a source");
3785     break;
3786   }
3787   }
3788
3789   // Now check immediate ranges. Separate from the above as there is overlap
3790   // in the instructions being checked and this keeps the nested conditionals
3791   // to a minimum.
3792   switch (Inst.getOpcode()) {
3793   case ARM64::ANDWrs:
3794   case ARM64::ANDSWrs:
3795   case ARM64::EORWrs:
3796   case ARM64::ORRWrs: {
3797     if (!Inst.getOperand(3).isImm())
3798       return Error(Loc[3], "immediate value expected");
3799     int64_t shifter = Inst.getOperand(3).getImm();
3800     ARM64_AM::ShiftType ST = ARM64_AM::getShiftType(shifter);
3801     if (ST == ARM64_AM::LSL && shifter > 31)
3802       return Error(Loc[3], "shift value out of range");
3803     return false;
3804   }
3805   case ARM64::ADDSWri:
3806   case ARM64::ADDSXri:
3807   case ARM64::ADDWri:
3808   case ARM64::ADDXri:
3809   case ARM64::SUBSWri:
3810   case ARM64::SUBSXri:
3811   case ARM64::SUBWri:
3812   case ARM64::SUBXri: {
3813     if (!Inst.getOperand(3).isImm())
3814       return Error(Loc[3], "immediate value expected");
3815     int64_t shifter = Inst.getOperand(3).getImm();
3816     if (shifter != 0 && shifter != 12)
3817       return Error(Loc[3], "shift value out of range");
3818     // The imm12 operand can be an expression. Validate that it's legit.
3819     // FIXME: We really, really want to allow arbitrary expressions here
3820     // and resolve the value and validate the result at fixup time, but
3821     // that's hard as we have long since lost any source information we
3822     // need to generate good diagnostics by that point.
3823     if (Inst.getOpcode() == ARM64::ADDXri && Inst.getOperand(2).isExpr()) {
3824       const MCExpr *Expr = Inst.getOperand(2).getExpr();
3825       ARM64MCExpr::VariantKind ELFRefKind;
3826       MCSymbolRefExpr::VariantKind DarwinRefKind;
3827       const MCConstantExpr *Addend;
3828       if (!classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3829         return Error(Loc[2], "invalid immediate expression");
3830       }
3831
3832       if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
3833           DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF ||
3834           ELFRefKind == ARM64MCExpr::VK_LO12 ||
3835           ELFRefKind == ARM64MCExpr::VK_DTPREL_LO12 ||
3836           ELFRefKind == ARM64MCExpr::VK_DTPREL_LO12_NC ||
3837           ELFRefKind == ARM64MCExpr::VK_TPREL_LO12 ||
3838           ELFRefKind == ARM64MCExpr::VK_TPREL_LO12_NC ||
3839           ELFRefKind == ARM64MCExpr::VK_TLSDESC_LO12) {
3840         // Note that we don't range-check the addend. It's adjusted
3841         // modulo page size when converted, so there is no "out of range"
3842         // condition when using @pageoff. Any validity checking for the value
3843         // was done in the is*() predicate function.
3844         return false;
3845       } else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF) {
3846         // @gotpageoff can only be used directly, not with an addend.
3847         return Addend != 0;
3848       }
3849
3850       // Otherwise, we're not sure, so don't allow it for now.
3851       return Error(Loc[2], "invalid immediate expression");
3852     }
3853
3854     // If it's anything but an immediate, it's not legit.
3855     if (!Inst.getOperand(2).isImm())
3856       return Error(Loc[2], "invalid immediate expression");
3857     int64_t imm = Inst.getOperand(2).getImm();
3858     if (imm > 4095 || imm < 0)
3859       return Error(Loc[2], "immediate value out of range");
3860     return false;
3861   }
3862   case ARM64::LDRBpre:
3863   case ARM64::LDRHpre:
3864   case ARM64::LDRSBWpre:
3865   case ARM64::LDRSBXpre:
3866   case ARM64::LDRSHWpre:
3867   case ARM64::LDRSHXpre:
3868   case ARM64::LDRWpre:
3869   case ARM64::LDRXpre:
3870   case ARM64::LDRSpre:
3871   case ARM64::LDRDpre:
3872   case ARM64::LDRQpre:
3873   case ARM64::STRBpre:
3874   case ARM64::STRHpre:
3875   case ARM64::STRWpre:
3876   case ARM64::STRXpre:
3877   case ARM64::STRSpre:
3878   case ARM64::STRDpre:
3879   case ARM64::STRQpre:
3880   case ARM64::LDRBpost:
3881   case ARM64::LDRHpost:
3882   case ARM64::LDRSBWpost:
3883   case ARM64::LDRSBXpost:
3884   case ARM64::LDRSHWpost:
3885   case ARM64::LDRSHXpost:
3886   case ARM64::LDRWpost:
3887   case ARM64::LDRXpost:
3888   case ARM64::LDRSpost:
3889   case ARM64::LDRDpost:
3890   case ARM64::LDRQpost:
3891   case ARM64::STRBpost:
3892   case ARM64::STRHpost:
3893   case ARM64::STRWpost:
3894   case ARM64::STRXpost:
3895   case ARM64::STRSpost:
3896   case ARM64::STRDpost:
3897   case ARM64::STRQpost:
3898   case ARM64::LDTRXi:
3899   case ARM64::LDTRWi:
3900   case ARM64::LDTRHi:
3901   case ARM64::LDTRBi:
3902   case ARM64::LDTRSHWi:
3903   case ARM64::LDTRSHXi:
3904   case ARM64::LDTRSBWi:
3905   case ARM64::LDTRSBXi:
3906   case ARM64::LDTRSWi:
3907   case ARM64::STTRWi:
3908   case ARM64::STTRXi:
3909   case ARM64::STTRHi:
3910   case ARM64::STTRBi:
3911   case ARM64::LDURWi:
3912   case ARM64::LDURXi:
3913   case ARM64::LDURSi:
3914   case ARM64::LDURDi:
3915   case ARM64::LDURQi:
3916   case ARM64::LDURHi:
3917   case ARM64::LDURBi:
3918   case ARM64::LDURSHWi:
3919   case ARM64::LDURSHXi:
3920   case ARM64::LDURSBWi:
3921   case ARM64::LDURSBXi:
3922   case ARM64::LDURSWi:
3923   case ARM64::PRFUMi:
3924   case ARM64::STURWi:
3925   case ARM64::STURXi:
3926   case ARM64::STURSi:
3927   case ARM64::STURDi:
3928   case ARM64::STURQi:
3929   case ARM64::STURHi:
3930   case ARM64::STURBi: {
3931     // FIXME: Should accept expressions and error in fixup evaluation
3932     // if out of range.
3933     if (!Inst.getOperand(2).isImm())
3934       return Error(Loc[1], "immediate value expected");
3935     int64_t offset = Inst.getOperand(2).getImm();
3936     if (offset > 255 || offset < -256)
3937       return Error(Loc[1], "offset value out of range");
3938     return false;
3939   }
3940   case ARM64::LDRSro:
3941   case ARM64::LDRWro:
3942   case ARM64::LDRSWro:
3943   case ARM64::STRWro:
3944   case ARM64::STRSro: {
3945     // FIXME: Should accept expressions and error in fixup evaluation
3946     // if out of range.
3947     if (!Inst.getOperand(3).isImm())
3948       return Error(Loc[1], "immediate value expected");
3949     int64_t shift = Inst.getOperand(3).getImm();
3950     ARM64_AM::ExtendType type = ARM64_AM::getMemExtendType(shift);
3951     if (type != ARM64_AM::UXTW && type != ARM64_AM::UXTX &&
3952         type != ARM64_AM::SXTW && type != ARM64_AM::SXTX)
3953       return Error(Loc[1], "shift type invalid");
3954     return false;
3955   }
3956   case ARM64::LDRDro:
3957   case ARM64::LDRQro:
3958   case ARM64::LDRXro:
3959   case ARM64::PRFMro:
3960   case ARM64::STRXro:
3961   case ARM64::STRDro:
3962   case ARM64::STRQro: {
3963     // FIXME: Should accept expressions and error in fixup evaluation
3964     // if out of range.
3965     if (!Inst.getOperand(3).isImm())
3966       return Error(Loc[1], "immediate value expected");
3967     int64_t shift = Inst.getOperand(3).getImm();
3968     ARM64_AM::ExtendType type = ARM64_AM::getMemExtendType(shift);
3969     if (type != ARM64_AM::UXTW && type != ARM64_AM::UXTX &&
3970         type != ARM64_AM::SXTW && type != ARM64_AM::SXTX)
3971       return Error(Loc[1], "shift type invalid");
3972     return false;
3973   }
3974   case ARM64::LDRHro:
3975   case ARM64::LDRHHro:
3976   case ARM64::LDRSHWro:
3977   case ARM64::LDRSHXro:
3978   case ARM64::STRHro:
3979   case ARM64::STRHHro: {
3980     // FIXME: Should accept expressions and error in fixup evaluation
3981     // if out of range.
3982     if (!Inst.getOperand(3).isImm())
3983       return Error(Loc[1], "immediate value expected");
3984     int64_t shift = Inst.getOperand(3).getImm();
3985     ARM64_AM::ExtendType type = ARM64_AM::getMemExtendType(shift);
3986     if (type != ARM64_AM::UXTW && type != ARM64_AM::UXTX &&
3987         type != ARM64_AM::SXTW && type != ARM64_AM::SXTX)
3988       return Error(Loc[1], "shift type invalid");
3989     return false;
3990   }
3991   case ARM64::LDRBro:
3992   case ARM64::LDRBBro:
3993   case ARM64::LDRSBWro:
3994   case ARM64::LDRSBXro:
3995   case ARM64::STRBro:
3996   case ARM64::STRBBro: {
3997     // FIXME: Should accept expressions and error in fixup evaluation
3998     // if out of range.
3999     if (!Inst.getOperand(3).isImm())
4000       return Error(Loc[1], "immediate value expected");
4001     int64_t shift = Inst.getOperand(3).getImm();
4002     ARM64_AM::ExtendType type = ARM64_AM::getMemExtendType(shift);
4003     if (type != ARM64_AM::UXTW && type != ARM64_AM::UXTX &&
4004         type != ARM64_AM::SXTW && type != ARM64_AM::SXTX)
4005       return Error(Loc[1], "shift type invalid");
4006     return false;
4007   }
4008   case ARM64::LDPWi:
4009   case ARM64::LDPXi:
4010   case ARM64::LDPSi:
4011   case ARM64::LDPDi:
4012   case ARM64::LDPQi:
4013   case ARM64::LDPSWi:
4014   case ARM64::STPWi:
4015   case ARM64::STPXi:
4016   case ARM64::STPSi:
4017   case ARM64::STPDi:
4018   case ARM64::STPQi:
4019   case ARM64::LDPWpre:
4020   case ARM64::LDPXpre:
4021   case ARM64::LDPSpre:
4022   case ARM64::LDPDpre:
4023   case ARM64::LDPQpre:
4024   case ARM64::LDPSWpre:
4025   case ARM64::STPWpre:
4026   case ARM64::STPXpre:
4027   case ARM64::STPSpre:
4028   case ARM64::STPDpre:
4029   case ARM64::STPQpre:
4030   case ARM64::LDPWpost:
4031   case ARM64::LDPXpost:
4032   case ARM64::LDPSpost:
4033   case ARM64::LDPDpost:
4034   case ARM64::LDPQpost:
4035   case ARM64::LDPSWpost:
4036   case ARM64::STPWpost:
4037   case ARM64::STPXpost:
4038   case ARM64::STPSpost:
4039   case ARM64::STPDpost:
4040   case ARM64::STPQpost:
4041   case ARM64::LDNPWi:
4042   case ARM64::LDNPXi:
4043   case ARM64::LDNPSi:
4044   case ARM64::LDNPDi:
4045   case ARM64::LDNPQi:
4046   case ARM64::STNPWi:
4047   case ARM64::STNPXi:
4048   case ARM64::STNPSi:
4049   case ARM64::STNPDi:
4050   case ARM64::STNPQi: {
4051     // FIXME: Should accept expressions and error in fixup evaluation
4052     // if out of range.
4053     if (!Inst.getOperand(3).isImm())
4054       return Error(Loc[2], "immediate value expected");
4055     int64_t offset = Inst.getOperand(3).getImm();
4056     if (offset > 63 || offset < -64)
4057       return Error(Loc[2], "offset value out of range");
4058     return false;
4059   }
4060   default:
4061     return false;
4062   }
4063 }
4064
4065 static void rewriteMOV(ARM64AsmParser::OperandVector &Operands,
4066                        StringRef mnemonic, uint64_t imm, unsigned shift,
4067                        MCContext &Context) {
4068   ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[0]);
4069   ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
4070   Operands[0] =
4071       ARM64Operand::CreateToken(mnemonic, false, Op->getStartLoc(), Context);
4072
4073   const MCExpr *NewImm = MCConstantExpr::Create(imm >> shift, Context);
4074   Operands[2] = ARM64Operand::CreateImm(NewImm, Op2->getStartLoc(),
4075                                         Op2->getEndLoc(), Context);
4076
4077   Operands.push_back(ARM64Operand::CreateShifter(
4078       ARM64_AM::LSL, shift, Op2->getStartLoc(), Op2->getEndLoc(), Context));
4079   delete Op2;
4080   delete Op;
4081 }
4082
4083 bool ARM64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
4084   switch (ErrCode) {
4085   case Match_MissingFeature:
4086     return Error(Loc,
4087                  "instruction requires a CPU feature not currently enabled");
4088   case Match_InvalidOperand:
4089     return Error(Loc, "invalid operand for instruction");
4090   case Match_InvalidSuffix:
4091     return Error(Loc, "invalid type suffix for instruction");
4092   case Match_InvalidMemoryIndexedSImm9:
4093     return Error(Loc, "index must be an integer in range [-256,255].");
4094   case Match_InvalidMemoryIndexed32SImm7:
4095     return Error(Loc, "index must be a multiple of 4 in range [-256,252].");
4096   case Match_InvalidMemoryIndexed64SImm7:
4097     return Error(Loc, "index must be a multiple of 8 in range [-512,504].");
4098   case Match_InvalidMemoryIndexed128SImm7:
4099     return Error(Loc, "index must be a multiple of 16 in range [-1024,1008].");
4100   case Match_InvalidMemoryIndexed8:
4101     return Error(Loc, "index must be an integer in range [0,4095].");
4102   case Match_InvalidMemoryIndexed16:
4103     return Error(Loc, "index must be a multiple of 2 in range [0,8190].");
4104   case Match_InvalidMemoryIndexed32:
4105     return Error(Loc, "index must be a multiple of 4 in range [0,16380].");
4106   case Match_InvalidMemoryIndexed64:
4107     return Error(Loc, "index must be a multiple of 8 in range [0,32760].");
4108   case Match_InvalidMemoryIndexed128:
4109     return Error(Loc, "index must be a multiple of 16 in range [0,65520].");
4110   case Match_InvalidImm1_8:
4111     return Error(Loc, "immediate must be an integer in range [1,8].");
4112   case Match_InvalidImm1_16:
4113     return Error(Loc, "immediate must be an integer in range [1,16].");
4114   case Match_InvalidImm1_32:
4115     return Error(Loc, "immediate must be an integer in range [1,32].");
4116   case Match_InvalidImm1_64:
4117     return Error(Loc, "immediate must be an integer in range [1,64].");
4118   case Match_MnemonicFail:
4119     return Error(Loc, "unrecognized instruction mnemonic");
4120   default:
4121     assert(0 && "unexpected error code!");
4122     return Error(Loc, "invalid instruction format");
4123   }
4124 }
4125
4126 bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
4127                                              OperandVector &Operands,
4128                                              MCStreamer &Out,
4129                                              unsigned &ErrorInfo,
4130                                              bool MatchingInlineAsm) {
4131   assert(!Operands.empty() && "Unexpect empty operand list!");
4132   ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[0]);
4133   assert(Op->isToken() && "Leading operand should always be a mnemonic!");
4134
4135   StringRef Tok = Op->getToken();
4136   // Translate CMN/CMP pseudos to ADDS/SUBS with zero register destination.
4137   // This needs to be done before the special handling of ADD/SUB immediates.
4138   if (Tok == "cmp" || Tok == "cmn") {
4139     // Replace the opcode with either ADDS or SUBS.
4140     const char *Repl = StringSwitch<const char *>(Tok)
4141                            .Case("cmp", "subs")
4142                            .Case("cmn", "adds")
4143                            .Default(0);
4144     assert(Repl && "Unknown compare instruction");
4145     delete Operands[0];
4146     Operands[0] = ARM64Operand::CreateToken(Repl, false, IDLoc, getContext());
4147
4148     // Insert WZR or XZR as destination operand.
4149     ARM64Operand *RegOp = static_cast<ARM64Operand *>(Operands[1]);
4150     unsigned ZeroReg;
4151     if (RegOp->isReg() &&
4152         (isGPR32Register(RegOp->getReg()) || RegOp->getReg() == ARM64::WZR))
4153       ZeroReg = ARM64::WZR;
4154     else
4155       ZeroReg = ARM64::XZR;
4156     Operands.insert(
4157         Operands.begin() + 1,
4158         ARM64Operand::CreateReg(ZeroReg, false, IDLoc, IDLoc, getContext()));
4159     // Update since we modified it above.
4160     ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[0]);
4161     Tok = Op->getToken();
4162   }
4163
4164   unsigned NumOperands = Operands.size();
4165
4166   if (Tok == "mov" && NumOperands == 3) {
4167     // The MOV mnemomic is aliased to movn/movz, depending on the value of
4168     // the immediate being instantiated.
4169     // FIXME: Catching this here is a total hack, and we should use tblgen
4170     // support to implement this instead as soon as it is available.
4171
4172     ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
4173     if (Op2->isImm()) {
4174       if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op2->getImm())) {
4175         uint64_t Val = CE->getValue();
4176         uint64_t NVal = ~Val;
4177
4178         // If this is a 32-bit register and the value has none of the upper
4179         // set, clear the complemented upper 32-bits so the logic below works
4180         // for 32-bit registers too.
4181         ARM64Operand *Op1 = static_cast<ARM64Operand *>(Operands[1]);
4182         if (Op1->isReg() && isGPR32Register(Op1->getReg()) &&
4183             (Val & 0xFFFFFFFFULL) == Val)
4184           NVal &= 0x00000000FFFFFFFFULL;
4185
4186         // MOVK Rd, imm << 0
4187         if ((Val & 0xFFFF) == Val)
4188           rewriteMOV(Operands, "movz", Val, 0, getContext());
4189
4190         // MOVK Rd, imm << 16
4191         else if ((Val & 0xFFFF0000ULL) == Val)
4192           rewriteMOV(Operands, "movz", Val, 16, getContext());
4193
4194         // MOVK Rd, imm << 32
4195         else if ((Val & 0xFFFF00000000ULL) == Val)
4196           rewriteMOV(Operands, "movz", Val, 32, getContext());
4197
4198         // MOVK Rd, imm << 48
4199         else if ((Val & 0xFFFF000000000000ULL) == Val)
4200           rewriteMOV(Operands, "movz", Val, 48, getContext());
4201
4202         // MOVN Rd, (~imm << 0)
4203         else if ((NVal & 0xFFFFULL) == NVal)
4204           rewriteMOV(Operands, "movn", NVal, 0, getContext());
4205
4206         // MOVN Rd, ~(imm << 16)
4207         else if ((NVal & 0xFFFF0000ULL) == NVal)
4208           rewriteMOV(Operands, "movn", NVal, 16, getContext());
4209
4210         // MOVN Rd, ~(imm << 32)
4211         else if ((NVal & 0xFFFF00000000ULL) == NVal)
4212           rewriteMOV(Operands, "movn", NVal, 32, getContext());
4213
4214         // MOVN Rd, ~(imm << 48)
4215         else if ((NVal & 0xFFFF000000000000ULL) == NVal)
4216           rewriteMOV(Operands, "movn", NVal, 48, getContext());
4217       }
4218     }
4219   } else if (NumOperands == 4) {
4220     if (Tok == "add" || Tok == "adds" || Tok == "sub" || Tok == "subs") {
4221       // Handle the uimm24 immediate form, where the shift is not specified.
4222       ARM64Operand *Op3 = static_cast<ARM64Operand *>(Operands[3]);
4223       if (Op3->isImm()) {
4224         if (const MCConstantExpr *CE =
4225                 dyn_cast<MCConstantExpr>(Op3->getImm())) {
4226           uint64_t Val = CE->getValue();
4227           if (Val >= (1 << 24)) {
4228             Error(IDLoc, "immediate value is too large");
4229             return true;
4230           }
4231           if (Val < (1 << 12)) {
4232             Operands.push_back(ARM64Operand::CreateShifter(
4233                 ARM64_AM::LSL, 0, IDLoc, IDLoc, getContext()));
4234           } else if ((Val & 0xfff) == 0) {
4235             delete Operands[3];
4236             CE = MCConstantExpr::Create(Val >> 12, getContext());
4237             Operands[3] =
4238                 ARM64Operand::CreateImm(CE, IDLoc, IDLoc, getContext());
4239             Operands.push_back(ARM64Operand::CreateShifter(
4240                 ARM64_AM::LSL, 12, IDLoc, IDLoc, getContext()));
4241           } else {
4242             Error(IDLoc, "immediate value is too large");
4243             return true;
4244           }
4245         } else {
4246           Operands.push_back(ARM64Operand::CreateShifter(
4247               ARM64_AM::LSL, 0, IDLoc, IDLoc, getContext()));
4248         }
4249       }
4250
4251       // FIXME: Horible hack to handle the LSL -> UBFM alias.
4252     } else if (NumOperands == 4 && Tok == "lsl") {
4253       ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
4254       ARM64Operand *Op3 = static_cast<ARM64Operand *>(Operands[3]);
4255       if (Op2->isReg() && Op3->isImm()) {
4256         const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3->getImm());
4257         if (Op3CE) {
4258           uint64_t Op3Val = Op3CE->getValue();
4259           uint64_t NewOp3Val = 0;
4260           uint64_t NewOp4Val = 0;
4261           if (isGPR32Register(Op2->getReg()) || Op2->getReg() == ARM64::WZR) {
4262             NewOp3Val = (32 - Op3Val) & 0x1f;
4263             NewOp4Val = 31 - Op3Val;
4264           } else {
4265             NewOp3Val = (64 - Op3Val) & 0x3f;
4266             NewOp4Val = 63 - Op3Val;
4267           }
4268
4269           const MCExpr *NewOp3 =
4270               MCConstantExpr::Create(NewOp3Val, getContext());
4271           const MCExpr *NewOp4 =
4272               MCConstantExpr::Create(NewOp4Val, getContext());
4273
4274           Operands[0] = ARM64Operand::CreateToken(
4275               "ubfm", false, Op->getStartLoc(), getContext());
4276           Operands[3] = ARM64Operand::CreateImm(NewOp3, Op3->getStartLoc(),
4277                                                 Op3->getEndLoc(), getContext());
4278           Operands.push_back(ARM64Operand::CreateImm(
4279               NewOp4, Op3->getStartLoc(), Op3->getEndLoc(), getContext()));
4280           delete Op3;
4281           delete Op;
4282         }
4283       }
4284
4285       // FIXME: Horrible hack to handle the optional LSL shift for vector
4286       //        instructions.
4287     } else if (NumOperands == 4 && (Tok == "bic" || Tok == "orr")) {
4288       ARM64Operand *Op1 = static_cast<ARM64Operand *>(Operands[1]);
4289       ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
4290       ARM64Operand *Op3 = static_cast<ARM64Operand *>(Operands[3]);
4291       if ((Op1->isToken() && Op2->isVectorReg() && Op3->isImm()) ||
4292           (Op1->isVectorReg() && Op2->isToken() && Op3->isImm()))
4293         Operands.push_back(ARM64Operand::CreateShifter(ARM64_AM::LSL, 0, IDLoc,
4294                                                        IDLoc, getContext()));
4295     } else if (NumOperands == 4 && (Tok == "movi" || Tok == "mvni")) {
4296       ARM64Operand *Op1 = static_cast<ARM64Operand *>(Operands[1]);
4297       ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
4298       ARM64Operand *Op3 = static_cast<ARM64Operand *>(Operands[3]);
4299       if ((Op1->isToken() && Op2->isVectorReg() && Op3->isImm()) ||
4300           (Op1->isVectorReg() && Op2->isToken() && Op3->isImm())) {
4301         StringRef Suffix = Op1->isToken() ? Op1->getToken() : Op2->getToken();
4302         // Canonicalize on lower-case for ease of comparison.
4303         std::string CanonicalSuffix = Suffix.lower();
4304         if (Tok != "movi" ||
4305             (CanonicalSuffix != ".1d" && CanonicalSuffix != ".2d" &&
4306              CanonicalSuffix != ".8b" && CanonicalSuffix != ".16b"))
4307           Operands.push_back(ARM64Operand::CreateShifter(
4308               ARM64_AM::LSL, 0, IDLoc, IDLoc, getContext()));
4309       }
4310     }
4311   } else if (NumOperands == 5) {
4312     // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and
4313     // UBFIZ -> UBFM aliases.
4314     if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") {
4315       ARM64Operand *Op1 = static_cast<ARM64Operand *>(Operands[1]);
4316       ARM64Operand *Op3 = static_cast<ARM64Operand *>(Operands[3]);
4317       ARM64Operand *Op4 = static_cast<ARM64Operand *>(Operands[4]);
4318
4319       if (Op1->isReg() && Op3->isImm() && Op4->isImm()) {
4320         const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3->getImm());
4321         const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4->getImm());
4322
4323         if (Op3CE && Op4CE) {
4324           uint64_t Op3Val = Op3CE->getValue();
4325           uint64_t Op4Val = Op4CE->getValue();
4326
4327           uint64_t NewOp3Val = 0;
4328           if (isGPR32Register(Op1->getReg()))
4329             NewOp3Val = (32 - Op3Val) & 0x1f;
4330           else
4331             NewOp3Val = (64 - Op3Val) & 0x3f;
4332
4333           uint64_t NewOp4Val = Op4Val - 1;
4334
4335           const MCExpr *NewOp3 =
4336               MCConstantExpr::Create(NewOp3Val, getContext());
4337           const MCExpr *NewOp4 =
4338               MCConstantExpr::Create(NewOp4Val, getContext());
4339           Operands[3] = ARM64Operand::CreateImm(NewOp3, Op3->getStartLoc(),
4340                                                 Op3->getEndLoc(), getContext());
4341           Operands[4] = ARM64Operand::CreateImm(NewOp4, Op4->getStartLoc(),
4342                                                 Op4->getEndLoc(), getContext());
4343           if (Tok == "bfi")
4344             Operands[0] = ARM64Operand::CreateToken(
4345                 "bfm", false, Op->getStartLoc(), getContext());
4346           else if (Tok == "sbfiz")
4347             Operands[0] = ARM64Operand::CreateToken(
4348                 "sbfm", false, Op->getStartLoc(), getContext());
4349           else if (Tok == "ubfiz")
4350             Operands[0] = ARM64Operand::CreateToken(
4351                 "ubfm", false, Op->getStartLoc(), getContext());
4352           else
4353             llvm_unreachable("No valid mnemonic for alias?");
4354
4355           delete Op;
4356           delete Op3;
4357           delete Op4;
4358         }
4359       }
4360
4361       // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and
4362       // UBFX -> UBFM aliases.
4363     } else if (NumOperands == 5 &&
4364                (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) {
4365       ARM64Operand *Op1 = static_cast<ARM64Operand *>(Operands[1]);
4366       ARM64Operand *Op3 = static_cast<ARM64Operand *>(Operands[3]);
4367       ARM64Operand *Op4 = static_cast<ARM64Operand *>(Operands[4]);
4368
4369       if (Op1->isReg() && Op3->isImm() && Op4->isImm()) {
4370         const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3->getImm());
4371         const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4->getImm());
4372
4373         if (Op3CE && Op4CE) {
4374           uint64_t Op3Val = Op3CE->getValue();
4375           uint64_t Op4Val = Op4CE->getValue();
4376           uint64_t NewOp4Val = Op3Val + Op4Val - 1;
4377
4378           if (NewOp4Val >= Op3Val) {
4379             const MCExpr *NewOp4 =
4380                 MCConstantExpr::Create(NewOp4Val, getContext());
4381             Operands[4] = ARM64Operand::CreateImm(
4382                 NewOp4, Op4->getStartLoc(), Op4->getEndLoc(), getContext());
4383             if (Tok == "bfxil")
4384               Operands[0] = ARM64Operand::CreateToken(
4385                   "bfm", false, Op->getStartLoc(), getContext());
4386             else if (Tok == "sbfx")
4387               Operands[0] = ARM64Operand::CreateToken(
4388                   "sbfm", false, Op->getStartLoc(), getContext());
4389             else if (Tok == "ubfx")
4390               Operands[0] = ARM64Operand::CreateToken(
4391                   "ubfm", false, Op->getStartLoc(), getContext());
4392             else
4393               llvm_unreachable("No valid mnemonic for alias?");
4394
4395             delete Op;
4396             delete Op4;
4397           }
4398         }
4399       }
4400     }
4401   }
4402   // FIXME: Horrible hack for tbz and tbnz with Wn register operand.
4403   //        InstAlias can't quite handle this since the reg classes aren't
4404   //        subclasses.
4405   if (NumOperands == 4 && (Tok == "tbz" || Tok == "tbnz")) {
4406     ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[2]);
4407     if (Op->isImm()) {
4408       if (const MCConstantExpr *OpCE = dyn_cast<MCConstantExpr>(Op->getImm())) {
4409         if (OpCE->getValue() < 32) {
4410           // The source register can be Wn here, but the matcher expects a
4411           // GPR64. Twiddle it here if necessary.
4412           ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[1]);
4413           if (Op->isReg()) {
4414             unsigned Reg = getXRegFromWReg(Op->getReg());
4415             Operands[1] = ARM64Operand::CreateReg(
4416                 Reg, false, Op->getStartLoc(), Op->getEndLoc(), getContext());
4417             delete Op;
4418           }
4419         }
4420       }
4421     }
4422   }
4423   // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands.
4424   //        InstAlias can't quite handle this since the reg classes aren't
4425   //        subclasses.
4426   if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) {
4427     // The source register can be Wn here, but the matcher expects a
4428     // GPR64. Twiddle it here if necessary.
4429     ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[2]);
4430     if (Op->isReg()) {
4431       unsigned Reg = getXRegFromWReg(Op->getReg());
4432       Operands[2] = ARM64Operand::CreateReg(Reg, false, Op->getStartLoc(),
4433                                             Op->getEndLoc(), getContext());
4434       delete Op;
4435     }
4436   }
4437   // FIXME: Likewise for [su]xt[bh] with a Xd dst operand
4438   else if (NumOperands == 3 &&
4439            (Tok == "sxtb" || Tok == "uxtb" || Tok == "sxth" || Tok == "uxth")) {
4440     ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[1]);
4441     if (Op->isReg() && isGPR64Reg(Op->getReg())) {
4442       // The source register can be Wn here, but the matcher expects a
4443       // GPR64. Twiddle it here if necessary.
4444       ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[2]);
4445       if (Op->isReg()) {
4446         unsigned Reg = getXRegFromWReg(Op->getReg());
4447         Operands[2] = ARM64Operand::CreateReg(Reg, false, Op->getStartLoc(),
4448                                               Op->getEndLoc(), getContext());
4449         delete Op;
4450       }
4451     }
4452   }
4453
4454   // Yet another horrible hack to handle FMOV Rd, #0.0 using [WX]ZR.
4455   if (NumOperands == 3 && Tok == "fmov") {
4456     ARM64Operand *RegOp = static_cast<ARM64Operand *>(Operands[1]);
4457     ARM64Operand *ImmOp = static_cast<ARM64Operand *>(Operands[2]);
4458     if (RegOp->isReg() && ImmOp->isFPImm() &&
4459         ImmOp->getFPImm() == (unsigned)-1) {
4460       unsigned zreg =
4461           isFPR32Register(RegOp->getReg()) ? ARM64::WZR : ARM64::XZR;
4462       Operands[2] = ARM64Operand::CreateReg(zreg, false, Op->getStartLoc(),
4463                                             Op->getEndLoc(), getContext());
4464       delete ImmOp;
4465     }
4466   }
4467
4468   // FIXME: Horrible hack to handle the literal .d[1] vector index on
4469   // FMOV instructions. The index isn't an actual instruction operand
4470   // but rather syntactic sugar. It really should be part of the mnemonic,
4471   // not the operand, but whatever.
4472   if ((NumOperands == 5) && Tok == "fmov") {
4473     // If the last operand is a vectorindex of '1', then replace it with
4474     // a '[' '1' ']' token sequence, which is what the matcher
4475     // (annoyingly) expects for a literal vector index operand.
4476     ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[NumOperands - 1]);
4477     if (Op->isVectorIndexD() && Op->getVectorIndex() == 1) {
4478       SMLoc Loc = Op->getStartLoc();
4479       Operands.pop_back();
4480       Operands.push_back(
4481           ARM64Operand::CreateToken("[", false, Loc, getContext()));
4482       Operands.push_back(
4483           ARM64Operand::CreateToken("1", false, Loc, getContext()));
4484       Operands.push_back(
4485           ARM64Operand::CreateToken("]", false, Loc, getContext()));
4486     } else if (Op->isReg()) {
4487       // Similarly, check the destination operand for the GPR->High-lane
4488       // variant.
4489       unsigned OpNo = NumOperands - 2;
4490       ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[OpNo]);
4491       if (Op->isVectorIndexD() && Op->getVectorIndex() == 1) {
4492         SMLoc Loc = Op->getStartLoc();
4493         Operands[OpNo] =
4494             ARM64Operand::CreateToken("[", false, Loc, getContext());
4495         Operands.insert(
4496             Operands.begin() + OpNo + 1,
4497             ARM64Operand::CreateToken("1", false, Loc, getContext()));
4498         Operands.insert(
4499             Operands.begin() + OpNo + 2,
4500             ARM64Operand::CreateToken("]", false, Loc, getContext()));
4501       }
4502     }
4503   }
4504
4505   MCInst Inst;
4506   // First try to match against the secondary set of tables containing the
4507   // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
4508   unsigned MatchResult =
4509       MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1);
4510
4511   // If that fails, try against the alternate table containing long-form NEON:
4512   // "fadd v0.2s, v1.2s, v2.2s"
4513   if (MatchResult != Match_Success)
4514     MatchResult =
4515         MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0);
4516
4517   switch (MatchResult) {
4518   case Match_Success: {
4519     // Perform range checking and other semantic validations
4520     SmallVector<SMLoc, 8> OperandLocs;
4521     NumOperands = Operands.size();
4522     for (unsigned i = 1; i < NumOperands; ++i)
4523       OperandLocs.push_back(Operands[i]->getStartLoc());
4524     if (validateInstruction(Inst, OperandLocs))
4525       return true;
4526
4527     Inst.setLoc(IDLoc);
4528     Out.EmitInstruction(Inst, STI);
4529     return false;
4530   }
4531   case Match_MissingFeature:
4532   case Match_MnemonicFail:
4533     return showMatchError(IDLoc, MatchResult);
4534   case Match_InvalidOperand: {
4535     SMLoc ErrorLoc = IDLoc;
4536     if (ErrorInfo != ~0U) {
4537       if (ErrorInfo >= Operands.size())
4538         return Error(IDLoc, "too few operands for instruction");
4539
4540       ErrorLoc = ((ARM64Operand *)Operands[ErrorInfo])->getStartLoc();
4541       if (ErrorLoc == SMLoc())
4542         ErrorLoc = IDLoc;
4543     }
4544     // If the match failed on a suffix token operand, tweak the diagnostic
4545     // accordingly.
4546     if (((ARM64Operand *)Operands[ErrorInfo])->isToken() &&
4547         ((ARM64Operand *)Operands[ErrorInfo])->isTokenSuffix())
4548       MatchResult = Match_InvalidSuffix;
4549
4550     return showMatchError(ErrorLoc, MatchResult);
4551   }
4552   case Match_InvalidMemoryIndexedSImm9: {
4553     // If there is not a '!' after the memory operand that failed, we really
4554     // want the diagnostic for the non-pre-indexed instruction variant instead.
4555     // Be careful to check for the post-indexed variant as well, which also
4556     // uses this match diagnostic. Also exclude the explicitly unscaled
4557     // mnemonics, as they want the unscaled diagnostic as well.
4558     if (Operands.size() == ErrorInfo + 1 &&
4559         !((ARM64Operand *)Operands[ErrorInfo])->isImm() &&
4560         !Tok.startswith("stur") && !Tok.startswith("ldur")) {
4561       // whether we want an Indexed64 or Indexed32 diagnostic depends on
4562       // the register class of the previous operand. Default to 64 in case
4563       // we see something unexpected.
4564       MatchResult = Match_InvalidMemoryIndexed64;
4565       if (ErrorInfo) {
4566         ARM64Operand *PrevOp = (ARM64Operand *)Operands[ErrorInfo - 1];
4567         if (PrevOp->isReg() && ARM64MCRegisterClasses[ARM64::GPR32RegClassID]
4568                                    .contains(PrevOp->getReg()))
4569           MatchResult = Match_InvalidMemoryIndexed32;
4570       }
4571     }
4572     SMLoc ErrorLoc = ((ARM64Operand *)Operands[ErrorInfo])->getStartLoc();
4573     if (ErrorLoc == SMLoc())
4574       ErrorLoc = IDLoc;
4575     return showMatchError(ErrorLoc, MatchResult);
4576   }
4577   case Match_InvalidMemoryIndexed32:
4578   case Match_InvalidMemoryIndexed64:
4579   case Match_InvalidMemoryIndexed128:
4580     // If there is a '!' after the memory operand that failed, we really
4581     // want the diagnostic for the pre-indexed instruction variant instead.
4582     if (Operands.size() > ErrorInfo + 1 &&
4583         ((ARM64Operand *)Operands[ErrorInfo + 1])->isTokenEqual("!"))
4584       MatchResult = Match_InvalidMemoryIndexedSImm9;
4585   // FALL THROUGH
4586   case Match_InvalidMemoryIndexed8:
4587   case Match_InvalidMemoryIndexed16:
4588   case Match_InvalidMemoryIndexed32SImm7:
4589   case Match_InvalidMemoryIndexed64SImm7:
4590   case Match_InvalidMemoryIndexed128SImm7:
4591   case Match_InvalidImm1_8:
4592   case Match_InvalidImm1_16:
4593   case Match_InvalidImm1_32:
4594   case Match_InvalidImm1_64: {
4595     // Any time we get here, there's nothing fancy to do. Just get the
4596     // operand SMLoc and display the diagnostic.
4597     SMLoc ErrorLoc = ((ARM64Operand *)Operands[ErrorInfo])->getStartLoc();
4598     // If it's a memory operand, the error is with the offset immediate,
4599     // so get that location instead.
4600     if (((ARM64Operand *)Operands[ErrorInfo])->isMem())
4601       ErrorLoc = ((ARM64Operand *)Operands[ErrorInfo])->getOffsetLoc();
4602     if (ErrorLoc == SMLoc())
4603       ErrorLoc = IDLoc;
4604     return showMatchError(ErrorLoc, MatchResult);
4605   }
4606   }
4607
4608   llvm_unreachable("Implement any new match types added!");
4609   return true;
4610 }
4611
4612 /// ParseDirective parses the arm specific directives
4613 bool ARM64AsmParser::ParseDirective(AsmToken DirectiveID) {
4614   StringRef IDVal = DirectiveID.getIdentifier();
4615   SMLoc Loc = DirectiveID.getLoc();
4616   if (IDVal == ".hword")
4617     return parseDirectiveWord(2, Loc);
4618   if (IDVal == ".word")
4619     return parseDirectiveWord(4, Loc);
4620   if (IDVal == ".xword")
4621     return parseDirectiveWord(8, Loc);
4622   if (IDVal == ".tlsdesccall")
4623     return parseDirectiveTLSDescCall(Loc);
4624
4625   return parseDirectiveLOH(IDVal, Loc);
4626 }
4627
4628 /// parseDirectiveWord
4629 ///  ::= .word [ expression (, expression)* ]
4630 bool ARM64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
4631   if (getLexer().isNot(AsmToken::EndOfStatement)) {
4632     for (;;) {
4633       const MCExpr *Value;
4634       if (getParser().parseExpression(Value))
4635         return true;
4636
4637       getParser().getStreamer().EmitValue(Value, Size);
4638
4639       if (getLexer().is(AsmToken::EndOfStatement))
4640         break;
4641
4642       // FIXME: Improve diagnostic.
4643       if (getLexer().isNot(AsmToken::Comma))
4644         return Error(L, "unexpected token in directive");
4645       Parser.Lex();
4646     }
4647   }
4648
4649   Parser.Lex();
4650   return false;
4651 }
4652
4653 // parseDirectiveTLSDescCall:
4654 //   ::= .tlsdesccall symbol
4655 bool ARM64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
4656   StringRef Name;
4657   if (getParser().parseIdentifier(Name))
4658     return Error(L, "expected symbol after directive");
4659
4660   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
4661   const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, getContext());
4662   Expr = ARM64MCExpr::Create(Expr, ARM64MCExpr::VK_TLSDESC, getContext());
4663
4664   MCInst Inst;
4665   Inst.setOpcode(ARM64::TLSDESCCALL);
4666   Inst.addOperand(MCOperand::CreateExpr(Expr));
4667
4668   getParser().getStreamer().EmitInstruction(Inst, STI);
4669   return false;
4670 }
4671
4672 /// ::= .loh <lohName | lohId> label1, ..., labelN
4673 /// The number of arguments depends on the loh identifier.
4674 bool ARM64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
4675   if (IDVal != MCLOHDirectiveName())
4676     return true;
4677   MCLOHType Kind;
4678   if (getParser().getTok().isNot(AsmToken::Identifier)) {
4679     if (getParser().getTok().isNot(AsmToken::Integer))
4680       return TokError("expected an identifier or a number in directive");
4681     // We successfully get a numeric value for the identifier.
4682     // Check if it is valid.
4683     int64_t Id = getParser().getTok().getIntVal();
4684     Kind = (MCLOHType)Id;
4685     // Check that Id does not overflow MCLOHType.
4686     if (!isValidMCLOHType(Kind) || Id != Kind)
4687       return TokError("invalid numeric identifier in directive");
4688   } else {
4689     StringRef Name = getTok().getIdentifier();
4690     // We successfully parse an identifier.
4691     // Check if it is a recognized one.
4692     int Id = MCLOHNameToId(Name);
4693
4694     if (Id == -1)
4695       return TokError("invalid identifier in directive");
4696     Kind = (MCLOHType)Id;
4697   }
4698   // Consume the identifier.
4699   Lex();
4700   // Get the number of arguments of this LOH.
4701   int NbArgs = MCLOHIdToNbArgs(Kind);
4702
4703   assert(NbArgs != -1 && "Invalid number of arguments");
4704
4705   SmallVector<MCSymbol *, 3> Args;
4706   for (int Idx = 0; Idx < NbArgs; ++Idx) {
4707     StringRef Name;
4708     if (getParser().parseIdentifier(Name))
4709       return TokError("expected identifier in directive");
4710     Args.push_back(getContext().GetOrCreateSymbol(Name));
4711
4712     if (Idx + 1 == NbArgs)
4713       break;
4714     if (getLexer().isNot(AsmToken::Comma))
4715       return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
4716     Lex();
4717   }
4718   if (getLexer().isNot(AsmToken::EndOfStatement))
4719     return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
4720
4721   getStreamer().EmitLOHDirective((MCLOHType)Kind, Args);
4722   return false;
4723 }
4724
4725 bool
4726 ARM64AsmParser::classifySymbolRef(const MCExpr *Expr,
4727                                   ARM64MCExpr::VariantKind &ELFRefKind,
4728                                   MCSymbolRefExpr::VariantKind &DarwinRefKind,
4729                                   const MCConstantExpr *&Addend) {
4730   ELFRefKind = ARM64MCExpr::VK_INVALID;
4731   DarwinRefKind = MCSymbolRefExpr::VK_None;
4732
4733   if (const ARM64MCExpr *AE = dyn_cast<ARM64MCExpr>(Expr)) {
4734     ELFRefKind = AE->getKind();
4735     Expr = AE->getSubExpr();
4736   }
4737
4738   const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr);
4739   if (SE) {
4740     // It's a simple symbol reference with no addend.
4741     DarwinRefKind = SE->getKind();
4742     Addend = 0;
4743     return true;
4744   }
4745
4746   const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
4747   if (!BE)
4748     return false;
4749
4750   SE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
4751   if (!SE)
4752     return false;
4753   DarwinRefKind = SE->getKind();
4754
4755   if (BE->getOpcode() != MCBinaryExpr::Add)
4756     return false;
4757
4758   // See if the addend is is a constant, otherwise there's more going
4759   // on here than we can deal with.
4760   Addend = dyn_cast<MCConstantExpr>(BE->getRHS());
4761   if (!Addend)
4762     return false;
4763
4764   // It's some symbol reference + a constant addend, but really
4765   // shouldn't use both Darwin and ELF syntax.
4766   return ELFRefKind == ARM64MCExpr::VK_INVALID ||
4767          DarwinRefKind == MCSymbolRefExpr::VK_None;
4768 }
4769
4770 /// Force static initialization.
4771 extern "C" void LLVMInitializeARM64AsmParser() {
4772   RegisterMCAsmParser<ARM64AsmParser> X(TheARM64Target);
4773 }
4774
4775 #define GET_REGISTER_MATCHER
4776 #define GET_MATCHER_IMPLEMENTATION
4777 #include "ARM64GenAsmMatcher.inc"
4778
4779 // Define this matcher function after the auto-generated include so we
4780 // have the match class enum definitions.
4781 unsigned ARM64AsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp,
4782                                                     unsigned Kind) {
4783   ARM64Operand *Op = static_cast<ARM64Operand *>(AsmOp);
4784   // If the kind is a token for a literal immediate, check if our asm
4785   // operand matches. This is for InstAliases which have a fixed-value
4786   // immediate in the syntax.
4787   int64_t ExpectedVal;
4788   switch (Kind) {
4789   default:
4790     return Match_InvalidOperand;
4791   case MCK__35_0:
4792     ExpectedVal = 0;
4793     break;
4794   case MCK__35_1:
4795     ExpectedVal = 1;
4796     break;
4797   case MCK__35_12:
4798     ExpectedVal = 12;
4799     break;
4800   case MCK__35_16:
4801     ExpectedVal = 16;
4802     break;
4803   case MCK__35_2:
4804     ExpectedVal = 2;
4805     break;
4806   case MCK__35_24:
4807     ExpectedVal = 24;
4808     break;
4809   case MCK__35_3:
4810     ExpectedVal = 3;
4811     break;
4812   case MCK__35_32:
4813     ExpectedVal = 32;
4814     break;
4815   case MCK__35_4:
4816     ExpectedVal = 4;
4817     break;
4818   case MCK__35_48:
4819     ExpectedVal = 48;
4820     break;
4821   case MCK__35_6:
4822     ExpectedVal = 6;
4823     break;
4824   case MCK__35_64:
4825     ExpectedVal = 64;
4826     break;
4827   case MCK__35_8:
4828     ExpectedVal = 8;
4829     break;
4830   }
4831   if (!Op->isImm())
4832     return Match_InvalidOperand;
4833   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
4834   if (!CE)
4835     return Match_InvalidOperand;
4836   if (CE->getValue() == ExpectedVal)
4837     return Match_Success;
4838   return Match_InvalidOperand;
4839 }