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