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 // Helper function to parse and generate identifier with relocation. 69 const MCExpr *parseIdentifier(StringRef Identifier); 70 // Custom parse functions for VE specific operands. 71 OperandMatchResultTy parseMEMOperand(OperandVector &Operands); 72 OperandMatchResultTy parseMEMAsOperand(OperandVector &Operands); 73 OperandMatchResultTy parseCCOpOperand(OperandVector &Operands); 74 OperandMatchResultTy parseRDOpOperand(OperandVector &Operands); 75 OperandMatchResultTy parseMImmOperand(OperandVector &Operands); 76 OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name); 77 OperandMatchResultTy parseVEAsmOperand(std::unique_ptr<VEOperand> &Operand); 78 // Split the mnemonic stripping conditional code and quantifiers 79 StringRef splitMnemonic(StringRef Name, SMLoc NameLoc, 80 OperandVector *Operands); 81 82 public: 83 VEAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser, 84 const MCInstrInfo &MII, const MCTargetOptions &Options) 85 : MCTargetAsmParser(Options, sti, MII), Parser(parser) { 86 // Initialize the set of available features. 87 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); 88 } 89 }; 90 91 } // end anonymous namespace 92 93 static const MCPhysReg I32Regs[64] = { 94 VE::SW0, VE::SW1, VE::SW2, VE::SW3, VE::SW4, VE::SW5, VE::SW6, 95 VE::SW7, VE::SW8, VE::SW9, VE::SW10, VE::SW11, VE::SW12, VE::SW13, 96 VE::SW14, VE::SW15, VE::SW16, VE::SW17, VE::SW18, VE::SW19, VE::SW20, 97 VE::SW21, VE::SW22, VE::SW23, VE::SW24, VE::SW25, VE::SW26, VE::SW27, 98 VE::SW28, VE::SW29, VE::SW30, VE::SW31, VE::SW32, VE::SW33, VE::SW34, 99 VE::SW35, VE::SW36, VE::SW37, VE::SW38, VE::SW39, VE::SW40, VE::SW41, 100 VE::SW42, VE::SW43, VE::SW44, VE::SW45, VE::SW46, VE::SW47, VE::SW48, 101 VE::SW49, VE::SW50, VE::SW51, VE::SW52, VE::SW53, VE::SW54, VE::SW55, 102 VE::SW56, VE::SW57, VE::SW58, VE::SW59, VE::SW60, VE::SW61, VE::SW62, 103 VE::SW63}; 104 105 static const MCPhysReg F32Regs[64] = { 106 VE::SF0, VE::SF1, VE::SF2, VE::SF3, VE::SF4, VE::SF5, VE::SF6, 107 VE::SF7, VE::SF8, VE::SF9, VE::SF10, VE::SF11, VE::SF12, VE::SF13, 108 VE::SF14, VE::SF15, VE::SF16, VE::SF17, VE::SF18, VE::SF19, VE::SF20, 109 VE::SF21, VE::SF22, VE::SF23, VE::SF24, VE::SF25, VE::SF26, VE::SF27, 110 VE::SF28, VE::SF29, VE::SF30, VE::SF31, VE::SF32, VE::SF33, VE::SF34, 111 VE::SF35, VE::SF36, VE::SF37, VE::SF38, VE::SF39, VE::SF40, VE::SF41, 112 VE::SF42, VE::SF43, VE::SF44, VE::SF45, VE::SF46, VE::SF47, VE::SF48, 113 VE::SF49, VE::SF50, VE::SF51, VE::SF52, VE::SF53, VE::SF54, VE::SF55, 114 VE::SF56, VE::SF57, VE::SF58, VE::SF59, VE::SF60, VE::SF61, VE::SF62, 115 VE::SF63}; 116 117 static const MCPhysReg F128Regs[32] = { 118 VE::Q0, VE::Q1, VE::Q2, VE::Q3, VE::Q4, VE::Q5, VE::Q6, VE::Q7, 119 VE::Q8, VE::Q9, VE::Q10, VE::Q11, VE::Q12, VE::Q13, VE::Q14, VE::Q15, 120 VE::Q16, VE::Q17, VE::Q18, VE::Q19, VE::Q20, VE::Q21, VE::Q22, VE::Q23, 121 VE::Q24, VE::Q25, VE::Q26, VE::Q27, VE::Q28, VE::Q29, VE::Q30, VE::Q31}; 122 123 static const MCPhysReg MISCRegs[31] = { 124 VE::USRCC, VE::PSW, VE::SAR, VE::NoRegister, 125 VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::PMMR, 126 VE::PMCR0, VE::PMCR1, VE::PMCR2, VE::PMCR3, 127 VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::NoRegister, 128 VE::PMC0, VE::PMC1, VE::PMC2, VE::PMC3, 129 VE::PMC4, VE::PMC5, VE::PMC6, VE::PMC7, 130 VE::PMC8, VE::PMC9, VE::PMC10, VE::PMC11, 131 VE::PMC12, VE::PMC13, VE::PMC14}; 132 133 namespace { 134 135 /// VEOperand - Instances of this class represent a parsed VE machine 136 /// instruction. 137 class VEOperand : public MCParsedAsmOperand { 138 private: 139 enum KindTy { 140 k_Token, 141 k_Register, 142 k_Immediate, 143 // SX-Aurora ASX form is disp(index, base). 144 k_MemoryRegRegImm, // base=reg, index=reg, disp=imm 145 k_MemoryRegImmImm, // base=reg, index=imm, disp=imm 146 k_MemoryZeroRegImm, // base=0, index=reg, disp=imm 147 k_MemoryZeroImmImm, // base=0, index=imm, disp=imm 148 // SX-Aurora AS form is disp(base). 149 k_MemoryRegImm, // base=reg, disp=imm 150 k_MemoryZeroImm, // base=0, disp=imm 151 // Other special cases for Aurora VE 152 k_CCOp, // condition code 153 k_RDOp, // rounding mode 154 k_MImmOp, // Special immediate value of sequential bit stream of 0 or 1. 155 } Kind; 156 157 SMLoc StartLoc, EndLoc; 158 159 struct Token { 160 const char *Data; 161 unsigned Length; 162 }; 163 164 struct RegOp { 165 unsigned RegNum; 166 }; 167 168 struct ImmOp { 169 const MCExpr *Val; 170 }; 171 172 struct MemOp { 173 unsigned Base; 174 unsigned IndexReg; 175 const MCExpr *Index; 176 const MCExpr *Offset; 177 }; 178 179 struct CCOp { 180 unsigned CCVal; 181 }; 182 183 struct RDOp { 184 unsigned RDVal; 185 }; 186 187 struct MImmOp { 188 const MCExpr *Val; 189 bool M0Flag; 190 }; 191 192 union { 193 struct Token Tok; 194 struct RegOp Reg; 195 struct ImmOp Imm; 196 struct MemOp Mem; 197 struct CCOp CC; 198 struct RDOp RD; 199 struct MImmOp MImm; 200 }; 201 202 public: 203 VEOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 204 205 bool isToken() const override { return Kind == k_Token; } 206 bool isReg() const override { return Kind == k_Register; } 207 bool isImm() const override { return Kind == k_Immediate; } 208 bool isMem() const override { 209 return isMEMrri() || isMEMrii() || isMEMzri() || isMEMzii() || isMEMri() || 210 isMEMzi(); 211 } 212 bool isMEMrri() const { return Kind == k_MemoryRegRegImm; } 213 bool isMEMrii() const { return Kind == k_MemoryRegImmImm; } 214 bool isMEMzri() const { return Kind == k_MemoryZeroRegImm; } 215 bool isMEMzii() const { return Kind == k_MemoryZeroImmImm; } 216 bool isMEMri() const { return Kind == k_MemoryRegImm; } 217 bool isMEMzi() const { return Kind == k_MemoryZeroImm; } 218 bool isCCOp() const { return Kind == k_CCOp; } 219 bool isRDOp() const { return Kind == k_RDOp; } 220 bool isZero() { 221 if (!isImm()) 222 return false; 223 224 // Constant case 225 if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) { 226 int64_t Value = ConstExpr->getValue(); 227 return Value == 0; 228 } 229 return false; 230 } 231 bool isUImm0to2() { 232 if (!isImm()) 233 return false; 234 235 // Constant case 236 if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) { 237 int64_t Value = ConstExpr->getValue(); 238 return Value >= 0 && Value < 3; 239 } 240 return false; 241 } 242 bool isUImm1() { 243 if (!isImm()) 244 return false; 245 246 // Constant case 247 if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) { 248 int64_t Value = ConstExpr->getValue(); 249 return isUInt<1>(Value); 250 } 251 return false; 252 } 253 bool isUImm2() { 254 if (!isImm()) 255 return false; 256 257 // Constant case 258 if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) { 259 int64_t Value = ConstExpr->getValue(); 260 return isUInt<2>(Value); 261 } 262 return false; 263 } 264 bool isUImm3() { 265 if (!isImm()) 266 return false; 267 268 // Constant case 269 if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) { 270 int64_t Value = ConstExpr->getValue(); 271 return isUInt<3>(Value); 272 } 273 return false; 274 } 275 bool isUImm6() { 276 if (!isImm()) 277 return false; 278 279 // Constant case 280 if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) { 281 int64_t Value = ConstExpr->getValue(); 282 return isUInt<6>(Value); 283 } 284 return false; 285 } 286 bool isUImm7() { 287 if (!isImm()) 288 return false; 289 290 // Constant case 291 if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) { 292 int64_t Value = ConstExpr->getValue(); 293 return isUInt<7>(Value); 294 } 295 return false; 296 } 297 bool isSImm7() { 298 if (!isImm()) 299 return false; 300 301 // Constant case 302 if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) { 303 int64_t Value = ConstExpr->getValue(); 304 return isInt<7>(Value); 305 } 306 return false; 307 } 308 bool isMImm() const { 309 if (Kind != k_MImmOp) 310 return false; 311 312 // Constant case 313 if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(MImm.Val)) { 314 int64_t Value = ConstExpr->getValue(); 315 return isUInt<6>(Value); 316 } 317 return false; 318 } 319 320 StringRef getToken() const { 321 assert(Kind == k_Token && "Invalid access!"); 322 return StringRef(Tok.Data, Tok.Length); 323 } 324 325 unsigned getReg() const override { 326 assert((Kind == k_Register) && "Invalid access!"); 327 return Reg.RegNum; 328 } 329 330 const MCExpr *getImm() const { 331 assert((Kind == k_Immediate) && "Invalid access!"); 332 return Imm.Val; 333 } 334 335 unsigned getMemBase() const { 336 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm || 337 Kind == k_MemoryRegImm) && 338 "Invalid access!"); 339 return Mem.Base; 340 } 341 342 unsigned getMemIndexReg() const { 343 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryZeroRegImm) && 344 "Invalid access!"); 345 return Mem.IndexReg; 346 } 347 348 const MCExpr *getMemIndex() const { 349 assert((Kind == k_MemoryRegImmImm || Kind == k_MemoryZeroImmImm) && 350 "Invalid access!"); 351 return Mem.Index; 352 } 353 354 const MCExpr *getMemOffset() const { 355 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm || 356 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm || 357 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) && 358 "Invalid access!"); 359 return Mem.Offset; 360 } 361 362 void setMemOffset(const MCExpr *off) { 363 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm || 364 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm || 365 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) && 366 "Invalid access!"); 367 Mem.Offset = off; 368 } 369 370 unsigned getCCVal() const { 371 assert((Kind == k_CCOp) && "Invalid access!"); 372 return CC.CCVal; 373 } 374 375 unsigned getRDVal() const { 376 assert((Kind == k_RDOp) && "Invalid access!"); 377 return RD.RDVal; 378 } 379 380 const MCExpr *getMImmVal() const { 381 assert((Kind == k_MImmOp) && "Invalid access!"); 382 return MImm.Val; 383 } 384 bool getM0Flag() const { 385 assert((Kind == k_MImmOp) && "Invalid access!"); 386 return MImm.M0Flag; 387 } 388 389 /// getStartLoc - Get the location of the first token of this operand. 390 SMLoc getStartLoc() const override { return StartLoc; } 391 /// getEndLoc - Get the location of the last token of this operand. 392 SMLoc getEndLoc() const override { return EndLoc; } 393 394 void print(raw_ostream &OS) const override { 395 switch (Kind) { 396 case k_Token: 397 OS << "Token: " << getToken() << "\n"; 398 break; 399 case k_Register: 400 OS << "Reg: #" << getReg() << "\n"; 401 break; 402 case k_Immediate: 403 OS << "Imm: " << getImm() << "\n"; 404 break; 405 case k_MemoryRegRegImm: 406 assert(getMemOffset() != nullptr); 407 OS << "Mem: #" << getMemBase() << "+#" << getMemIndexReg() << "+" 408 << *getMemOffset() << "\n"; 409 break; 410 case k_MemoryRegImmImm: 411 assert(getMemIndex() != nullptr && getMemOffset() != nullptr); 412 OS << "Mem: #" << getMemBase() << "+" << *getMemIndex() << "+" 413 << *getMemOffset() << "\n"; 414 break; 415 case k_MemoryZeroRegImm: 416 assert(getMemOffset() != nullptr); 417 OS << "Mem: 0+#" << getMemIndexReg() << "+" << *getMemOffset() << "\n"; 418 break; 419 case k_MemoryZeroImmImm: 420 assert(getMemIndex() != nullptr && getMemOffset() != nullptr); 421 OS << "Mem: 0+" << *getMemIndex() << "+" << *getMemOffset() << "\n"; 422 break; 423 case k_MemoryRegImm: 424 assert(getMemOffset() != nullptr); 425 OS << "Mem: #" << getMemBase() << "+" << *getMemOffset() << "\n"; 426 break; 427 case k_MemoryZeroImm: 428 assert(getMemOffset() != nullptr); 429 OS << "Mem: 0+" << *getMemOffset() << "\n"; 430 break; 431 case k_CCOp: 432 OS << "CCOp: " << getCCVal() << "\n"; 433 break; 434 case k_RDOp: 435 OS << "RDOp: " << getRDVal() << "\n"; 436 break; 437 case k_MImmOp: 438 OS << "MImm: (" << getMImmVal() << (getM0Flag() ? ")0" : ")1") << "\n"; 439 break; 440 } 441 } 442 443 void addRegOperands(MCInst &Inst, unsigned N) const { 444 assert(N == 1 && "Invalid number of operands!"); 445 Inst.addOperand(MCOperand::createReg(getReg())); 446 } 447 448 void addImmOperands(MCInst &Inst, unsigned N) const { 449 assert(N == 1 && "Invalid number of operands!"); 450 const MCExpr *Expr = getImm(); 451 addExpr(Inst, Expr); 452 } 453 454 void addZeroOperands(MCInst &Inst, unsigned N) const { 455 addImmOperands(Inst, N); 456 } 457 458 void addUImm0to2Operands(MCInst &Inst, unsigned N) const { 459 addImmOperands(Inst, N); 460 } 461 462 void addUImm1Operands(MCInst &Inst, unsigned N) const { 463 addImmOperands(Inst, N); 464 } 465 466 void addUImm2Operands(MCInst &Inst, unsigned N) const { 467 addImmOperands(Inst, N); 468 } 469 470 void addUImm3Operands(MCInst &Inst, unsigned N) const { 471 addImmOperands(Inst, N); 472 } 473 474 void addUImm6Operands(MCInst &Inst, unsigned N) const { 475 addImmOperands(Inst, N); 476 } 477 478 void addUImm7Operands(MCInst &Inst, unsigned N) const { 479 addImmOperands(Inst, N); 480 } 481 482 void addSImm7Operands(MCInst &Inst, unsigned N) const { 483 addImmOperands(Inst, N); 484 } 485 486 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 487 // Add as immediate when possible. Null MCExpr = 0. 488 if (!Expr) 489 Inst.addOperand(MCOperand::createImm(0)); 490 else if (const auto *CE = dyn_cast<MCConstantExpr>(Expr)) 491 Inst.addOperand(MCOperand::createImm(CE->getValue())); 492 else 493 Inst.addOperand(MCOperand::createExpr(Expr)); 494 } 495 496 void addMEMrriOperands(MCInst &Inst, unsigned N) const { 497 assert(N == 3 && "Invalid number of operands!"); 498 499 Inst.addOperand(MCOperand::createReg(getMemBase())); 500 Inst.addOperand(MCOperand::createReg(getMemIndexReg())); 501 addExpr(Inst, getMemOffset()); 502 } 503 504 void addMEMriiOperands(MCInst &Inst, unsigned N) const { 505 assert(N == 3 && "Invalid number of operands!"); 506 507 Inst.addOperand(MCOperand::createReg(getMemBase())); 508 addExpr(Inst, getMemIndex()); 509 addExpr(Inst, getMemOffset()); 510 } 511 512 void addMEMzriOperands(MCInst &Inst, unsigned N) const { 513 assert(N == 3 && "Invalid number of operands!"); 514 515 Inst.addOperand(MCOperand::createImm(0)); 516 Inst.addOperand(MCOperand::createReg(getMemIndexReg())); 517 addExpr(Inst, getMemOffset()); 518 } 519 520 void addMEMziiOperands(MCInst &Inst, unsigned N) const { 521 assert(N == 3 && "Invalid number of operands!"); 522 523 Inst.addOperand(MCOperand::createImm(0)); 524 addExpr(Inst, getMemIndex()); 525 addExpr(Inst, getMemOffset()); 526 } 527 528 void addMEMriOperands(MCInst &Inst, unsigned N) const { 529 assert(N == 2 && "Invalid number of operands!"); 530 531 Inst.addOperand(MCOperand::createReg(getMemBase())); 532 addExpr(Inst, getMemOffset()); 533 } 534 535 void addMEMziOperands(MCInst &Inst, unsigned N) const { 536 assert(N == 2 && "Invalid number of operands!"); 537 538 Inst.addOperand(MCOperand::createImm(0)); 539 addExpr(Inst, getMemOffset()); 540 } 541 542 void addCCOpOperands(MCInst &Inst, unsigned N) const { 543 assert(N == 1 && "Invalid number of operands!"); 544 545 Inst.addOperand(MCOperand::createImm(getCCVal())); 546 } 547 548 void addRDOpOperands(MCInst &Inst, unsigned N) const { 549 assert(N == 1 && "Invalid number of operands!"); 550 551 Inst.addOperand(MCOperand::createImm(getRDVal())); 552 } 553 554 void addMImmOperands(MCInst &Inst, unsigned N) const { 555 assert(N == 1 && "Invalid number of operands!"); 556 const auto *ConstExpr = dyn_cast<MCConstantExpr>(getMImmVal()); 557 assert(ConstExpr && "Null operands!"); 558 int64_t Value = ConstExpr->getValue(); 559 if (getM0Flag()) 560 Value += 64; 561 Inst.addOperand(MCOperand::createImm(Value)); 562 } 563 564 static std::unique_ptr<VEOperand> CreateToken(StringRef Str, SMLoc S) { 565 auto Op = std::make_unique<VEOperand>(k_Token); 566 Op->Tok.Data = Str.data(); 567 Op->Tok.Length = Str.size(); 568 Op->StartLoc = S; 569 Op->EndLoc = S; 570 return Op; 571 } 572 573 static std::unique_ptr<VEOperand> CreateReg(unsigned RegNum, SMLoc S, 574 SMLoc E) { 575 auto Op = std::make_unique<VEOperand>(k_Register); 576 Op->Reg.RegNum = RegNum; 577 Op->StartLoc = S; 578 Op->EndLoc = E; 579 return Op; 580 } 581 582 static std::unique_ptr<VEOperand> CreateImm(const MCExpr *Val, SMLoc S, 583 SMLoc E) { 584 auto Op = std::make_unique<VEOperand>(k_Immediate); 585 Op->Imm.Val = Val; 586 Op->StartLoc = S; 587 Op->EndLoc = E; 588 return Op; 589 } 590 591 static std::unique_ptr<VEOperand> CreateCCOp(unsigned CCVal, SMLoc S, 592 SMLoc E) { 593 auto Op = std::make_unique<VEOperand>(k_CCOp); 594 Op->CC.CCVal = CCVal; 595 Op->StartLoc = S; 596 Op->EndLoc = E; 597 return Op; 598 } 599 600 static std::unique_ptr<VEOperand> CreateRDOp(unsigned RDVal, SMLoc S, 601 SMLoc E) { 602 auto Op = std::make_unique<VEOperand>(k_RDOp); 603 Op->RD.RDVal = RDVal; 604 Op->StartLoc = S; 605 Op->EndLoc = E; 606 return Op; 607 } 608 609 static std::unique_ptr<VEOperand> CreateMImm(const MCExpr *Val, bool Flag, 610 SMLoc S, SMLoc E) { 611 auto Op = std::make_unique<VEOperand>(k_MImmOp); 612 Op->MImm.Val = Val; 613 Op->MImm.M0Flag = Flag; 614 Op->StartLoc = S; 615 Op->EndLoc = E; 616 return Op; 617 } 618 619 static bool MorphToI32Reg(VEOperand &Op) { 620 unsigned Reg = Op.getReg(); 621 unsigned regIdx = Reg - VE::SX0; 622 if (regIdx > 63) 623 return false; 624 Op.Reg.RegNum = I32Regs[regIdx]; 625 return true; 626 } 627 628 static bool MorphToF32Reg(VEOperand &Op) { 629 unsigned Reg = Op.getReg(); 630 unsigned regIdx = Reg - VE::SX0; 631 if (regIdx > 63) 632 return false; 633 Op.Reg.RegNum = F32Regs[regIdx]; 634 return true; 635 } 636 637 static bool MorphToF128Reg(VEOperand &Op) { 638 unsigned Reg = Op.getReg(); 639 unsigned regIdx = Reg - VE::SX0; 640 if (regIdx % 2 || regIdx > 63) 641 return false; 642 Op.Reg.RegNum = F128Regs[regIdx / 2]; 643 return true; 644 } 645 646 static bool MorphToMISCReg(VEOperand &Op) { 647 const auto *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm()); 648 if (!ConstExpr) 649 return false; 650 unsigned regIdx = ConstExpr->getValue(); 651 if (regIdx > 31 || MISCRegs[regIdx] == VE::NoRegister) 652 return false; 653 Op.Kind = k_Register; 654 Op.Reg.RegNum = MISCRegs[regIdx]; 655 return true; 656 } 657 658 static std::unique_ptr<VEOperand> 659 MorphToMEMri(unsigned Base, std::unique_ptr<VEOperand> Op) { 660 const MCExpr *Imm = Op->getImm(); 661 Op->Kind = k_MemoryRegImm; 662 Op->Mem.Base = Base; 663 Op->Mem.IndexReg = 0; 664 Op->Mem.Index = nullptr; 665 Op->Mem.Offset = Imm; 666 return Op; 667 } 668 669 static std::unique_ptr<VEOperand> 670 MorphToMEMzi(std::unique_ptr<VEOperand> Op) { 671 const MCExpr *Imm = Op->getImm(); 672 Op->Kind = k_MemoryZeroImm; 673 Op->Mem.Base = 0; 674 Op->Mem.IndexReg = 0; 675 Op->Mem.Index = nullptr; 676 Op->Mem.Offset = Imm; 677 return Op; 678 } 679 680 static std::unique_ptr<VEOperand> 681 MorphToMEMrri(unsigned Base, unsigned Index, std::unique_ptr<VEOperand> Op) { 682 const MCExpr *Imm = Op->getImm(); 683 Op->Kind = k_MemoryRegRegImm; 684 Op->Mem.Base = Base; 685 Op->Mem.IndexReg = Index; 686 Op->Mem.Index = nullptr; 687 Op->Mem.Offset = Imm; 688 return Op; 689 } 690 691 static std::unique_ptr<VEOperand> 692 MorphToMEMrii(unsigned Base, const MCExpr *Index, 693 std::unique_ptr<VEOperand> Op) { 694 const MCExpr *Imm = Op->getImm(); 695 Op->Kind = k_MemoryRegImmImm; 696 Op->Mem.Base = Base; 697 Op->Mem.IndexReg = 0; 698 Op->Mem.Index = Index; 699 Op->Mem.Offset = Imm; 700 return Op; 701 } 702 703 static std::unique_ptr<VEOperand> 704 MorphToMEMzri(unsigned Index, std::unique_ptr<VEOperand> Op) { 705 const MCExpr *Imm = Op->getImm(); 706 Op->Kind = k_MemoryZeroRegImm; 707 Op->Mem.Base = 0; 708 Op->Mem.IndexReg = Index; 709 Op->Mem.Index = nullptr; 710 Op->Mem.Offset = Imm; 711 return Op; 712 } 713 714 static std::unique_ptr<VEOperand> 715 MorphToMEMzii(const MCExpr *Index, std::unique_ptr<VEOperand> Op) { 716 const MCExpr *Imm = Op->getImm(); 717 Op->Kind = k_MemoryZeroImmImm; 718 Op->Mem.Base = 0; 719 Op->Mem.IndexReg = 0; 720 Op->Mem.Index = Index; 721 Op->Mem.Offset = Imm; 722 return Op; 723 } 724 }; 725 726 } // end anonymous namespace 727 728 bool VEAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 729 OperandVector &Operands, 730 MCStreamer &Out, uint64_t &ErrorInfo, 731 bool MatchingInlineAsm) { 732 MCInst Inst; 733 unsigned MatchResult = 734 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 735 switch (MatchResult) { 736 case Match_Success: 737 Inst.setLoc(IDLoc); 738 Out.emitInstruction(Inst, getSTI()); 739 return false; 740 741 case Match_MissingFeature: 742 return Error(IDLoc, 743 "instruction requires a CPU feature not currently enabled"); 744 745 case Match_InvalidOperand: { 746 SMLoc ErrorLoc = IDLoc; 747 if (ErrorInfo != ~0ULL) { 748 if (ErrorInfo >= Operands.size()) 749 return Error(IDLoc, "too few operands for instruction"); 750 751 ErrorLoc = ((VEOperand &)*Operands[ErrorInfo]).getStartLoc(); 752 if (ErrorLoc == SMLoc()) 753 ErrorLoc = IDLoc; 754 } 755 756 return Error(ErrorLoc, "invalid operand for instruction"); 757 } 758 case Match_MnemonicFail: 759 return Error(IDLoc, "invalid instruction mnemonic"); 760 } 761 llvm_unreachable("Implement any new match types added!"); 762 } 763 764 bool VEAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 765 SMLoc &EndLoc) { 766 if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success) 767 return Error(StartLoc, "invalid register name"); 768 return false; 769 } 770 771 /// Parses a register name using a given matching function. 772 /// Checks for lowercase or uppercase if necessary. 773 int VEAsmParser::parseRegisterName(unsigned (*matchFn)(StringRef)) { 774 StringRef Name = Parser.getTok().getString(); 775 776 int RegNum = matchFn(Name); 777 778 // GCC supports case insensitive register names. All of the VE registers 779 // are all lower case. 780 if (RegNum == VE::NoRegister) { 781 RegNum = matchFn(Name.lower()); 782 } 783 784 return RegNum; 785 } 786 787 /// Maps from the set of all register names to a register number. 788 /// \note Generated by TableGen. 789 static unsigned MatchRegisterName(StringRef Name); 790 791 /// Maps from the set of all alternative registernames to a register number. 792 /// \note Generated by TableGen. 793 static unsigned MatchRegisterAltName(StringRef Name); 794 795 OperandMatchResultTy 796 VEAsmParser::tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { 797 const AsmToken Tok = Parser.getTok(); 798 StartLoc = Tok.getLoc(); 799 EndLoc = Tok.getEndLoc(); 800 RegNo = 0; 801 if (getLexer().getKind() != AsmToken::Percent) 802 return MatchOperand_NoMatch; 803 Parser.Lex(); 804 805 RegNo = parseRegisterName(&MatchRegisterName); 806 if (RegNo == VE::NoRegister) 807 RegNo = parseRegisterName(&MatchRegisterAltName); 808 809 if (RegNo != VE::NoRegister) { 810 Parser.Lex(); 811 return MatchOperand_Success; 812 } 813 814 getLexer().UnLex(Tok); 815 return MatchOperand_NoMatch; 816 } 817 818 static StringRef parseCC(StringRef Name, unsigned Prefix, unsigned Suffix, 819 bool IntegerCC, bool OmitCC, SMLoc NameLoc, 820 OperandVector *Operands) { 821 // Parse instructions with a conditional code. For example, 'bne' is 822 // converted into two operands 'b' and 'ne'. 823 StringRef Cond = Name.slice(Prefix, Suffix); 824 VECC::CondCode CondCode = 825 IntegerCC ? stringToVEICondCode(Cond) : stringToVEFCondCode(Cond); 826 827 // If OmitCC is enabled, CC_AT and CC_AF is treated as a part of mnemonic. 828 if (CondCode != VECC::UNKNOWN && 829 (!OmitCC || (CondCode != VECC::CC_AT && CondCode != VECC::CC_AF))) { 830 StringRef SuffixStr = Name.substr(Suffix); 831 // Push "b". 832 Name = Name.slice(0, Prefix); 833 Operands->push_back(VEOperand::CreateToken(Name, NameLoc)); 834 // Push $cond part. 835 SMLoc CondLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Prefix); 836 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Suffix); 837 Operands->push_back(VEOperand::CreateCCOp(CondCode, CondLoc, SuffixLoc)); 838 // push suffix like ".l.t" 839 if (!SuffixStr.empty()) 840 Operands->push_back(VEOperand::CreateToken(SuffixStr, SuffixLoc)); 841 } else { 842 Operands->push_back(VEOperand::CreateToken(Name, NameLoc)); 843 } 844 return Name; 845 } 846 847 static StringRef parseRD(StringRef Name, unsigned Prefix, SMLoc NameLoc, 848 OperandVector *Operands) { 849 // Parse instructions with a conditional code. For example, 'cvt.w.d.sx.rz' 850 // is converted into two operands 'cvt.w.d.sx' and '.rz'. 851 StringRef RD = Name.substr(Prefix); 852 VERD::RoundingMode RoundingMode = stringToVERD(RD); 853 854 if (RoundingMode != VERD::UNKNOWN) { 855 Name = Name.slice(0, Prefix); 856 // push 1st like `cvt.w.d.sx` 857 Operands->push_back(VEOperand::CreateToken(Name, NameLoc)); 858 SMLoc SuffixLoc = 859 SMLoc::getFromPointer(NameLoc.getPointer() + (RD.data() - Name.data())); 860 SMLoc SuffixEnd = 861 SMLoc::getFromPointer(NameLoc.getPointer() + (RD.end() - Name.data())); 862 // push $round if it has rounding mode 863 Operands->push_back( 864 VEOperand::CreateRDOp(RoundingMode, SuffixLoc, SuffixEnd)); 865 } else { 866 Operands->push_back(VEOperand::CreateToken(Name, NameLoc)); 867 } 868 return Name; 869 } 870 871 // Split the mnemonic into ASM operand, conditional code and instruction 872 // qualifier (half-word, byte). 873 StringRef VEAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc, 874 OperandVector *Operands) { 875 // Create the leading tokens for the mnemonic 876 StringRef Mnemonic = Name; 877 878 if (Name[0] == 'b') { 879 // Match b?? or br??. 880 size_t Start = 1; 881 size_t Next = Name.find('.'); 882 // Adjust position of CondCode. 883 if (Name.size() > 1 && Name[1] == 'r') 884 Start = 2; 885 // Check suffix. 886 bool ICC = true; 887 if (Next + 1 < Name.size() && 888 (Name[Next + 1] == 'd' || Name[Next + 1] == 's')) 889 ICC = false; 890 Mnemonic = parseCC(Name, Start, Next, ICC, true, NameLoc, Operands); 891 } else if (Name.startswith("cmov.l.") || Name.startswith("cmov.w.") || 892 Name.startswith("cmov.d.") || Name.startswith("cmov.s.")) { 893 bool ICC = Name[5] == 'l' || Name[5] == 'w'; 894 Mnemonic = parseCC(Name, 7, Name.size(), ICC, false, NameLoc, Operands); 895 } else if (Name.startswith("cvt.w.d.sx") || Name.startswith("cvt.w.d.zx") || 896 Name.startswith("cvt.w.s.sx") || Name.startswith("cvt.w.s.zx")) { 897 Mnemonic = parseRD(Name, 10, NameLoc, Operands); 898 } else if (Name.startswith("cvt.l.d")) { 899 Mnemonic = parseRD(Name, 7, NameLoc, Operands); 900 } else { 901 Operands->push_back(VEOperand::CreateToken(Mnemonic, NameLoc)); 902 } 903 904 return Mnemonic; 905 } 906 907 static void applyMnemonicAliases(StringRef &Mnemonic, 908 const FeatureBitset &Features, 909 unsigned VariantID); 910 911 bool VEAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 912 SMLoc NameLoc, OperandVector &Operands) { 913 // If the target architecture uses MnemonicAlias, call it here to parse 914 // operands correctly. 915 applyMnemonicAliases(Name, getAvailableFeatures(), 0); 916 917 // Split name to first token and the rest, e.g. "bgt.l.t" to "b", "gt", and 918 // ".l.t". We treat "b" as a mnemonic, "gt" as first operand, and ".l.t" 919 // as second operand. 920 StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands); 921 922 if (getLexer().isNot(AsmToken::EndOfStatement)) { 923 // Read the first operand. 924 if (parseOperand(Operands, Mnemonic) != MatchOperand_Success) { 925 SMLoc Loc = getLexer().getLoc(); 926 return Error(Loc, "unexpected token"); 927 } 928 929 while (getLexer().is(AsmToken::Comma)) { 930 Parser.Lex(); // Eat the comma. 931 // Parse and remember the operand. 932 if (parseOperand(Operands, Mnemonic) != MatchOperand_Success) { 933 SMLoc Loc = getLexer().getLoc(); 934 return Error(Loc, "unexpected token"); 935 } 936 } 937 } 938 if (getLexer().isNot(AsmToken::EndOfStatement)) { 939 SMLoc Loc = getLexer().getLoc(); 940 return Error(Loc, "unexpected token"); 941 } 942 Parser.Lex(); // Consume the EndOfStatement. 943 return false; 944 } 945 946 bool VEAsmParser::ParseDirective(AsmToken DirectiveID) { 947 // Let the MC layer to handle other directives. 948 return true; 949 } 950 951 const MCExpr *VEAsmParser::parseIdentifier(StringRef Identifier) { 952 StringRef Modifier; 953 // Search @modifiers like "symbol@hi". 954 size_t at = Identifier.rfind('@'); 955 if (at != 0 || at != StringRef::npos) { 956 std::pair<StringRef, StringRef> Pair = Identifier.rsplit("@"); 957 if (!Pair.first.empty() && !Pair.second.empty()) { 958 Identifier = Pair.first; 959 Modifier = Pair.second; 960 } 961 } 962 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 963 const MCExpr *Res = 964 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 965 VEMCExpr::VariantKind VK = VEMCExpr::parseVariantKind(Modifier); 966 if (VK == VEMCExpr::VK_VE_None) { 967 // Create identifier using default variant kind 968 VEMCExpr::VariantKind Kind = VEMCExpr::VK_VE_REFLONG; 969 return VEMCExpr::create(Kind, Res, getContext()); 970 } 971 return VEMCExpr::create(VK, Res, getContext()); 972 } 973 974 OperandMatchResultTy VEAsmParser::parseMEMOperand(OperandVector &Operands) { 975 LLVM_DEBUG(dbgs() << "parseMEMOperand\n"); 976 const AsmToken &Tok = Parser.getTok(); 977 SMLoc S = Tok.getLoc(); 978 SMLoc E = Tok.getEndLoc(); 979 // Parse ASX format 980 // disp 981 // disp(, base) 982 // disp(index) 983 // disp(index, base) 984 // (, base) 985 // (index) 986 // (index, base) 987 988 std::unique_ptr<VEOperand> Offset; 989 switch (getLexer().getKind()) { 990 default: 991 return MatchOperand_NoMatch; 992 993 case AsmToken::Minus: 994 case AsmToken::Integer: 995 case AsmToken::Dot: { 996 const MCExpr *EVal; 997 if (!getParser().parseExpression(EVal, E)) 998 Offset = VEOperand::CreateImm(EVal, S, E); 999 else 1000 return MatchOperand_NoMatch; 1001 break; 1002 } 1003 1004 case AsmToken::Identifier: { 1005 StringRef Identifier; 1006 if (!getParser().parseIdentifier(Identifier)) { 1007 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1008 const MCExpr *EVal = parseIdentifier(Identifier); 1009 1010 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1011 Offset = VEOperand::CreateImm(EVal, S, E); 1012 } 1013 break; 1014 } 1015 1016 case AsmToken::LParen: 1017 // empty disp (= 0) 1018 Offset = 1019 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E); 1020 break; 1021 } 1022 1023 switch (getLexer().getKind()) { 1024 default: 1025 return MatchOperand_ParseFail; 1026 1027 case AsmToken::EndOfStatement: 1028 Operands.push_back(VEOperand::MorphToMEMzii( 1029 MCConstantExpr::create(0, getContext()), std::move(Offset))); 1030 return MatchOperand_Success; 1031 1032 case AsmToken::LParen: 1033 Parser.Lex(); // Eat the ( 1034 break; 1035 } 1036 1037 const MCExpr *IndexValue = nullptr; 1038 unsigned IndexReg = 0; 1039 1040 switch (getLexer().getKind()) { 1041 default: 1042 if (ParseRegister(IndexReg, S, E)) 1043 return MatchOperand_ParseFail; 1044 break; 1045 1046 case AsmToken::Minus: 1047 case AsmToken::Integer: 1048 case AsmToken::Dot: 1049 if (getParser().parseExpression(IndexValue, E)) 1050 return MatchOperand_ParseFail; 1051 break; 1052 1053 case AsmToken::Comma: 1054 // empty index 1055 IndexValue = MCConstantExpr::create(0, getContext()); 1056 break; 1057 } 1058 1059 switch (getLexer().getKind()) { 1060 default: 1061 return MatchOperand_ParseFail; 1062 1063 case AsmToken::RParen: 1064 Parser.Lex(); // Eat the ) 1065 Operands.push_back( 1066 IndexValue ? VEOperand::MorphToMEMzii(IndexValue, std::move(Offset)) 1067 : VEOperand::MorphToMEMzri(IndexReg, std::move(Offset))); 1068 return MatchOperand_Success; 1069 1070 case AsmToken::Comma: 1071 Parser.Lex(); // Eat the , 1072 break; 1073 } 1074 1075 unsigned BaseReg = 0; 1076 if (ParseRegister(BaseReg, S, E)) 1077 return MatchOperand_ParseFail; 1078 1079 if (!Parser.getTok().is(AsmToken::RParen)) 1080 return MatchOperand_ParseFail; 1081 1082 Parser.Lex(); // Eat the ) 1083 Operands.push_back( 1084 IndexValue 1085 ? VEOperand::MorphToMEMrii(BaseReg, IndexValue, std::move(Offset)) 1086 : VEOperand::MorphToMEMrri(BaseReg, IndexReg, std::move(Offset))); 1087 1088 return MatchOperand_Success; 1089 } 1090 1091 OperandMatchResultTy VEAsmParser::parseMEMAsOperand(OperandVector &Operands) { 1092 LLVM_DEBUG(dbgs() << "parseMEMAsOperand\n"); 1093 const AsmToken &Tok = Parser.getTok(); 1094 SMLoc S = Tok.getLoc(); 1095 SMLoc E = Tok.getEndLoc(); 1096 // Parse AS format 1097 // disp 1098 // disp(, base) 1099 // disp(base) 1100 // disp() 1101 // (, base) 1102 // (base) 1103 // base 1104 1105 unsigned BaseReg = VE::NoRegister; 1106 std::unique_ptr<VEOperand> Offset; 1107 switch (getLexer().getKind()) { 1108 default: 1109 return MatchOperand_NoMatch; 1110 1111 case AsmToken::Minus: 1112 case AsmToken::Integer: 1113 case AsmToken::Dot: { 1114 const MCExpr *EVal; 1115 if (!getParser().parseExpression(EVal, E)) 1116 Offset = VEOperand::CreateImm(EVal, S, E); 1117 else 1118 return MatchOperand_NoMatch; 1119 break; 1120 } 1121 1122 case AsmToken::Percent: 1123 if (ParseRegister(BaseReg, S, E)) 1124 return MatchOperand_NoMatch; 1125 Offset = 1126 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E); 1127 break; 1128 1129 case AsmToken::LParen: 1130 // empty disp (= 0) 1131 Offset = 1132 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E); 1133 break; 1134 } 1135 1136 switch (getLexer().getKind()) { 1137 default: 1138 return MatchOperand_ParseFail; 1139 1140 case AsmToken::EndOfStatement: 1141 case AsmToken::Comma: 1142 Operands.push_back(BaseReg != VE::NoRegister 1143 ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset)) 1144 : VEOperand::MorphToMEMzi(std::move(Offset))); 1145 return MatchOperand_Success; 1146 1147 case AsmToken::LParen: 1148 if (BaseReg != VE::NoRegister) 1149 return MatchOperand_ParseFail; 1150 Parser.Lex(); // Eat the ( 1151 break; 1152 } 1153 1154 switch (getLexer().getKind()) { 1155 default: 1156 if (ParseRegister(BaseReg, S, E)) 1157 return MatchOperand_ParseFail; 1158 break; 1159 1160 case AsmToken::Comma: 1161 Parser.Lex(); // Eat the , 1162 if (ParseRegister(BaseReg, S, E)) 1163 return MatchOperand_ParseFail; 1164 break; 1165 1166 case AsmToken::RParen: 1167 break; 1168 } 1169 1170 if (!Parser.getTok().is(AsmToken::RParen)) 1171 return MatchOperand_ParseFail; 1172 1173 Parser.Lex(); // Eat the ) 1174 Operands.push_back(BaseReg != VE::NoRegister 1175 ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset)) 1176 : VEOperand::MorphToMEMzi(std::move(Offset))); 1177 1178 return MatchOperand_Success; 1179 } 1180 1181 OperandMatchResultTy VEAsmParser::parseMImmOperand(OperandVector &Operands) { 1182 LLVM_DEBUG(dbgs() << "parseMImmOperand\n"); 1183 1184 // Parsing "(" + number + ")0/1" 1185 const AsmToken Tok1 = Parser.getTok(); 1186 if (!Tok1.is(AsmToken::LParen)) 1187 return MatchOperand_NoMatch; 1188 1189 Parser.Lex(); // Eat the '('. 1190 1191 const AsmToken Tok2 = Parser.getTok(); 1192 SMLoc E; 1193 const MCExpr *EVal; 1194 if (!Tok2.is(AsmToken::Integer) || getParser().parseExpression(EVal, E)) { 1195 getLexer().UnLex(Tok1); 1196 return MatchOperand_NoMatch; 1197 } 1198 1199 const AsmToken Tok3 = Parser.getTok(); 1200 if (!Tok3.is(AsmToken::RParen)) { 1201 getLexer().UnLex(Tok2); 1202 getLexer().UnLex(Tok1); 1203 return MatchOperand_NoMatch; 1204 } 1205 Parser.Lex(); // Eat the ')'. 1206 1207 const AsmToken &Tok4 = Parser.getTok(); 1208 StringRef Suffix = Tok4.getString(); 1209 if (Suffix != "1" && Suffix != "0") { 1210 getLexer().UnLex(Tok3); 1211 getLexer().UnLex(Tok2); 1212 getLexer().UnLex(Tok1); 1213 return MatchOperand_NoMatch; 1214 } 1215 Parser.Lex(); // Eat the value. 1216 SMLoc EndLoc = SMLoc::getFromPointer(Suffix.end()); 1217 Operands.push_back( 1218 VEOperand::CreateMImm(EVal, Suffix == "0", Tok1.getLoc(), EndLoc)); 1219 return MatchOperand_Success; 1220 } 1221 1222 OperandMatchResultTy VEAsmParser::parseOperand(OperandVector &Operands, 1223 StringRef Mnemonic) { 1224 LLVM_DEBUG(dbgs() << "parseOperand\n"); 1225 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1226 1227 // If there wasn't a custom match, try the generic matcher below. Otherwise, 1228 // there was a match, but an error occurred, in which case, just return that 1229 // the operand parsing failed. 1230 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail) 1231 return ResTy; 1232 1233 switch (getLexer().getKind()) { 1234 case AsmToken::LParen: 1235 // FIXME: Parsing "(" + %vreg + ", " + %vreg + ")" 1236 // FALLTHROUGH 1237 default: { 1238 std::unique_ptr<VEOperand> Op; 1239 ResTy = parseVEAsmOperand(Op); 1240 if (ResTy != MatchOperand_Success || !Op) 1241 return MatchOperand_ParseFail; 1242 1243 // Push the parsed operand into the list of operands 1244 Operands.push_back(std::move(Op)); 1245 1246 if (!Parser.getTok().is(AsmToken::LParen)) 1247 break; 1248 1249 // FIXME: Parsing %vec-reg + "(" + %sclar-reg/number + ")" 1250 break; 1251 } 1252 } 1253 1254 return MatchOperand_Success; 1255 } 1256 1257 OperandMatchResultTy 1258 VEAsmParser::parseVEAsmOperand(std::unique_ptr<VEOperand> &Op) { 1259 LLVM_DEBUG(dbgs() << "parseVEAsmOperand\n"); 1260 SMLoc S = Parser.getTok().getLoc(); 1261 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1262 const MCExpr *EVal; 1263 1264 Op = nullptr; 1265 switch (getLexer().getKind()) { 1266 default: 1267 break; 1268 1269 case AsmToken::Percent: 1270 unsigned RegNo; 1271 if (tryParseRegister(RegNo, S, E) == MatchOperand_Success) 1272 Op = VEOperand::CreateReg(RegNo, S, E); 1273 break; 1274 1275 case AsmToken::Minus: 1276 case AsmToken::Integer: 1277 case AsmToken::Dot: 1278 if (!getParser().parseExpression(EVal, E)) 1279 Op = VEOperand::CreateImm(EVal, S, E); 1280 break; 1281 1282 case AsmToken::Identifier: { 1283 StringRef Identifier; 1284 if (!getParser().parseIdentifier(Identifier)) { 1285 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1286 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1287 1288 const MCExpr *Res = 1289 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1290 Op = VEOperand::CreateImm(Res, S, E); 1291 } 1292 break; 1293 } 1294 } 1295 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail; 1296 } 1297 1298 // Force static initialization. 1299 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmParser() { 1300 RegisterMCAsmParser<VEAsmParser> A(getTheVETarget()); 1301 } 1302 1303 #define GET_REGISTER_MATCHER 1304 #define GET_MATCHER_IMPLEMENTATION 1305 #include "VEGenAsmMatcher.inc" 1306 1307 unsigned VEAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp, 1308 unsigned Kind) { 1309 VEOperand &Op = (VEOperand &)GOp; 1310 1311 // VE uses identical register name for all registers like both 1312 // F32 and I32 uses "%s23". Need to convert the name of them 1313 // for validation. 1314 switch (Kind) { 1315 default: 1316 break; 1317 case MCK_F32: 1318 if (Op.isReg() && VEOperand::MorphToF32Reg(Op)) 1319 return MCTargetAsmParser::Match_Success; 1320 break; 1321 case MCK_I32: 1322 if (Op.isReg() && VEOperand::MorphToI32Reg(Op)) 1323 return MCTargetAsmParser::Match_Success; 1324 break; 1325 case MCK_F128: 1326 if (Op.isReg() && VEOperand::MorphToF128Reg(Op)) 1327 return MCTargetAsmParser::Match_Success; 1328 break; 1329 case MCK_MISC: 1330 if (Op.isImm() && VEOperand::MorphToMISCReg(Op)) 1331 return MCTargetAsmParser::Match_Success; 1332 break; 1333 } 1334 return Match_InvalidOperand; 1335 } 1336