blob: 1219ffc513c9025a572e7f8ea81de195facaf522 [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;
2641 auto MRSMapper = AArch64SysReg::MRSMapper(STI.getFeatureBits());
2642 uint32_t MRSReg = MRSMapper.fromString(Tok.getString(), IsKnown);
2643 assert(IsKnown == (MRSReg != -1U) &&
2644 "register should be -1 if and only if it's unknown");
2645
2646 auto MSRMapper = AArch64SysReg::MSRMapper(STI.getFeatureBits());
2647 uint32_t MSRReg = MSRMapper.fromString(Tok.getString(), IsKnown);
2648 assert(IsKnown == (MSRReg != -1U) &&
2649 "register should be -1 if and only if it's unknown");
2650
Vladimir Sukharev017d10b2015-03-26 17:29:53 +00002651 auto PStateMapper = AArch64PState::PStateMapper();
2652 uint32_t PStateField = PStateMapper.fromString(Tok.getString(), IsKnown);
Tim Northover7cd58932015-01-22 17:23:04 +00002653 assert(IsKnown == (PStateField != -1U) &&
2654 "register should be -1 if and only if it's unknown");
2655
2656 Operands.push_back(AArch64Operand::CreateSysReg(
2657 Tok.getString(), getLoc(), MRSReg, MSRReg, PStateField, getContext()));
Tim Northover3b0846e2014-05-24 12:50:23 +00002658 Parser.Lex(); // Eat identifier
2659
2660 return MatchOperand_Success;
2661}
2662
2663/// tryParseVectorRegister - Parse a vector register operand.
2664bool AArch64AsmParser::tryParseVectorRegister(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002665 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002666 if (Parser.getTok().isNot(AsmToken::Identifier))
2667 return true;
2668
2669 SMLoc S = getLoc();
2670 // Check for a vector register specifier first.
2671 StringRef Kind;
2672 int64_t Reg = tryMatchVectorRegister(Kind, false);
2673 if (Reg == -1)
2674 return true;
2675 Operands.push_back(
2676 AArch64Operand::CreateReg(Reg, true, S, getLoc(), getContext()));
2677 // If there was an explicit qualifier, that goes on as a literal text
2678 // operand.
2679 if (!Kind.empty())
2680 Operands.push_back(
2681 AArch64Operand::CreateToken(Kind, false, S, getContext()));
2682
2683 // If there is an index specifier following the register, parse that too.
2684 if (Parser.getTok().is(AsmToken::LBrac)) {
2685 SMLoc SIdx = getLoc();
2686 Parser.Lex(); // Eat left bracket token.
2687
2688 const MCExpr *ImmVal;
2689 if (getParser().parseExpression(ImmVal))
2690 return false;
2691 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2692 if (!MCE) {
2693 TokError("immediate value expected for vector index");
2694 return false;
2695 }
2696
2697 SMLoc E = getLoc();
2698 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2699 Error(E, "']' expected");
2700 return false;
2701 }
2702
2703 Parser.Lex(); // Eat right bracket token.
2704
2705 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
2706 E, getContext()));
2707 }
2708
2709 return false;
2710}
2711
2712/// parseRegister - Parse a non-vector register operand.
2713bool AArch64AsmParser::parseRegister(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002714 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002715 SMLoc S = getLoc();
2716 // Try for a vector register.
2717 if (!tryParseVectorRegister(Operands))
2718 return false;
2719
2720 // Try for a scalar register.
2721 int64_t Reg = tryParseRegister();
2722 if (Reg == -1)
2723 return true;
2724 Operands.push_back(
2725 AArch64Operand::CreateReg(Reg, false, S, getLoc(), getContext()));
2726
2727 // A small number of instructions (FMOVXDhighr, for example) have "[1]"
2728 // as a string token in the instruction itself.
2729 if (getLexer().getKind() == AsmToken::LBrac) {
2730 SMLoc LBracS = getLoc();
2731 Parser.Lex();
2732 const AsmToken &Tok = Parser.getTok();
2733 if (Tok.is(AsmToken::Integer)) {
2734 SMLoc IntS = getLoc();
2735 int64_t Val = Tok.getIntVal();
2736 if (Val == 1) {
2737 Parser.Lex();
2738 if (getLexer().getKind() == AsmToken::RBrac) {
2739 SMLoc RBracS = getLoc();
2740 Parser.Lex();
2741 Operands.push_back(
2742 AArch64Operand::CreateToken("[", false, LBracS, getContext()));
2743 Operands.push_back(
2744 AArch64Operand::CreateToken("1", false, IntS, getContext()));
2745 Operands.push_back(
2746 AArch64Operand::CreateToken("]", false, RBracS, getContext()));
2747 return false;
2748 }
2749 }
2750 }
2751 }
2752
2753 return false;
2754}
2755
2756bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002757 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002758 bool HasELFModifier = false;
2759 AArch64MCExpr::VariantKind RefKind;
2760
2761 if (Parser.getTok().is(AsmToken::Colon)) {
2762 Parser.Lex(); // Eat ':"
2763 HasELFModifier = true;
2764
2765 if (Parser.getTok().isNot(AsmToken::Identifier)) {
2766 Error(Parser.getTok().getLoc(),
2767 "expect relocation specifier in operand after ':'");
2768 return true;
2769 }
2770
2771 std::string LowerCase = Parser.getTok().getIdentifier().lower();
2772 RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
2773 .Case("lo12", AArch64MCExpr::VK_LO12)
2774 .Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
2775 .Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
2776 .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
2777 .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
2778 .Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
2779 .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
2780 .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
2781 .Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
2782 .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
2783 .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
2784 .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
2785 .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
2786 .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
2787 .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
2788 .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
2789 .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
2790 .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
2791 .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
2792 .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
2793 .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
2794 .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
2795 .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
2796 .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
2797 .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
2798 .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
2799 .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
2800 .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
2801 .Case("got", AArch64MCExpr::VK_GOT_PAGE)
2802 .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
2803 .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
2804 .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
2805 .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
2806 .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
2807 .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
2808 .Default(AArch64MCExpr::VK_INVALID);
2809
2810 if (RefKind == AArch64MCExpr::VK_INVALID) {
2811 Error(Parser.getTok().getLoc(),
2812 "expect relocation specifier in operand after ':'");
2813 return true;
2814 }
2815
2816 Parser.Lex(); // Eat identifier
2817
2818 if (Parser.getTok().isNot(AsmToken::Colon)) {
2819 Error(Parser.getTok().getLoc(), "expect ':' after relocation specifier");
2820 return true;
2821 }
2822 Parser.Lex(); // Eat ':'
2823 }
2824
2825 if (getParser().parseExpression(ImmVal))
2826 return true;
2827
2828 if (HasELFModifier)
2829 ImmVal = AArch64MCExpr::Create(ImmVal, RefKind, getContext());
2830
2831 return false;
2832}
2833
2834/// parseVectorList - Parse a vector list operand for AdvSIMD instructions.
2835bool AArch64AsmParser::parseVectorList(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002836 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002837 assert(Parser.getTok().is(AsmToken::LCurly) && "Token is not a Left Bracket");
2838 SMLoc S = getLoc();
2839 Parser.Lex(); // Eat left bracket token.
2840 StringRef Kind;
2841 int64_t FirstReg = tryMatchVectorRegister(Kind, true);
2842 if (FirstReg == -1)
2843 return true;
2844 int64_t PrevReg = FirstReg;
2845 unsigned Count = 1;
2846
2847 if (Parser.getTok().is(AsmToken::Minus)) {
2848 Parser.Lex(); // Eat the minus.
2849
2850 SMLoc Loc = getLoc();
2851 StringRef NextKind;
2852 int64_t Reg = tryMatchVectorRegister(NextKind, true);
2853 if (Reg == -1)
2854 return true;
2855 // Any Kind suffices must match on all regs in the list.
2856 if (Kind != NextKind)
2857 return Error(Loc, "mismatched register size suffix");
2858
2859 unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg);
2860
2861 if (Space == 0 || Space > 3) {
2862 return Error(Loc, "invalid number of vectors");
2863 }
2864
2865 Count += Space;
2866 }
2867 else {
2868 while (Parser.getTok().is(AsmToken::Comma)) {
2869 Parser.Lex(); // Eat the comma token.
2870
2871 SMLoc Loc = getLoc();
2872 StringRef NextKind;
2873 int64_t Reg = tryMatchVectorRegister(NextKind, true);
2874 if (Reg == -1)
2875 return true;
2876 // Any Kind suffices must match on all regs in the list.
2877 if (Kind != NextKind)
2878 return Error(Loc, "mismatched register size suffix");
2879
2880 // Registers must be incremental (with wraparound at 31)
2881 if (getContext().getRegisterInfo()->getEncodingValue(Reg) !=
2882 (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32)
2883 return Error(Loc, "registers must be sequential");
2884
2885 PrevReg = Reg;
2886 ++Count;
2887 }
2888 }
2889
2890 if (Parser.getTok().isNot(AsmToken::RCurly))
2891 return Error(getLoc(), "'}' expected");
2892 Parser.Lex(); // Eat the '}' token.
2893
2894 if (Count > 4)
2895 return Error(S, "invalid number of vectors");
2896
2897 unsigned NumElements = 0;
2898 char ElementKind = 0;
2899 if (!Kind.empty())
2900 parseValidVectorKind(Kind, NumElements, ElementKind);
2901
2902 Operands.push_back(AArch64Operand::CreateVectorList(
2903 FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext()));
2904
2905 // If there is an index specifier following the list, parse that too.
2906 if (Parser.getTok().is(AsmToken::LBrac)) {
2907 SMLoc SIdx = getLoc();
2908 Parser.Lex(); // Eat left bracket token.
2909
2910 const MCExpr *ImmVal;
2911 if (getParser().parseExpression(ImmVal))
2912 return false;
2913 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2914 if (!MCE) {
2915 TokError("immediate value expected for vector index");
2916 return false;
2917 }
2918
2919 SMLoc E = getLoc();
2920 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2921 Error(E, "']' expected");
2922 return false;
2923 }
2924
2925 Parser.Lex(); // Eat right bracket token.
2926
2927 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
2928 E, getContext()));
2929 }
2930 return false;
2931}
2932
2933AArch64AsmParser::OperandMatchResultTy
2934AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002935 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002936 const AsmToken &Tok = Parser.getTok();
2937 if (!Tok.is(AsmToken::Identifier))
2938 return MatchOperand_NoMatch;
2939
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00002940 unsigned RegNum = matchRegisterNameAlias(Tok.getString().lower(), false);
Tim Northover3b0846e2014-05-24 12:50:23 +00002941
2942 MCContext &Ctx = getContext();
2943 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2944 if (!RI->getRegClass(AArch64::GPR64spRegClassID).contains(RegNum))
2945 return MatchOperand_NoMatch;
2946
2947 SMLoc S = getLoc();
2948 Parser.Lex(); // Eat register
2949
2950 if (Parser.getTok().isNot(AsmToken::Comma)) {
2951 Operands.push_back(
2952 AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
2953 return MatchOperand_Success;
2954 }
2955 Parser.Lex(); // Eat comma.
2956
2957 if (Parser.getTok().is(AsmToken::Hash))
2958 Parser.Lex(); // Eat hash
2959
2960 if (Parser.getTok().isNot(AsmToken::Integer)) {
2961 Error(getLoc(), "index must be absent or #0");
2962 return MatchOperand_ParseFail;
2963 }
2964
2965 const MCExpr *ImmVal;
2966 if (Parser.parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
2967 cast<MCConstantExpr>(ImmVal)->getValue() != 0) {
2968 Error(getLoc(), "index must be absent or #0");
2969 return MatchOperand_ParseFail;
2970 }
2971
2972 Operands.push_back(
2973 AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
2974 return MatchOperand_Success;
2975}
2976
2977/// parseOperand - Parse a arm instruction operand. For now this parses the
2978/// operand regardless of the mnemonic.
2979bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
2980 bool invertCondCode) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002981 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00002982 // Check if the current operand has a custom associated parser, if so, try to
2983 // custom parse the operand, or fallback to the general approach.
2984 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2985 if (ResTy == MatchOperand_Success)
2986 return false;
2987 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2988 // there was a match, but an error occurred, in which case, just return that
2989 // the operand parsing failed.
2990 if (ResTy == MatchOperand_ParseFail)
2991 return true;
2992
2993 // Nothing custom, so do general case parsing.
2994 SMLoc S, E;
2995 switch (getLexer().getKind()) {
2996 default: {
2997 SMLoc S = getLoc();
2998 const MCExpr *Expr;
2999 if (parseSymbolicImmVal(Expr))
3000 return Error(S, "invalid operand");
3001
3002 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3003 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
3004 return false;
3005 }
3006 case AsmToken::LBrac: {
3007 SMLoc Loc = Parser.getTok().getLoc();
3008 Operands.push_back(AArch64Operand::CreateToken("[", false, Loc,
3009 getContext()));
3010 Parser.Lex(); // Eat '['
3011
3012 // There's no comma after a '[', so we can parse the next operand
3013 // immediately.
3014 return parseOperand(Operands, false, false);
3015 }
3016 case AsmToken::LCurly:
3017 return parseVectorList(Operands);
3018 case AsmToken::Identifier: {
3019 // If we're expecting a Condition Code operand, then just parse that.
3020 if (isCondCode)
3021 return parseCondCode(Operands, invertCondCode);
3022
3023 // If it's a register name, parse it.
3024 if (!parseRegister(Operands))
3025 return false;
3026
3027 // This could be an optional "shift" or "extend" operand.
3028 OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands);
3029 // We can only continue if no tokens were eaten.
3030 if (GotShift != MatchOperand_NoMatch)
3031 return GotShift;
3032
3033 // This was not a register so parse other operands that start with an
3034 // identifier (like labels) as expressions and create them as immediates.
3035 const MCExpr *IdVal;
3036 S = getLoc();
3037 if (getParser().parseExpression(IdVal))
3038 return true;
3039
3040 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3041 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
3042 return false;
3043 }
3044 case AsmToken::Integer:
3045 case AsmToken::Real:
3046 case AsmToken::Hash: {
3047 // #42 -> immediate.
3048 S = getLoc();
3049 if (getLexer().is(AsmToken::Hash))
3050 Parser.Lex();
3051
3052 // Parse a negative sign
3053 bool isNegative = false;
3054 if (Parser.getTok().is(AsmToken::Minus)) {
3055 isNegative = true;
3056 // We need to consume this token only when we have a Real, otherwise
3057 // we let parseSymbolicImmVal take care of it
3058 if (Parser.getLexer().peekTok().is(AsmToken::Real))
3059 Parser.Lex();
3060 }
3061
3062 // The only Real that should come through here is a literal #0.0 for
3063 // the fcmp[e] r, #0.0 instructions. They expect raw token operands,
3064 // so convert the value.
3065 const AsmToken &Tok = Parser.getTok();
3066 if (Tok.is(AsmToken::Real)) {
3067 APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
3068 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
3069 if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" &&
3070 Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" &&
3071 Mnemonic != "fcmlt")
3072 return TokError("unexpected floating point literal");
3073 else if (IntVal != 0 || isNegative)
3074 return TokError("expected floating-point constant #0.0");
3075 Parser.Lex(); // Eat the token.
3076
3077 Operands.push_back(
3078 AArch64Operand::CreateToken("#0", false, S, getContext()));
3079 Operands.push_back(
3080 AArch64Operand::CreateToken(".0", false, S, getContext()));
3081 return false;
3082 }
3083
3084 const MCExpr *ImmVal;
3085 if (parseSymbolicImmVal(ImmVal))
3086 return true;
3087
3088 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3089 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
3090 return false;
3091 }
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00003092 case AsmToken::Equal: {
3093 SMLoc Loc = Parser.getTok().getLoc();
3094 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
3095 return Error(Loc, "unexpected token in operand");
3096 Parser.Lex(); // Eat '='
3097 const MCExpr *SubExprVal;
3098 if (getParser().parseExpression(SubExprVal))
3099 return true;
3100
David Peixottoae5ba762014-07-18 16:05:14 +00003101 if (Operands.size() < 2 ||
3102 !static_cast<AArch64Operand &>(*Operands[1]).isReg())
3103 return true;
3104
3105 bool IsXReg =
3106 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3107 Operands[1]->getReg());
3108
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00003109 MCContext& Ctx = getContext();
3110 E = SMLoc::getFromPointer(Loc.getPointer() - 1);
3111 // 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 +00003112 if (isa<MCConstantExpr>(SubExprVal)) {
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00003113 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
3114 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
3115 while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) {
3116 ShiftAmt += 16;
3117 Imm >>= 16;
3118 }
3119 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
3120 Operands[0] = AArch64Operand::CreateToken("movz", false, Loc, Ctx);
3121 Operands.push_back(AArch64Operand::CreateImm(
3122 MCConstantExpr::Create(Imm, Ctx), S, E, Ctx));
3123 if (ShiftAmt)
3124 Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL,
3125 ShiftAmt, true, S, E, Ctx));
3126 return false;
3127 }
David Peixottoae5ba762014-07-18 16:05:14 +00003128 APInt Simm = APInt(64, Imm << ShiftAmt);
3129 // check if the immediate is an unsigned or signed 32-bit int for W regs
3130 if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32)))
3131 return Error(Loc, "Immediate too large for register");
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00003132 }
3133 // 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 +00003134 const MCExpr *CPLoc =
3135 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4);
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00003136 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
3137 return false;
3138 }
Tim Northover3b0846e2014-05-24 12:50:23 +00003139 }
3140}
3141
3142/// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its
3143/// operands.
3144bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
3145 StringRef Name, SMLoc NameLoc,
3146 OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00003147 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00003148 Name = StringSwitch<StringRef>(Name.lower())
3149 .Case("beq", "b.eq")
3150 .Case("bne", "b.ne")
3151 .Case("bhs", "b.hs")
3152 .Case("bcs", "b.cs")
3153 .Case("blo", "b.lo")
3154 .Case("bcc", "b.cc")
3155 .Case("bmi", "b.mi")
3156 .Case("bpl", "b.pl")
3157 .Case("bvs", "b.vs")
3158 .Case("bvc", "b.vc")
3159 .Case("bhi", "b.hi")
3160 .Case("bls", "b.ls")
3161 .Case("bge", "b.ge")
3162 .Case("blt", "b.lt")
3163 .Case("bgt", "b.gt")
3164 .Case("ble", "b.le")
3165 .Case("bal", "b.al")
3166 .Case("bnv", "b.nv")
3167 .Default(Name);
3168
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00003169 // First check for the AArch64-specific .req directive.
3170 if (Parser.getTok().is(AsmToken::Identifier) &&
3171 Parser.getTok().getIdentifier() == ".req") {
3172 parseDirectiveReq(Name, NameLoc);
3173 // We always return 'error' for this, as we're done with this
3174 // statement and don't need to match the 'instruction."
3175 return true;
3176 }
3177
Tim Northover3b0846e2014-05-24 12:50:23 +00003178 // Create the leading tokens for the mnemonic, split by '.' characters.
3179 size_t Start = 0, Next = Name.find('.');
3180 StringRef Head = Name.slice(Start, Next);
3181
3182 // IC, DC, AT, and TLBI instructions are aliases for the SYS instruction.
3183 if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi") {
3184 bool IsError = parseSysAlias(Head, NameLoc, Operands);
3185 if (IsError && getLexer().isNot(AsmToken::EndOfStatement))
3186 Parser.eatToEndOfStatement();
3187 return IsError;
3188 }
3189
3190 Operands.push_back(
3191 AArch64Operand::CreateToken(Head, false, NameLoc, getContext()));
3192 Mnemonic = Head;
3193
3194 // Handle condition codes for a branch mnemonic
3195 if (Head == "b" && Next != StringRef::npos) {
3196 Start = Next;
3197 Next = Name.find('.', Start + 1);
3198 Head = Name.slice(Start + 1, Next);
3199
3200 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3201 (Head.data() - Name.data()));
3202 AArch64CC::CondCode CC = parseCondCodeString(Head);
3203 if (CC == AArch64CC::Invalid)
3204 return Error(SuffixLoc, "invalid condition code");
3205 Operands.push_back(
3206 AArch64Operand::CreateToken(".", true, SuffixLoc, getContext()));
3207 Operands.push_back(
3208 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
3209 }
3210
3211 // Add the remaining tokens in the mnemonic.
3212 while (Next != StringRef::npos) {
3213 Start = Next;
3214 Next = Name.find('.', Start + 1);
3215 Head = Name.slice(Start, Next);
3216 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3217 (Head.data() - Name.data()) + 1);
3218 Operands.push_back(
3219 AArch64Operand::CreateToken(Head, true, SuffixLoc, getContext()));
3220 }
3221
3222 // Conditional compare instructions have a Condition Code operand, which needs
3223 // to be parsed and an immediate operand created.
3224 bool condCodeFourthOperand =
3225 (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" ||
3226 Head == "fccmpe" || Head == "fcsel" || Head == "csel" ||
3227 Head == "csinc" || Head == "csinv" || Head == "csneg");
3228
3229 // These instructions are aliases to some of the conditional select
3230 // instructions. However, the condition code is inverted in the aliased
3231 // instruction.
3232 //
3233 // FIXME: Is this the correct way to handle these? Or should the parser
3234 // generate the aliased instructions directly?
3235 bool condCodeSecondOperand = (Head == "cset" || Head == "csetm");
3236 bool condCodeThirdOperand =
3237 (Head == "cinc" || Head == "cinv" || Head == "cneg");
3238
3239 // Read the remaining operands.
3240 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3241 // Read the first operand.
3242 if (parseOperand(Operands, false, false)) {
3243 Parser.eatToEndOfStatement();
3244 return true;
3245 }
3246
3247 unsigned N = 2;
3248 while (getLexer().is(AsmToken::Comma)) {
3249 Parser.Lex(); // Eat the comma.
3250
3251 // Parse and remember the operand.
3252 if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
3253 (N == 3 && condCodeThirdOperand) ||
3254 (N == 2 && condCodeSecondOperand),
3255 condCodeSecondOperand || condCodeThirdOperand)) {
3256 Parser.eatToEndOfStatement();
3257 return true;
3258 }
3259
3260 // After successfully parsing some operands there are two special cases to
3261 // consider (i.e. notional operands not separated by commas). Both are due
3262 // to memory specifiers:
3263 // + An RBrac will end an address for load/store/prefetch
3264 // + An '!' will indicate a pre-indexed operation.
3265 //
3266 // It's someone else's responsibility to make sure these tokens are sane
3267 // in the given context!
3268 if (Parser.getTok().is(AsmToken::RBrac)) {
3269 SMLoc Loc = Parser.getTok().getLoc();
3270 Operands.push_back(AArch64Operand::CreateToken("]", false, Loc,
3271 getContext()));
3272 Parser.Lex();
3273 }
3274
3275 if (Parser.getTok().is(AsmToken::Exclaim)) {
3276 SMLoc Loc = Parser.getTok().getLoc();
3277 Operands.push_back(AArch64Operand::CreateToken("!", false, Loc,
3278 getContext()));
3279 Parser.Lex();
3280 }
3281
3282 ++N;
3283 }
3284 }
3285
3286 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3287 SMLoc Loc = Parser.getTok().getLoc();
3288 Parser.eatToEndOfStatement();
3289 return Error(Loc, "unexpected token in argument list");
3290 }
3291
3292 Parser.Lex(); // Consume the EndOfStatement
3293 return false;
3294}
3295
3296// FIXME: This entire function is a giant hack to provide us with decent
3297// operand range validation/diagnostics until TableGen/MC can be extended
3298// to support autogeneration of this kind of validation.
3299bool AArch64AsmParser::validateInstruction(MCInst &Inst,
3300 SmallVectorImpl<SMLoc> &Loc) {
3301 const MCRegisterInfo *RI = getContext().getRegisterInfo();
3302 // Check for indexed addressing modes w/ the base register being the
3303 // same as a destination/source register or pair load where
3304 // the Rt == Rt2. All of those are undefined behaviour.
3305 switch (Inst.getOpcode()) {
3306 case AArch64::LDPSWpre:
3307 case AArch64::LDPWpost:
3308 case AArch64::LDPWpre:
3309 case AArch64::LDPXpost:
3310 case AArch64::LDPXpre: {
3311 unsigned Rt = Inst.getOperand(1).getReg();
3312 unsigned Rt2 = Inst.getOperand(2).getReg();
3313 unsigned Rn = Inst.getOperand(3).getReg();
3314 if (RI->isSubRegisterEq(Rn, Rt))
3315 return Error(Loc[0], "unpredictable LDP instruction, writeback base "
3316 "is also a destination");
3317 if (RI->isSubRegisterEq(Rn, Rt2))
3318 return Error(Loc[1], "unpredictable LDP instruction, writeback base "
3319 "is also a destination");
3320 // FALLTHROUGH
3321 }
3322 case AArch64::LDPDi:
3323 case AArch64::LDPQi:
3324 case AArch64::LDPSi:
3325 case AArch64::LDPSWi:
3326 case AArch64::LDPWi:
3327 case AArch64::LDPXi: {
3328 unsigned Rt = Inst.getOperand(0).getReg();
3329 unsigned Rt2 = Inst.getOperand(1).getReg();
3330 if (Rt == Rt2)
3331 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3332 break;
3333 }
3334 case AArch64::LDPDpost:
3335 case AArch64::LDPDpre:
3336 case AArch64::LDPQpost:
3337 case AArch64::LDPQpre:
3338 case AArch64::LDPSpost:
3339 case AArch64::LDPSpre:
3340 case AArch64::LDPSWpost: {
3341 unsigned Rt = Inst.getOperand(1).getReg();
3342 unsigned Rt2 = Inst.getOperand(2).getReg();
3343 if (Rt == Rt2)
3344 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3345 break;
3346 }
3347 case AArch64::STPDpost:
3348 case AArch64::STPDpre:
3349 case AArch64::STPQpost:
3350 case AArch64::STPQpre:
3351 case AArch64::STPSpost:
3352 case AArch64::STPSpre:
3353 case AArch64::STPWpost:
3354 case AArch64::STPWpre:
3355 case AArch64::STPXpost:
3356 case AArch64::STPXpre: {
3357 unsigned Rt = Inst.getOperand(1).getReg();
3358 unsigned Rt2 = Inst.getOperand(2).getReg();
3359 unsigned Rn = Inst.getOperand(3).getReg();
3360 if (RI->isSubRegisterEq(Rn, Rt))
3361 return Error(Loc[0], "unpredictable STP instruction, writeback base "
3362 "is also a source");
3363 if (RI->isSubRegisterEq(Rn, Rt2))
3364 return Error(Loc[1], "unpredictable STP instruction, writeback base "
3365 "is also a source");
3366 break;
3367 }
3368 case AArch64::LDRBBpre:
3369 case AArch64::LDRBpre:
3370 case AArch64::LDRHHpre:
3371 case AArch64::LDRHpre:
3372 case AArch64::LDRSBWpre:
3373 case AArch64::LDRSBXpre:
3374 case AArch64::LDRSHWpre:
3375 case AArch64::LDRSHXpre:
3376 case AArch64::LDRSWpre:
3377 case AArch64::LDRWpre:
3378 case AArch64::LDRXpre:
3379 case AArch64::LDRBBpost:
3380 case AArch64::LDRBpost:
3381 case AArch64::LDRHHpost:
3382 case AArch64::LDRHpost:
3383 case AArch64::LDRSBWpost:
3384 case AArch64::LDRSBXpost:
3385 case AArch64::LDRSHWpost:
3386 case AArch64::LDRSHXpost:
3387 case AArch64::LDRSWpost:
3388 case AArch64::LDRWpost:
3389 case AArch64::LDRXpost: {
3390 unsigned Rt = Inst.getOperand(1).getReg();
3391 unsigned Rn = Inst.getOperand(2).getReg();
3392 if (RI->isSubRegisterEq(Rn, Rt))
3393 return Error(Loc[0], "unpredictable LDR instruction, writeback base "
3394 "is also a source");
3395 break;
3396 }
3397 case AArch64::STRBBpost:
3398 case AArch64::STRBpost:
3399 case AArch64::STRHHpost:
3400 case AArch64::STRHpost:
3401 case AArch64::STRWpost:
3402 case AArch64::STRXpost:
3403 case AArch64::STRBBpre:
3404 case AArch64::STRBpre:
3405 case AArch64::STRHHpre:
3406 case AArch64::STRHpre:
3407 case AArch64::STRWpre:
3408 case AArch64::STRXpre: {
3409 unsigned Rt = Inst.getOperand(1).getReg();
3410 unsigned Rn = Inst.getOperand(2).getReg();
3411 if (RI->isSubRegisterEq(Rn, Rt))
3412 return Error(Loc[0], "unpredictable STR instruction, writeback base "
3413 "is also a source");
3414 break;
3415 }
3416 }
3417
3418 // Now check immediate ranges. Separate from the above as there is overlap
3419 // in the instructions being checked and this keeps the nested conditionals
3420 // to a minimum.
3421 switch (Inst.getOpcode()) {
3422 case AArch64::ADDSWri:
3423 case AArch64::ADDSXri:
3424 case AArch64::ADDWri:
3425 case AArch64::ADDXri:
3426 case AArch64::SUBSWri:
3427 case AArch64::SUBSXri:
3428 case AArch64::SUBWri:
3429 case AArch64::SUBXri: {
3430 // Annoyingly we can't do this in the isAddSubImm predicate, so there is
3431 // some slight duplication here.
3432 if (Inst.getOperand(2).isExpr()) {
3433 const MCExpr *Expr = Inst.getOperand(2).getExpr();
3434 AArch64MCExpr::VariantKind ELFRefKind;
3435 MCSymbolRefExpr::VariantKind DarwinRefKind;
3436 int64_t Addend;
3437 if (!classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3438 return Error(Loc[2], "invalid immediate expression");
3439 }
3440
3441 // Only allow these with ADDXri.
3442 if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
3443 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) &&
3444 Inst.getOpcode() == AArch64::ADDXri)
3445 return false;
3446
3447 // Only allow these with ADDXri/ADDWri
3448 if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
3449 ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
3450 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
3451 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
3452 ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
3453 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
3454 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
3455 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) &&
3456 (Inst.getOpcode() == AArch64::ADDXri ||
3457 Inst.getOpcode() == AArch64::ADDWri))
3458 return false;
3459
3460 // Don't allow expressions in the immediate field otherwise
3461 return Error(Loc[2], "invalid immediate expression");
3462 }
3463 return false;
3464 }
3465 default:
3466 return false;
3467 }
3468}
3469
3470bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
3471 switch (ErrCode) {
3472 case Match_MissingFeature:
3473 return Error(Loc,
3474 "instruction requires a CPU feature not currently enabled");
3475 case Match_InvalidOperand:
3476 return Error(Loc, "invalid operand for instruction");
3477 case Match_InvalidSuffix:
3478 return Error(Loc, "invalid type suffix for instruction");
3479 case Match_InvalidCondCode:
3480 return Error(Loc, "expected AArch64 condition code");
3481 case Match_AddSubRegExtendSmall:
3482 return Error(Loc,
3483 "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]");
3484 case Match_AddSubRegExtendLarge:
3485 return Error(Loc,
3486 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
3487 case Match_AddSubSecondSource:
3488 return Error(Loc,
3489 "expected compatible register, symbol or integer in range [0, 4095]");
3490 case Match_LogicalSecondSource:
3491 return Error(Loc, "expected compatible register or logical immediate");
3492 case Match_InvalidMovImm32Shift:
3493 return Error(Loc, "expected 'lsl' with optional integer 0 or 16");
3494 case Match_InvalidMovImm64Shift:
3495 return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48");
3496 case Match_AddSubRegShift32:
3497 return Error(Loc,
3498 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
3499 case Match_AddSubRegShift64:
3500 return Error(Loc,
3501 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
3502 case Match_InvalidFPImm:
3503 return Error(Loc,
3504 "expected compatible register or floating-point constant");
3505 case Match_InvalidMemoryIndexedSImm9:
3506 return Error(Loc, "index must be an integer in range [-256, 255].");
3507 case Match_InvalidMemoryIndexed4SImm7:
3508 return Error(Loc, "index must be a multiple of 4 in range [-256, 252].");
3509 case Match_InvalidMemoryIndexed8SImm7:
3510 return Error(Loc, "index must be a multiple of 8 in range [-512, 504].");
3511 case Match_InvalidMemoryIndexed16SImm7:
3512 return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008].");
3513 case Match_InvalidMemoryWExtend8:
3514 return Error(Loc,
3515 "expected 'uxtw' or 'sxtw' with optional shift of #0");
3516 case Match_InvalidMemoryWExtend16:
3517 return Error(Loc,
3518 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
3519 case Match_InvalidMemoryWExtend32:
3520 return Error(Loc,
3521 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
3522 case Match_InvalidMemoryWExtend64:
3523 return Error(Loc,
3524 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
3525 case Match_InvalidMemoryWExtend128:
3526 return Error(Loc,
3527 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
3528 case Match_InvalidMemoryXExtend8:
3529 return Error(Loc,
3530 "expected 'lsl' or 'sxtx' with optional shift of #0");
3531 case Match_InvalidMemoryXExtend16:
3532 return Error(Loc,
3533 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
3534 case Match_InvalidMemoryXExtend32:
3535 return Error(Loc,
3536 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
3537 case Match_InvalidMemoryXExtend64:
3538 return Error(Loc,
3539 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
3540 case Match_InvalidMemoryXExtend128:
3541 return Error(Loc,
3542 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
3543 case Match_InvalidMemoryIndexed1:
3544 return Error(Loc, "index must be an integer in range [0, 4095].");
3545 case Match_InvalidMemoryIndexed2:
3546 return Error(Loc, "index must be a multiple of 2 in range [0, 8190].");
3547 case Match_InvalidMemoryIndexed4:
3548 return Error(Loc, "index must be a multiple of 4 in range [0, 16380].");
3549 case Match_InvalidMemoryIndexed8:
3550 return Error(Loc, "index must be a multiple of 8 in range [0, 32760].");
3551 case Match_InvalidMemoryIndexed16:
3552 return Error(Loc, "index must be a multiple of 16 in range [0, 65520].");
3553 case Match_InvalidImm0_7:
3554 return Error(Loc, "immediate must be an integer in range [0, 7].");
3555 case Match_InvalidImm0_15:
3556 return Error(Loc, "immediate must be an integer in range [0, 15].");
3557 case Match_InvalidImm0_31:
3558 return Error(Loc, "immediate must be an integer in range [0, 31].");
3559 case Match_InvalidImm0_63:
3560 return Error(Loc, "immediate must be an integer in range [0, 63].");
3561 case Match_InvalidImm0_127:
3562 return Error(Loc, "immediate must be an integer in range [0, 127].");
3563 case Match_InvalidImm0_65535:
3564 return Error(Loc, "immediate must be an integer in range [0, 65535].");
3565 case Match_InvalidImm1_8:
3566 return Error(Loc, "immediate must be an integer in range [1, 8].");
3567 case Match_InvalidImm1_16:
3568 return Error(Loc, "immediate must be an integer in range [1, 16].");
3569 case Match_InvalidImm1_32:
3570 return Error(Loc, "immediate must be an integer in range [1, 32].");
3571 case Match_InvalidImm1_64:
3572 return Error(Loc, "immediate must be an integer in range [1, 64].");
3573 case Match_InvalidIndex1:
3574 return Error(Loc, "expected lane specifier '[1]'");
3575 case Match_InvalidIndexB:
3576 return Error(Loc, "vector lane must be an integer in range [0, 15].");
3577 case Match_InvalidIndexH:
3578 return Error(Loc, "vector lane must be an integer in range [0, 7].");
3579 case Match_InvalidIndexS:
3580 return Error(Loc, "vector lane must be an integer in range [0, 3].");
3581 case Match_InvalidIndexD:
3582 return Error(Loc, "vector lane must be an integer in range [0, 1].");
3583 case Match_InvalidLabel:
3584 return Error(Loc, "expected label or encodable integer pc offset");
3585 case Match_MRS:
3586 return Error(Loc, "expected readable system register");
3587 case Match_MSR:
3588 return Error(Loc, "expected writable system register or pstate");
3589 case Match_MnemonicFail:
3590 return Error(Loc, "unrecognized instruction mnemonic");
3591 default:
Craig Topper35b2f752014-06-19 06:10:58 +00003592 llvm_unreachable("unexpected error code!");
Tim Northover3b0846e2014-05-24 12:50:23 +00003593 }
3594}
3595
Tim Northover26bb14e2014-08-18 11:49:42 +00003596static const char *getSubtargetFeatureName(uint64_t Val);
Tim Northover3b0846e2014-05-24 12:50:23 +00003597
3598bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3599 OperandVector &Operands,
3600 MCStreamer &Out,
Tim Northover26bb14e2014-08-18 11:49:42 +00003601 uint64_t &ErrorInfo,
Tim Northover3b0846e2014-05-24 12:50:23 +00003602 bool MatchingInlineAsm) {
3603 assert(!Operands.empty() && "Unexpect empty operand list!");
David Blaikie960ea3f2014-06-08 16:18:35 +00003604 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]);
3605 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
Tim Northover3b0846e2014-05-24 12:50:23 +00003606
David Blaikie960ea3f2014-06-08 16:18:35 +00003607 StringRef Tok = Op.getToken();
Tim Northover3b0846e2014-05-24 12:50:23 +00003608 unsigned NumOperands = Operands.size();
3609
3610 if (NumOperands == 4 && Tok == "lsl") {
David Blaikie960ea3f2014-06-08 16:18:35 +00003611 AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
3612 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3613 if (Op2.isReg() && Op3.isImm()) {
3614 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
Tim Northover3b0846e2014-05-24 12:50:23 +00003615 if (Op3CE) {
3616 uint64_t Op3Val = Op3CE->getValue();
3617 uint64_t NewOp3Val = 0;
3618 uint64_t NewOp4Val = 0;
3619 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003620 Op2.getReg())) {
Tim Northover3b0846e2014-05-24 12:50:23 +00003621 NewOp3Val = (32 - Op3Val) & 0x1f;
3622 NewOp4Val = 31 - Op3Val;
3623 } else {
3624 NewOp3Val = (64 - Op3Val) & 0x3f;
3625 NewOp4Val = 63 - Op3Val;
3626 }
3627
3628 const MCExpr *NewOp3 = MCConstantExpr::Create(NewOp3Val, getContext());
3629 const MCExpr *NewOp4 = MCConstantExpr::Create(NewOp4Val, getContext());
3630
3631 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003632 "ubfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003633 Operands.push_back(AArch64Operand::CreateImm(
David Blaikie960ea3f2014-06-08 16:18:35 +00003634 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
3635 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
3636 Op3.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003637 }
3638 }
3639 } else if (NumOperands == 5) {
3640 // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and
3641 // UBFIZ -> UBFM aliases.
3642 if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") {
David Blaikie960ea3f2014-06-08 16:18:35 +00003643 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3644 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3645 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
Tim Northover3b0846e2014-05-24 12:50:23 +00003646
David Blaikie960ea3f2014-06-08 16:18:35 +00003647 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3648 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3649 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
Tim Northover3b0846e2014-05-24 12:50:23 +00003650
3651 if (Op3CE && Op4CE) {
3652 uint64_t Op3Val = Op3CE->getValue();
3653 uint64_t Op4Val = Op4CE->getValue();
3654
3655 uint64_t RegWidth = 0;
3656 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003657 Op1.getReg()))
Tim Northover3b0846e2014-05-24 12:50:23 +00003658 RegWidth = 64;
3659 else
3660 RegWidth = 32;
3661
3662 if (Op3Val >= RegWidth)
David Blaikie960ea3f2014-06-08 16:18:35 +00003663 return Error(Op3.getStartLoc(),
Tim Northover3b0846e2014-05-24 12:50:23 +00003664 "expected integer in range [0, 31]");
3665 if (Op4Val < 1 || Op4Val > RegWidth)
David Blaikie960ea3f2014-06-08 16:18:35 +00003666 return Error(Op4.getStartLoc(),
Tim Northover3b0846e2014-05-24 12:50:23 +00003667 "expected integer in range [1, 32]");
3668
3669 uint64_t NewOp3Val = 0;
3670 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003671 Op1.getReg()))
Tim Northover3b0846e2014-05-24 12:50:23 +00003672 NewOp3Val = (32 - Op3Val) & 0x1f;
3673 else
3674 NewOp3Val = (64 - Op3Val) & 0x3f;
3675
3676 uint64_t NewOp4Val = Op4Val - 1;
3677
3678 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
David Blaikie960ea3f2014-06-08 16:18:35 +00003679 return Error(Op4.getStartLoc(),
Tim Northover3b0846e2014-05-24 12:50:23 +00003680 "requested insert overflows register");
3681
3682 const MCExpr *NewOp3 =
3683 MCConstantExpr::Create(NewOp3Val, getContext());
3684 const MCExpr *NewOp4 =
3685 MCConstantExpr::Create(NewOp4Val, getContext());
3686 Operands[3] = AArch64Operand::CreateImm(
David Blaikie960ea3f2014-06-08 16:18:35 +00003687 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003688 Operands[4] = AArch64Operand::CreateImm(
David Blaikie960ea3f2014-06-08 16:18:35 +00003689 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003690 if (Tok == "bfi")
3691 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003692 "bfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003693 else if (Tok == "sbfiz")
3694 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003695 "sbfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003696 else if (Tok == "ubfiz")
3697 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003698 "ubfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003699 else
3700 llvm_unreachable("No valid mnemonic for alias?");
Tim Northover3b0846e2014-05-24 12:50:23 +00003701 }
3702 }
3703
3704 // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and
3705 // UBFX -> UBFM aliases.
3706 } else if (NumOperands == 5 &&
3707 (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) {
David Blaikie960ea3f2014-06-08 16:18:35 +00003708 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3709 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3710 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
Tim Northover3b0846e2014-05-24 12:50:23 +00003711
David Blaikie960ea3f2014-06-08 16:18:35 +00003712 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3713 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3714 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
Tim Northover3b0846e2014-05-24 12:50:23 +00003715
3716 if (Op3CE && Op4CE) {
3717 uint64_t Op3Val = Op3CE->getValue();
3718 uint64_t Op4Val = Op4CE->getValue();
3719
3720 uint64_t RegWidth = 0;
3721 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003722 Op1.getReg()))
Tim Northover3b0846e2014-05-24 12:50:23 +00003723 RegWidth = 64;
3724 else
3725 RegWidth = 32;
3726
3727 if (Op3Val >= RegWidth)
David Blaikie960ea3f2014-06-08 16:18:35 +00003728 return Error(Op3.getStartLoc(),
Tim Northover3b0846e2014-05-24 12:50:23 +00003729 "expected integer in range [0, 31]");
3730 if (Op4Val < 1 || Op4Val > RegWidth)
David Blaikie960ea3f2014-06-08 16:18:35 +00003731 return Error(Op4.getStartLoc(),
Tim Northover3b0846e2014-05-24 12:50:23 +00003732 "expected integer in range [1, 32]");
3733
3734 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
3735
3736 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
David Blaikie960ea3f2014-06-08 16:18:35 +00003737 return Error(Op4.getStartLoc(),
Tim Northover3b0846e2014-05-24 12:50:23 +00003738 "requested extract overflows register");
3739
3740 const MCExpr *NewOp4 =
3741 MCConstantExpr::Create(NewOp4Val, getContext());
3742 Operands[4] = AArch64Operand::CreateImm(
David Blaikie960ea3f2014-06-08 16:18:35 +00003743 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003744 if (Tok == "bfxil")
3745 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003746 "bfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003747 else if (Tok == "sbfx")
3748 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003749 "sbfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003750 else if (Tok == "ubfx")
3751 Operands[0] = AArch64Operand::CreateToken(
David Blaikie960ea3f2014-06-08 16:18:35 +00003752 "ubfm", false, Op.getStartLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003753 else
3754 llvm_unreachable("No valid mnemonic for alias?");
Tim Northover3b0846e2014-05-24 12:50:23 +00003755 }
3756 }
3757 }
3758 }
3759 // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands.
3760 // InstAlias can't quite handle this since the reg classes aren't
3761 // subclasses.
3762 if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) {
3763 // The source register can be Wn here, but the matcher expects a
3764 // GPR64. Twiddle it here if necessary.
David Blaikie960ea3f2014-06-08 16:18:35 +00003765 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3766 if (Op.isReg()) {
3767 unsigned Reg = getXRegFromWReg(Op.getReg());
3768 Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3769 Op.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003770 }
3771 }
3772 // FIXME: Likewise for sxt[bh] with a Xd dst operand
3773 else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) {
David Blaikie960ea3f2014-06-08 16:18:35 +00003774 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3775 if (Op.isReg() &&
Tim Northover3b0846e2014-05-24 12:50:23 +00003776 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003777 Op.getReg())) {
Tim Northover3b0846e2014-05-24 12:50:23 +00003778 // The source register can be Wn here, but the matcher expects a
3779 // GPR64. Twiddle it here if necessary.
David Blaikie960ea3f2014-06-08 16:18:35 +00003780 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3781 if (Op.isReg()) {
3782 unsigned Reg = getXRegFromWReg(Op.getReg());
3783 Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3784 Op.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003785 }
3786 }
3787 }
3788 // FIXME: Likewise for uxt[bh] with a Xd dst operand
3789 else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) {
David Blaikie960ea3f2014-06-08 16:18:35 +00003790 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3791 if (Op.isReg() &&
Tim Northover3b0846e2014-05-24 12:50:23 +00003792 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003793 Op.getReg())) {
Tim Northover3b0846e2014-05-24 12:50:23 +00003794 // The source register can be Wn here, but the matcher expects a
3795 // GPR32. Twiddle it here if necessary.
David Blaikie960ea3f2014-06-08 16:18:35 +00003796 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3797 if (Op.isReg()) {
3798 unsigned Reg = getWRegFromXReg(Op.getReg());
3799 Operands[1] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3800 Op.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003801 }
3802 }
3803 }
3804
3805 // Yet another horrible hack to handle FMOV Rd, #0.0 using [WX]ZR.
3806 if (NumOperands == 3 && Tok == "fmov") {
David Blaikie960ea3f2014-06-08 16:18:35 +00003807 AArch64Operand &RegOp = static_cast<AArch64Operand &>(*Operands[1]);
3808 AArch64Operand &ImmOp = static_cast<AArch64Operand &>(*Operands[2]);
3809 if (RegOp.isReg() && ImmOp.isFPImm() && ImmOp.getFPImm() == (unsigned)-1) {
Tim Northover3b0846e2014-05-24 12:50:23 +00003810 unsigned zreg =
3811 AArch64MCRegisterClasses[AArch64::FPR32RegClassID].contains(
David Blaikie960ea3f2014-06-08 16:18:35 +00003812 RegOp.getReg())
Tim Northover3b0846e2014-05-24 12:50:23 +00003813 ? AArch64::WZR
3814 : AArch64::XZR;
David Blaikie960ea3f2014-06-08 16:18:35 +00003815 Operands[2] = AArch64Operand::CreateReg(zreg, false, Op.getStartLoc(),
3816 Op.getEndLoc(), getContext());
Tim Northover3b0846e2014-05-24 12:50:23 +00003817 }
3818 }
3819
3820 MCInst Inst;
3821 // First try to match against the secondary set of tables containing the
3822 // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
3823 unsigned MatchResult =
3824 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1);
3825
3826 // If that fails, try against the alternate table containing long-form NEON:
3827 // "fadd v0.2s, v1.2s, v2.2s"
3828 if (MatchResult != Match_Success)
3829 MatchResult =
3830 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0);
3831
3832 switch (MatchResult) {
3833 case Match_Success: {
3834 // Perform range checking and other semantic validations
3835 SmallVector<SMLoc, 8> OperandLocs;
3836 NumOperands = Operands.size();
3837 for (unsigned i = 1; i < NumOperands; ++i)
3838 OperandLocs.push_back(Operands[i]->getStartLoc());
3839 if (validateInstruction(Inst, OperandLocs))
3840 return true;
3841
3842 Inst.setLoc(IDLoc);
3843 Out.EmitInstruction(Inst, STI);
3844 return false;
3845 }
3846 case Match_MissingFeature: {
3847 assert(ErrorInfo && "Unknown missing feature!");
3848 // Special case the error message for the very common case where only
3849 // a single subtarget feature is missing (neon, e.g.).
3850 std::string Msg = "instruction requires:";
Tim Northover26bb14e2014-08-18 11:49:42 +00003851 uint64_t Mask = 1;
Tim Northover3b0846e2014-05-24 12:50:23 +00003852 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
3853 if (ErrorInfo & Mask) {
3854 Msg += " ";
3855 Msg += getSubtargetFeatureName(ErrorInfo & Mask);
3856 }
3857 Mask <<= 1;
3858 }
3859 return Error(IDLoc, Msg);
3860 }
3861 case Match_MnemonicFail:
3862 return showMatchError(IDLoc, MatchResult);
3863 case Match_InvalidOperand: {
3864 SMLoc ErrorLoc = IDLoc;
Tim Northover26bb14e2014-08-18 11:49:42 +00003865 if (ErrorInfo != ~0ULL) {
Tim Northover3b0846e2014-05-24 12:50:23 +00003866 if (ErrorInfo >= Operands.size())
3867 return Error(IDLoc, "too few operands for instruction");
3868
David Blaikie960ea3f2014-06-08 16:18:35 +00003869 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
Tim Northover3b0846e2014-05-24 12:50:23 +00003870 if (ErrorLoc == SMLoc())
3871 ErrorLoc = IDLoc;
3872 }
3873 // If the match failed on a suffix token operand, tweak the diagnostic
3874 // accordingly.
David Blaikie960ea3f2014-06-08 16:18:35 +00003875 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
3876 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
Tim Northover3b0846e2014-05-24 12:50:23 +00003877 MatchResult = Match_InvalidSuffix;
3878
3879 return showMatchError(ErrorLoc, MatchResult);
3880 }
3881 case Match_InvalidMemoryIndexed1:
3882 case Match_InvalidMemoryIndexed2:
3883 case Match_InvalidMemoryIndexed4:
3884 case Match_InvalidMemoryIndexed8:
3885 case Match_InvalidMemoryIndexed16:
3886 case Match_InvalidCondCode:
3887 case Match_AddSubRegExtendSmall:
3888 case Match_AddSubRegExtendLarge:
3889 case Match_AddSubSecondSource:
3890 case Match_LogicalSecondSource:
3891 case Match_AddSubRegShift32:
3892 case Match_AddSubRegShift64:
3893 case Match_InvalidMovImm32Shift:
3894 case Match_InvalidMovImm64Shift:
3895 case Match_InvalidFPImm:
3896 case Match_InvalidMemoryWExtend8:
3897 case Match_InvalidMemoryWExtend16:
3898 case Match_InvalidMemoryWExtend32:
3899 case Match_InvalidMemoryWExtend64:
3900 case Match_InvalidMemoryWExtend128:
3901 case Match_InvalidMemoryXExtend8:
3902 case Match_InvalidMemoryXExtend16:
3903 case Match_InvalidMemoryXExtend32:
3904 case Match_InvalidMemoryXExtend64:
3905 case Match_InvalidMemoryXExtend128:
3906 case Match_InvalidMemoryIndexed4SImm7:
3907 case Match_InvalidMemoryIndexed8SImm7:
3908 case Match_InvalidMemoryIndexed16SImm7:
3909 case Match_InvalidMemoryIndexedSImm9:
3910 case Match_InvalidImm0_7:
3911 case Match_InvalidImm0_15:
3912 case Match_InvalidImm0_31:
3913 case Match_InvalidImm0_63:
3914 case Match_InvalidImm0_127:
3915 case Match_InvalidImm0_65535:
3916 case Match_InvalidImm1_8:
3917 case Match_InvalidImm1_16:
3918 case Match_InvalidImm1_32:
3919 case Match_InvalidImm1_64:
3920 case Match_InvalidIndex1:
3921 case Match_InvalidIndexB:
3922 case Match_InvalidIndexH:
3923 case Match_InvalidIndexS:
3924 case Match_InvalidIndexD:
3925 case Match_InvalidLabel:
3926 case Match_MSR:
3927 case Match_MRS: {
Artyom Skrobov7e9e31e2014-05-29 11:26:15 +00003928 if (ErrorInfo >= Operands.size())
3929 return Error(IDLoc, "too few operands for instruction");
Tim Northover3b0846e2014-05-24 12:50:23 +00003930 // Any time we get here, there's nothing fancy to do. Just get the
3931 // operand SMLoc and display the diagnostic.
David Blaikie960ea3f2014-06-08 16:18:35 +00003932 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
Tim Northover3b0846e2014-05-24 12:50:23 +00003933 if (ErrorLoc == SMLoc())
3934 ErrorLoc = IDLoc;
3935 return showMatchError(ErrorLoc, MatchResult);
3936 }
3937 }
3938
3939 llvm_unreachable("Implement any new match types added!");
Tim Northover3b0846e2014-05-24 12:50:23 +00003940}
3941
3942/// ParseDirective parses the arm specific directives
3943bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
Chad Rosierdcd2a302014-10-22 20:35:57 +00003944 const MCObjectFileInfo::Environment Format =
3945 getContext().getObjectFileInfo()->getObjectFileType();
3946 bool IsMachO = Format == MCObjectFileInfo::IsMachO;
3947 bool IsCOFF = Format == MCObjectFileInfo::IsCOFF;
3948
Tim Northover3b0846e2014-05-24 12:50:23 +00003949 StringRef IDVal = DirectiveID.getIdentifier();
3950 SMLoc Loc = DirectiveID.getLoc();
3951 if (IDVal == ".hword")
3952 return parseDirectiveWord(2, Loc);
3953 if (IDVal == ".word")
3954 return parseDirectiveWord(4, Loc);
3955 if (IDVal == ".xword")
3956 return parseDirectiveWord(8, Loc);
3957 if (IDVal == ".tlsdesccall")
3958 return parseDirectiveTLSDescCall(Loc);
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00003959 if (IDVal == ".ltorg" || IDVal == ".pool")
3960 return parseDirectiveLtorg(Loc);
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00003961 if (IDVal == ".unreq")
3962 return parseDirectiveUnreq(DirectiveID.getLoc());
3963
Chad Rosierdcd2a302014-10-22 20:35:57 +00003964 if (!IsMachO && !IsCOFF) {
3965 if (IDVal == ".inst")
3966 return parseDirectiveInst(Loc);
3967 }
3968
Tim Northover3b0846e2014-05-24 12:50:23 +00003969 return parseDirectiveLOH(IDVal, Loc);
3970}
3971
3972/// parseDirectiveWord
3973/// ::= .word [ expression (, expression)* ]
3974bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00003975 MCAsmParser &Parser = getParser();
Tim Northover3b0846e2014-05-24 12:50:23 +00003976 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3977 for (;;) {
3978 const MCExpr *Value;
3979 if (getParser().parseExpression(Value))
3980 return true;
3981
3982 getParser().getStreamer().EmitValue(Value, Size);
3983
3984 if (getLexer().is(AsmToken::EndOfStatement))
3985 break;
3986
3987 // FIXME: Improve diagnostic.
3988 if (getLexer().isNot(AsmToken::Comma))
3989 return Error(L, "unexpected token in directive");
3990 Parser.Lex();
3991 }
3992 }
3993
3994 Parser.Lex();
3995 return false;
3996}
3997
Chad Rosierdcd2a302014-10-22 20:35:57 +00003998/// parseDirectiveInst
3999/// ::= .inst opcode [, ...]
4000bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
Rafael Espindola961d4692014-11-11 05:18:41 +00004001 MCAsmParser &Parser = getParser();
Chad Rosierdcd2a302014-10-22 20:35:57 +00004002 if (getLexer().is(AsmToken::EndOfStatement)) {
4003 Parser.eatToEndOfStatement();
4004 Error(Loc, "expected expression following directive");
4005 return false;
4006 }
4007
4008 for (;;) {
4009 const MCExpr *Expr;
4010
4011 if (getParser().parseExpression(Expr)) {
4012 Error(Loc, "expected expression");
4013 return false;
4014 }
4015
4016 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
4017 if (!Value) {
4018 Error(Loc, "expected constant expression");
4019 return false;
4020 }
4021
4022 getTargetStreamer().emitInst(Value->getValue());
4023
4024 if (getLexer().is(AsmToken::EndOfStatement))
4025 break;
4026
4027 if (getLexer().isNot(AsmToken::Comma)) {
4028 Error(Loc, "unexpected token in directive");
4029 return false;
4030 }
4031
4032 Parser.Lex(); // Eat comma.
4033 }
4034
4035 Parser.Lex();
4036 return false;
4037}
4038
Tim Northover3b0846e2014-05-24 12:50:23 +00004039// parseDirectiveTLSDescCall:
4040// ::= .tlsdesccall symbol
4041bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
4042 StringRef Name;
4043 if (getParser().parseIdentifier(Name))
4044 return Error(L, "expected symbol after directive");
4045
4046 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
4047 const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, getContext());
4048 Expr = AArch64MCExpr::Create(Expr, AArch64MCExpr::VK_TLSDESC, getContext());
4049
4050 MCInst Inst;
4051 Inst.setOpcode(AArch64::TLSDESCCALL);
4052 Inst.addOperand(MCOperand::CreateExpr(Expr));
4053
4054 getParser().getStreamer().EmitInstruction(Inst, STI);
4055 return false;
4056}
4057
4058/// ::= .loh <lohName | lohId> label1, ..., labelN
4059/// The number of arguments depends on the loh identifier.
4060bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
4061 if (IDVal != MCLOHDirectiveName())
4062 return true;
4063 MCLOHType Kind;
4064 if (getParser().getTok().isNot(AsmToken::Identifier)) {
4065 if (getParser().getTok().isNot(AsmToken::Integer))
4066 return TokError("expected an identifier or a number in directive");
4067 // We successfully get a numeric value for the identifier.
4068 // Check if it is valid.
4069 int64_t Id = getParser().getTok().getIntVal();
Alexey Samsonov700964e2014-08-29 22:34:28 +00004070 if (Id <= -1U && !isValidMCLOHType(Id))
Tim Northover3b0846e2014-05-24 12:50:23 +00004071 return TokError("invalid numeric identifier in directive");
Alexey Samsonov700964e2014-08-29 22:34:28 +00004072 Kind = (MCLOHType)Id;
Tim Northover3b0846e2014-05-24 12:50:23 +00004073 } else {
4074 StringRef Name = getTok().getIdentifier();
4075 // We successfully parse an identifier.
4076 // Check if it is a recognized one.
4077 int Id = MCLOHNameToId(Name);
4078
4079 if (Id == -1)
4080 return TokError("invalid identifier in directive");
4081 Kind = (MCLOHType)Id;
4082 }
4083 // Consume the identifier.
4084 Lex();
4085 // Get the number of arguments of this LOH.
4086 int NbArgs = MCLOHIdToNbArgs(Kind);
4087
4088 assert(NbArgs != -1 && "Invalid number of arguments");
4089
4090 SmallVector<MCSymbol *, 3> Args;
4091 for (int Idx = 0; Idx < NbArgs; ++Idx) {
4092 StringRef Name;
4093 if (getParser().parseIdentifier(Name))
4094 return TokError("expected identifier in directive");
4095 Args.push_back(getContext().GetOrCreateSymbol(Name));
4096
4097 if (Idx + 1 == NbArgs)
4098 break;
4099 if (getLexer().isNot(AsmToken::Comma))
4100 return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
4101 Lex();
4102 }
4103 if (getLexer().isNot(AsmToken::EndOfStatement))
4104 return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
4105
4106 getStreamer().EmitLOHDirective((MCLOHType)Kind, Args);
4107 return false;
4108}
4109
Weiming Zhaob1d4dbd2014-06-24 16:21:38 +00004110/// parseDirectiveLtorg
4111/// ::= .ltorg | .pool
4112bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
4113 getTargetStreamer().emitCurrentConstantPool();
4114 return false;
4115}
4116
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00004117/// parseDirectiveReq
4118/// ::= name .req registername
4119bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00004120 MCAsmParser &Parser = getParser();
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00004121 Parser.Lex(); // Eat the '.req' token.
4122 SMLoc SRegLoc = getLoc();
4123 unsigned RegNum = tryParseRegister();
4124 bool IsVector = false;
4125
4126 if (RegNum == static_cast<unsigned>(-1)) {
4127 StringRef Kind;
4128 RegNum = tryMatchVectorRegister(Kind, false);
4129 if (!Kind.empty()) {
4130 Error(SRegLoc, "vector register without type specifier expected");
4131 return false;
4132 }
4133 IsVector = true;
4134 }
4135
4136 if (RegNum == static_cast<unsigned>(-1)) {
4137 Parser.eatToEndOfStatement();
4138 Error(SRegLoc, "register name or alias expected");
4139 return false;
4140 }
4141
4142 // Shouldn't be anything else.
4143 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4144 Error(Parser.getTok().getLoc(), "unexpected input in .req directive");
4145 Parser.eatToEndOfStatement();
4146 return false;
4147 }
4148
4149 Parser.Lex(); // Consume the EndOfStatement
4150
4151 auto pair = std::make_pair(IsVector, RegNum);
Frederic Rissb61f01f2015-02-04 03:10:03 +00004152 if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00004153 Warning(L, "ignoring redefinition of register alias '" + Name + "'");
4154
4155 return true;
4156}
4157
4158/// parseDirectiveUneq
4159/// ::= .unreq registername
4160bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00004161 MCAsmParser &Parser = getParser();
Saleem Abdulrasool2e09c512014-07-02 04:50:23 +00004162 if (Parser.getTok().isNot(AsmToken::Identifier)) {
4163 Error(Parser.getTok().getLoc(), "unexpected input in .unreq directive.");
4164 Parser.eatToEndOfStatement();
4165 return false;
4166 }
4167 RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
4168 Parser.Lex(); // Eat the identifier.
4169 return false;
4170}
4171
Tim Northover3b0846e2014-05-24 12:50:23 +00004172bool
4173AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
4174 AArch64MCExpr::VariantKind &ELFRefKind,
4175 MCSymbolRefExpr::VariantKind &DarwinRefKind,
4176 int64_t &Addend) {
4177 ELFRefKind = AArch64MCExpr::VK_INVALID;
4178 DarwinRefKind = MCSymbolRefExpr::VK_None;
4179 Addend = 0;
4180
4181 if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
4182 ELFRefKind = AE->getKind();
4183 Expr = AE->getSubExpr();
4184 }
4185
4186 const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr);
4187 if (SE) {
4188 // It's a simple symbol reference with no addend.
4189 DarwinRefKind = SE->getKind();
4190 return true;
4191 }
4192
4193 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
4194 if (!BE)
4195 return false;
4196
4197 SE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
4198 if (!SE)
4199 return false;
4200 DarwinRefKind = SE->getKind();
4201
4202 if (BE->getOpcode() != MCBinaryExpr::Add &&
4203 BE->getOpcode() != MCBinaryExpr::Sub)
4204 return false;
4205
4206 // See if the addend is is a constant, otherwise there's more going
4207 // on here than we can deal with.
4208 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
4209 if (!AddendExpr)
4210 return false;
4211
4212 Addend = AddendExpr->getValue();
4213 if (BE->getOpcode() == MCBinaryExpr::Sub)
4214 Addend = -Addend;
4215
4216 // It's some symbol reference + a constant addend, but really
4217 // shouldn't use both Darwin and ELF syntax.
4218 return ELFRefKind == AArch64MCExpr::VK_INVALID ||
4219 DarwinRefKind == MCSymbolRefExpr::VK_None;
4220}
4221
4222/// Force static initialization.
4223extern "C" void LLVMInitializeAArch64AsmParser() {
4224 RegisterMCAsmParser<AArch64AsmParser> X(TheAArch64leTarget);
4225 RegisterMCAsmParser<AArch64AsmParser> Y(TheAArch64beTarget);
Tim Northover35910d72014-07-23 12:58:11 +00004226 RegisterMCAsmParser<AArch64AsmParser> Z(TheARM64Target);
Tim Northover3b0846e2014-05-24 12:50:23 +00004227}
4228
4229#define GET_REGISTER_MATCHER
4230#define GET_SUBTARGET_FEATURE_NAME
4231#define GET_MATCHER_IMPLEMENTATION
4232#include "AArch64GenAsmMatcher.inc"
4233
4234// Define this matcher function after the auto-generated include so we
4235// have the match class enum definitions.
David Blaikie960ea3f2014-06-08 16:18:35 +00004236unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
Tim Northover3b0846e2014-05-24 12:50:23 +00004237 unsigned Kind) {
David Blaikie960ea3f2014-06-08 16:18:35 +00004238 AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp);
Tim Northover3b0846e2014-05-24 12:50:23 +00004239 // If the kind is a token for a literal immediate, check if our asm
4240 // operand matches. This is for InstAliases which have a fixed-value
4241 // immediate in the syntax.
4242 int64_t ExpectedVal;
4243 switch (Kind) {
4244 default:
4245 return Match_InvalidOperand;
4246 case MCK__35_0:
4247 ExpectedVal = 0;
4248 break;
4249 case MCK__35_1:
4250 ExpectedVal = 1;
4251 break;
4252 case MCK__35_12:
4253 ExpectedVal = 12;
4254 break;
4255 case MCK__35_16:
4256 ExpectedVal = 16;
4257 break;
4258 case MCK__35_2:
4259 ExpectedVal = 2;
4260 break;
4261 case MCK__35_24:
4262 ExpectedVal = 24;
4263 break;
4264 case MCK__35_3:
4265 ExpectedVal = 3;
4266 break;
4267 case MCK__35_32:
4268 ExpectedVal = 32;
4269 break;
4270 case MCK__35_4:
4271 ExpectedVal = 4;
4272 break;
4273 case MCK__35_48:
4274 ExpectedVal = 48;
4275 break;
4276 case MCK__35_6:
4277 ExpectedVal = 6;
4278 break;
4279 case MCK__35_64:
4280 ExpectedVal = 64;
4281 break;
4282 case MCK__35_8:
4283 ExpectedVal = 8;
4284 break;
4285 }
David Blaikie960ea3f2014-06-08 16:18:35 +00004286 if (!Op.isImm())
Tim Northover3b0846e2014-05-24 12:50:23 +00004287 return Match_InvalidOperand;
David Blaikie960ea3f2014-06-08 16:18:35 +00004288 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm());
Tim Northover3b0846e2014-05-24 12:50:23 +00004289 if (!CE)
4290 return Match_InvalidOperand;
4291 if (CE->getValue() == ExpectedVal)
4292 return Match_Success;
4293 return Match_InvalidOperand;
4294}