blob: 5eec0cde1180c668ee27b2b60ee4cea59bbbe0f5 [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());
2093 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
2094 // If we had a '-' in front, toggle the sign bit.
2095 IntVal ^= (uint64_t)isNegative << 63;
2096 int Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
2097 Parser.Lex(); // Eat the token.
2098 // Check for out of range values. As an exception, we let Zero through,
2099 // as we handle that special case in post-processing before matching in
2100 // order to use the zero register for it.
2101 if (Val == -1 && !RealVal.isZero()) {
2102 TokError("expected compatible register or floating-point constant");
2103 return MatchOperand_ParseFail;
2104 }
2105 Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
2106 return MatchOperand_Success;
2107 }
2108 if (Tok.is(AsmToken::Integer)) {
2109 int64_t Val;
2110 if (!isNegative && Tok.getString().startswith("0x")) {
2111 Val = Tok.getIntVal();
2112 if (Val > 255 || Val < 0) {
2113 TokError("encoded floating point value out of range");
2114 return MatchOperand_ParseFail;
2115 }
2116 } else {
2117 APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
2118 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
2119 // If we had a '-' in front, toggle the sign bit.
2120 IntVal ^= (uint64_t)isNegative << 63;
2121 Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
2122 }
2123 Parser.Lex(); // Eat the token.
2124 Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
2125 return MatchOperand_Success;
2126 }
2127
2128 if (!Hash)
2129 return MatchOperand_NoMatch;
2130
2131 TokError("invalid floating point immediate");
2132 return MatchOperand_ParseFail;
2133}
2134
2135/// tryParseAddSubImm - Parse ADD/SUB shifted immediate operand
2136AArch64AsmParser::OperandMatchResultTy
2137AArch64AsmParser::tryParseAddSubImm(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002138 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002139 SMLoc S = getLoc();
2140
2141 if (Parser.getTok().is(AsmToken::Hash))
2142 Parser.Lex(); // Eat '#'
2143 else if (Parser.getTok().isNot(AsmToken::Integer))
2144 // Operand should start from # or should be integer, emit error otherwise.
2145 return MatchOperand_NoMatch;
2146
2147 const MCExpr *Imm;
2148 if (parseSymbolicImmVal(Imm))
2149 return MatchOperand_ParseFail;
2150 else if (Parser.getTok().isNot(AsmToken::Comma)) {
2151 uint64_t ShiftAmount = 0;
2152 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm);
2153 if (MCE) {
2154 int64_t Val = MCE->getValue();
2155 if (Val > 0xfff && (Val & 0xfff) == 0) {
2156 Imm = MCConstantExpr::Create(Val >> 12, getContext());
2157 ShiftAmount = 12;
2158 }
2159 }
2160 SMLoc E = Parser.getTok().getLoc();
2161 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S, E,
2162 getContext()));
2163 return MatchOperand_Success;
2164 }
2165
2166 // Eat ','
2167 Parser.Lex();
2168
2169 // The optional operand must be "lsl #N" where N is non-negative.
2170 if (!Parser.getTok().is(AsmToken::Identifier) ||
2171 !Parser.getTok().getIdentifier().equals_lower("lsl")) {
2172 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
2173 return MatchOperand_ParseFail;
2174 }
2175
2176 // Eat 'lsl'
2177 Parser.Lex();
2178
2179 if (Parser.getTok().is(AsmToken::Hash)) {
2180 Parser.Lex();
2181 }
2182
2183 if (Parser.getTok().isNot(AsmToken::Integer)) {
2184 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
2185 return MatchOperand_ParseFail;
2186 }
2187
2188 int64_t ShiftAmount = Parser.getTok().getIntVal();
2189
2190 if (ShiftAmount < 0) {
2191 Error(Parser.getTok().getLoc(), "positive shift amount required");
2192 return MatchOperand_ParseFail;
2193 }
2194 Parser.Lex(); // Eat the number
2195
2196 SMLoc E = Parser.getTok().getLoc();
2197 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount,
2198 S, E, getContext()));
2199 return MatchOperand_Success;
2200}
2201
2202/// parseCondCodeString - Parse a Condition Code string.
2203AArch64CC::CondCode AArch64AsmParser::parseCondCodeString(StringRef Cond) {
2204 AArch64CC::CondCode CC = StringSwitch<AArch64CC::CondCode>(Cond.lower())
2205 .Case("eq", AArch64CC::EQ)
2206 .Case("ne", AArch64CC::NE)
2207 .Case("cs", AArch64CC::HS)
2208 .Case("hs", AArch64CC::HS)
2209 .Case("cc", AArch64CC::LO)
2210 .Case("lo", AArch64CC::LO)
2211 .Case("mi", AArch64CC::MI)
2212 .Case("pl", AArch64CC::PL)
2213 .Case("vs", AArch64CC::VS)
2214 .Case("vc", AArch64CC::VC)
2215 .Case("hi", AArch64CC::HI)
2216 .Case("ls", AArch64CC::LS)
2217 .Case("ge", AArch64CC::GE)
2218 .Case("lt", AArch64CC::LT)
2219 .Case("gt", AArch64CC::GT)
2220 .Case("le", AArch64CC::LE)
2221 .Case("al", AArch64CC::AL)
2222 .Case("nv", AArch64CC::NV)
2223 .Default(AArch64CC::Invalid);
2224 return CC;
2225}
2226
2227/// parseCondCode - Parse a Condition Code operand.
2228bool AArch64AsmParser::parseCondCode(OperandVector &Operands,
2229 bool invertCondCode) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002230 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002231 SMLoc S = getLoc();
2232 const AsmToken &Tok = Parser.getTok();
2233 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2234
2235 StringRef Cond = Tok.getString();
2236 AArch64CC::CondCode CC = parseCondCodeString(Cond);
2237 if (CC == AArch64CC::Invalid)
2238 return TokError("invalid condition code");
2239 Parser.Lex(); // Eat identifier token.
2240
Artyom Skrobov6c8682e2014-06-10 13:11:35 +00002241 if (invertCondCode) {
2242 if (CC == AArch64CC::AL || CC == AArch64CC::NV)
2243 return TokError("condition codes AL and NV are invalid for this instruction");
Tim Northover3b0846e2014-05-24 12:50:23 +00002244 CC = AArch64CC::getInvertedCondCode(AArch64CC::CondCode(CC));
Artyom Skrobov6c8682e2014-06-10 13:11:35 +00002245 }
Tim Northover3b0846e2014-05-24 12:50:23 +00002246
2247 Operands.push_back(
2248 AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext()));
2249 return false;
2250}
2251
2252/// tryParseOptionalShift - Some operands take an optional shift argument. Parse
2253/// them if present.
2254AArch64AsmParser::OperandMatchResultTy
2255AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002256 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002257 const AsmToken &Tok = Parser.getTok();
2258 std::string LowerID = Tok.getString().lower();
2259 AArch64_AM::ShiftExtendType ShOp =
2260 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
2261 .Case("lsl", AArch64_AM::LSL)
2262 .Case("lsr", AArch64_AM::LSR)
2263 .Case("asr", AArch64_AM::ASR)
2264 .Case("ror", AArch64_AM::ROR)
2265 .Case("msl", AArch64_AM::MSL)
2266 .Case("uxtb", AArch64_AM::UXTB)
2267 .Case("uxth", AArch64_AM::UXTH)
2268 .Case("uxtw", AArch64_AM::UXTW)
2269 .Case("uxtx", AArch64_AM::UXTX)
2270 .Case("sxtb", AArch64_AM::SXTB)
2271 .Case("sxth", AArch64_AM::SXTH)
2272 .Case("sxtw", AArch64_AM::SXTW)
2273 .Case("sxtx", AArch64_AM::SXTX)
2274 .Default(AArch64_AM::InvalidShiftExtend);
2275
2276 if (ShOp == AArch64_AM::InvalidShiftExtend)
2277 return MatchOperand_NoMatch;
2278
2279 SMLoc S = Tok.getLoc();
2280 Parser.Lex();
2281
2282 bool Hash = getLexer().is(AsmToken::Hash);
2283 if (!Hash && getLexer().isNot(AsmToken::Integer)) {
2284 if (ShOp == AArch64_AM::LSL || ShOp == AArch64_AM::LSR ||
2285 ShOp == AArch64_AM::ASR || ShOp == AArch64_AM::ROR ||
2286 ShOp == AArch64_AM::MSL) {
2287 // We expect a number here.
2288 TokError("expected #imm after shift specifier");
2289 return MatchOperand_ParseFail;
2290 }
2291
2292 // "extend" type operatoins don't need an immediate, #0 is implicit.
2293 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2294 Operands.push_back(
2295 AArch64Operand::CreateShiftExtend(ShOp, 0, false, S, E, getContext()));
2296 return MatchOperand_Success;
2297 }
2298
2299 if (Hash)
2300 Parser.Lex(); // Eat the '#'.
2301
Jim Grosbach57fd2622014-09-23 22:16:02 +00002302 // Make sure we do actually have a number or a parenthesized expression.
2303 SMLoc E = Parser.getTok().getLoc();
2304 if (!Parser.getTok().is(AsmToken::Integer) &&
2305 !Parser.getTok().is(AsmToken::LParen)) {
2306 Error(E, "expected integer shift amount");
Tim Northover3b0846e2014-05-24 12:50:23 +00002307 return MatchOperand_ParseFail;
2308 }
2309
2310 const MCExpr *ImmVal;
2311 if (getParser().parseExpression(ImmVal))
2312 return MatchOperand_ParseFail;
2313
2314 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2315 if (!MCE) {
Jim Grosbach57fd2622014-09-23 22:16:02 +00002316 Error(E, "expected constant '#imm' after shift specifier");
Tim Northover3b0846e2014-05-24 12:50:23 +00002317 return MatchOperand_ParseFail;
2318 }
2319
Jim Grosbach57fd2622014-09-23 22:16:02 +00002320 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
Tim Northover3b0846e2014-05-24 12:50:23 +00002321 Operands.push_back(AArch64Operand::CreateShiftExtend(
2322 ShOp, MCE->getValue(), true, S, E, getContext()));
2323 return MatchOperand_Success;
2324}
2325
2326/// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for
2327/// the SYS instruction. Parse them specially so that we create a SYS MCInst.
2328bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
2329 OperandVector &Operands) {
2330 if (Name.find('.') != StringRef::npos)
2331 return TokError("invalid operand");
2332
2333 Mnemonic = Name;
2334 Operands.push_back(
2335 AArch64Operand::CreateToken("sys", false, NameLoc, getContext()));
2336
Rafael Espindola961d4692014-11-11 05:18:41 +00002337 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002338 const AsmToken &Tok = Parser.getTok();
2339 StringRef Op = Tok.getString();
2340 SMLoc S = Tok.getLoc();
2341
2342 const MCExpr *Expr = nullptr;
2343
2344#define SYS_ALIAS(op1, Cn, Cm, op2) \
2345 do { \
2346 Expr = MCConstantExpr::Create(op1, getContext()); \
2347 Operands.push_back( \
2348 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); \
2349 Operands.push_back( \
2350 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext())); \
2351 Operands.push_back( \
2352 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext())); \
2353 Expr = MCConstantExpr::Create(op2, getContext()); \
2354 Operands.push_back( \
2355 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); \
2356 } while (0)
2357
2358 if (Mnemonic == "ic") {
2359 if (!Op.compare_lower("ialluis")) {
2360 // SYS #0, C7, C1, #0
2361 SYS_ALIAS(0, 7, 1, 0);
2362 } else if (!Op.compare_lower("iallu")) {
2363 // SYS #0, C7, C5, #0
2364 SYS_ALIAS(0, 7, 5, 0);
2365 } else if (!Op.compare_lower("ivau")) {
2366 // SYS #3, C7, C5, #1
2367 SYS_ALIAS(3, 7, 5, 1);
2368 } else {
2369 return TokError("invalid operand for IC instruction");
2370 }
2371 } else if (Mnemonic == "dc") {
2372 if (!Op.compare_lower("zva")) {
2373 // SYS #3, C7, C4, #1
2374 SYS_ALIAS(3, 7, 4, 1);
2375 } else if (!Op.compare_lower("ivac")) {
2376 // SYS #3, C7, C6, #1
2377 SYS_ALIAS(0, 7, 6, 1);
2378 } else if (!Op.compare_lower("isw")) {
2379 // SYS #0, C7, C6, #2
2380 SYS_ALIAS(0, 7, 6, 2);
2381 } else if (!Op.compare_lower("cvac")) {
2382 // SYS #3, C7, C10, #1
2383 SYS_ALIAS(3, 7, 10, 1);
2384 } else if (!Op.compare_lower("csw")) {
2385 // SYS #0, C7, C10, #2
2386 SYS_ALIAS(0, 7, 10, 2);
2387 } else if (!Op.compare_lower("cvau")) {
2388 // SYS #3, C7, C11, #1
2389 SYS_ALIAS(3, 7, 11, 1);
2390 } else if (!Op.compare_lower("civac")) {
2391 // SYS #3, C7, C14, #1
2392 SYS_ALIAS(3, 7, 14, 1);
2393 } else if (!Op.compare_lower("cisw")) {
2394 // SYS #0, C7, C14, #2
2395 SYS_ALIAS(0, 7, 14, 2);
2396 } else {
2397 return TokError("invalid operand for DC instruction");
2398 }
2399 } else if (Mnemonic == "at") {
2400 if (!Op.compare_lower("s1e1r")) {
2401 // SYS #0, C7, C8, #0
2402 SYS_ALIAS(0, 7, 8, 0);
2403 } else if (!Op.compare_lower("s1e2r")) {
2404 // SYS #4, C7, C8, #0
2405 SYS_ALIAS(4, 7, 8, 0);
2406 } else if (!Op.compare_lower("s1e3r")) {
2407 // SYS #6, C7, C8, #0
2408 SYS_ALIAS(6, 7, 8, 0);
2409 } else if (!Op.compare_lower("s1e1w")) {
2410 // SYS #0, C7, C8, #1
2411 SYS_ALIAS(0, 7, 8, 1);
2412 } else if (!Op.compare_lower("s1e2w")) {
2413 // SYS #4, C7, C8, #1
2414 SYS_ALIAS(4, 7, 8, 1);
2415 } else if (!Op.compare_lower("s1e3w")) {
2416 // SYS #6, C7, C8, #1
2417 SYS_ALIAS(6, 7, 8, 1);
2418 } else if (!Op.compare_lower("s1e0r")) {
2419 // SYS #0, C7, C8, #3
2420 SYS_ALIAS(0, 7, 8, 2);
2421 } else if (!Op.compare_lower("s1e0w")) {
2422 // SYS #0, C7, C8, #3
2423 SYS_ALIAS(0, 7, 8, 3);
2424 } else if (!Op.compare_lower("s12e1r")) {
2425 // SYS #4, C7, C8, #4
2426 SYS_ALIAS(4, 7, 8, 4);
2427 } else if (!Op.compare_lower("s12e1w")) {
2428 // SYS #4, C7, C8, #5
2429 SYS_ALIAS(4, 7, 8, 5);
2430 } else if (!Op.compare_lower("s12e0r")) {
2431 // SYS #4, C7, C8, #6
2432 SYS_ALIAS(4, 7, 8, 6);
2433 } else if (!Op.compare_lower("s12e0w")) {
2434 // SYS #4, C7, C8, #7
2435 SYS_ALIAS(4, 7, 8, 7);
2436 } else {
2437 return TokError("invalid operand for AT instruction");
2438 }
2439 } else if (Mnemonic == "tlbi") {
2440 if (!Op.compare_lower("vmalle1is")) {
2441 // SYS #0, C8, C3, #0
2442 SYS_ALIAS(0, 8, 3, 0);
2443 } else if (!Op.compare_lower("alle2is")) {
2444 // SYS #4, C8, C3, #0
2445 SYS_ALIAS(4, 8, 3, 0);
2446 } else if (!Op.compare_lower("alle3is")) {
2447 // SYS #6, C8, C3, #0
2448 SYS_ALIAS(6, 8, 3, 0);
2449 } else if (!Op.compare_lower("vae1is")) {
2450 // SYS #0, C8, C3, #1
2451 SYS_ALIAS(0, 8, 3, 1);
2452 } else if (!Op.compare_lower("vae2is")) {
2453 // SYS #4, C8, C3, #1
2454 SYS_ALIAS(4, 8, 3, 1);
2455 } else if (!Op.compare_lower("vae3is")) {
2456 // SYS #6, C8, C3, #1
2457 SYS_ALIAS(6, 8, 3, 1);
2458 } else if (!Op.compare_lower("aside1is")) {
2459 // SYS #0, C8, C3, #2
2460 SYS_ALIAS(0, 8, 3, 2);
2461 } else if (!Op.compare_lower("vaae1is")) {
2462 // SYS #0, C8, C3, #3
2463 SYS_ALIAS(0, 8, 3, 3);
2464 } else if (!Op.compare_lower("alle1is")) {
2465 // SYS #4, C8, C3, #4
2466 SYS_ALIAS(4, 8, 3, 4);
2467 } else if (!Op.compare_lower("vale1is")) {
2468 // SYS #0, C8, C3, #5
2469 SYS_ALIAS(0, 8, 3, 5);
2470 } else if (!Op.compare_lower("vaale1is")) {
2471 // SYS #0, C8, C3, #7
2472 SYS_ALIAS(0, 8, 3, 7);
2473 } else if (!Op.compare_lower("vmalle1")) {
2474 // SYS #0, C8, C7, #0
2475 SYS_ALIAS(0, 8, 7, 0);
2476 } else if (!Op.compare_lower("alle2")) {
2477 // SYS #4, C8, C7, #0
2478 SYS_ALIAS(4, 8, 7, 0);
2479 } else if (!Op.compare_lower("vale2is")) {
2480 // SYS #4, C8, C3, #5
2481 SYS_ALIAS(4, 8, 3, 5);
2482 } else if (!Op.compare_lower("vale3is")) {
2483 // SYS #6, C8, C3, #5
2484 SYS_ALIAS(6, 8, 3, 5);
2485 } else if (!Op.compare_lower("alle3")) {
2486 // SYS #6, C8, C7, #0
2487 SYS_ALIAS(6, 8, 7, 0);
2488 } else if (!Op.compare_lower("vae1")) {
2489 // SYS #0, C8, C7, #1
2490 SYS_ALIAS(0, 8, 7, 1);
2491 } else if (!Op.compare_lower("vae2")) {
2492 // SYS #4, C8, C7, #1
2493 SYS_ALIAS(4, 8, 7, 1);
2494 } else if (!Op.compare_lower("vae3")) {
2495 // SYS #6, C8, C7, #1
2496 SYS_ALIAS(6, 8, 7, 1);
2497 } else if (!Op.compare_lower("aside1")) {
2498 // SYS #0, C8, C7, #2
2499 SYS_ALIAS(0, 8, 7, 2);
2500 } else if (!Op.compare_lower("vaae1")) {
2501 // SYS #0, C8, C7, #3
2502 SYS_ALIAS(0, 8, 7, 3);
2503 } else if (!Op.compare_lower("alle1")) {
2504 // SYS #4, C8, C7, #4
2505 SYS_ALIAS(4, 8, 7, 4);
2506 } else if (!Op.compare_lower("vale1")) {
2507 // SYS #0, C8, C7, #5
2508 SYS_ALIAS(0, 8, 7, 5);
2509 } else if (!Op.compare_lower("vale2")) {
2510 // SYS #4, C8, C7, #5
2511 SYS_ALIAS(4, 8, 7, 5);
2512 } else if (!Op.compare_lower("vale3")) {
2513 // SYS #6, C8, C7, #5
2514 SYS_ALIAS(6, 8, 7, 5);
2515 } else if (!Op.compare_lower("vaale1")) {
2516 // SYS #0, C8, C7, #7
2517 SYS_ALIAS(0, 8, 7, 7);
2518 } else if (!Op.compare_lower("ipas2e1")) {
2519 // SYS #4, C8, C4, #1
2520 SYS_ALIAS(4, 8, 4, 1);
2521 } else if (!Op.compare_lower("ipas2le1")) {
2522 // SYS #4, C8, C4, #5
2523 SYS_ALIAS(4, 8, 4, 5);
2524 } else if (!Op.compare_lower("ipas2e1is")) {
2525 // SYS #4, C8, C4, #1
2526 SYS_ALIAS(4, 8, 0, 1);
2527 } else if (!Op.compare_lower("ipas2le1is")) {
2528 // SYS #4, C8, C4, #5
2529 SYS_ALIAS(4, 8, 0, 5);
2530 } else if (!Op.compare_lower("vmalls12e1")) {
2531 // SYS #4, C8, C7, #6
2532 SYS_ALIAS(4, 8, 7, 6);
2533 } else if (!Op.compare_lower("vmalls12e1is")) {
2534 // SYS #4, C8, C3, #6
2535 SYS_ALIAS(4, 8, 3, 6);
2536 } else {
2537 return TokError("invalid operand for TLBI instruction");
2538 }
2539 }
2540
2541#undef SYS_ALIAS
2542
2543 Parser.Lex(); // Eat operand.
2544
2545 bool ExpectRegister = (Op.lower().find("all") == StringRef::npos);
2546 bool HasRegister = false;
2547
2548 // Check for the optional register operand.
2549 if (getLexer().is(AsmToken::Comma)) {
2550 Parser.Lex(); // Eat comma.
2551
2552 if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands))
2553 return TokError("expected register operand");
2554
2555 HasRegister = true;
2556 }
2557
2558 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2559 Parser.eatToEndOfStatement();
2560 return TokError("unexpected token in argument list");
2561 }
2562
2563 if (ExpectRegister && !HasRegister) {
2564 return TokError("specified " + Mnemonic + " op requires a register");
2565 }
2566 else if (!ExpectRegister && HasRegister) {
2567 return TokError("specified " + Mnemonic + " op does not use a register");
2568 }
2569
2570 Parser.Lex(); // Consume the EndOfStatement
2571 return false;
2572}
2573
2574AArch64AsmParser::OperandMatchResultTy
2575AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002576 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002577 const AsmToken &Tok = Parser.getTok();
2578
2579 // Can be either a #imm style literal or an option name
2580 bool Hash = Tok.is(AsmToken::Hash);
2581 if (Hash || Tok.is(AsmToken::Integer)) {
2582 // Immediate operand.
2583 if (Hash)
2584 Parser.Lex(); // Eat the '#'
2585 const MCExpr *ImmVal;
2586 SMLoc ExprLoc = getLoc();
2587 if (getParser().parseExpression(ImmVal))
2588 return MatchOperand_ParseFail;
2589 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2590 if (!MCE) {
2591 Error(ExprLoc, "immediate value expected for barrier operand");
2592 return MatchOperand_ParseFail;
2593 }
2594 if (MCE->getValue() < 0 || MCE->getValue() > 15) {
2595 Error(ExprLoc, "barrier operand out of range");
2596 return MatchOperand_ParseFail;
2597 }
Vladimir Sukharev017d10b2015-03-26 17:29:53 +00002598 bool Valid;
2599 auto Mapper = AArch64DB::DBarrierMapper();
2600 StringRef Name = Mapper.toString(MCE->getValue(), Valid);
2601 Operands.push_back( AArch64Operand::CreateBarrier(MCE->getValue(), Name,
2602 ExprLoc, getContext()));
Tim Northover3b0846e2014-05-24 12:50:23 +00002603 return MatchOperand_Success;
2604 }
2605
2606 if (Tok.isNot(AsmToken::Identifier)) {
2607 TokError("invalid operand for instruction");
2608 return MatchOperand_ParseFail;
2609 }
2610
2611 bool Valid;
Vladimir Sukharev017d10b2015-03-26 17:29:53 +00002612 auto Mapper = AArch64DB::DBarrierMapper();
2613 unsigned Opt = Mapper.fromString(Tok.getString(), Valid);
Tim Northover3b0846e2014-05-24 12:50:23 +00002614 if (!Valid) {
2615 TokError("invalid barrier option name");
2616 return MatchOperand_ParseFail;
2617 }
2618
2619 // The only valid named option for ISB is 'sy'
2620 if (Mnemonic == "isb" && Opt != AArch64DB::SY) {
2621 TokError("'sy' or #imm operand expected");
2622 return MatchOperand_ParseFail;
2623 }
2624
Vladimir Sukharev017d10b2015-03-26 17:29:53 +00002625 Operands.push_back( AArch64Operand::CreateBarrier(Opt, Tok.getString(),
2626 getLoc(), getContext()));
Tim Northover3b0846e2014-05-24 12:50:23 +00002627 Parser.Lex(); // Consume the option
2628
2629 return MatchOperand_Success;
2630}
2631
2632AArch64AsmParser::OperandMatchResultTy
2633AArch64AsmParser::tryParseSysReg(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002634 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002635 const AsmToken &Tok = Parser.getTok();
2636
2637 if (Tok.isNot(AsmToken::Identifier))
2638 return MatchOperand_NoMatch;
2639
Tim Northover7cd58932015-01-22 17:23:04 +00002640 bool IsKnown;
Vladimir Sukharev45523ff2015-03-27 17:11:29 +00002641 auto MRSMapper = AArch64SysReg::MRSMapper();
2642 uint32_t MRSReg = MRSMapper.fromString(Tok.getString(), STI.getFeatureBits(),
2643 IsKnown);
Tim Northover7cd58932015-01-22 17:23:04 +00002644 assert(IsKnown == (MRSReg != -1U) &&
2645 "register should be -1 if and only if it's unknown");
2646
Vladimir Sukharev45523ff2015-03-27 17:11:29 +00002647 auto MSRMapper = AArch64SysReg::MSRMapper();
2648 uint32_t MSRReg = MSRMapper.fromString(Tok.getString(), STI.getFeatureBits(),
2649 IsKnown);
Tim Northover7cd58932015-01-22 17:23:04 +00002650 assert(IsKnown == (MSRReg != -1U) &&
2651 "register should be -1 if and only if it's unknown");
2652
Vladimir Sukharev017d10b2015-03-26 17:29:53 +00002653 auto PStateMapper = AArch64PState::PStateMapper();
2654 uint32_t PStateField = PStateMapper.fromString(Tok.getString(), IsKnown);
Tim Northover7cd58932015-01-22 17:23:04 +00002655 assert(IsKnown == (PStateField != -1U) &&
2656 "register should be -1 if and only if it's unknown");
2657
2658 Operands.push_back(AArch64Operand::CreateSysReg(
2659 Tok.getString(), getLoc(), MRSReg, MSRReg, PStateField, getContext()));
Tim Northover3b0846e2014-05-24 12:50:23 +00002660 Parser.Lex(); // Eat identifier
2661
2662 return MatchOperand_Success;
2663}
2664
2665/// tryParseVectorRegister - Parse a vector register operand.
2666bool AArch64AsmParser::tryParseVectorRegister(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002667 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002668 if (Parser.getTok().isNot(AsmToken::Identifier))
2669 return true;
2670
2671 SMLoc S = getLoc();
2672 // Check for a vector register specifier first.
2673 StringRef Kind;
2674 int64_t Reg = tryMatchVectorRegister(Kind, false);
2675 if (Reg == -1)
2676 return true;
2677 Operands.push_back(
2678 AArch64Operand::CreateReg(Reg, true, S, getLoc(), getContext()));
2679 // If there was an explicit qualifier, that goes on as a literal text
2680 // operand.
2681 if (!Kind.empty())
2682 Operands.push_back(
2683 AArch64Operand::CreateToken(Kind, false, S, getContext()));
2684
2685 // If there is an index specifier following the register, parse that too.
2686 if (Parser.getTok().is(AsmToken::LBrac)) {
2687 SMLoc SIdx = getLoc();
2688 Parser.Lex(); // Eat left bracket token.
2689
2690 const MCExpr *ImmVal;
2691 if (getParser().parseExpression(ImmVal))
2692 return false;
2693 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2694 if (!MCE) {
2695 TokError("immediate value expected for vector index");
2696 return false;
2697 }
2698
2699 SMLoc E = getLoc();
2700 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2701 Error(E, "']' expected");
2702 return false;
2703 }
2704
2705 Parser.Lex(); // Eat right bracket token.
2706
2707 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
2708 E, getContext()));
2709 }
2710
2711 return false;
2712}
2713
2714/// parseRegister - Parse a non-vector register operand.
2715bool AArch64AsmParser::parseRegister(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002716 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002717 SMLoc S = getLoc();
2718 // Try for a vector register.
2719 if (!tryParseVectorRegister(Operands))
2720 return false;
2721
2722 // Try for a scalar register.
2723 int64_t Reg = tryParseRegister();
2724 if (Reg == -1)
2725 return true;
2726 Operands.push_back(
2727 AArch64Operand::CreateReg(Reg, false, S, getLoc(), getContext()));
2728
2729 // A small number of instructions (FMOVXDhighr, for example) have "[1]"
2730 // as a string token in the instruction itself.
2731 if (getLexer().getKind() == AsmToken::LBrac) {
2732 SMLoc LBracS = getLoc();
2733 Parser.Lex();
2734 const AsmToken &Tok = Parser.getTok();
2735 if (Tok.is(AsmToken::Integer)) {
2736 SMLoc IntS = getLoc();
2737 int64_t Val = Tok.getIntVal();
2738 if (Val == 1) {
2739 Parser.Lex();
2740 if (getLexer().getKind() == AsmToken::RBrac) {
2741 SMLoc RBracS = getLoc();
2742 Parser.Lex();
2743 Operands.push_back(
2744 AArch64Operand::CreateToken("[", false, LBracS, getContext()));
2745 Operands.push_back(
2746 AArch64Operand::CreateToken("1", false, IntS, getContext()));
2747 Operands.push_back(
2748 AArch64Operand::CreateToken("]", false, RBracS, getContext()));
2749 return false;
2750 }
2751 }
2752 }
2753 }
2754
2755 return false;
2756}
2757
2758bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002759 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002760 bool HasELFModifier = false;
2761 AArch64MCExpr::VariantKind RefKind;
2762
2763 if (Parser.getTok().is(AsmToken::Colon)) {
2764 Parser.Lex(); // Eat ':"
2765 HasELFModifier = true;
2766
2767 if (Parser.getTok().isNot(AsmToken::Identifier)) {
2768 Error(Parser.getTok().getLoc(),
2769 "expect relocation specifier in operand after ':'");
2770 return true;
2771 }
2772
2773 std::string LowerCase = Parser.getTok().getIdentifier().lower();
2774 RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
2775 .Case("lo12", AArch64MCExpr::VK_LO12)
2776 .Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
2777 .Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
2778 .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
2779 .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
2780 .Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
2781 .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
2782 .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
2783 .Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
2784 .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
2785 .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
2786 .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
2787 .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
2788 .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
2789 .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
2790 .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
2791 .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
2792 .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
2793 .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
2794 .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
2795 .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
2796 .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
2797 .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
2798 .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
2799 .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
2800 .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
2801 .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
2802 .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
2803 .Case("got", AArch64MCExpr::VK_GOT_PAGE)
2804 .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
2805 .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
2806 .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
2807 .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
2808 .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
2809 .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
2810 .Default(AArch64MCExpr::VK_INVALID);
2811
2812 if (RefKind == AArch64MCExpr::VK_INVALID) {
2813 Error(Parser.getTok().getLoc(),
2814 "expect relocation specifier in operand after ':'");
2815 return true;
2816 }
2817
2818 Parser.Lex(); // Eat identifier
2819
2820 if (Parser.getTok().isNot(AsmToken::Colon)) {
2821 Error(Parser.getTok().getLoc(), "expect ':' after relocation specifier");
2822 return true;
2823 }
2824 Parser.Lex(); // Eat ':'
2825 }
2826
2827 if (getParser().parseExpression(ImmVal))
2828 return true;
2829
2830 if (HasELFModifier)
2831 ImmVal = AArch64MCExpr::Create(ImmVal, RefKind, getContext());
2832
2833 return false;
2834}
2835
2836/// parseVectorList - Parse a vector list operand for AdvSIMD instructions.
2837bool AArch64AsmParser::parseVectorList(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002838 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002839 assert(Parser.getTok().is(AsmToken::LCurly) && "Token is not a Left Bracket");
2840 SMLoc S = getLoc();
2841 Parser.Lex(); // Eat left bracket token.
2842 StringRef Kind;
2843 int64_t FirstReg = tryMatchVectorRegister(Kind, true);
2844 if (FirstReg == -1)
2845 return true;
2846 int64_t PrevReg = FirstReg;
2847 unsigned Count = 1;
2848
2849 if (Parser.getTok().is(AsmToken::Minus)) {
2850 Parser.Lex(); // Eat the minus.
2851
2852 SMLoc Loc = getLoc();
2853 StringRef NextKind;
2854 int64_t Reg = tryMatchVectorRegister(NextKind, true);
2855 if (Reg == -1)
2856 return true;
2857 // Any Kind suffices must match on all regs in the list.
2858 if (Kind != NextKind)
2859 return Error(Loc, "mismatched register size suffix");
2860
2861 unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg);
2862
2863 if (Space == 0 || Space > 3) {
2864 return Error(Loc, "invalid number of vectors");
2865 }
2866
2867 Count += Space;
2868 }
2869 else {
2870 while (Parser.getTok().is(AsmToken::Comma)) {
2871 Parser.Lex(); // Eat the comma token.
2872
2873 SMLoc Loc = getLoc();
2874 StringRef NextKind;
2875 int64_t Reg = tryMatchVectorRegister(NextKind, true);
2876 if (Reg == -1)
2877 return true;
2878 // Any Kind suffices must match on all regs in the list.
2879 if (Kind != NextKind)
2880 return Error(Loc, "mismatched register size suffix");
2881
2882 // Registers must be incremental (with wraparound at 31)
2883 if (getContext().getRegisterInfo()->getEncodingValue(Reg) !=
2884 (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32)
2885 return Error(Loc, "registers must be sequential");
2886
2887 PrevReg = Reg;
2888 ++Count;
2889 }
2890 }
2891
2892 if (Parser.getTok().isNot(AsmToken::RCurly))
2893 return Error(getLoc(), "'}' expected");
2894 Parser.Lex(); // Eat the '}' token.
2895
2896 if (Count > 4)
2897 return Error(S, "invalid number of vectors");
2898
2899 unsigned NumElements = 0;
2900 char ElementKind = 0;
2901 if (!Kind.empty())
2902 parseValidVectorKind(Kind, NumElements, ElementKind);
2903
2904 Operands.push_back(AArch64Operand::CreateVectorList(
2905 FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext()));
2906
2907 // If there is an index specifier following the list, parse that too.
2908 if (Parser.getTok().is(AsmToken::LBrac)) {
2909 SMLoc SIdx = getLoc();
2910 Parser.Lex(); // Eat left bracket token.
2911
2912 const MCExpr *ImmVal;
2913 if (getParser().parseExpression(ImmVal))
2914 return false;
2915 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2916 if (!MCE) {
2917 TokError("immediate value expected for vector index");
2918 return false;
2919 }
2920
2921 SMLoc E = getLoc();
2922 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2923 Error(E, "']' expected");
2924 return false;
2925 }
2926
2927 Parser.Lex(); // Eat right bracket token.
2928
2929 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
2930 E, getContext()));
2931 }
2932 return false;
2933}
2934
2935AArch64AsmParser::OperandMatchResultTy
2936AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002937 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002938 const AsmToken &Tok = Parser.getTok();
2939 if (!Tok.is(AsmToken::Identifier))
2940 return MatchOperand_NoMatch;
2941
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00002942 unsigned RegNum = matchRegisterNameAlias(Tok.getString().lower(), false);
Tim Northover3b0846e2014-05-24 12:50:23 +00002943
2944 MCContext &Ctx = getContext();
2945 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2946 if (!RI->getRegClass(AArch64::GPR64spRegClassID).contains(RegNum))
2947 return MatchOperand_NoMatch;
2948
2949 SMLoc S = getLoc();
2950 Parser.Lex(); // Eat register
2951
2952 if (Parser.getTok().isNot(AsmToken::Comma)) {
2953 Operands.push_back(
2954 AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
2955 return MatchOperand_Success;
2956 }
2957 Parser.Lex(); // Eat comma.
2958
2959 if (Parser.getTok().is(AsmToken::Hash))
2960 Parser.Lex(); // Eat hash
2961
2962 if (Parser.getTok().isNot(AsmToken::Integer)) {
2963 Error(getLoc(), "index must be absent or #0");
2964 return MatchOperand_ParseFail;
2965 }
2966
2967 const MCExpr *ImmVal;
2968 if (Parser.parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
2969 cast<MCConstantExpr>(ImmVal)->getValue() != 0) {
2970 Error(getLoc(), "index must be absent or #0");
2971 return MatchOperand_ParseFail;
2972 }
2973
2974 Operands.push_back(
2975 AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
2976 return MatchOperand_Success;
2977}
2978
2979/// parseOperand - Parse a arm instruction operand. For now this parses the
2980/// operand regardless of the mnemonic.
2981bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
2982 bool invertCondCode) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002983 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002984 // Check if the current operand has a custom associated parser, if so, try to
2985 // custom parse the operand, or fallback to the general approach.
2986 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2987 if (ResTy == MatchOperand_Success)
2988 return false;
2989 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2990 // there was a match, but an error occurred, in which case, just return that
2991 // the operand parsing failed.
2992 if (ResTy == MatchOperand_ParseFail)
2993 return true;
2994
2995 // Nothing custom, so do general case parsing.
2996 SMLoc S, E;
2997 switch (getLexer().getKind()) {
2998 default: {
2999 SMLoc S = getLoc();
3000 const MCExpr *Expr;
3001 if (parseSymbolicImmVal(Expr))
3002 return Error(S, "invalid operand");
3003
3004 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3005 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
3006 return false;
3007 }
3008 case AsmToken::LBrac: {
3009 SMLoc Loc = Parser.getTok().getLoc();
3010 Operands.push_back(AArch64Operand::CreateToken("[", false, Loc,
3011 getContext()));
3012 Parser.Lex(); // Eat '['
3013
3014 // There's no comma after a '[', so we can parse the next operand
3015 // immediately.
3016 return parseOperand(Operands, false, false);
3017 }
3018 case AsmToken::LCurly:
3019 return parseVectorList(Operands);
3020 case AsmToken::Identifier: {
3021 // If we're expecting a Condition Code operand, then just parse that.
3022 if (isCondCode)
3023 return parseCondCode(Operands, invertCondCode);
3024
3025 // If it's a register name, parse it.
3026 if (!parseRegister(Operands))
3027 return false;
3028
3029 // This could be an optional "shift" or "extend" operand.
3030 OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands);
3031 // We can only continue if no tokens were eaten.
3032 if (GotShift != MatchOperand_NoMatch)
3033 return GotShift;
3034
3035 // This was not a register so parse other operands that start with an
3036 // identifier (like labels) as expressions and create them as immediates.
3037 const MCExpr *IdVal;
3038 S = getLoc();
3039 if (getParser().parseExpression(IdVal))
3040 return true;
3041
3042 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3043 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
3044 return false;
3045 }
3046 case AsmToken::Integer:
3047 case AsmToken::Real:
3048 case AsmToken::Hash: {
3049 // #42 -> immediate.
3050 S = getLoc();
3051 if (getLexer().is(AsmToken::Hash))
3052 Parser.Lex();
3053
3054 // Parse a negative sign
3055 bool isNegative = false;
3056 if (Parser.getTok().is(AsmToken::Minus)) {
3057 isNegative = true;
3058 // We need to consume this token only when we have a Real, otherwise
3059 // we let parseSymbolicImmVal take care of it
3060 if (Parser.getLexer().peekTok().is(AsmToken::Real))
3061 Parser.Lex();
3062 }
3063
3064 // The only Real that should come through here is a literal #0.0 for
3065 // the fcmp[e] r, #0.0 instructions. They expect raw token operands,
3066 // so convert the value.
3067 const AsmToken &Tok = Parser.getTok();
3068 if (Tok.is(AsmToken::Real)) {
3069 APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
3070 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
3071 if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" &&
3072 Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" &&
3073 Mnemonic != "fcmlt")
3074 return TokError("unexpected floating point literal");
3075 else if (IntVal != 0 || isNegative)
3076 return TokError("expected floating-point constant #0.0");
3077 Parser.Lex(); // Eat the token.
3078
3079 Operands.push_back(
3080 AArch64Operand::CreateToken("#0", false, S, getContext()));
3081 Operands.push_back(
3082 AArch64Operand::CreateToken(".0", false, S, getContext()));
3083 return false;
3084 }
3085
3086 const MCExpr *ImmVal;
3087 if (parseSymbolicImmVal(ImmVal))
3088 return true;
3089
3090 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3091 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
3092 return false;
3093 }
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00003094 case AsmToken::Equal: {
3095 SMLoc Loc = Parser.getTok().getLoc();
3096 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
3097 return Error(Loc, "unexpected token in operand");
3098 Parser.Lex(); // Eat '='
3099 const MCExpr *SubExprVal;
3100 if (getParser().parseExpression(SubExprVal))
3101 return true;
3102
David Peixottoae5ba762014-07-18 16:05:14 +00003103 if (Operands.size() < 2 ||
3104 !static_cast<AArch64Operand &>(*Operands[1]).isReg())
3105 return true;
3106
3107 bool IsXReg =
3108 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3109 Operands[1]->getReg());
3110
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00003111 MCContext& Ctx = getContext();
3112 E = SMLoc::getFromPointer(Loc.getPointer() - 1);
3113 // 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 +00003114 if (isa<MCConstantExpr>(SubExprVal)) {
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00003115 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
3116 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
3117 while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) {
3118 ShiftAmt += 16;
3119 Imm >>= 16;
3120 }
3121 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
3122 Operands[0] = AArch64Operand::CreateToken("movz", false, Loc, Ctx);
3123 Operands.push_back(AArch64Operand::CreateImm(
3124 MCConstantExpr::Create(Imm, Ctx), S, E, Ctx));
3125 if (ShiftAmt)
3126 Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL,
3127 ShiftAmt, true, S, E, Ctx));
3128 return false;
3129 }
David Peixottoae5ba762014-07-18 16:05:14 +00003130 APInt Simm = APInt(64, Imm << ShiftAmt);
3131 // check if the immediate is an unsigned or signed 32-bit int for W regs
3132 if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32)))
3133 return Error(Loc, "Immediate too large for register");
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00003134 }
3135 // 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 +00003136 const MCExpr *CPLoc =
3137 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4);
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00003138 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
3139 return false;
3140 }
Tim Northover3b0846e2014-05-24 12:50:23 +00003141 }
3142}
3143
3144/// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its
3145/// operands.
3146bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
3147 StringRef Name, SMLoc NameLoc,
3148 OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00003149 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00003150 Name = StringSwitch<StringRef>(Name.lower())
3151 .Case("beq", "b.eq")
3152 .Case("bne", "b.ne")
3153 .Case("bhs", "b.hs")
3154 .Case("bcs", "b.cs")
3155 .Case("blo", "b.lo")
3156 .Case("bcc", "b.cc")
3157 .Case("bmi", "b.mi")
3158 .Case("bpl", "b.pl")
3159 .Case("bvs", "b.vs")
3160 .Case("bvc", "b.vc")
3161 .Case("bhi", "b.hi")
3162 .Case("bls", "b.ls")
3163 .Case("bge", "b.ge")
3164 .Case("blt", "b.lt")
3165 .Case("bgt", "b.gt")
3166 .Case("ble", "b.le")
3167 .Case("bal", "b.al")
3168 .Case("bnv", "b.nv")
3169 .Default(Name);
3170
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00003171 // First check for the AArch64-specific .req directive.
3172 if (Parser.getTok().is(AsmToken::Identifier) &&
3173 Parser.getTok().getIdentifier() == ".req") {
3174 parseDirectiveReq(Name, NameLoc);
3175 // We always return 'error' for this, as we're done with this
3176 // statement and don't need to match the 'instruction."
3177 return true;
3178 }
3179
Tim Northover3b0846e2014-05-24 12:50:23 +00003180 // Create the leading tokens for the mnemonic, split by '.' characters.
3181 size_t Start = 0, Next = Name.find('.');
3182 StringRef Head = Name.slice(Start, Next);
3183
3184 // IC, DC, AT, and TLBI instructions are aliases for the SYS instruction.
3185 if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi") {
3186 bool IsError = parseSysAlias(Head, NameLoc, Operands);
3187 if (IsError && getLexer().isNot(AsmToken::EndOfStatement))
3188 Parser.eatToEndOfStatement();
3189 return IsError;
3190 }
3191
3192 Operands.push_back(
3193 AArch64Operand::CreateToken(Head, false, NameLoc, getContext()));
3194 Mnemonic = Head;
3195
3196 // Handle condition codes for a branch mnemonic
3197 if (Head == "b" && Next != StringRef::npos) {
3198 Start = Next;
3199 Next = Name.find('.', Start + 1);
3200 Head = Name.slice(Start + 1, Next);
3201
3202 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3203 (Head.data() - Name.data()));
3204 AArch64CC::CondCode CC = parseCondCodeString(Head);
3205 if (CC == AArch64CC::Invalid)
3206 return Error(SuffixLoc, "invalid condition code");
3207 Operands.push_back(
3208 AArch64Operand::CreateToken(".", true, SuffixLoc, getContext()));
3209 Operands.push_back(
3210 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
3211 }
3212
3213 // Add the remaining tokens in the mnemonic.
3214 while (Next != StringRef::npos) {
3215 Start = Next;
3216 Next = Name.find('.', Start + 1);
3217 Head = Name.slice(Start, Next);
3218 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3219 (Head.data() - Name.data()) + 1);
3220 Operands.push_back(
3221 AArch64Operand::CreateToken(Head, true, SuffixLoc, getContext()));
3222 }
3223
3224 // Conditional compare instructions have a Condition Code operand, which needs
3225 // to be parsed and an immediate operand created.
3226 bool condCodeFourthOperand =
3227 (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" ||
3228 Head == "fccmpe" || Head == "fcsel" || Head == "csel" ||
3229 Head == "csinc" || Head == "csinv" || Head == "csneg");
3230
3231 // These instructions are aliases to some of the conditional select
3232 // instructions. However, the condition code is inverted in the aliased
3233 // instruction.
3234 //
3235 // FIXME: Is this the correct way to handle these? Or should the parser
3236 // generate the aliased instructions directly?
3237 bool condCodeSecondOperand = (Head == "cset" || Head == "csetm");
3238 bool condCodeThirdOperand =
3239 (Head == "cinc" || Head == "cinv" || Head == "cneg");
3240
3241 // Read the remaining operands.
3242 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3243 // Read the first operand.
3244 if (parseOperand(Operands, false, false)) {
3245 Parser.eatToEndOfStatement();
3246 return true;
3247 }
3248
3249 unsigned N = 2;
3250 while (getLexer().is(AsmToken::Comma)) {
3251 Parser.Lex(); // Eat the comma.
3252
3253 // Parse and remember the operand.
3254 if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
3255 (N == 3 && condCodeThirdOperand) ||
3256 (N == 2 && condCodeSecondOperand),
3257 condCodeSecondOperand || condCodeThirdOperand)) {
3258 Parser.eatToEndOfStatement();
3259 return true;
3260 }
3261
3262 // After successfully parsing some operands there are two special cases to
3263 // consider (i.e. notional operands not separated by commas). Both are due
3264 // to memory specifiers:
3265 // + An RBrac will end an address for load/store/prefetch
3266 // + An '!' will indicate a pre-indexed operation.
3267 //
3268 // It's someone else's responsibility to make sure these tokens are sane
3269 // in the given context!
3270 if (Parser.getTok().is(AsmToken::RBrac)) {
3271 SMLoc Loc = Parser.getTok().getLoc();
3272 Operands.push_back(AArch64Operand::CreateToken("]", false, Loc,
3273 getContext()));
3274 Parser.Lex();
3275 }
3276
3277 if (Parser.getTok().is(AsmToken::Exclaim)) {
3278 SMLoc Loc = Parser.getTok().getLoc();
3279 Operands.push_back(AArch64Operand::CreateToken("!", false, Loc,
3280 getContext()));
3281 Parser.Lex();
3282 }
3283
3284 ++N;
3285 }
3286 }
3287
3288 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3289 SMLoc Loc = Parser.getTok().getLoc();
3290 Parser.eatToEndOfStatement();
3291 return Error(Loc, "unexpected token in argument list");
3292 }
3293
3294 Parser.Lex(); // Consume the EndOfStatement
3295 return false;
3296}
3297
3298// FIXME: This entire function is a giant hack to provide us with decent
3299// operand range validation/diagnostics until TableGen/MC can be extended
3300// to support autogeneration of this kind of validation.
3301bool AArch64AsmParser::validateInstruction(MCInst &Inst,
3302 SmallVectorImpl<SMLoc> &Loc) {
3303 const MCRegisterInfo *RI = getContext().getRegisterInfo();
3304 // Check for indexed addressing modes w/ the base register being the
3305 // same as a destination/source register or pair load where
3306 // the Rt == Rt2. All of those are undefined behaviour.
3307 switch (Inst.getOpcode()) {
3308 case AArch64::LDPSWpre:
3309 case AArch64::LDPWpost:
3310 case AArch64::LDPWpre:
3311 case AArch64::LDPXpost:
3312 case AArch64::LDPXpre: {
3313 unsigned Rt = Inst.getOperand(1).getReg();
3314 unsigned Rt2 = Inst.getOperand(2).getReg();
3315 unsigned Rn = Inst.getOperand(3).getReg();
3316 if (RI->isSubRegisterEq(Rn, Rt))
3317 return Error(Loc[0], "unpredictable LDP instruction, writeback base "
3318 "is also a destination");
3319 if (RI->isSubRegisterEq(Rn, Rt2))
3320 return Error(Loc[1], "unpredictable LDP instruction, writeback base "
3321 "is also a destination");
3322 // FALLTHROUGH
3323 }
3324 case AArch64::LDPDi:
3325 case AArch64::LDPQi:
3326 case AArch64::LDPSi:
3327 case AArch64::LDPSWi:
3328 case AArch64::LDPWi:
3329 case AArch64::LDPXi: {
3330 unsigned Rt = Inst.getOperand(0).getReg();
3331 unsigned Rt2 = Inst.getOperand(1).getReg();
3332 if (Rt == Rt2)
3333 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3334 break;
3335 }
3336 case AArch64::LDPDpost:
3337 case AArch64::LDPDpre:
3338 case AArch64::LDPQpost:
3339 case AArch64::LDPQpre:
3340 case AArch64::LDPSpost:
3341 case AArch64::LDPSpre:
3342 case AArch64::LDPSWpost: {
3343 unsigned Rt = Inst.getOperand(1).getReg();
3344 unsigned Rt2 = Inst.getOperand(2).getReg();
3345 if (Rt == Rt2)
3346 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3347 break;
3348 }
3349 case AArch64::STPDpost:
3350 case AArch64::STPDpre:
3351 case AArch64::STPQpost:
3352 case AArch64::STPQpre:
3353 case AArch64::STPSpost:
3354 case AArch64::STPSpre:
3355 case AArch64::STPWpost:
3356 case AArch64::STPWpre:
3357 case AArch64::STPXpost:
3358 case AArch64::STPXpre: {
3359 unsigned Rt = Inst.getOperand(1).getReg();
3360 unsigned Rt2 = Inst.getOperand(2).getReg();
3361 unsigned Rn = Inst.getOperand(3).getReg();
3362 if (RI->isSubRegisterEq(Rn, Rt))
3363 return Error(Loc[0], "unpredictable STP instruction, writeback base "
3364 "is also a source");
3365 if (RI->isSubRegisterEq(Rn, Rt2))
3366 return Error(Loc[1], "unpredictable STP instruction, writeback base "
3367 "is also a source");
3368 break;
3369 }
3370 case AArch64::LDRBBpre:
3371 case AArch64::LDRBpre:
3372 case AArch64::LDRHHpre:
3373 case AArch64::LDRHpre:
3374 case AArch64::LDRSBWpre:
3375 case AArch64::LDRSBXpre:
3376 case AArch64::LDRSHWpre:
3377 case AArch64::LDRSHXpre:
3378 case AArch64::LDRSWpre:
3379 case AArch64::LDRWpre:
3380 case AArch64::LDRXpre:
3381 case AArch64::LDRBBpost:
3382 case AArch64::LDRBpost:
3383 case AArch64::LDRHHpost:
3384 case AArch64::LDRHpost:
3385 case AArch64::LDRSBWpost:
3386 case AArch64::LDRSBXpost:
3387 case AArch64::LDRSHWpost:
3388 case AArch64::LDRSHXpost:
3389 case AArch64::LDRSWpost:
3390 case AArch64::LDRWpost:
3391 case AArch64::LDRXpost: {
3392 unsigned Rt = Inst.getOperand(1).getReg();
3393 unsigned Rn = Inst.getOperand(2).getReg();
3394 if (RI->isSubRegisterEq(Rn, Rt))
3395 return Error(Loc[0], "unpredictable LDR instruction, writeback base "
3396 "is also a source");
3397 break;
3398 }
3399 case AArch64::STRBBpost:
3400 case AArch64::STRBpost:
3401 case AArch64::STRHHpost:
3402 case AArch64::STRHpost:
3403 case AArch64::STRWpost:
3404 case AArch64::STRXpost:
3405 case AArch64::STRBBpre:
3406 case AArch64::STRBpre:
3407 case AArch64::STRHHpre:
3408 case AArch64::STRHpre:
3409 case AArch64::STRWpre:
3410 case AArch64::STRXpre: {
3411 unsigned Rt = Inst.getOperand(1).getReg();
3412 unsigned Rn = Inst.getOperand(2).getReg();
3413 if (RI->isSubRegisterEq(Rn, Rt))
3414 return Error(Loc[0], "unpredictable STR instruction, writeback base "
3415 "is also a source");
3416 break;
3417 }
3418 }
3419
3420 // Now check immediate ranges. Separate from the above as there is overlap
3421 // in the instructions being checked and this keeps the nested conditionals
3422 // to a minimum.
3423 switch (Inst.getOpcode()) {
3424 case AArch64::ADDSWri:
3425 case AArch64::ADDSXri:
3426 case AArch64::ADDWri:
3427 case AArch64::ADDXri:
3428 case AArch64::SUBSWri:
3429 case AArch64::SUBSXri:
3430 case AArch64::SUBWri:
3431 case AArch64::SUBXri: {
3432 // Annoyingly we can't do this in the isAddSubImm predicate, so there is
3433 // some slight duplication here.
3434 if (Inst.getOperand(2).isExpr()) {
3435 const MCExpr *Expr = Inst.getOperand(2).getExpr();
3436 AArch64MCExpr::VariantKind ELFRefKind;
3437 MCSymbolRefExpr::VariantKind DarwinRefKind;
3438 int64_t Addend;
3439 if (!classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3440 return Error(Loc[2], "invalid immediate expression");
3441 }
3442
3443 // Only allow these with ADDXri.
3444 if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
3445 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) &&
3446 Inst.getOpcode() == AArch64::ADDXri)
3447 return false;
3448
3449 // Only allow these with ADDXri/ADDWri
3450 if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
3451 ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
3452 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
3453 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
3454 ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
3455 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
3456 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
3457 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) &&
3458 (Inst.getOpcode() == AArch64::ADDXri ||
3459 Inst.getOpcode() == AArch64::ADDWri))
3460 return false;
3461
3462 // Don't allow expressions in the immediate field otherwise
3463 return Error(Loc[2], "invalid immediate expression");
3464 }
3465 return false;
3466 }
3467 default:
3468 return false;
3469 }
3470}
3471
3472bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
3473 switch (ErrCode) {
3474 case Match_MissingFeature:
3475 return Error(Loc,
3476 "instruction requires a CPU feature not currently enabled");
3477 case Match_InvalidOperand:
3478 return Error(Loc, "invalid operand for instruction");
3479 case Match_InvalidSuffix:
3480 return Error(Loc, "invalid type suffix for instruction");
3481 case Match_InvalidCondCode:
3482 return Error(Loc, "expected AArch64 condition code");
3483 case Match_AddSubRegExtendSmall:
3484 return Error(Loc,
3485 "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]");
3486 case Match_AddSubRegExtendLarge:
3487 return Error(Loc,
3488 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
3489 case Match_AddSubSecondSource:
3490 return Error(Loc,
3491 "expected compatible register, symbol or integer in range [0, 4095]");
3492 case Match_LogicalSecondSource:
3493 return Error(Loc, "expected compatible register or logical immediate");
3494 case Match_InvalidMovImm32Shift:
3495 return Error(Loc, "expected 'lsl' with optional integer 0 or 16");
3496 case Match_InvalidMovImm64Shift:
3497 return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48");
3498 case Match_AddSubRegShift32:
3499 return Error(Loc,
3500 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
3501 case Match_AddSubRegShift64:
3502 return Error(Loc,
3503 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
3504 case Match_InvalidFPImm:
3505 return Error(Loc,
3506 "expected compatible register or floating-point constant");
3507 case Match_InvalidMemoryIndexedSImm9:
3508 return Error(Loc, "index must be an integer in range [-256, 255].");
3509 case Match_InvalidMemoryIndexed4SImm7:
3510 return Error(Loc, "index must be a multiple of 4 in range [-256, 252].");
3511 case Match_InvalidMemoryIndexed8SImm7:
3512 return Error(Loc, "index must be a multiple of 8 in range [-512, 504].");
3513 case Match_InvalidMemoryIndexed16SImm7:
3514 return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008].");
3515 case Match_InvalidMemoryWExtend8:
3516 return Error(Loc,
3517 "expected 'uxtw' or 'sxtw' with optional shift of #0");
3518 case Match_InvalidMemoryWExtend16:
3519 return Error(Loc,
3520 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
3521 case Match_InvalidMemoryWExtend32:
3522 return Error(Loc,
3523 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
3524 case Match_InvalidMemoryWExtend64:
3525 return Error(Loc,
3526 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
3527 case Match_InvalidMemoryWExtend128:
3528 return Error(Loc,
3529 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
3530 case Match_InvalidMemoryXExtend8:
3531 return Error(Loc,
3532 "expected 'lsl' or 'sxtx' with optional shift of #0");
3533 case Match_InvalidMemoryXExtend16:
3534 return Error(Loc,
3535 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
3536 case Match_InvalidMemoryXExtend32:
3537 return Error(Loc,
3538 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
3539 case Match_InvalidMemoryXExtend64:
3540 return Error(Loc,
3541 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
3542 case Match_InvalidMemoryXExtend128:
3543 return Error(Loc,
3544 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
3545 case Match_InvalidMemoryIndexed1:
3546 return Error(Loc, "index must be an integer in range [0, 4095].");
3547 case Match_InvalidMemoryIndexed2:
3548 return Error(Loc, "index must be a multiple of 2 in range [0, 8190].");
3549 case Match_InvalidMemoryIndexed4:
3550 return Error(Loc, "index must be a multiple of 4 in range [0, 16380].");
3551 case Match_InvalidMemoryIndexed8:
3552 return Error(Loc, "index must be a multiple of 8 in range [0, 32760].");
3553 case Match_InvalidMemoryIndexed16:
3554 return Error(Loc, "index must be a multiple of 16 in range [0, 65520].");
3555 case Match_InvalidImm0_7:
3556 return Error(Loc, "immediate must be an integer in range [0, 7].");
3557 case Match_InvalidImm0_15:
3558 return Error(Loc, "immediate must be an integer in range [0, 15].");
3559 case Match_InvalidImm0_31:
3560 return Error(Loc, "immediate must be an integer in range [0, 31].");
3561 case Match_InvalidImm0_63:
3562 return Error(Loc, "immediate must be an integer in range [0, 63].");
3563 case Match_InvalidImm0_127:
3564 return Error(Loc, "immediate must be an integer in range [0, 127].");
3565 case Match_InvalidImm0_65535:
3566 return Error(Loc, "immediate must be an integer in range [0, 65535].");
3567 case Match_InvalidImm1_8:
3568 return Error(Loc, "immediate must be an integer in range [1, 8].");
3569 case Match_InvalidImm1_16:
3570 return Error(Loc, "immediate must be an integer in range [1, 16].");
3571 case Match_InvalidImm1_32:
3572 return Error(Loc, "immediate must be an integer in range [1, 32].");
3573 case Match_InvalidImm1_64:
3574 return Error(Loc, "immediate must be an integer in range [1, 64].");
3575 case Match_InvalidIndex1:
3576 return Error(Loc, "expected lane specifier '[1]'");
3577 case Match_InvalidIndexB:
3578 return Error(Loc, "vector lane must be an integer in range [0, 15].");
3579 case Match_InvalidIndexH:
3580 return Error(Loc, "vector lane must be an integer in range [0, 7].");
3581 case Match_InvalidIndexS:
3582 return Error(Loc, "vector lane must be an integer in range [0, 3].");
3583 case Match_InvalidIndexD:
3584 return Error(Loc, "vector lane must be an integer in range [0, 1].");
3585 case Match_InvalidLabel:
3586 return Error(Loc, "expected label or encodable integer pc offset");
3587 case Match_MRS:
3588 return Error(Loc, "expected readable system register");
3589 case Match_MSR:
3590 return Error(Loc, "expected writable system register or pstate");
3591 case Match_MnemonicFail:
3592 return Error(Loc, "unrecognized instruction mnemonic");
3593 default:
Craig Topper35b2f752014-06-19 06:10:58 +00003594 llvm_unreachable("unexpected error code!");
Tim Northover3b0846e2014-05-24 12:50:23 +00003595 }
3596}
3597
Tim Northover26bb14e2014-08-18 11:49:42 +00003598static const char *getSubtargetFeatureName(uint64_t Val);
Tim Northover3b0846e2014-05-24 12:50:23 +00003599
3600bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3601 OperandVector &Operands,
3602 MCStreamer &Out,
Tim Northover26bb14e2014-08-18 11:49:42 +00003603 uint64_t &ErrorInfo,
Tim Northover3b0846e2014-05-24 12:50:23 +00003604 bool MatchingInlineAsm) {
3605 assert(!Operands.empty() && "Unexpect empty operand list!");
David Blaikie960ea3f2014-06-08 16:18:35 +00003606 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]);
3607 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
Tim Northover3b0846e2014-05-24 12:50:23 +00003608
David Blaikie960ea3f2014-06-08 16:18:35 +00003609 StringRef Tok = Op.getToken();
Tim Northover3b0846e2014-05-24 12:50:23 +00003610 unsigned NumOperands = Operands.size();
3611
3612 if (NumOperands == 4 && Tok == "lsl") {
David Blaikie960ea3f2014-06-08 16:18:35 +00003613 AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
3614 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3615 if (Op2.isReg() && Op3.isImm()) {
3616 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
Tim Northover3b0846e2014-05-24 12:50:23 +00003617 if (Op3CE) {
3618 uint64_t Op3Val = Op3CE->getValue();
3619 uint64_t NewOp3Val = 0;
3620 uint64_t NewOp4Val = 0;
3621 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003622 Op2.getReg())) {
Tim Northover3b0846e2014-05-24 12:50:23 +00003623 NewOp3Val = (32 - Op3Val) & 0x1f;
3624 NewOp4Val = 31 - Op3Val;
3625 } else {
3626 NewOp3Val = (64 - Op3Val) & 0x3f;
3627 NewOp4Val = 63 - Op3Val;
3628 }
3629
3630 const MCExpr *NewOp3 = MCConstantExpr::Create(NewOp3Val, getContext());
3631 const MCExpr *NewOp4 = MCConstantExpr::Create(NewOp4Val, getContext());
3632
3633 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003634 "ubfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003635 Operands.push_back(AArch64Operand::CreateImm(
David Blaikie960ea3f2014-06-08 16:18:35 +00003636 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
3637 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
3638 Op3.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003639 }
3640 }
3641 } else if (NumOperands == 5) {
3642 // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and
3643 // UBFIZ -> UBFM aliases.
3644 if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") {
David Blaikie960ea3f2014-06-08 16:18:35 +00003645 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3646 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3647 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
Tim Northover3b0846e2014-05-24 12:50:23 +00003648
David Blaikie960ea3f2014-06-08 16:18:35 +00003649 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3650 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3651 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
Tim Northover3b0846e2014-05-24 12:50:23 +00003652
3653 if (Op3CE && Op4CE) {
3654 uint64_t Op3Val = Op3CE->getValue();
3655 uint64_t Op4Val = Op4CE->getValue();
3656
3657 uint64_t RegWidth = 0;
3658 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003659 Op1.getReg()))
Tim Northover3b0846e2014-05-24 12:50:23 +00003660 RegWidth = 64;
3661 else
3662 RegWidth = 32;
3663
3664 if (Op3Val >= RegWidth)
David Blaikie960ea3f2014-06-08 16:18:35 +00003665 return Error(Op3.getStartLoc(),
Tim Northover3b0846e2014-05-24 12:50:23 +00003666 "expected integer in range [0, 31]");
3667 if (Op4Val < 1 || Op4Val > RegWidth)
David Blaikie960ea3f2014-06-08 16:18:35 +00003668 return Error(Op4.getStartLoc(),
Tim Northover3b0846e2014-05-24 12:50:23 +00003669 "expected integer in range [1, 32]");
3670
3671 uint64_t NewOp3Val = 0;
3672 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003673 Op1.getReg()))
Tim Northover3b0846e2014-05-24 12:50:23 +00003674 NewOp3Val = (32 - Op3Val) & 0x1f;
3675 else
3676 NewOp3Val = (64 - Op3Val) & 0x3f;
3677
3678 uint64_t NewOp4Val = Op4Val - 1;
3679
3680 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
David Blaikie960ea3f2014-06-08 16:18:35 +00003681 return Error(Op4.getStartLoc(),
Tim Northover3b0846e2014-05-24 12:50:23 +00003682 "requested insert overflows register");
3683
3684 const MCExpr *NewOp3 =
3685 MCConstantExpr::Create(NewOp3Val, getContext());
3686 const MCExpr *NewOp4 =
3687 MCConstantExpr::Create(NewOp4Val, getContext());
3688 Operands[3] = AArch64Operand::CreateImm(
David Blaikie960ea3f2014-06-08 16:18:35 +00003689 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003690 Operands[4] = AArch64Operand::CreateImm(
David Blaikie960ea3f2014-06-08 16:18:35 +00003691 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003692 if (Tok == "bfi")
3693 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003694 "bfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003695 else if (Tok == "sbfiz")
3696 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003697 "sbfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003698 else if (Tok == "ubfiz")
3699 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003700 "ubfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003701 else
3702 llvm_unreachable("No valid mnemonic for alias?");
Tim Northover3b0846e2014-05-24 12:50:23 +00003703 }
3704 }
3705
3706 // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and
3707 // UBFX -> UBFM aliases.
3708 } else if (NumOperands == 5 &&
3709 (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) {
David Blaikie960ea3f2014-06-08 16:18:35 +00003710 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3711 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3712 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
Tim Northover3b0846e2014-05-24 12:50:23 +00003713
David Blaikie960ea3f2014-06-08 16:18:35 +00003714 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3715 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3716 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
Tim Northover3b0846e2014-05-24 12:50:23 +00003717
3718 if (Op3CE && Op4CE) {
3719 uint64_t Op3Val = Op3CE->getValue();
3720 uint64_t Op4Val = Op4CE->getValue();
3721
3722 uint64_t RegWidth = 0;
3723 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003724 Op1.getReg()))
Tim Northover3b0846e2014-05-24 12:50:23 +00003725 RegWidth = 64;
3726 else
3727 RegWidth = 32;
3728
3729 if (Op3Val >= RegWidth)
David Blaikie960ea3f2014-06-08 16:18:35 +00003730 return Error(Op3.getStartLoc(),
Tim Northover3b0846e2014-05-24 12:50:23 +00003731 "expected integer in range [0, 31]");
3732 if (Op4Val < 1 || Op4Val > RegWidth)
David Blaikie960ea3f2014-06-08 16:18:35 +00003733 return Error(Op4.getStartLoc(),
Tim Northover3b0846e2014-05-24 12:50:23 +00003734 "expected integer in range [1, 32]");
3735
3736 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
3737
3738 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
David Blaikie960ea3f2014-06-08 16:18:35 +00003739 return Error(Op4.getStartLoc(),
Tim Northover3b0846e2014-05-24 12:50:23 +00003740 "requested extract overflows register");
3741
3742 const MCExpr *NewOp4 =
3743 MCConstantExpr::Create(NewOp4Val, getContext());
3744 Operands[4] = AArch64Operand::CreateImm(
David Blaikie960ea3f2014-06-08 16:18:35 +00003745 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003746 if (Tok == "bfxil")
3747 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003748 "bfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003749 else if (Tok == "sbfx")
3750 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003751 "sbfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003752 else if (Tok == "ubfx")
3753 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003754 "ubfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003755 else
3756 llvm_unreachable("No valid mnemonic for alias?");
Tim Northover3b0846e2014-05-24 12:50:23 +00003757 }
3758 }
3759 }
3760 }
3761 // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands.
3762 // InstAlias can't quite handle this since the reg classes aren't
3763 // subclasses.
3764 if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) {
3765 // The source register can be Wn here, but the matcher expects a
3766 // GPR64. Twiddle it here if necessary.
David Blaikie960ea3f2014-06-08 16:18:35 +00003767 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3768 if (Op.isReg()) {
3769 unsigned Reg = getXRegFromWReg(Op.getReg());
3770 Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3771 Op.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003772 }
3773 }
3774 // FIXME: Likewise for sxt[bh] with a Xd dst operand
3775 else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) {
David Blaikie960ea3f2014-06-08 16:18:35 +00003776 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3777 if (Op.isReg() &&
Tim Northover3b0846e2014-05-24 12:50:23 +00003778 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003779 Op.getReg())) {
Tim Northover3b0846e2014-05-24 12:50:23 +00003780 // The source register can be Wn here, but the matcher expects a
3781 // GPR64. Twiddle it here if necessary.
David Blaikie960ea3f2014-06-08 16:18:35 +00003782 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3783 if (Op.isReg()) {
3784 unsigned Reg = getXRegFromWReg(Op.getReg());
3785 Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3786 Op.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003787 }
3788 }
3789 }
3790 // FIXME: Likewise for uxt[bh] with a Xd dst operand
3791 else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) {
David Blaikie960ea3f2014-06-08 16:18:35 +00003792 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3793 if (Op.isReg() &&
Tim Northover3b0846e2014-05-24 12:50:23 +00003794 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003795 Op.getReg())) {
Tim Northover3b0846e2014-05-24 12:50:23 +00003796 // The source register can be Wn here, but the matcher expects a
3797 // GPR32. Twiddle it here if necessary.
David Blaikie960ea3f2014-06-08 16:18:35 +00003798 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3799 if (Op.isReg()) {
3800 unsigned Reg = getWRegFromXReg(Op.getReg());
3801 Operands[1] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3802 Op.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003803 }
3804 }
3805 }
3806
3807 // Yet another horrible hack to handle FMOV Rd, #0.0 using [WX]ZR.
3808 if (NumOperands == 3 && Tok == "fmov") {
David Blaikie960ea3f2014-06-08 16:18:35 +00003809 AArch64Operand &RegOp = static_cast<AArch64Operand &>(*Operands[1]);
3810 AArch64Operand &ImmOp = static_cast<AArch64Operand &>(*Operands[2]);
3811 if (RegOp.isReg() && ImmOp.isFPImm() && ImmOp.getFPImm() == (unsigned)-1) {
Tim Northover3b0846e2014-05-24 12:50:23 +00003812 unsigned zreg =
3813 AArch64MCRegisterClasses[AArch64::FPR32RegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003814 RegOp.getReg())
Tim Northover3b0846e2014-05-24 12:50:23 +00003815 ? AArch64::WZR
3816 : AArch64::XZR;
David Blaikie960ea3f2014-06-08 16:18:35 +00003817 Operands[2] = AArch64Operand::CreateReg(zreg, false, Op.getStartLoc(),
3818 Op.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003819 }
3820 }
3821
3822 MCInst Inst;
3823 // First try to match against the secondary set of tables containing the
3824 // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
3825 unsigned MatchResult =
3826 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1);
3827
3828 // If that fails, try against the alternate table containing long-form NEON:
3829 // "fadd v0.2s, v1.2s, v2.2s"
3830 if (MatchResult != Match_Success)
3831 MatchResult =
3832 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0);
3833
3834 switch (MatchResult) {
3835 case Match_Success: {
3836 // Perform range checking and other semantic validations
3837 SmallVector<SMLoc, 8> OperandLocs;
3838 NumOperands = Operands.size();
3839 for (unsigned i = 1; i < NumOperands; ++i)
3840 OperandLocs.push_back(Operands[i]->getStartLoc());
3841 if (validateInstruction(Inst, OperandLocs))
3842 return true;
3843
3844 Inst.setLoc(IDLoc);
3845 Out.EmitInstruction(Inst, STI);
3846 return false;
3847 }
3848 case Match_MissingFeature: {
3849 assert(ErrorInfo && "Unknown missing feature!");
3850 // Special case the error message for the very common case where only
3851 // a single subtarget feature is missing (neon, e.g.).
3852 std::string Msg = "instruction requires:";
Tim Northover26bb14e2014-08-18 11:49:42 +00003853 uint64_t Mask = 1;
Tim Northover3b0846e2014-05-24 12:50:23 +00003854 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
3855 if (ErrorInfo & Mask) {
3856 Msg += " ";
3857 Msg += getSubtargetFeatureName(ErrorInfo & Mask);
3858 }
3859 Mask <<= 1;
3860 }
3861 return Error(IDLoc, Msg);
3862 }
3863 case Match_MnemonicFail:
3864 return showMatchError(IDLoc, MatchResult);
3865 case Match_InvalidOperand: {
3866 SMLoc ErrorLoc = IDLoc;
Tim Northover26bb14e2014-08-18 11:49:42 +00003867 if (ErrorInfo != ~0ULL) {
Tim Northover3b0846e2014-05-24 12:50:23 +00003868 if (ErrorInfo >= Operands.size())
3869 return Error(IDLoc, "too few operands for instruction");
3870
David Blaikie960ea3f2014-06-08 16:18:35 +00003871 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
Tim Northover3b0846e2014-05-24 12:50:23 +00003872 if (ErrorLoc == SMLoc())
3873 ErrorLoc = IDLoc;
3874 }
3875 // If the match failed on a suffix token operand, tweak the diagnostic
3876 // accordingly.
David Blaikie960ea3f2014-06-08 16:18:35 +00003877 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
3878 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
Tim Northover3b0846e2014-05-24 12:50:23 +00003879 MatchResult = Match_InvalidSuffix;
3880
3881 return showMatchError(ErrorLoc, MatchResult);
3882 }
3883 case Match_InvalidMemoryIndexed1:
3884 case Match_InvalidMemoryIndexed2:
3885 case Match_InvalidMemoryIndexed4:
3886 case Match_InvalidMemoryIndexed8:
3887 case Match_InvalidMemoryIndexed16:
3888 case Match_InvalidCondCode:
3889 case Match_AddSubRegExtendSmall:
3890 case Match_AddSubRegExtendLarge:
3891 case Match_AddSubSecondSource:
3892 case Match_LogicalSecondSource:
3893 case Match_AddSubRegShift32:
3894 case Match_AddSubRegShift64:
3895 case Match_InvalidMovImm32Shift:
3896 case Match_InvalidMovImm64Shift:
3897 case Match_InvalidFPImm:
3898 case Match_InvalidMemoryWExtend8:
3899 case Match_InvalidMemoryWExtend16:
3900 case Match_InvalidMemoryWExtend32:
3901 case Match_InvalidMemoryWExtend64:
3902 case Match_InvalidMemoryWExtend128:
3903 case Match_InvalidMemoryXExtend8:
3904 case Match_InvalidMemoryXExtend16:
3905 case Match_InvalidMemoryXExtend32:
3906 case Match_InvalidMemoryXExtend64:
3907 case Match_InvalidMemoryXExtend128:
3908 case Match_InvalidMemoryIndexed4SImm7:
3909 case Match_InvalidMemoryIndexed8SImm7:
3910 case Match_InvalidMemoryIndexed16SImm7:
3911 case Match_InvalidMemoryIndexedSImm9:
3912 case Match_InvalidImm0_7:
3913 case Match_InvalidImm0_15:
3914 case Match_InvalidImm0_31:
3915 case Match_InvalidImm0_63:
3916 case Match_InvalidImm0_127:
3917 case Match_InvalidImm0_65535:
3918 case Match_InvalidImm1_8:
3919 case Match_InvalidImm1_16:
3920 case Match_InvalidImm1_32:
3921 case Match_InvalidImm1_64:
3922 case Match_InvalidIndex1:
3923 case Match_InvalidIndexB:
3924 case Match_InvalidIndexH:
3925 case Match_InvalidIndexS:
3926 case Match_InvalidIndexD:
3927 case Match_InvalidLabel:
3928 case Match_MSR:
3929 case Match_MRS: {
Artyom Skrobov7e9e31e2014-05-29 11:26:15 +00003930 if (ErrorInfo >= Operands.size())
3931 return Error(IDLoc, "too few operands for instruction");
Tim Northover3b0846e2014-05-24 12:50:23 +00003932 // Any time we get here, there's nothing fancy to do. Just get the
3933 // operand SMLoc and display the diagnostic.
David Blaikie960ea3f2014-06-08 16:18:35 +00003934 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
Tim Northover3b0846e2014-05-24 12:50:23 +00003935 if (ErrorLoc == SMLoc())
3936 ErrorLoc = IDLoc;
3937 return showMatchError(ErrorLoc, MatchResult);
3938 }
3939 }
3940
3941 llvm_unreachable("Implement any new match types added!");
Tim Northover3b0846e2014-05-24 12:50:23 +00003942}
3943
3944/// ParseDirective parses the arm specific directives
3945bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
Chad Rosierdcd2a302014-10-22 20:35:57 +00003946 const MCObjectFileInfo::Environment Format =
3947 getContext().getObjectFileInfo()->getObjectFileType();
3948 bool IsMachO = Format == MCObjectFileInfo::IsMachO;
3949 bool IsCOFF = Format == MCObjectFileInfo::IsCOFF;
3950
Tim Northover3b0846e2014-05-24 12:50:23 +00003951 StringRef IDVal = DirectiveID.getIdentifier();
3952 SMLoc Loc = DirectiveID.getLoc();
3953 if (IDVal == ".hword")
3954 return parseDirectiveWord(2, Loc);
3955 if (IDVal == ".word")
3956 return parseDirectiveWord(4, Loc);
3957 if (IDVal == ".xword")
3958 return parseDirectiveWord(8, Loc);
3959 if (IDVal == ".tlsdesccall")
3960 return parseDirectiveTLSDescCall(Loc);
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00003961 if (IDVal == ".ltorg" || IDVal == ".pool")
3962 return parseDirectiveLtorg(Loc);
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00003963 if (IDVal == ".unreq")
3964 return parseDirectiveUnreq(DirectiveID.getLoc());
3965
Chad Rosierdcd2a302014-10-22 20:35:57 +00003966 if (!IsMachO && !IsCOFF) {
3967 if (IDVal == ".inst")
3968 return parseDirectiveInst(Loc);
3969 }
3970
Tim Northover3b0846e2014-05-24 12:50:23 +00003971 return parseDirectiveLOH(IDVal, Loc);
3972}
3973
3974/// parseDirectiveWord
3975/// ::= .word [ expression (, expression)* ]
3976bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00003977 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00003978 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3979 for (;;) {
3980 const MCExpr *Value;
3981 if (getParser().parseExpression(Value))
3982 return true;
3983
3984 getParser().getStreamer().EmitValue(Value, Size);
3985
3986 if (getLexer().is(AsmToken::EndOfStatement))
3987 break;
3988
3989 // FIXME: Improve diagnostic.
3990 if (getLexer().isNot(AsmToken::Comma))
3991 return Error(L, "unexpected token in directive");
3992 Parser.Lex();
3993 }
3994 }
3995
3996 Parser.Lex();
3997 return false;
3998}
3999
Chad Rosierdcd2a302014-10-22 20:35:57 +00004000/// parseDirectiveInst
4001/// ::= .inst opcode [, ...]
4002bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
Rafael Espindola961d4692014-11-11 05:18:41 +00004003 MCAsmParser &Parser = getParser();
Chad Rosierdcd2a302014-10-22 20:35:57 +00004004 if (getLexer().is(AsmToken::EndOfStatement)) {
4005 Parser.eatToEndOfStatement();
4006 Error(Loc, "expected expression following directive");
4007 return false;
4008 }
4009
4010 for (;;) {
4011 const MCExpr *Expr;
4012
4013 if (getParser().parseExpression(Expr)) {
4014 Error(Loc, "expected expression");
4015 return false;
4016 }
4017
4018 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
4019 if (!Value) {
4020 Error(Loc, "expected constant expression");
4021 return false;
4022 }
4023
4024 getTargetStreamer().emitInst(Value->getValue());
4025
4026 if (getLexer().is(AsmToken::EndOfStatement))
4027 break;
4028
4029 if (getLexer().isNot(AsmToken::Comma)) {
4030 Error(Loc, "unexpected token in directive");
4031 return false;
4032 }
4033
4034 Parser.Lex(); // Eat comma.
4035 }
4036
4037 Parser.Lex();
4038 return false;
4039}
4040
Tim Northover3b0846e2014-05-24 12:50:23 +00004041// parseDirectiveTLSDescCall:
4042// ::= .tlsdesccall symbol
4043bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
4044 StringRef Name;
4045 if (getParser().parseIdentifier(Name))
4046 return Error(L, "expected symbol after directive");
4047
4048 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
4049 const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, getContext());
4050 Expr = AArch64MCExpr::Create(Expr, AArch64MCExpr::VK_TLSDESC, getContext());
4051
4052 MCInst Inst;
4053 Inst.setOpcode(AArch64::TLSDESCCALL);
4054 Inst.addOperand(MCOperand::CreateExpr(Expr));
4055
4056 getParser().getStreamer().EmitInstruction(Inst, STI);
4057 return false;
4058}
4059
4060/// ::= .loh <lohName | lohId> label1, ..., labelN
4061/// The number of arguments depends on the loh identifier.
4062bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
4063 if (IDVal != MCLOHDirectiveName())
4064 return true;
4065 MCLOHType Kind;
4066 if (getParser().getTok().isNot(AsmToken::Identifier)) {
4067 if (getParser().getTok().isNot(AsmToken::Integer))
4068 return TokError("expected an identifier or a number in directive");
4069 // We successfully get a numeric value for the identifier.
4070 // Check if it is valid.
4071 int64_t Id = getParser().getTok().getIntVal();
Alexey Samsonov700964e2014-08-29 22:34:28 +00004072 if (Id <= -1U && !isValidMCLOHType(Id))
Tim Northover3b0846e2014-05-24 12:50:23 +00004073 return TokError("invalid numeric identifier in directive");
Alexey Samsonov700964e2014-08-29 22:34:28 +00004074 Kind = (MCLOHType)Id;
Tim Northover3b0846e2014-05-24 12:50:23 +00004075 } else {
4076 StringRef Name = getTok().getIdentifier();
4077 // We successfully parse an identifier.
4078 // Check if it is a recognized one.
4079 int Id = MCLOHNameToId(Name);
4080
4081 if (Id == -1)
4082 return TokError("invalid identifier in directive");
4083 Kind = (MCLOHType)Id;
4084 }
4085 // Consume the identifier.
4086 Lex();
4087 // Get the number of arguments of this LOH.
4088 int NbArgs = MCLOHIdToNbArgs(Kind);
4089
4090 assert(NbArgs != -1 && "Invalid number of arguments");
4091
4092 SmallVector<MCSymbol *, 3> Args;
4093 for (int Idx = 0; Idx < NbArgs; ++Idx) {
4094 StringRef Name;
4095 if (getParser().parseIdentifier(Name))
4096 return TokError("expected identifier in directive");
4097 Args.push_back(getContext().GetOrCreateSymbol(Name));
4098
4099 if (Idx + 1 == NbArgs)
4100 break;
4101 if (getLexer().isNot(AsmToken::Comma))
4102 return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
4103 Lex();
4104 }
4105 if (getLexer().isNot(AsmToken::EndOfStatement))
4106 return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
4107
4108 getStreamer().EmitLOHDirective((MCLOHType)Kind, Args);
4109 return false;
4110}
4111
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00004112/// parseDirectiveLtorg
4113/// ::= .ltorg | .pool
4114bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
4115 getTargetStreamer().emitCurrentConstantPool();
4116 return false;
4117}
4118
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00004119/// parseDirectiveReq
4120/// ::= name .req registername
4121bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00004122 MCAsmParser &Parser = getParser();
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00004123 Parser.Lex(); // Eat the '.req' token.
4124 SMLoc SRegLoc = getLoc();
4125 unsigned RegNum = tryParseRegister();
4126 bool IsVector = false;
4127
4128 if (RegNum == static_cast<unsigned>(-1)) {
4129 StringRef Kind;
4130 RegNum = tryMatchVectorRegister(Kind, false);
4131 if (!Kind.empty()) {
4132 Error(SRegLoc, "vector register without type specifier expected");
4133 return false;
4134 }
4135 IsVector = true;
4136 }
4137
4138 if (RegNum == static_cast<unsigned>(-1)) {
4139 Parser.eatToEndOfStatement();
4140 Error(SRegLoc, "register name or alias expected");
4141 return false;
4142 }
4143
4144 // Shouldn't be anything else.
4145 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4146 Error(Parser.getTok().getLoc(), "unexpected input in .req directive");
4147 Parser.eatToEndOfStatement();
4148 return false;
4149 }
4150
4151 Parser.Lex(); // Consume the EndOfStatement
4152
4153 auto pair = std::make_pair(IsVector, RegNum);
Frederic Rissb61f01f2015-02-04 03:10:03 +00004154 if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00004155 Warning(L, "ignoring redefinition of register alias '" + Name + "'");
4156
4157 return true;
4158}
4159
4160/// parseDirectiveUneq
4161/// ::= .unreq registername
4162bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00004163 MCAsmParser &Parser = getParser();
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00004164 if (Parser.getTok().isNot(AsmToken::Identifier)) {
4165 Error(Parser.getTok().getLoc(), "unexpected input in .unreq directive.");
4166 Parser.eatToEndOfStatement();
4167 return false;
4168 }
4169 RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
4170 Parser.Lex(); // Eat the identifier.
4171 return false;
4172}
4173
Tim Northover3b0846e2014-05-24 12:50:23 +00004174bool
4175AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
4176 AArch64MCExpr::VariantKind &ELFRefKind,
4177 MCSymbolRefExpr::VariantKind &DarwinRefKind,
4178 int64_t &Addend) {
4179 ELFRefKind = AArch64MCExpr::VK_INVALID;
4180 DarwinRefKind = MCSymbolRefExpr::VK_None;
4181 Addend = 0;
4182
4183 if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
4184 ELFRefKind = AE->getKind();
4185 Expr = AE->getSubExpr();
4186 }
4187
4188 const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr);
4189 if (SE) {
4190 // It's a simple symbol reference with no addend.
4191 DarwinRefKind = SE->getKind();
4192 return true;
4193 }
4194
4195 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
4196 if (!BE)
4197 return false;
4198
4199 SE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
4200 if (!SE)
4201 return false;
4202 DarwinRefKind = SE->getKind();
4203
4204 if (BE->getOpcode() != MCBinaryExpr::Add &&
4205 BE->getOpcode() != MCBinaryExpr::Sub)
4206 return false;
4207
4208 // See if the addend is is a constant, otherwise there's more going
4209 // on here than we can deal with.
4210 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
4211 if (!AddendExpr)
4212 return false;
4213
4214 Addend = AddendExpr->getValue();
4215 if (BE->getOpcode() == MCBinaryExpr::Sub)
4216 Addend = -Addend;
4217
4218 // It's some symbol reference + a constant addend, but really
4219 // shouldn't use both Darwin and ELF syntax.
4220 return ELFRefKind == AArch64MCExpr::VK_INVALID ||
4221 DarwinRefKind == MCSymbolRefExpr::VK_None;
4222}
4223
4224/// Force static initialization.
4225extern "C" void LLVMInitializeAArch64AsmParser() {
4226 RegisterMCAsmParser<AArch64AsmParser> X(TheAArch64leTarget);
4227 RegisterMCAsmParser<AArch64AsmParser> Y(TheAArch64beTarget);
Tim Northover35910d72014-07-23 12:58:11 +00004228 RegisterMCAsmParser<AArch64AsmParser> Z(TheARM64Target);
Tim Northover3b0846e2014-05-24 12:50:23 +00004229}
4230
4231#define GET_REGISTER_MATCHER
4232#define GET_SUBTARGET_FEATURE_NAME
4233#define GET_MATCHER_IMPLEMENTATION
4234#include "AArch64GenAsmMatcher.inc"
4235
4236// Define this matcher function after the auto-generated include so we
4237// have the match class enum definitions.
David Blaikie960ea3f2014-06-08 16:18:35 +00004238unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
Tim Northover3b0846e2014-05-24 12:50:23 +00004239 unsigned Kind) {
David Blaikie960ea3f2014-06-08 16:18:35 +00004240 AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp);
Tim Northover3b0846e2014-05-24 12:50:23 +00004241 // If the kind is a token for a literal immediate, check if our asm
4242 // operand matches. This is for InstAliases which have a fixed-value
4243 // immediate in the syntax.
4244 int64_t ExpectedVal;
4245 switch (Kind) {
4246 default:
4247 return Match_InvalidOperand;
4248 case MCK__35_0:
4249 ExpectedVal = 0;
4250 break;
4251 case MCK__35_1:
4252 ExpectedVal = 1;
4253 break;
4254 case MCK__35_12:
4255 ExpectedVal = 12;
4256 break;
4257 case MCK__35_16:
4258 ExpectedVal = 16;
4259 break;
4260 case MCK__35_2:
4261 ExpectedVal = 2;
4262 break;
4263 case MCK__35_24:
4264 ExpectedVal = 24;
4265 break;
4266 case MCK__35_3:
4267 ExpectedVal = 3;
4268 break;
4269 case MCK__35_32:
4270 ExpectedVal = 32;
4271 break;
4272 case MCK__35_4:
4273 ExpectedVal = 4;
4274 break;
4275 case MCK__35_48:
4276 ExpectedVal = 48;
4277 break;
4278 case MCK__35_6:
4279 ExpectedVal = 6;
4280 break;
4281 case MCK__35_64:
4282 ExpectedVal = 64;
4283 break;
4284 case MCK__35_8:
4285 ExpectedVal = 8;
4286 break;
4287 }
David Blaikie960ea3f2014-06-08 16:18:35 +00004288 if (!Op.isImm())
Tim Northover3b0846e2014-05-24 12:50:23 +00004289 return Match_InvalidOperand;
David Blaikie960ea3f2014-06-08 16:18:35 +00004290 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm());
Tim Northover3b0846e2014-05-24 12:50:23 +00004291 if (!CE)
4292 return Match_InvalidOperand;
4293 if (CE->getValue() == ExpectedVal)
4294 return Match_Success;
4295 return Match_InvalidOperand;
4296}