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