1 //===-- VEAsmParser.cpp - Parse VE assembly to MCInst instructions --------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "MCTargetDesc/VEMCExpr.h" 10 #include "MCTargetDesc/VEMCTargetDesc.h" 11 #include "TargetInfo/VETargetInfo.h" 12 #include "VE.h" 13 #include "llvm/ADT/STLExtras.h" 14 #include "llvm/ADT/SmallVector.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/ADT/Twine.h" 17 #include "llvm/MC/MCContext.h" 18 #include "llvm/MC/MCExpr.h" 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/MC/MCParser/MCAsmLexer.h" 21 #include "llvm/MC/MCParser/MCAsmParser.h" 22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 23 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 24 #include "llvm/MC/MCRegisterInfo.h" 25 #include "llvm/MC/MCStreamer.h" 26 #include "llvm/MC/MCSubtargetInfo.h" 27 #include "llvm/MC/MCSymbol.h" 28 #include "llvm/Support/TargetRegistry.h" 29 #include "llvm/Support/raw_ostream.h" 30 #include <algorithm> 31 #include <memory> 32 33 using namespace llvm; 34 35 #define DEBUG_TYPE "ve-asmparser" 36 37 namespace { 38 39 class VEOperand; 40 41 class VEAsmParser : public MCTargetAsmParser { 42 MCAsmParser &Parser; 43 44 /// @name Auto-generated Match Functions 45 /// { 46 47 #define GET_ASSEMBLER_HEADER 48 #include "VEGenAsmMatcher.inc" 49 50 /// } 51 52 // public interface of the MCTargetAsmParser. 53 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 54 OperandVector &Operands, MCStreamer &Out, 55 uint64_t &ErrorInfo, 56 bool MatchingInlineAsm) override; 57 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 58 int parseRegisterName(unsigned (*matchFn)(StringRef)); 59 OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, 60 SMLoc &EndLoc) override; 61 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 62 SMLoc NameLoc, OperandVector &Operands) override; 63 bool ParseDirective(AsmToken DirectiveID) override; 64 65 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 66 unsigned Kind) override; 67 68 // Custom parse functions for VE specific operands. 69 OperandMatchResultTy parseMEMOperand(OperandVector &Operands); 70 OperandMatchResultTy parseMEMAsOperand(OperandVector &Operands); 71 OperandMatchResultTy parseCCOpOperand(OperandVector &Operands); 72 OperandMatchResultTy parseRDOpOperand(OperandVector &Operands); 73 OperandMatchResultTy parseMImmOperand(OperandVector &Operands); 74 OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name); 75 OperandMatchResultTy parseVEAsmOperand(std::unique_ptr<VEOperand> &Operand); 76 77 // Helper function to parse expression with a symbol. 78 const MCExpr *extractModifierFromExpr(const MCExpr *E, 79 VEMCExpr::VariantKind &Variant); 80 const MCExpr *fixupVariantKind(const MCExpr *E); 81 bool parseExpression(const MCExpr *&EVal); 82 83 // Split the mnemonic stripping conditional code and quantifiers 84 StringRef splitMnemonic(StringRef Name, SMLoc NameLoc, 85 OperandVector *Operands); 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) : MCParsedAsmOperand(), 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 unsigned 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(unsigned &RegNo, SMLoc &StartLoc, 797 SMLoc &EndLoc) { 798 if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success) 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(unsigned (*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 unsigned MatchRegisterName(StringRef Name); 822 823 /// Maps from the set of all alternative registernames to a register number. 824 /// \note Generated by TableGen. 825 static unsigned MatchRegisterAltName(StringRef Name); 826 827 OperandMatchResultTy 828 VEAsmParser::tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { 829 const AsmToken Tok = Parser.getTok(); 830 StartLoc = Tok.getLoc(); 831 EndLoc = Tok.getEndLoc(); 832 RegNo = 0; 833 if (getLexer().getKind() != AsmToken::Percent) 834 return MatchOperand_NoMatch; 835 Parser.Lex(); 836 837 RegNo = parseRegisterName(&MatchRegisterName); 838 if (RegNo == VE::NoRegister) 839 RegNo = parseRegisterName(&MatchRegisterAltName); 840 841 if (RegNo != VE::NoRegister) { 842 Parser.Lex(); 843 return MatchOperand_Success; 844 } 845 846 getLexer().UnLex(Tok); 847 return MatchOperand_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.startswith("cmov.l.") || Name.startswith("cmov.w.") || 924 Name.startswith("cmov.d.") || Name.startswith("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.startswith("cvt.w.d.sx") || Name.startswith("cvt.w.d.zx") || 928 Name.startswith("cvt.w.s.sx") || Name.startswith("cvt.w.s.zx")) { 929 Mnemonic = parseRD(Name, 10, NameLoc, Operands); 930 } else if (Name.startswith("cvt.l.d")) { 931 Mnemonic = parseRD(Name, 7, NameLoc, Operands); 932 } else if (Name.startswith("vcvt.w.d.sx") || Name.startswith("vcvt.w.d.zx") || 933 Name.startswith("vcvt.w.s.sx") || Name.startswith("vcvt.w.s.zx")) { 934 Mnemonic = parseRD(Name, 11, NameLoc, Operands); 935 } else if (Name.startswith("vcvt.l.d")) { 936 Mnemonic = parseRD(Name, 8, NameLoc, Operands); 937 } else if (Name.startswith("pvcvt.w.s.lo") || 938 Name.startswith("pvcvt.w.s.up")) { 939 Mnemonic = parseRD(Name, 12, NameLoc, Operands); 940 } else if (Name.startswith("pvcvt.w.s")) { 941 Mnemonic = parseRD(Name, 9, NameLoc, Operands); 942 } else if (Name.startswith("vfmk.l.") || Name.startswith("vfmk.w.") || 943 Name.startswith("vfmk.d.") || Name.startswith("vfmk.s.")) { 944 bool ICC = Name[5] == 'l' || Name[5] == 'w' ? true : false; 945 Mnemonic = parseCC(Name, 7, Name.size(), ICC, true, NameLoc, Operands); 946 } else if (Name.startswith("pvfmk.w.lo.") || Name.startswith("pvfmk.w.up.") || 947 Name.startswith("pvfmk.s.lo.") || Name.startswith("pvfmk.s.up.")) { 948 bool ICC = Name[6] == 'l' || Name[6] == 'w' ? true : false; 949 Mnemonic = parseCC(Name, 11, Name.size(), ICC, true, NameLoc, Operands); 950 } else { 951 Operands->push_back(VEOperand::CreateToken(Mnemonic, NameLoc)); 952 } 953 954 return Mnemonic; 955 } 956 957 static void applyMnemonicAliases(StringRef &Mnemonic, 958 const FeatureBitset &Features, 959 unsigned VariantID); 960 961 bool VEAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 962 SMLoc NameLoc, OperandVector &Operands) { 963 // If the target architecture uses MnemonicAlias, call it here to parse 964 // operands correctly. 965 applyMnemonicAliases(Name, getAvailableFeatures(), 0); 966 967 // Split name to first token and the rest, e.g. "bgt.l.t" to "b", "gt", and 968 // ".l.t". We treat "b" as a mnemonic, "gt" as first operand, and ".l.t" 969 // as second operand. 970 StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands); 971 972 if (getLexer().isNot(AsmToken::EndOfStatement)) { 973 // Read the first operand. 974 if (parseOperand(Operands, Mnemonic) != MatchOperand_Success) { 975 SMLoc Loc = getLexer().getLoc(); 976 return Error(Loc, "unexpected token"); 977 } 978 979 while (getLexer().is(AsmToken::Comma)) { 980 Parser.Lex(); // Eat the comma. 981 // Parse and remember the operand. 982 if (parseOperand(Operands, Mnemonic) != MatchOperand_Success) { 983 SMLoc Loc = getLexer().getLoc(); 984 return Error(Loc, "unexpected token"); 985 } 986 } 987 } 988 if (getLexer().isNot(AsmToken::EndOfStatement)) { 989 SMLoc Loc = getLexer().getLoc(); 990 return Error(Loc, "unexpected token"); 991 } 992 Parser.Lex(); // Consume the EndOfStatement. 993 return false; 994 } 995 996 bool VEAsmParser::ParseDirective(AsmToken DirectiveID) { 997 // Let the MC layer to handle other directives. 998 return true; 999 } 1000 1001 /// Extract \code @lo32/@hi32/etc \endcode modifier from expression. 1002 /// Recursively scan the expression and check for VK_VE_HI32/LO32/etc 1003 /// symbol variants. If all symbols with modifier use the same 1004 /// variant, return the corresponding VEMCExpr::VariantKind, 1005 /// and a modified expression using the default symbol variant. 1006 /// Otherwise, return NULL. 1007 const MCExpr * 1008 VEAsmParser::extractModifierFromExpr(const MCExpr *E, 1009 VEMCExpr::VariantKind &Variant) { 1010 MCContext &Context = getParser().getContext(); 1011 Variant = VEMCExpr::VK_VE_None; 1012 1013 switch (E->getKind()) { 1014 case MCExpr::Target: 1015 case MCExpr::Constant: 1016 return nullptr; 1017 1018 case MCExpr::SymbolRef: { 1019 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 1020 1021 switch (SRE->getKind()) { 1022 case MCSymbolRefExpr::VK_None: 1023 // Use VK_VE_REFLONG to a symbol without modifiers. 1024 Variant = VEMCExpr::VK_VE_REFLONG; 1025 break; 1026 case MCSymbolRefExpr::VK_VE_HI32: 1027 Variant = VEMCExpr::VK_VE_HI32; 1028 break; 1029 case MCSymbolRefExpr::VK_VE_LO32: 1030 Variant = VEMCExpr::VK_VE_LO32; 1031 break; 1032 case MCSymbolRefExpr::VK_VE_PC_HI32: 1033 Variant = VEMCExpr::VK_VE_PC_HI32; 1034 break; 1035 case MCSymbolRefExpr::VK_VE_PC_LO32: 1036 Variant = VEMCExpr::VK_VE_PC_LO32; 1037 break; 1038 case MCSymbolRefExpr::VK_VE_GOT_HI32: 1039 Variant = VEMCExpr::VK_VE_GOT_HI32; 1040 break; 1041 case MCSymbolRefExpr::VK_VE_GOT_LO32: 1042 Variant = VEMCExpr::VK_VE_GOT_LO32; 1043 break; 1044 case MCSymbolRefExpr::VK_VE_GOTOFF_HI32: 1045 Variant = VEMCExpr::VK_VE_GOTOFF_HI32; 1046 break; 1047 case MCSymbolRefExpr::VK_VE_GOTOFF_LO32: 1048 Variant = VEMCExpr::VK_VE_GOTOFF_LO32; 1049 break; 1050 case MCSymbolRefExpr::VK_VE_PLT_HI32: 1051 Variant = VEMCExpr::VK_VE_PLT_HI32; 1052 break; 1053 case MCSymbolRefExpr::VK_VE_PLT_LO32: 1054 Variant = VEMCExpr::VK_VE_PLT_LO32; 1055 break; 1056 case MCSymbolRefExpr::VK_VE_TLS_GD_HI32: 1057 Variant = VEMCExpr::VK_VE_TLS_GD_HI32; 1058 break; 1059 case MCSymbolRefExpr::VK_VE_TLS_GD_LO32: 1060 Variant = VEMCExpr::VK_VE_TLS_GD_LO32; 1061 break; 1062 case MCSymbolRefExpr::VK_VE_TPOFF_HI32: 1063 Variant = VEMCExpr::VK_VE_TPOFF_HI32; 1064 break; 1065 case MCSymbolRefExpr::VK_VE_TPOFF_LO32: 1066 Variant = VEMCExpr::VK_VE_TPOFF_LO32; 1067 break; 1068 default: 1069 return nullptr; 1070 } 1071 1072 return MCSymbolRefExpr::create(&SRE->getSymbol(), Context); 1073 } 1074 1075 case MCExpr::Unary: { 1076 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); 1077 const MCExpr *Sub = extractModifierFromExpr(UE->getSubExpr(), Variant); 1078 if (!Sub) 1079 return nullptr; 1080 return MCUnaryExpr::create(UE->getOpcode(), Sub, Context); 1081 } 1082 1083 case MCExpr::Binary: { 1084 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 1085 VEMCExpr::VariantKind LHSVariant, RHSVariant; 1086 const MCExpr *LHS = extractModifierFromExpr(BE->getLHS(), LHSVariant); 1087 const MCExpr *RHS = extractModifierFromExpr(BE->getRHS(), RHSVariant); 1088 1089 if (!LHS && !RHS) 1090 return nullptr; 1091 1092 if (!LHS) 1093 LHS = BE->getLHS(); 1094 if (!RHS) 1095 RHS = BE->getRHS(); 1096 1097 if (LHSVariant == VEMCExpr::VK_VE_None) 1098 Variant = RHSVariant; 1099 else if (RHSVariant == VEMCExpr::VK_VE_None) 1100 Variant = LHSVariant; 1101 else if (LHSVariant == RHSVariant) 1102 Variant = LHSVariant; 1103 else 1104 return nullptr; 1105 1106 return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context); 1107 } 1108 } 1109 1110 llvm_unreachable("Invalid expression kind!"); 1111 } 1112 1113 const MCExpr *VEAsmParser::fixupVariantKind(const MCExpr *E) { 1114 MCContext &Context = getParser().getContext(); 1115 1116 switch (E->getKind()) { 1117 case MCExpr::Target: 1118 case MCExpr::Constant: 1119 case MCExpr::SymbolRef: 1120 return E; 1121 1122 case MCExpr::Unary: { 1123 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); 1124 const MCExpr *Sub = fixupVariantKind(UE->getSubExpr()); 1125 if (Sub == UE->getSubExpr()) 1126 return E; 1127 return MCUnaryExpr::create(UE->getOpcode(), Sub, Context); 1128 } 1129 1130 case MCExpr::Binary: { 1131 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 1132 const MCExpr *LHS = fixupVariantKind(BE->getLHS()); 1133 const MCExpr *RHS = fixupVariantKind(BE->getRHS()); 1134 if (LHS == BE->getLHS() && RHS == BE->getRHS()) 1135 return E; 1136 return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context); 1137 } 1138 } 1139 1140 llvm_unreachable("Invalid expression kind!"); 1141 } 1142 1143 /// ParseExpression. This differs from the default "parseExpression" in that 1144 /// it handles modifiers. 1145 bool VEAsmParser::parseExpression(const MCExpr *&EVal) { 1146 // Handle \code symbol @lo32/@hi32/etc \endcode. 1147 if (getParser().parseExpression(EVal)) 1148 return true; 1149 1150 // Convert MCSymbolRefExpr with VK_* to MCExpr with VK_*. 1151 EVal = fixupVariantKind(EVal); 1152 VEMCExpr::VariantKind Variant; 1153 const MCExpr *E = extractModifierFromExpr(EVal, Variant); 1154 if (E) 1155 EVal = VEMCExpr::create(Variant, E, getParser().getContext()); 1156 1157 return false; 1158 } 1159 1160 OperandMatchResultTy VEAsmParser::parseMEMOperand(OperandVector &Operands) { 1161 LLVM_DEBUG(dbgs() << "parseMEMOperand\n"); 1162 const AsmToken &Tok = Parser.getTok(); 1163 SMLoc S = Tok.getLoc(); 1164 SMLoc E = Tok.getEndLoc(); 1165 // Parse ASX format 1166 // disp 1167 // disp(, base) 1168 // disp(index) 1169 // disp(index, base) 1170 // (, base) 1171 // (index) 1172 // (index, base) 1173 1174 std::unique_ptr<VEOperand> Offset; 1175 switch (getLexer().getKind()) { 1176 default: 1177 return MatchOperand_NoMatch; 1178 1179 case AsmToken::Minus: 1180 case AsmToken::Integer: 1181 case AsmToken::Dot: 1182 case AsmToken::Identifier: { 1183 const MCExpr *EVal; 1184 if (!parseExpression(EVal)) 1185 Offset = VEOperand::CreateImm(EVal, S, E); 1186 else 1187 return MatchOperand_NoMatch; 1188 break; 1189 } 1190 1191 case AsmToken::LParen: 1192 // empty disp (= 0) 1193 Offset = 1194 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E); 1195 break; 1196 } 1197 1198 switch (getLexer().getKind()) { 1199 default: 1200 return MatchOperand_ParseFail; 1201 1202 case AsmToken::EndOfStatement: 1203 Operands.push_back(VEOperand::MorphToMEMzii( 1204 MCConstantExpr::create(0, getContext()), std::move(Offset))); 1205 return MatchOperand_Success; 1206 1207 case AsmToken::LParen: 1208 Parser.Lex(); // Eat the ( 1209 break; 1210 } 1211 1212 const MCExpr *IndexValue = nullptr; 1213 unsigned IndexReg = 0; 1214 1215 switch (getLexer().getKind()) { 1216 default: 1217 if (ParseRegister(IndexReg, S, E)) 1218 return MatchOperand_ParseFail; 1219 break; 1220 1221 case AsmToken::Minus: 1222 case AsmToken::Integer: 1223 case AsmToken::Dot: 1224 if (getParser().parseExpression(IndexValue, E)) 1225 return MatchOperand_ParseFail; 1226 break; 1227 1228 case AsmToken::Comma: 1229 // empty index 1230 IndexValue = MCConstantExpr::create(0, getContext()); 1231 break; 1232 } 1233 1234 switch (getLexer().getKind()) { 1235 default: 1236 return MatchOperand_ParseFail; 1237 1238 case AsmToken::RParen: 1239 Parser.Lex(); // Eat the ) 1240 Operands.push_back( 1241 IndexValue ? VEOperand::MorphToMEMzii(IndexValue, std::move(Offset)) 1242 : VEOperand::MorphToMEMzri(IndexReg, std::move(Offset))); 1243 return MatchOperand_Success; 1244 1245 case AsmToken::Comma: 1246 Parser.Lex(); // Eat the , 1247 break; 1248 } 1249 1250 unsigned BaseReg = 0; 1251 if (ParseRegister(BaseReg, S, E)) 1252 return MatchOperand_ParseFail; 1253 1254 if (!Parser.getTok().is(AsmToken::RParen)) 1255 return MatchOperand_ParseFail; 1256 1257 Parser.Lex(); // Eat the ) 1258 Operands.push_back( 1259 IndexValue 1260 ? VEOperand::MorphToMEMrii(BaseReg, IndexValue, std::move(Offset)) 1261 : VEOperand::MorphToMEMrri(BaseReg, IndexReg, std::move(Offset))); 1262 1263 return MatchOperand_Success; 1264 } 1265 1266 OperandMatchResultTy VEAsmParser::parseMEMAsOperand(OperandVector &Operands) { 1267 LLVM_DEBUG(dbgs() << "parseMEMAsOperand\n"); 1268 const AsmToken &Tok = Parser.getTok(); 1269 SMLoc S = Tok.getLoc(); 1270 SMLoc E = Tok.getEndLoc(); 1271 // Parse AS format 1272 // disp 1273 // disp(, base) 1274 // disp(base) 1275 // disp() 1276 // (, base) 1277 // (base) 1278 // base 1279 1280 unsigned BaseReg = VE::NoRegister; 1281 std::unique_ptr<VEOperand> Offset; 1282 switch (getLexer().getKind()) { 1283 default: 1284 return MatchOperand_NoMatch; 1285 1286 case AsmToken::Minus: 1287 case AsmToken::Integer: 1288 case AsmToken::Dot: 1289 case AsmToken::Identifier: { 1290 const MCExpr *EVal; 1291 if (!parseExpression(EVal)) 1292 Offset = VEOperand::CreateImm(EVal, S, E); 1293 else 1294 return MatchOperand_NoMatch; 1295 break; 1296 } 1297 1298 case AsmToken::Percent: 1299 if (ParseRegister(BaseReg, S, E)) 1300 return MatchOperand_NoMatch; 1301 Offset = 1302 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E); 1303 break; 1304 1305 case AsmToken::LParen: 1306 // empty disp (= 0) 1307 Offset = 1308 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E); 1309 break; 1310 } 1311 1312 switch (getLexer().getKind()) { 1313 default: 1314 return MatchOperand_ParseFail; 1315 1316 case AsmToken::EndOfStatement: 1317 case AsmToken::Comma: 1318 Operands.push_back(BaseReg != VE::NoRegister 1319 ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset)) 1320 : VEOperand::MorphToMEMzi(std::move(Offset))); 1321 return MatchOperand_Success; 1322 1323 case AsmToken::LParen: 1324 if (BaseReg != VE::NoRegister) 1325 return MatchOperand_ParseFail; 1326 Parser.Lex(); // Eat the ( 1327 break; 1328 } 1329 1330 switch (getLexer().getKind()) { 1331 default: 1332 if (ParseRegister(BaseReg, S, E)) 1333 return MatchOperand_ParseFail; 1334 break; 1335 1336 case AsmToken::Comma: 1337 Parser.Lex(); // Eat the , 1338 if (ParseRegister(BaseReg, S, E)) 1339 return MatchOperand_ParseFail; 1340 break; 1341 1342 case AsmToken::RParen: 1343 break; 1344 } 1345 1346 if (!Parser.getTok().is(AsmToken::RParen)) 1347 return MatchOperand_ParseFail; 1348 1349 Parser.Lex(); // Eat the ) 1350 Operands.push_back(BaseReg != VE::NoRegister 1351 ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset)) 1352 : VEOperand::MorphToMEMzi(std::move(Offset))); 1353 1354 return MatchOperand_Success; 1355 } 1356 1357 OperandMatchResultTy VEAsmParser::parseMImmOperand(OperandVector &Operands) { 1358 LLVM_DEBUG(dbgs() << "parseMImmOperand\n"); 1359 1360 // Parsing "(" + number + ")0/1" 1361 const AsmToken Tok1 = Parser.getTok(); 1362 if (!Tok1.is(AsmToken::LParen)) 1363 return MatchOperand_NoMatch; 1364 1365 Parser.Lex(); // Eat the '('. 1366 1367 const AsmToken Tok2 = Parser.getTok(); 1368 SMLoc E; 1369 const MCExpr *EVal; 1370 if (!Tok2.is(AsmToken::Integer) || getParser().parseExpression(EVal, E)) { 1371 getLexer().UnLex(Tok1); 1372 return MatchOperand_NoMatch; 1373 } 1374 1375 const AsmToken Tok3 = Parser.getTok(); 1376 if (!Tok3.is(AsmToken::RParen)) { 1377 getLexer().UnLex(Tok2); 1378 getLexer().UnLex(Tok1); 1379 return MatchOperand_NoMatch; 1380 } 1381 Parser.Lex(); // Eat the ')'. 1382 1383 const AsmToken &Tok4 = Parser.getTok(); 1384 StringRef Suffix = Tok4.getString(); 1385 if (Suffix != "1" && Suffix != "0") { 1386 getLexer().UnLex(Tok3); 1387 getLexer().UnLex(Tok2); 1388 getLexer().UnLex(Tok1); 1389 return MatchOperand_NoMatch; 1390 } 1391 Parser.Lex(); // Eat the value. 1392 SMLoc EndLoc = SMLoc::getFromPointer(Suffix.end()); 1393 Operands.push_back( 1394 VEOperand::CreateMImm(EVal, Suffix == "0", Tok1.getLoc(), EndLoc)); 1395 return MatchOperand_Success; 1396 } 1397 1398 OperandMatchResultTy VEAsmParser::parseOperand(OperandVector &Operands, 1399 StringRef Mnemonic) { 1400 LLVM_DEBUG(dbgs() << "parseOperand\n"); 1401 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1402 1403 // If there wasn't a custom match, try the generic matcher below. Otherwise, 1404 // there was a match, but an error occurred, in which case, just return that 1405 // the operand parsing failed. 1406 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail) 1407 return ResTy; 1408 1409 switch (getLexer().getKind()) { 1410 case AsmToken::LParen: { 1411 // Parsing "(" + %vreg + ", " + %vreg + ")" 1412 const AsmToken Tok1 = Parser.getTok(); 1413 Parser.Lex(); // Eat the '('. 1414 1415 unsigned RegNo1; 1416 SMLoc S1, E1; 1417 if (tryParseRegister(RegNo1, S1, E1) != MatchOperand_Success) { 1418 getLexer().UnLex(Tok1); 1419 return MatchOperand_NoMatch; 1420 } 1421 1422 if (!Parser.getTok().is(AsmToken::Comma)) 1423 return MatchOperand_ParseFail; 1424 Parser.Lex(); // Eat the ','. 1425 1426 unsigned RegNo2; 1427 SMLoc S2, E2; 1428 if (tryParseRegister(RegNo2, S2, E2) != MatchOperand_Success) 1429 return MatchOperand_ParseFail; 1430 1431 if (!Parser.getTok().is(AsmToken::RParen)) 1432 return MatchOperand_ParseFail; 1433 1434 Operands.push_back(VEOperand::CreateToken(Tok1.getString(), Tok1.getLoc())); 1435 Operands.push_back(VEOperand::CreateReg(RegNo1, S1, E1)); 1436 Operands.push_back(VEOperand::CreateReg(RegNo2, S2, E2)); 1437 Operands.push_back(VEOperand::CreateToken(Parser.getTok().getString(), 1438 Parser.getTok().getLoc())); 1439 Parser.Lex(); // Eat the ')'. 1440 break; 1441 } 1442 default: { 1443 std::unique_ptr<VEOperand> Op; 1444 ResTy = parseVEAsmOperand(Op); 1445 if (ResTy != MatchOperand_Success || !Op) 1446 return MatchOperand_ParseFail; 1447 1448 // Push the parsed operand into the list of operands 1449 Operands.push_back(std::move(Op)); 1450 1451 if (!Parser.getTok().is(AsmToken::LParen)) 1452 break; 1453 1454 // Parsing %vec-reg + "(" + %sclar-reg/number + ")" 1455 std::unique_ptr<VEOperand> Op1 = VEOperand::CreateToken( 1456 Parser.getTok().getString(), Parser.getTok().getLoc()); 1457 Parser.Lex(); // Eat the '('. 1458 1459 std::unique_ptr<VEOperand> Op2; 1460 ResTy = parseVEAsmOperand(Op2); 1461 if (ResTy != MatchOperand_Success || !Op2) 1462 return MatchOperand_ParseFail; 1463 1464 if (!Parser.getTok().is(AsmToken::RParen)) 1465 return MatchOperand_ParseFail; 1466 1467 Operands.push_back(std::move(Op1)); 1468 Operands.push_back(std::move(Op2)); 1469 Operands.push_back(VEOperand::CreateToken(Parser.getTok().getString(), 1470 Parser.getTok().getLoc())); 1471 Parser.Lex(); // Eat the ')'. 1472 break; 1473 } 1474 } 1475 1476 return MatchOperand_Success; 1477 } 1478 1479 OperandMatchResultTy 1480 VEAsmParser::parseVEAsmOperand(std::unique_ptr<VEOperand> &Op) { 1481 LLVM_DEBUG(dbgs() << "parseVEAsmOperand\n"); 1482 SMLoc S = Parser.getTok().getLoc(); 1483 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1484 const MCExpr *EVal; 1485 1486 Op = nullptr; 1487 switch (getLexer().getKind()) { 1488 default: 1489 break; 1490 1491 case AsmToken::Percent: 1492 unsigned RegNo; 1493 if (tryParseRegister(RegNo, S, E) == MatchOperand_Success) 1494 Op = VEOperand::CreateReg(RegNo, S, E); 1495 break; 1496 1497 case AsmToken::Minus: 1498 case AsmToken::Integer: 1499 case AsmToken::Dot: 1500 case AsmToken::Identifier: 1501 if (!parseExpression(EVal)) 1502 Op = VEOperand::CreateImm(EVal, S, E); 1503 break; 1504 } 1505 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail; 1506 } 1507 1508 // Force static initialization. 1509 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmParser() { 1510 RegisterMCAsmParser<VEAsmParser> A(getTheVETarget()); 1511 } 1512 1513 #define GET_REGISTER_MATCHER 1514 #define GET_MATCHER_IMPLEMENTATION 1515 #include "VEGenAsmMatcher.inc" 1516 1517 unsigned VEAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp, 1518 unsigned Kind) { 1519 VEOperand &Op = (VEOperand &)GOp; 1520 1521 // VE uses identical register name for all registers like both 1522 // F32 and I32 uses "%s23". Need to convert the name of them 1523 // for validation. 1524 switch (Kind) { 1525 default: 1526 break; 1527 case MCK_F32: 1528 if (Op.isReg() && VEOperand::MorphToF32Reg(Op)) 1529 return MCTargetAsmParser::Match_Success; 1530 break; 1531 case MCK_I32: 1532 if (Op.isReg() && VEOperand::MorphToI32Reg(Op)) 1533 return MCTargetAsmParser::Match_Success; 1534 break; 1535 case MCK_F128: 1536 if (Op.isReg() && VEOperand::MorphToF128Reg(Op)) 1537 return MCTargetAsmParser::Match_Success; 1538 break; 1539 case MCK_VM512: 1540 if (Op.isReg() && VEOperand::MorphToVM512Reg(Op)) 1541 return MCTargetAsmParser::Match_Success; 1542 break; 1543 case MCK_MISC: 1544 if (Op.isImm() && VEOperand::MorphToMISCReg(Op)) 1545 return MCTargetAsmParser::Match_Success; 1546 break; 1547 } 1548 return Match_InvalidOperand; 1549 } 1550