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