1 //===-- VEAsmParser.cpp - Parse VE assembly to MCInst instructions --------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "MCTargetDesc/VEMCExpr.h" 10 #include "MCTargetDesc/VEMCTargetDesc.h" 11 #include "TargetInfo/VETargetInfo.h" 12 #include "VE.h" 13 #include "llvm/ADT/STLExtras.h" 14 #include "llvm/ADT/SmallVector.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/ADT/Twine.h" 17 #include "llvm/MC/MCContext.h" 18 #include "llvm/MC/MCExpr.h" 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/MC/MCParser/MCAsmLexer.h" 21 #include "llvm/MC/MCParser/MCAsmParser.h" 22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 23 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 24 #include "llvm/MC/MCRegisterInfo.h" 25 #include "llvm/MC/MCStreamer.h" 26 #include "llvm/MC/MCSubtargetInfo.h" 27 #include "llvm/MC/MCSymbol.h" 28 #include "llvm/Support/TargetRegistry.h" 29 #include "llvm/Support/raw_ostream.h" 30 #include <algorithm> 31 #include <memory> 32 33 using namespace llvm; 34 35 #define DEBUG_TYPE "ve-asmparser" 36 37 namespace { 38 39 class VEOperand; 40 41 class VEAsmParser : public MCTargetAsmParser { 42 MCAsmParser &Parser; 43 44 /// @name Auto-generated Match Functions 45 /// { 46 47 #define GET_ASSEMBLER_HEADER 48 #include "VEGenAsmMatcher.inc" 49 50 /// } 51 52 // public interface of the MCTargetAsmParser. 53 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 54 OperandVector &Operands, MCStreamer &Out, 55 uint64_t &ErrorInfo, 56 bool MatchingInlineAsm) override; 57 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 58 int parseRegisterName(unsigned (*matchFn)(StringRef)); 59 OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, 60 SMLoc &EndLoc) override; 61 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 62 SMLoc NameLoc, OperandVector &Operands) override; 63 bool ParseDirective(AsmToken DirectiveID) override; 64 65 // Custom parse functions for VE specific operands. 66 OperandMatchResultTy parseMEMOperand(OperandVector &Operands); 67 OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name); 68 OperandMatchResultTy parseVEAsmOperand(std::unique_ptr<VEOperand> &Operand); 69 70 public: 71 VEAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser, 72 const MCInstrInfo &MII, const MCTargetOptions &Options) 73 : MCTargetAsmParser(Options, sti, MII), Parser(parser) { 74 // Initialize the set of available features. 75 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); 76 } 77 }; 78 79 } // end anonymous namespace 80 81 namespace { 82 83 /// VEOperand - Instances of this class represent a parsed VE machine 84 /// instruction. 85 class VEOperand : public MCParsedAsmOperand { 86 private: 87 enum KindTy { 88 k_Token, 89 k_Register, 90 k_Immediate, 91 // SX-Aurora ASX form is disp(index, base). 92 k_MemoryRegRegImm, // base=reg, index=reg, disp=imm 93 k_MemoryRegImmImm, // base=reg, index=imm, disp=imm 94 k_MemoryZeroRegImm, // base=0, index=reg, disp=imm 95 k_MemoryZeroImmImm, // base=0, index=imm, disp=imm 96 } Kind; 97 98 SMLoc StartLoc, EndLoc; 99 100 struct Token { 101 const char *Data; 102 unsigned Length; 103 }; 104 105 struct RegOp { 106 unsigned RegNum; 107 }; 108 109 struct ImmOp { 110 const MCExpr *Val; 111 }; 112 113 struct MemOp { 114 unsigned Base; 115 unsigned IndexReg; 116 const MCExpr *Index; 117 const MCExpr *Offset; 118 }; 119 120 union { 121 struct Token Tok; 122 struct RegOp Reg; 123 struct ImmOp Imm; 124 struct MemOp Mem; 125 }; 126 127 public: 128 VEOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 129 130 bool isToken() const override { return Kind == k_Token; } 131 bool isReg() const override { return Kind == k_Register; } 132 bool isImm() const override { return Kind == k_Immediate; } 133 bool isMem() const override { 134 return isMEMrri() || isMEMrii() || isMEMzri() || isMEMzii() || isMEMri() || 135 isMEMzi(); 136 } 137 bool isMEMrri() const { return Kind == k_MemoryRegRegImm; } 138 bool isMEMrii() const { return Kind == k_MemoryRegImmImm; } 139 bool isMEMzri() const { return Kind == k_MemoryZeroRegImm; } 140 bool isMEMzii() const { return Kind == k_MemoryZeroImmImm; } 141 // isMEMri and isMEMzi will be implemented later. 142 bool isMEMri() const { return false; } 143 bool isMEMzi() const { return false; } 144 bool isSImm7() { 145 if (!isImm()) 146 return false; 147 148 // Constant case 149 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) { 150 int64_t Value = ConstExpr->getValue(); 151 return isInt<7>(Value); 152 } 153 return false; 154 } 155 156 StringRef getToken() const { 157 assert(Kind == k_Token && "Invalid access!"); 158 return StringRef(Tok.Data, Tok.Length); 159 } 160 161 unsigned getReg() const override { 162 assert((Kind == k_Register) && "Invalid access!"); 163 return Reg.RegNum; 164 } 165 166 const MCExpr *getImm() const { 167 assert((Kind == k_Immediate) && "Invalid access!"); 168 return Imm.Val; 169 } 170 171 unsigned getMemBase() const { 172 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm) && 173 "Invalid access!"); 174 return Mem.Base; 175 } 176 177 unsigned getMemIndexReg() const { 178 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryZeroRegImm) && 179 "Invalid access!"); 180 return Mem.IndexReg; 181 } 182 183 const MCExpr *getMemIndex() const { 184 assert((Kind == k_MemoryRegImmImm || Kind == k_MemoryZeroImmImm) && 185 "Invalid access!"); 186 return Mem.Index; 187 } 188 189 const MCExpr *getMemOffset() const { 190 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm || 191 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm) && 192 "Invalid access!"); 193 return Mem.Offset; 194 } 195 196 void setMemOffset(const MCExpr *off) { 197 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm || 198 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm) && 199 "Invalid access!"); 200 Mem.Offset = off; 201 } 202 203 /// getStartLoc - Get the location of the first token of this operand. 204 SMLoc getStartLoc() const override { return StartLoc; } 205 /// getEndLoc - Get the location of the last token of this operand. 206 SMLoc getEndLoc() const override { return EndLoc; } 207 208 void print(raw_ostream &OS) const override { 209 switch (Kind) { 210 case k_Token: 211 OS << "Token: " << getToken() << "\n"; 212 break; 213 case k_Register: 214 OS << "Reg: #" << getReg() << "\n"; 215 break; 216 case k_Immediate: 217 OS << "Imm: " << getImm() << "\n"; 218 break; 219 case k_MemoryRegRegImm: 220 assert(getMemOffset() != nullptr); 221 OS << "Mem: #" << getMemBase() << "+#" << getMemIndexReg() << "+" 222 << *getMemOffset() << "\n"; 223 break; 224 case k_MemoryRegImmImm: 225 assert(getMemIndex() != nullptr && getMemOffset() != nullptr); 226 OS << "Mem: #" << getMemBase() << "+" << *getMemIndex() << "+" 227 << *getMemOffset() << "\n"; 228 break; 229 case k_MemoryZeroRegImm: 230 assert(getMemOffset() != nullptr); 231 OS << "Mem: 0+#" << getMemIndexReg() << "+" << *getMemOffset() << "\n"; 232 break; 233 case k_MemoryZeroImmImm: 234 assert(getMemIndex() != nullptr && getMemOffset() != nullptr); 235 OS << "Mem: 0+" << *getMemIndex() << "+" << *getMemOffset() << "\n"; 236 break; 237 } 238 } 239 240 void addRegOperands(MCInst &Inst, unsigned N) const { 241 assert(N == 1 && "Invalid number of operands!"); 242 Inst.addOperand(MCOperand::createReg(getReg())); 243 } 244 245 void addImmOperands(MCInst &Inst, unsigned N) const { 246 assert(N == 1 && "Invalid number of operands!"); 247 const MCExpr *Expr = getImm(); 248 addExpr(Inst, Expr); 249 } 250 251 void addSImm7Operands(MCInst &Inst, unsigned N) const { 252 addImmOperands(Inst, N); 253 } 254 255 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 256 // Add as immediate when possible. Null MCExpr = 0. 257 if (!Expr) 258 Inst.addOperand(MCOperand::createImm(0)); 259 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 260 Inst.addOperand(MCOperand::createImm(CE->getValue())); 261 else 262 Inst.addOperand(MCOperand::createExpr(Expr)); 263 } 264 265 void addMEMrriOperands(MCInst &Inst, unsigned N) const { 266 assert(N == 3 && "Invalid number of operands!"); 267 268 Inst.addOperand(MCOperand::createReg(getMemBase())); 269 Inst.addOperand(MCOperand::createReg(getMemIndexReg())); 270 addExpr(Inst, getMemOffset()); 271 } 272 273 void addMEMriiOperands(MCInst &Inst, unsigned N) const { 274 assert(N == 3 && "Invalid number of operands!"); 275 276 Inst.addOperand(MCOperand::createReg(getMemBase())); 277 addExpr(Inst, getMemIndex()); 278 addExpr(Inst, getMemOffset()); 279 } 280 281 void addMEMzriOperands(MCInst &Inst, unsigned N) const { 282 assert(N == 3 && "Invalid number of operands!"); 283 284 Inst.addOperand(MCOperand::createImm(0)); 285 Inst.addOperand(MCOperand::createReg(getMemIndexReg())); 286 addExpr(Inst, getMemOffset()); 287 } 288 289 void addMEMziiOperands(MCInst &Inst, unsigned N) const { 290 assert(N == 3 && "Invalid number of operands!"); 291 292 Inst.addOperand(MCOperand::createImm(0)); 293 addExpr(Inst, getMemIndex()); 294 addExpr(Inst, getMemOffset()); 295 } 296 297 void addMEMriOperands(MCInst &Inst, unsigned N) const { 298 // FIXME: implement 299 } 300 301 void addMEMziOperands(MCInst &Inst, unsigned N) const { 302 // FIXME: implement 303 } 304 305 static std::unique_ptr<VEOperand> CreateToken(StringRef Str, SMLoc S) { 306 auto Op = std::make_unique<VEOperand>(k_Token); 307 Op->Tok.Data = Str.data(); 308 Op->Tok.Length = Str.size(); 309 Op->StartLoc = S; 310 Op->EndLoc = S; 311 return Op; 312 } 313 314 static std::unique_ptr<VEOperand> CreateReg(unsigned RegNum, SMLoc S, 315 SMLoc E) { 316 auto Op = std::make_unique<VEOperand>(k_Register); 317 Op->Reg.RegNum = RegNum; 318 Op->StartLoc = S; 319 Op->EndLoc = E; 320 return Op; 321 } 322 323 static std::unique_ptr<VEOperand> CreateImm(const MCExpr *Val, SMLoc S, 324 SMLoc E) { 325 auto Op = std::make_unique<VEOperand>(k_Immediate); 326 Op->Imm.Val = Val; 327 Op->StartLoc = S; 328 Op->EndLoc = E; 329 return Op; 330 } 331 332 static std::unique_ptr<VEOperand> 333 MorphToMEMrri(unsigned Base, unsigned Index, std::unique_ptr<VEOperand> Op) { 334 const MCExpr *Imm = Op->getImm(); 335 Op->Kind = k_MemoryRegRegImm; 336 Op->Mem.Base = Base; 337 Op->Mem.IndexReg = Index; 338 Op->Mem.Index = nullptr; 339 Op->Mem.Offset = Imm; 340 return Op; 341 } 342 343 static std::unique_ptr<VEOperand> 344 MorphToMEMrii(unsigned Base, const MCExpr *Index, 345 std::unique_ptr<VEOperand> Op) { 346 const MCExpr *Imm = Op->getImm(); 347 Op->Kind = k_MemoryRegImmImm; 348 Op->Mem.Base = Base; 349 Op->Mem.IndexReg = 0; 350 Op->Mem.Index = Index; 351 Op->Mem.Offset = Imm; 352 return Op; 353 } 354 355 static std::unique_ptr<VEOperand> 356 MorphToMEMzri(unsigned Index, std::unique_ptr<VEOperand> Op) { 357 const MCExpr *Imm = Op->getImm(); 358 Op->Kind = k_MemoryZeroRegImm; 359 Op->Mem.Base = 0; 360 Op->Mem.IndexReg = Index; 361 Op->Mem.Index = nullptr; 362 Op->Mem.Offset = Imm; 363 return Op; 364 } 365 366 static std::unique_ptr<VEOperand> 367 MorphToMEMzii(const MCExpr *Index, std::unique_ptr<VEOperand> Op) { 368 const MCExpr *Imm = Op->getImm(); 369 Op->Kind = k_MemoryZeroImmImm; 370 Op->Mem.Base = 0; 371 Op->Mem.IndexReg = 0; 372 Op->Mem.Index = Index; 373 Op->Mem.Offset = Imm; 374 return Op; 375 } 376 }; 377 378 } // end anonymous namespace 379 380 bool VEAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 381 OperandVector &Operands, 382 MCStreamer &Out, uint64_t &ErrorInfo, 383 bool MatchingInlineAsm) { 384 MCInst Inst; 385 unsigned MatchResult = 386 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 387 switch (MatchResult) { 388 case Match_Success: 389 Inst.setLoc(IDLoc); 390 Out.emitInstruction(Inst, getSTI()); 391 return false; 392 393 case Match_MissingFeature: 394 return Error(IDLoc, 395 "instruction requires a CPU feature not currently enabled"); 396 397 case Match_InvalidOperand: { 398 SMLoc ErrorLoc = IDLoc; 399 if (ErrorInfo != ~0ULL) { 400 if (ErrorInfo >= Operands.size()) 401 return Error(IDLoc, "too few operands for instruction"); 402 403 ErrorLoc = ((VEOperand &)*Operands[ErrorInfo]).getStartLoc(); 404 if (ErrorLoc == SMLoc()) 405 ErrorLoc = IDLoc; 406 } 407 408 return Error(ErrorLoc, "invalid operand for instruction"); 409 } 410 case Match_MnemonicFail: 411 return Error(IDLoc, "invalid instruction mnemonic"); 412 } 413 llvm_unreachable("Implement any new match types added!"); 414 } 415 416 bool VEAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 417 SMLoc &EndLoc) { 418 if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success) 419 return Error(StartLoc, "invalid register name"); 420 return false; 421 } 422 423 /// Parses a register name using a given matching function. 424 /// Checks for lowercase or uppercase if necessary. 425 int VEAsmParser::parseRegisterName(unsigned (*matchFn)(StringRef)) { 426 StringRef Name = Parser.getTok().getString(); 427 428 int RegNum = matchFn(Name); 429 430 // GCC supports case insensitive register names. All of the VE registers 431 // are all lower case. 432 if (RegNum == VE::NoRegister) { 433 RegNum = matchFn(Name.lower()); 434 } 435 436 return RegNum; 437 } 438 439 /// Maps from the set of all register names to a register number. 440 /// \note Generated by TableGen. 441 static unsigned MatchRegisterName(StringRef Name); 442 443 /// Maps from the set of all alternative registernames to a register number. 444 /// \note Generated by TableGen. 445 static unsigned MatchRegisterAltName(StringRef Name); 446 447 OperandMatchResultTy 448 VEAsmParser::tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { 449 const AsmToken Tok = Parser.getTok(); 450 StartLoc = Tok.getLoc(); 451 EndLoc = Tok.getEndLoc(); 452 RegNo = 0; 453 if (getLexer().getKind() != AsmToken::Percent) 454 return MatchOperand_NoMatch; 455 Parser.Lex(); 456 457 RegNo = parseRegisterName(&MatchRegisterName); 458 if (RegNo == VE::NoRegister) 459 RegNo = parseRegisterName(&MatchRegisterAltName); 460 461 if (RegNo != VE::NoRegister) { 462 Parser.Lex(); 463 return MatchOperand_Success; 464 } 465 466 getLexer().UnLex(Tok); 467 return MatchOperand_NoMatch; 468 } 469 470 bool VEAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 471 SMLoc NameLoc, OperandVector &Operands) { 472 473 // First operand in MCInst is instruction mnemonic. 474 Operands.push_back(VEOperand::CreateToken(Name, NameLoc)); 475 476 if (getLexer().isNot(AsmToken::EndOfStatement)) { 477 // Read the first operand. 478 if (parseOperand(Operands, Name) != MatchOperand_Success) { 479 SMLoc Loc = getLexer().getLoc(); 480 return Error(Loc, "unexpected token"); 481 } 482 483 while (getLexer().is(AsmToken::Comma)) { 484 Parser.Lex(); // Eat the comma. 485 // Parse and remember the operand. 486 if (parseOperand(Operands, Name) != MatchOperand_Success) { 487 SMLoc Loc = getLexer().getLoc(); 488 return Error(Loc, "unexpected token"); 489 } 490 } 491 } 492 if (getLexer().isNot(AsmToken::EndOfStatement)) { 493 SMLoc Loc = getLexer().getLoc(); 494 return Error(Loc, "unexpected token"); 495 } 496 Parser.Lex(); // Consume the EndOfStatement. 497 return false; 498 } 499 500 bool VEAsmParser::ParseDirective(AsmToken DirectiveID) { 501 // Let the MC layer to handle other directives. 502 return true; 503 } 504 505 OperandMatchResultTy VEAsmParser::parseMEMOperand(OperandVector &Operands) { 506 LLVM_DEBUG(dbgs() << "parseMEMOperand\n"); 507 const AsmToken &Tok = Parser.getTok(); 508 SMLoc S = Tok.getLoc(); 509 SMLoc E = Tok.getEndLoc(); 510 // Parse ASX format 511 // disp 512 // disp(, base) 513 // disp(index) 514 // disp(index, base) 515 // (, base) 516 // (index) 517 // (index, base) 518 519 std::unique_ptr<VEOperand> Offset; 520 switch (getLexer().getKind()) { 521 default: 522 return MatchOperand_NoMatch; 523 524 case AsmToken::Minus: 525 case AsmToken::Integer: 526 case AsmToken::Dot: { 527 const MCExpr *EVal; 528 if (!getParser().parseExpression(EVal, E)) 529 Offset = VEOperand::CreateImm(EVal, S, E); 530 else 531 return MatchOperand_NoMatch; 532 break; 533 } 534 case AsmToken::LParen: 535 // empty disp (= 0) 536 Offset = 537 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E); 538 break; 539 } 540 541 switch (getLexer().getKind()) { 542 default: 543 return MatchOperand_ParseFail; 544 545 case AsmToken::EndOfStatement: 546 Operands.push_back(VEOperand::MorphToMEMzii( 547 MCConstantExpr::create(0, getContext()), std::move(Offset))); 548 return MatchOperand_Success; 549 550 case AsmToken::LParen: 551 Parser.Lex(); // Eat the ( 552 break; 553 } 554 555 const MCExpr *IndexValue = nullptr; 556 unsigned IndexReg = 0; 557 558 switch (getLexer().getKind()) { 559 default: 560 if (ParseRegister(IndexReg, S, E)) 561 return MatchOperand_ParseFail; 562 break; 563 564 case AsmToken::Minus: 565 case AsmToken::Integer: 566 case AsmToken::Dot: 567 if (getParser().parseExpression(IndexValue, E)) 568 return MatchOperand_ParseFail; 569 break; 570 571 case AsmToken::Comma: 572 // empty index 573 IndexValue = MCConstantExpr::create(0, getContext()); 574 break; 575 } 576 577 switch (getLexer().getKind()) { 578 default: 579 return MatchOperand_ParseFail; 580 581 case AsmToken::RParen: 582 Parser.Lex(); // Eat the ) 583 Operands.push_back( 584 IndexValue ? VEOperand::MorphToMEMzii(IndexValue, std::move(Offset)) 585 : VEOperand::MorphToMEMzri(IndexReg, std::move(Offset))); 586 return MatchOperand_Success; 587 588 case AsmToken::Comma: 589 Parser.Lex(); // Eat the , 590 break; 591 } 592 593 unsigned BaseReg = 0; 594 if (ParseRegister(BaseReg, S, E)) 595 return MatchOperand_ParseFail; 596 597 if (!Parser.getTok().is(AsmToken::RParen)) 598 return MatchOperand_ParseFail; 599 600 Parser.Lex(); // Eat the ) 601 Operands.push_back( 602 IndexValue 603 ? VEOperand::MorphToMEMrii(BaseReg, IndexValue, std::move(Offset)) 604 : VEOperand::MorphToMEMrri(BaseReg, IndexReg, std::move(Offset))); 605 606 return MatchOperand_Success; 607 } 608 609 OperandMatchResultTy VEAsmParser::parseOperand(OperandVector &Operands, 610 StringRef Mnemonic) { 611 LLVM_DEBUG(dbgs() << "parseOperand\n"); 612 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 613 614 // If there wasn't a custom match, try the generic matcher below. Otherwise, 615 // there was a match, but an error occurred, in which case, just return that 616 // the operand parsing failed. 617 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail) 618 return ResTy; 619 620 switch (getLexer().getKind()) { 621 case AsmToken::LParen: 622 // FIXME: Parsing "(" + %vreg + ", " + %vreg + ")" 623 // FALLTHROUGH 624 default: { 625 std::unique_ptr<VEOperand> Op; 626 ResTy = parseVEAsmOperand(Op); 627 if (ResTy != MatchOperand_Success || !Op) 628 return MatchOperand_ParseFail; 629 630 // Push the parsed operand into the list of operands 631 Operands.push_back(std::move(Op)); 632 633 if (!Parser.getTok().is(AsmToken::LParen)) 634 break; 635 636 // FIXME: Parsing %vec-reg + "(" + %sclar-reg/number + ")" 637 break; 638 } 639 } 640 641 return MatchOperand_Success; 642 } 643 644 OperandMatchResultTy 645 VEAsmParser::parseVEAsmOperand(std::unique_ptr<VEOperand> &Op) { 646 LLVM_DEBUG(dbgs() << "parseVEAsmOperand\n"); 647 SMLoc S = Parser.getTok().getLoc(); 648 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 649 const MCExpr *EVal; 650 651 Op = nullptr; 652 switch (getLexer().getKind()) { 653 default: 654 break; 655 656 case AsmToken::Percent: 657 unsigned RegNo; 658 if (tryParseRegister(RegNo, S, E) == MatchOperand_Success) 659 Op = VEOperand::CreateReg(RegNo, S, E); 660 break; 661 662 case AsmToken::Minus: 663 case AsmToken::Integer: 664 case AsmToken::Dot: 665 if (!getParser().parseExpression(EVal, E)) 666 Op = VEOperand::CreateImm(EVal, S, E); 667 break; 668 669 case AsmToken::Identifier: { 670 StringRef Identifier; 671 if (!getParser().parseIdentifier(Identifier)) { 672 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 673 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 674 675 const MCExpr *Res = 676 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 677 Op = VEOperand::CreateImm(Res, S, E); 678 } 679 break; 680 } 681 } 682 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail; 683 } 684 685 // Force static initialization. 686 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmParser() { 687 RegisterMCAsmParser<VEAsmParser> A(getTheVETarget()); 688 } 689 690 #define GET_REGISTER_MATCHER 691 #define GET_MATCHER_IMPLEMENTATION 692 #include "VEGenAsmMatcher.inc" 693