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 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 66 unsigned Kind) override; 67 68 // Custom parse functions for VE specific operands. 69 OperandMatchResultTy parseMEMOperand(OperandVector &Operands); 70 OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name); 71 OperandMatchResultTy parseVEAsmOperand(std::unique_ptr<VEOperand> &Operand); 72 73 public: 74 VEAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser, 75 const MCInstrInfo &MII, const MCTargetOptions &Options) 76 : MCTargetAsmParser(Options, sti, MII), Parser(parser) { 77 // Initialize the set of available features. 78 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); 79 } 80 }; 81 82 } // end anonymous namespace 83 84 static const MCPhysReg I32Regs[64] = { 85 VE::SW0, VE::SW1, VE::SW2, VE::SW3, VE::SW4, VE::SW5, VE::SW6, 86 VE::SW7, VE::SW8, VE::SW9, VE::SW10, VE::SW11, VE::SW12, VE::SW13, 87 VE::SW14, VE::SW15, VE::SW16, VE::SW17, VE::SW18, VE::SW19, VE::SW20, 88 VE::SW21, VE::SW22, VE::SW23, VE::SW24, VE::SW25, VE::SW26, VE::SW27, 89 VE::SW28, VE::SW29, VE::SW30, VE::SW31, VE::SW32, VE::SW33, VE::SW34, 90 VE::SW35, VE::SW36, VE::SW37, VE::SW38, VE::SW39, VE::SW40, VE::SW41, 91 VE::SW42, VE::SW43, VE::SW44, VE::SW45, VE::SW46, VE::SW47, VE::SW48, 92 VE::SW49, VE::SW50, VE::SW51, VE::SW52, VE::SW53, VE::SW54, VE::SW55, 93 VE::SW56, VE::SW57, VE::SW58, VE::SW59, VE::SW60, VE::SW61, VE::SW62, 94 VE::SW63}; 95 96 static const MCPhysReg F32Regs[64] = { 97 VE::SF0, VE::SF1, VE::SF2, VE::SF3, VE::SF4, VE::SF5, VE::SF6, 98 VE::SF7, VE::SF8, VE::SF9, VE::SF10, VE::SF11, VE::SF12, VE::SF13, 99 VE::SF14, VE::SF15, VE::SF16, VE::SF17, VE::SF18, VE::SF19, VE::SF20, 100 VE::SF21, VE::SF22, VE::SF23, VE::SF24, VE::SF25, VE::SF26, VE::SF27, 101 VE::SF28, VE::SF29, VE::SF30, VE::SF31, VE::SF32, VE::SF33, VE::SF34, 102 VE::SF35, VE::SF36, VE::SF37, VE::SF38, VE::SF39, VE::SF40, VE::SF41, 103 VE::SF42, VE::SF43, VE::SF44, VE::SF45, VE::SF46, VE::SF47, VE::SF48, 104 VE::SF49, VE::SF50, VE::SF51, VE::SF52, VE::SF53, VE::SF54, VE::SF55, 105 VE::SF56, VE::SF57, VE::SF58, VE::SF59, VE::SF60, VE::SF61, VE::SF62, 106 VE::SF63}; 107 108 namespace { 109 110 /// VEOperand - Instances of this class represent a parsed VE machine 111 /// instruction. 112 class VEOperand : public MCParsedAsmOperand { 113 private: 114 enum KindTy { 115 k_Token, 116 k_Register, 117 k_Immediate, 118 // SX-Aurora ASX form is disp(index, base). 119 k_MemoryRegRegImm, // base=reg, index=reg, disp=imm 120 k_MemoryRegImmImm, // base=reg, index=imm, disp=imm 121 k_MemoryZeroRegImm, // base=0, index=reg, disp=imm 122 k_MemoryZeroImmImm, // base=0, index=imm, disp=imm 123 } Kind; 124 125 SMLoc StartLoc, EndLoc; 126 127 struct Token { 128 const char *Data; 129 unsigned Length; 130 }; 131 132 struct RegOp { 133 unsigned RegNum; 134 }; 135 136 struct ImmOp { 137 const MCExpr *Val; 138 }; 139 140 struct MemOp { 141 unsigned Base; 142 unsigned IndexReg; 143 const MCExpr *Index; 144 const MCExpr *Offset; 145 }; 146 147 union { 148 struct Token Tok; 149 struct RegOp Reg; 150 struct ImmOp Imm; 151 struct MemOp Mem; 152 }; 153 154 public: 155 VEOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 156 157 bool isToken() const override { return Kind == k_Token; } 158 bool isReg() const override { return Kind == k_Register; } 159 bool isImm() const override { return Kind == k_Immediate; } 160 bool isMem() const override { 161 return isMEMrri() || isMEMrii() || isMEMzri() || isMEMzii() || isMEMri() || 162 isMEMzi(); 163 } 164 bool isMEMrri() const { return Kind == k_MemoryRegRegImm; } 165 bool isMEMrii() const { return Kind == k_MemoryRegImmImm; } 166 bool isMEMzri() const { return Kind == k_MemoryZeroRegImm; } 167 bool isMEMzii() const { return Kind == k_MemoryZeroImmImm; } 168 // isMEMri and isMEMzi will be implemented later. 169 bool isMEMri() const { return false; } 170 bool isMEMzi() const { return false; } 171 bool isSImm7() { 172 if (!isImm()) 173 return false; 174 175 // Constant case 176 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) { 177 int64_t Value = ConstExpr->getValue(); 178 return isInt<7>(Value); 179 } 180 return false; 181 } 182 183 StringRef getToken() const { 184 assert(Kind == k_Token && "Invalid access!"); 185 return StringRef(Tok.Data, Tok.Length); 186 } 187 188 unsigned getReg() const override { 189 assert((Kind == k_Register) && "Invalid access!"); 190 return Reg.RegNum; 191 } 192 193 const MCExpr *getImm() const { 194 assert((Kind == k_Immediate) && "Invalid access!"); 195 return Imm.Val; 196 } 197 198 unsigned getMemBase() const { 199 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm) && 200 "Invalid access!"); 201 return Mem.Base; 202 } 203 204 unsigned getMemIndexReg() const { 205 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryZeroRegImm) && 206 "Invalid access!"); 207 return Mem.IndexReg; 208 } 209 210 const MCExpr *getMemIndex() const { 211 assert((Kind == k_MemoryRegImmImm || Kind == k_MemoryZeroImmImm) && 212 "Invalid access!"); 213 return Mem.Index; 214 } 215 216 const MCExpr *getMemOffset() const { 217 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm || 218 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm) && 219 "Invalid access!"); 220 return Mem.Offset; 221 } 222 223 void setMemOffset(const MCExpr *off) { 224 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm || 225 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm) && 226 "Invalid access!"); 227 Mem.Offset = off; 228 } 229 230 /// getStartLoc - Get the location of the first token of this operand. 231 SMLoc getStartLoc() const override { return StartLoc; } 232 /// getEndLoc - Get the location of the last token of this operand. 233 SMLoc getEndLoc() const override { return EndLoc; } 234 235 void print(raw_ostream &OS) const override { 236 switch (Kind) { 237 case k_Token: 238 OS << "Token: " << getToken() << "\n"; 239 break; 240 case k_Register: 241 OS << "Reg: #" << getReg() << "\n"; 242 break; 243 case k_Immediate: 244 OS << "Imm: " << getImm() << "\n"; 245 break; 246 case k_MemoryRegRegImm: 247 assert(getMemOffset() != nullptr); 248 OS << "Mem: #" << getMemBase() << "+#" << getMemIndexReg() << "+" 249 << *getMemOffset() << "\n"; 250 break; 251 case k_MemoryRegImmImm: 252 assert(getMemIndex() != nullptr && getMemOffset() != nullptr); 253 OS << "Mem: #" << getMemBase() << "+" << *getMemIndex() << "+" 254 << *getMemOffset() << "\n"; 255 break; 256 case k_MemoryZeroRegImm: 257 assert(getMemOffset() != nullptr); 258 OS << "Mem: 0+#" << getMemIndexReg() << "+" << *getMemOffset() << "\n"; 259 break; 260 case k_MemoryZeroImmImm: 261 assert(getMemIndex() != nullptr && getMemOffset() != nullptr); 262 OS << "Mem: 0+" << *getMemIndex() << "+" << *getMemOffset() << "\n"; 263 break; 264 } 265 } 266 267 void addRegOperands(MCInst &Inst, unsigned N) const { 268 assert(N == 1 && "Invalid number of operands!"); 269 Inst.addOperand(MCOperand::createReg(getReg())); 270 } 271 272 void addImmOperands(MCInst &Inst, unsigned N) const { 273 assert(N == 1 && "Invalid number of operands!"); 274 const MCExpr *Expr = getImm(); 275 addExpr(Inst, Expr); 276 } 277 278 void addSImm7Operands(MCInst &Inst, unsigned N) const { 279 addImmOperands(Inst, N); 280 } 281 282 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 283 // Add as immediate when possible. Null MCExpr = 0. 284 if (!Expr) 285 Inst.addOperand(MCOperand::createImm(0)); 286 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 287 Inst.addOperand(MCOperand::createImm(CE->getValue())); 288 else 289 Inst.addOperand(MCOperand::createExpr(Expr)); 290 } 291 292 void addMEMrriOperands(MCInst &Inst, unsigned N) const { 293 assert(N == 3 && "Invalid number of operands!"); 294 295 Inst.addOperand(MCOperand::createReg(getMemBase())); 296 Inst.addOperand(MCOperand::createReg(getMemIndexReg())); 297 addExpr(Inst, getMemOffset()); 298 } 299 300 void addMEMriiOperands(MCInst &Inst, unsigned N) const { 301 assert(N == 3 && "Invalid number of operands!"); 302 303 Inst.addOperand(MCOperand::createReg(getMemBase())); 304 addExpr(Inst, getMemIndex()); 305 addExpr(Inst, getMemOffset()); 306 } 307 308 void addMEMzriOperands(MCInst &Inst, unsigned N) const { 309 assert(N == 3 && "Invalid number of operands!"); 310 311 Inst.addOperand(MCOperand::createImm(0)); 312 Inst.addOperand(MCOperand::createReg(getMemIndexReg())); 313 addExpr(Inst, getMemOffset()); 314 } 315 316 void addMEMziiOperands(MCInst &Inst, unsigned N) const { 317 assert(N == 3 && "Invalid number of operands!"); 318 319 Inst.addOperand(MCOperand::createImm(0)); 320 addExpr(Inst, getMemIndex()); 321 addExpr(Inst, getMemOffset()); 322 } 323 324 void addMEMriOperands(MCInst &Inst, unsigned N) const { 325 // FIXME: implement 326 } 327 328 void addMEMziOperands(MCInst &Inst, unsigned N) const { 329 // FIXME: implement 330 } 331 332 static std::unique_ptr<VEOperand> CreateToken(StringRef Str, SMLoc S) { 333 auto Op = std::make_unique<VEOperand>(k_Token); 334 Op->Tok.Data = Str.data(); 335 Op->Tok.Length = Str.size(); 336 Op->StartLoc = S; 337 Op->EndLoc = S; 338 return Op; 339 } 340 341 static std::unique_ptr<VEOperand> CreateReg(unsigned RegNum, SMLoc S, 342 SMLoc E) { 343 auto Op = std::make_unique<VEOperand>(k_Register); 344 Op->Reg.RegNum = RegNum; 345 Op->StartLoc = S; 346 Op->EndLoc = E; 347 return Op; 348 } 349 350 static std::unique_ptr<VEOperand> CreateImm(const MCExpr *Val, SMLoc S, 351 SMLoc E) { 352 auto Op = std::make_unique<VEOperand>(k_Immediate); 353 Op->Imm.Val = Val; 354 Op->StartLoc = S; 355 Op->EndLoc = E; 356 return Op; 357 } 358 359 static bool MorphToI32Reg(VEOperand &Op) { 360 unsigned Reg = Op.getReg(); 361 unsigned regIdx = Reg - VE::SX0; 362 if (regIdx > 63) 363 return false; 364 Op.Reg.RegNum = I32Regs[regIdx]; 365 return true; 366 } 367 368 static bool MorphToF32Reg(VEOperand &Op) { 369 unsigned Reg = Op.getReg(); 370 unsigned regIdx = Reg - VE::SX0; 371 if (regIdx > 63) 372 return false; 373 Op.Reg.RegNum = F32Regs[regIdx]; 374 return true; 375 } 376 377 static std::unique_ptr<VEOperand> 378 MorphToMEMrri(unsigned Base, unsigned Index, std::unique_ptr<VEOperand> Op) { 379 const MCExpr *Imm = Op->getImm(); 380 Op->Kind = k_MemoryRegRegImm; 381 Op->Mem.Base = Base; 382 Op->Mem.IndexReg = Index; 383 Op->Mem.Index = nullptr; 384 Op->Mem.Offset = Imm; 385 return Op; 386 } 387 388 static std::unique_ptr<VEOperand> 389 MorphToMEMrii(unsigned Base, const MCExpr *Index, 390 std::unique_ptr<VEOperand> Op) { 391 const MCExpr *Imm = Op->getImm(); 392 Op->Kind = k_MemoryRegImmImm; 393 Op->Mem.Base = Base; 394 Op->Mem.IndexReg = 0; 395 Op->Mem.Index = Index; 396 Op->Mem.Offset = Imm; 397 return Op; 398 } 399 400 static std::unique_ptr<VEOperand> 401 MorphToMEMzri(unsigned Index, std::unique_ptr<VEOperand> Op) { 402 const MCExpr *Imm = Op->getImm(); 403 Op->Kind = k_MemoryZeroRegImm; 404 Op->Mem.Base = 0; 405 Op->Mem.IndexReg = Index; 406 Op->Mem.Index = nullptr; 407 Op->Mem.Offset = Imm; 408 return Op; 409 } 410 411 static std::unique_ptr<VEOperand> 412 MorphToMEMzii(const MCExpr *Index, std::unique_ptr<VEOperand> Op) { 413 const MCExpr *Imm = Op->getImm(); 414 Op->Kind = k_MemoryZeroImmImm; 415 Op->Mem.Base = 0; 416 Op->Mem.IndexReg = 0; 417 Op->Mem.Index = Index; 418 Op->Mem.Offset = Imm; 419 return Op; 420 } 421 }; 422 423 } // end anonymous namespace 424 425 bool VEAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 426 OperandVector &Operands, 427 MCStreamer &Out, uint64_t &ErrorInfo, 428 bool MatchingInlineAsm) { 429 MCInst Inst; 430 unsigned MatchResult = 431 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 432 switch (MatchResult) { 433 case Match_Success: 434 Inst.setLoc(IDLoc); 435 Out.emitInstruction(Inst, getSTI()); 436 return false; 437 438 case Match_MissingFeature: 439 return Error(IDLoc, 440 "instruction requires a CPU feature not currently enabled"); 441 442 case Match_InvalidOperand: { 443 SMLoc ErrorLoc = IDLoc; 444 if (ErrorInfo != ~0ULL) { 445 if (ErrorInfo >= Operands.size()) 446 return Error(IDLoc, "too few operands for instruction"); 447 448 ErrorLoc = ((VEOperand &)*Operands[ErrorInfo]).getStartLoc(); 449 if (ErrorLoc == SMLoc()) 450 ErrorLoc = IDLoc; 451 } 452 453 return Error(ErrorLoc, "invalid operand for instruction"); 454 } 455 case Match_MnemonicFail: 456 return Error(IDLoc, "invalid instruction mnemonic"); 457 } 458 llvm_unreachable("Implement any new match types added!"); 459 } 460 461 bool VEAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 462 SMLoc &EndLoc) { 463 if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success) 464 return Error(StartLoc, "invalid register name"); 465 return false; 466 } 467 468 /// Parses a register name using a given matching function. 469 /// Checks for lowercase or uppercase if necessary. 470 int VEAsmParser::parseRegisterName(unsigned (*matchFn)(StringRef)) { 471 StringRef Name = Parser.getTok().getString(); 472 473 int RegNum = matchFn(Name); 474 475 // GCC supports case insensitive register names. All of the VE registers 476 // are all lower case. 477 if (RegNum == VE::NoRegister) { 478 RegNum = matchFn(Name.lower()); 479 } 480 481 return RegNum; 482 } 483 484 /// Maps from the set of all register names to a register number. 485 /// \note Generated by TableGen. 486 static unsigned MatchRegisterName(StringRef Name); 487 488 /// Maps from the set of all alternative registernames to a register number. 489 /// \note Generated by TableGen. 490 static unsigned MatchRegisterAltName(StringRef Name); 491 492 OperandMatchResultTy 493 VEAsmParser::tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { 494 const AsmToken Tok = Parser.getTok(); 495 StartLoc = Tok.getLoc(); 496 EndLoc = Tok.getEndLoc(); 497 RegNo = 0; 498 if (getLexer().getKind() != AsmToken::Percent) 499 return MatchOperand_NoMatch; 500 Parser.Lex(); 501 502 RegNo = parseRegisterName(&MatchRegisterName); 503 if (RegNo == VE::NoRegister) 504 RegNo = parseRegisterName(&MatchRegisterAltName); 505 506 if (RegNo != VE::NoRegister) { 507 Parser.Lex(); 508 return MatchOperand_Success; 509 } 510 511 getLexer().UnLex(Tok); 512 return MatchOperand_NoMatch; 513 } 514 515 bool VEAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 516 SMLoc NameLoc, OperandVector &Operands) { 517 518 // First operand in MCInst is instruction mnemonic. 519 Operands.push_back(VEOperand::CreateToken(Name, NameLoc)); 520 521 if (getLexer().isNot(AsmToken::EndOfStatement)) { 522 // Read the first operand. 523 if (parseOperand(Operands, Name) != MatchOperand_Success) { 524 SMLoc Loc = getLexer().getLoc(); 525 return Error(Loc, "unexpected token"); 526 } 527 528 while (getLexer().is(AsmToken::Comma)) { 529 Parser.Lex(); // Eat the comma. 530 // Parse and remember the operand. 531 if (parseOperand(Operands, Name) != MatchOperand_Success) { 532 SMLoc Loc = getLexer().getLoc(); 533 return Error(Loc, "unexpected token"); 534 } 535 } 536 } 537 if (getLexer().isNot(AsmToken::EndOfStatement)) { 538 SMLoc Loc = getLexer().getLoc(); 539 return Error(Loc, "unexpected token"); 540 } 541 Parser.Lex(); // Consume the EndOfStatement. 542 return false; 543 } 544 545 bool VEAsmParser::ParseDirective(AsmToken DirectiveID) { 546 // Let the MC layer to handle other directives. 547 return true; 548 } 549 550 OperandMatchResultTy VEAsmParser::parseMEMOperand(OperandVector &Operands) { 551 LLVM_DEBUG(dbgs() << "parseMEMOperand\n"); 552 const AsmToken &Tok = Parser.getTok(); 553 SMLoc S = Tok.getLoc(); 554 SMLoc E = Tok.getEndLoc(); 555 // Parse ASX format 556 // disp 557 // disp(, base) 558 // disp(index) 559 // disp(index, base) 560 // (, base) 561 // (index) 562 // (index, base) 563 564 std::unique_ptr<VEOperand> Offset; 565 switch (getLexer().getKind()) { 566 default: 567 return MatchOperand_NoMatch; 568 569 case AsmToken::Minus: 570 case AsmToken::Integer: 571 case AsmToken::Dot: { 572 const MCExpr *EVal; 573 if (!getParser().parseExpression(EVal, E)) 574 Offset = VEOperand::CreateImm(EVal, S, E); 575 else 576 return MatchOperand_NoMatch; 577 break; 578 } 579 case AsmToken::LParen: 580 // empty disp (= 0) 581 Offset = 582 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E); 583 break; 584 } 585 586 switch (getLexer().getKind()) { 587 default: 588 return MatchOperand_ParseFail; 589 590 case AsmToken::EndOfStatement: 591 Operands.push_back(VEOperand::MorphToMEMzii( 592 MCConstantExpr::create(0, getContext()), std::move(Offset))); 593 return MatchOperand_Success; 594 595 case AsmToken::LParen: 596 Parser.Lex(); // Eat the ( 597 break; 598 } 599 600 const MCExpr *IndexValue = nullptr; 601 unsigned IndexReg = 0; 602 603 switch (getLexer().getKind()) { 604 default: 605 if (ParseRegister(IndexReg, S, E)) 606 return MatchOperand_ParseFail; 607 break; 608 609 case AsmToken::Minus: 610 case AsmToken::Integer: 611 case AsmToken::Dot: 612 if (getParser().parseExpression(IndexValue, E)) 613 return MatchOperand_ParseFail; 614 break; 615 616 case AsmToken::Comma: 617 // empty index 618 IndexValue = MCConstantExpr::create(0, getContext()); 619 break; 620 } 621 622 switch (getLexer().getKind()) { 623 default: 624 return MatchOperand_ParseFail; 625 626 case AsmToken::RParen: 627 Parser.Lex(); // Eat the ) 628 Operands.push_back( 629 IndexValue ? VEOperand::MorphToMEMzii(IndexValue, std::move(Offset)) 630 : VEOperand::MorphToMEMzri(IndexReg, std::move(Offset))); 631 return MatchOperand_Success; 632 633 case AsmToken::Comma: 634 Parser.Lex(); // Eat the , 635 break; 636 } 637 638 unsigned BaseReg = 0; 639 if (ParseRegister(BaseReg, S, E)) 640 return MatchOperand_ParseFail; 641 642 if (!Parser.getTok().is(AsmToken::RParen)) 643 return MatchOperand_ParseFail; 644 645 Parser.Lex(); // Eat the ) 646 Operands.push_back( 647 IndexValue 648 ? VEOperand::MorphToMEMrii(BaseReg, IndexValue, std::move(Offset)) 649 : VEOperand::MorphToMEMrri(BaseReg, IndexReg, std::move(Offset))); 650 651 return MatchOperand_Success; 652 } 653 654 OperandMatchResultTy VEAsmParser::parseOperand(OperandVector &Operands, 655 StringRef Mnemonic) { 656 LLVM_DEBUG(dbgs() << "parseOperand\n"); 657 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 658 659 // If there wasn't a custom match, try the generic matcher below. Otherwise, 660 // there was a match, but an error occurred, in which case, just return that 661 // the operand parsing failed. 662 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail) 663 return ResTy; 664 665 switch (getLexer().getKind()) { 666 case AsmToken::LParen: 667 // FIXME: Parsing "(" + %vreg + ", " + %vreg + ")" 668 // FALLTHROUGH 669 default: { 670 std::unique_ptr<VEOperand> Op; 671 ResTy = parseVEAsmOperand(Op); 672 if (ResTy != MatchOperand_Success || !Op) 673 return MatchOperand_ParseFail; 674 675 // Push the parsed operand into the list of operands 676 Operands.push_back(std::move(Op)); 677 678 if (!Parser.getTok().is(AsmToken::LParen)) 679 break; 680 681 // FIXME: Parsing %vec-reg + "(" + %sclar-reg/number + ")" 682 break; 683 } 684 } 685 686 return MatchOperand_Success; 687 } 688 689 OperandMatchResultTy 690 VEAsmParser::parseVEAsmOperand(std::unique_ptr<VEOperand> &Op) { 691 LLVM_DEBUG(dbgs() << "parseVEAsmOperand\n"); 692 SMLoc S = Parser.getTok().getLoc(); 693 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 694 const MCExpr *EVal; 695 696 Op = nullptr; 697 switch (getLexer().getKind()) { 698 default: 699 break; 700 701 case AsmToken::Percent: 702 unsigned RegNo; 703 if (tryParseRegister(RegNo, S, E) == MatchOperand_Success) 704 Op = VEOperand::CreateReg(RegNo, S, E); 705 break; 706 707 case AsmToken::Minus: 708 case AsmToken::Integer: 709 case AsmToken::Dot: 710 if (!getParser().parseExpression(EVal, E)) 711 Op = VEOperand::CreateImm(EVal, S, E); 712 break; 713 714 case AsmToken::Identifier: { 715 StringRef Identifier; 716 if (!getParser().parseIdentifier(Identifier)) { 717 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 718 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 719 720 const MCExpr *Res = 721 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 722 Op = VEOperand::CreateImm(Res, S, E); 723 } 724 break; 725 } 726 } 727 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail; 728 } 729 730 // Force static initialization. 731 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmParser() { 732 RegisterMCAsmParser<VEAsmParser> A(getTheVETarget()); 733 } 734 735 #define GET_REGISTER_MATCHER 736 #define GET_MATCHER_IMPLEMENTATION 737 #include "VEGenAsmMatcher.inc" 738 739 unsigned VEAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp, 740 unsigned Kind) { 741 VEOperand &Op = (VEOperand &)GOp; 742 743 // VE uses identical register name for all registers like both 744 // F32 and I32 uses "%s23". Need to convert the name of them 745 // for validation. 746 switch (Kind) { 747 default: 748 break; 749 case MCK_F32: 750 if (Op.isReg() && VEOperand::MorphToF32Reg(Op)) 751 return MCTargetAsmParser::Match_Success; 752 break; 753 case MCK_I32: 754 if (Op.isReg() && VEOperand::MorphToI32Reg(Op)) 755 return MCTargetAsmParser::Match_Success; 756 break; 757 } 758 return Match_InvalidOperand; 759 } 760