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