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 isUImm6() { 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<6>(Value); 291 } 292 return false; 293 } 294 bool isUImm7() { 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<7>(Value); 302 } 303 return false; 304 } 305 bool isSImm7() { 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 isInt<7>(Value); 313 } 314 return false; 315 } 316 bool isMImm() const { 317 if (Kind != k_MImmOp) 318 return false; 319 320 // Constant case 321 if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(MImm.Val)) { 322 int64_t Value = ConstExpr->getValue(); 323 return isUInt<6>(Value); 324 } 325 return false; 326 } 327 328 StringRef getToken() const { 329 assert(Kind == k_Token && "Invalid access!"); 330 return StringRef(Tok.Data, Tok.Length); 331 } 332 333 unsigned getReg() const override { 334 assert((Kind == k_Register) && "Invalid access!"); 335 return Reg.RegNum; 336 } 337 338 const MCExpr *getImm() const { 339 assert((Kind == k_Immediate) && "Invalid access!"); 340 return Imm.Val; 341 } 342 343 unsigned getMemBase() const { 344 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm || 345 Kind == k_MemoryRegImm) && 346 "Invalid access!"); 347 return Mem.Base; 348 } 349 350 unsigned getMemIndexReg() const { 351 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryZeroRegImm) && 352 "Invalid access!"); 353 return Mem.IndexReg; 354 } 355 356 const MCExpr *getMemIndex() const { 357 assert((Kind == k_MemoryRegImmImm || Kind == k_MemoryZeroImmImm) && 358 "Invalid access!"); 359 return Mem.Index; 360 } 361 362 const MCExpr *getMemOffset() const { 363 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm || 364 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm || 365 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) && 366 "Invalid access!"); 367 return Mem.Offset; 368 } 369 370 void setMemOffset(const MCExpr *off) { 371 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm || 372 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm || 373 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) && 374 "Invalid access!"); 375 Mem.Offset = off; 376 } 377 378 unsigned getCCVal() const { 379 assert((Kind == k_CCOp) && "Invalid access!"); 380 return CC.CCVal; 381 } 382 383 unsigned getRDVal() const { 384 assert((Kind == k_RDOp) && "Invalid access!"); 385 return RD.RDVal; 386 } 387 388 const MCExpr *getMImmVal() const { 389 assert((Kind == k_MImmOp) && "Invalid access!"); 390 return MImm.Val; 391 } 392 bool getM0Flag() const { 393 assert((Kind == k_MImmOp) && "Invalid access!"); 394 return MImm.M0Flag; 395 } 396 397 /// getStartLoc - Get the location of the first token of this operand. 398 SMLoc getStartLoc() const override { return StartLoc; } 399 /// getEndLoc - Get the location of the last token of this operand. 400 SMLoc getEndLoc() const override { return EndLoc; } 401 402 void print(raw_ostream &OS) const override { 403 switch (Kind) { 404 case k_Token: 405 OS << "Token: " << getToken() << "\n"; 406 break; 407 case k_Register: 408 OS << "Reg: #" << getReg() << "\n"; 409 break; 410 case k_Immediate: 411 OS << "Imm: " << getImm() << "\n"; 412 break; 413 case k_MemoryRegRegImm: 414 assert(getMemOffset() != nullptr); 415 OS << "Mem: #" << getMemBase() << "+#" << getMemIndexReg() << "+" 416 << *getMemOffset() << "\n"; 417 break; 418 case k_MemoryRegImmImm: 419 assert(getMemIndex() != nullptr && getMemOffset() != nullptr); 420 OS << "Mem: #" << getMemBase() << "+" << *getMemIndex() << "+" 421 << *getMemOffset() << "\n"; 422 break; 423 case k_MemoryZeroRegImm: 424 assert(getMemOffset() != nullptr); 425 OS << "Mem: 0+#" << getMemIndexReg() << "+" << *getMemOffset() << "\n"; 426 break; 427 case k_MemoryZeroImmImm: 428 assert(getMemIndex() != nullptr && getMemOffset() != nullptr); 429 OS << "Mem: 0+" << *getMemIndex() << "+" << *getMemOffset() << "\n"; 430 break; 431 case k_MemoryRegImm: 432 assert(getMemOffset() != nullptr); 433 OS << "Mem: #" << getMemBase() << "+" << *getMemOffset() << "\n"; 434 break; 435 case k_MemoryZeroImm: 436 assert(getMemOffset() != nullptr); 437 OS << "Mem: 0+" << *getMemOffset() << "\n"; 438 break; 439 case k_CCOp: 440 OS << "CCOp: " << getCCVal() << "\n"; 441 break; 442 case k_RDOp: 443 OS << "RDOp: " << getRDVal() << "\n"; 444 break; 445 case k_MImmOp: 446 OS << "MImm: (" << getMImmVal() << (getM0Flag() ? ")0" : ")1") << "\n"; 447 break; 448 } 449 } 450 451 void addRegOperands(MCInst &Inst, unsigned N) const { 452 assert(N == 1 && "Invalid number of operands!"); 453 Inst.addOperand(MCOperand::createReg(getReg())); 454 } 455 456 void addImmOperands(MCInst &Inst, unsigned N) const { 457 assert(N == 1 && "Invalid number of operands!"); 458 const MCExpr *Expr = getImm(); 459 addExpr(Inst, Expr); 460 } 461 462 void addZeroOperands(MCInst &Inst, unsigned N) const { 463 addImmOperands(Inst, N); 464 } 465 466 void addUImm0to2Operands(MCInst &Inst, unsigned N) const { 467 addImmOperands(Inst, N); 468 } 469 470 void addUImm1Operands(MCInst &Inst, unsigned N) const { 471 addImmOperands(Inst, N); 472 } 473 474 void addUImm2Operands(MCInst &Inst, unsigned N) const { 475 addImmOperands(Inst, N); 476 } 477 478 void addUImm3Operands(MCInst &Inst, unsigned N) const { 479 addImmOperands(Inst, N); 480 } 481 482 void addUImm6Operands(MCInst &Inst, unsigned N) const { 483 addImmOperands(Inst, N); 484 } 485 486 void addUImm7Operands(MCInst &Inst, unsigned N) const { 487 addImmOperands(Inst, N); 488 } 489 490 void addSImm7Operands(MCInst &Inst, unsigned N) const { 491 addImmOperands(Inst, N); 492 } 493 494 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 495 // Add as immediate when possible. Null MCExpr = 0. 496 if (!Expr) 497 Inst.addOperand(MCOperand::createImm(0)); 498 else if (const auto *CE = dyn_cast<MCConstantExpr>(Expr)) 499 Inst.addOperand(MCOperand::createImm(CE->getValue())); 500 else 501 Inst.addOperand(MCOperand::createExpr(Expr)); 502 } 503 504 void addMEMrriOperands(MCInst &Inst, unsigned N) const { 505 assert(N == 3 && "Invalid number of operands!"); 506 507 Inst.addOperand(MCOperand::createReg(getMemBase())); 508 Inst.addOperand(MCOperand::createReg(getMemIndexReg())); 509 addExpr(Inst, getMemOffset()); 510 } 511 512 void addMEMriiOperands(MCInst &Inst, unsigned N) const { 513 assert(N == 3 && "Invalid number of operands!"); 514 515 Inst.addOperand(MCOperand::createReg(getMemBase())); 516 addExpr(Inst, getMemIndex()); 517 addExpr(Inst, getMemOffset()); 518 } 519 520 void addMEMzriOperands(MCInst &Inst, unsigned N) const { 521 assert(N == 3 && "Invalid number of operands!"); 522 523 Inst.addOperand(MCOperand::createImm(0)); 524 Inst.addOperand(MCOperand::createReg(getMemIndexReg())); 525 addExpr(Inst, getMemOffset()); 526 } 527 528 void addMEMziiOperands(MCInst &Inst, unsigned N) const { 529 assert(N == 3 && "Invalid number of operands!"); 530 531 Inst.addOperand(MCOperand::createImm(0)); 532 addExpr(Inst, getMemIndex()); 533 addExpr(Inst, getMemOffset()); 534 } 535 536 void addMEMriOperands(MCInst &Inst, unsigned N) const { 537 assert(N == 2 && "Invalid number of operands!"); 538 539 Inst.addOperand(MCOperand::createReg(getMemBase())); 540 addExpr(Inst, getMemOffset()); 541 } 542 543 void addMEMziOperands(MCInst &Inst, unsigned N) const { 544 assert(N == 2 && "Invalid number of operands!"); 545 546 Inst.addOperand(MCOperand::createImm(0)); 547 addExpr(Inst, getMemOffset()); 548 } 549 550 void addCCOpOperands(MCInst &Inst, unsigned N) const { 551 assert(N == 1 && "Invalid number of operands!"); 552 553 Inst.addOperand(MCOperand::createImm(getCCVal())); 554 } 555 556 void addRDOpOperands(MCInst &Inst, unsigned N) const { 557 assert(N == 1 && "Invalid number of operands!"); 558 559 Inst.addOperand(MCOperand::createImm(getRDVal())); 560 } 561 562 void addMImmOperands(MCInst &Inst, unsigned N) const { 563 assert(N == 1 && "Invalid number of operands!"); 564 const auto *ConstExpr = dyn_cast<MCConstantExpr>(getMImmVal()); 565 assert(ConstExpr && "Null operands!"); 566 int64_t Value = ConstExpr->getValue(); 567 if (getM0Flag()) 568 Value += 64; 569 Inst.addOperand(MCOperand::createImm(Value)); 570 } 571 572 static std::unique_ptr<VEOperand> CreateToken(StringRef Str, SMLoc S) { 573 auto Op = std::make_unique<VEOperand>(k_Token); 574 Op->Tok.Data = Str.data(); 575 Op->Tok.Length = Str.size(); 576 Op->StartLoc = S; 577 Op->EndLoc = S; 578 return Op; 579 } 580 581 static std::unique_ptr<VEOperand> CreateReg(unsigned RegNum, SMLoc S, 582 SMLoc E) { 583 auto Op = std::make_unique<VEOperand>(k_Register); 584 Op->Reg.RegNum = RegNum; 585 Op->StartLoc = S; 586 Op->EndLoc = E; 587 return Op; 588 } 589 590 static std::unique_ptr<VEOperand> CreateImm(const MCExpr *Val, SMLoc S, 591 SMLoc E) { 592 auto Op = std::make_unique<VEOperand>(k_Immediate); 593 Op->Imm.Val = Val; 594 Op->StartLoc = S; 595 Op->EndLoc = E; 596 return Op; 597 } 598 599 static std::unique_ptr<VEOperand> CreateCCOp(unsigned CCVal, SMLoc S, 600 SMLoc E) { 601 auto Op = std::make_unique<VEOperand>(k_CCOp); 602 Op->CC.CCVal = CCVal; 603 Op->StartLoc = S; 604 Op->EndLoc = E; 605 return Op; 606 } 607 608 static std::unique_ptr<VEOperand> CreateRDOp(unsigned RDVal, SMLoc S, 609 SMLoc E) { 610 auto Op = std::make_unique<VEOperand>(k_RDOp); 611 Op->RD.RDVal = RDVal; 612 Op->StartLoc = S; 613 Op->EndLoc = E; 614 return Op; 615 } 616 617 static std::unique_ptr<VEOperand> CreateMImm(const MCExpr *Val, bool Flag, 618 SMLoc S, SMLoc E) { 619 auto Op = std::make_unique<VEOperand>(k_MImmOp); 620 Op->MImm.Val = Val; 621 Op->MImm.M0Flag = Flag; 622 Op->StartLoc = S; 623 Op->EndLoc = E; 624 return Op; 625 } 626 627 static bool MorphToI32Reg(VEOperand &Op) { 628 unsigned Reg = Op.getReg(); 629 unsigned regIdx = Reg - VE::SX0; 630 if (regIdx > 63) 631 return false; 632 Op.Reg.RegNum = I32Regs[regIdx]; 633 return true; 634 } 635 636 static bool MorphToF32Reg(VEOperand &Op) { 637 unsigned Reg = Op.getReg(); 638 unsigned regIdx = Reg - VE::SX0; 639 if (regIdx > 63) 640 return false; 641 Op.Reg.RegNum = F32Regs[regIdx]; 642 return true; 643 } 644 645 static bool MorphToF128Reg(VEOperand &Op) { 646 unsigned Reg = Op.getReg(); 647 unsigned regIdx = Reg - VE::SX0; 648 if (regIdx % 2 || regIdx > 63) 649 return false; 650 Op.Reg.RegNum = F128Regs[regIdx / 2]; 651 return true; 652 } 653 654 static bool MorphToVM512Reg(VEOperand &Op) { 655 unsigned Reg = Op.getReg(); 656 unsigned regIdx = Reg - VE::VM0; 657 if (regIdx % 2 || regIdx > 15) 658 return false; 659 Op.Reg.RegNum = VM512Regs[regIdx / 2]; 660 return true; 661 } 662 663 static bool MorphToMISCReg(VEOperand &Op) { 664 const auto *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm()); 665 if (!ConstExpr) 666 return false; 667 unsigned regIdx = ConstExpr->getValue(); 668 if (regIdx > 31 || MISCRegs[regIdx] == VE::NoRegister) 669 return false; 670 Op.Kind = k_Register; 671 Op.Reg.RegNum = MISCRegs[regIdx]; 672 return true; 673 } 674 675 static std::unique_ptr<VEOperand> 676 MorphToMEMri(unsigned Base, std::unique_ptr<VEOperand> Op) { 677 const MCExpr *Imm = Op->getImm(); 678 Op->Kind = k_MemoryRegImm; 679 Op->Mem.Base = Base; 680 Op->Mem.IndexReg = 0; 681 Op->Mem.Index = nullptr; 682 Op->Mem.Offset = Imm; 683 return Op; 684 } 685 686 static std::unique_ptr<VEOperand> 687 MorphToMEMzi(std::unique_ptr<VEOperand> Op) { 688 const MCExpr *Imm = Op->getImm(); 689 Op->Kind = k_MemoryZeroImm; 690 Op->Mem.Base = 0; 691 Op->Mem.IndexReg = 0; 692 Op->Mem.Index = nullptr; 693 Op->Mem.Offset = Imm; 694 return Op; 695 } 696 697 static std::unique_ptr<VEOperand> 698 MorphToMEMrri(unsigned Base, unsigned Index, std::unique_ptr<VEOperand> Op) { 699 const MCExpr *Imm = Op->getImm(); 700 Op->Kind = k_MemoryRegRegImm; 701 Op->Mem.Base = Base; 702 Op->Mem.IndexReg = Index; 703 Op->Mem.Index = nullptr; 704 Op->Mem.Offset = Imm; 705 return Op; 706 } 707 708 static std::unique_ptr<VEOperand> 709 MorphToMEMrii(unsigned Base, const MCExpr *Index, 710 std::unique_ptr<VEOperand> Op) { 711 const MCExpr *Imm = Op->getImm(); 712 Op->Kind = k_MemoryRegImmImm; 713 Op->Mem.Base = Base; 714 Op->Mem.IndexReg = 0; 715 Op->Mem.Index = Index; 716 Op->Mem.Offset = Imm; 717 return Op; 718 } 719 720 static std::unique_ptr<VEOperand> 721 MorphToMEMzri(unsigned Index, std::unique_ptr<VEOperand> Op) { 722 const MCExpr *Imm = Op->getImm(); 723 Op->Kind = k_MemoryZeroRegImm; 724 Op->Mem.Base = 0; 725 Op->Mem.IndexReg = Index; 726 Op->Mem.Index = nullptr; 727 Op->Mem.Offset = Imm; 728 return Op; 729 } 730 731 static std::unique_ptr<VEOperand> 732 MorphToMEMzii(const MCExpr *Index, std::unique_ptr<VEOperand> Op) { 733 const MCExpr *Imm = Op->getImm(); 734 Op->Kind = k_MemoryZeroImmImm; 735 Op->Mem.Base = 0; 736 Op->Mem.IndexReg = 0; 737 Op->Mem.Index = Index; 738 Op->Mem.Offset = Imm; 739 return Op; 740 } 741 }; 742 743 } // end anonymous namespace 744 745 bool VEAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 746 OperandVector &Operands, 747 MCStreamer &Out, uint64_t &ErrorInfo, 748 bool MatchingInlineAsm) { 749 MCInst Inst; 750 unsigned MatchResult = 751 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 752 switch (MatchResult) { 753 case Match_Success: 754 Inst.setLoc(IDLoc); 755 Out.emitInstruction(Inst, getSTI()); 756 return false; 757 758 case Match_MissingFeature: 759 return Error(IDLoc, 760 "instruction requires a CPU feature not currently enabled"); 761 762 case Match_InvalidOperand: { 763 SMLoc ErrorLoc = IDLoc; 764 if (ErrorInfo != ~0ULL) { 765 if (ErrorInfo >= Operands.size()) 766 return Error(IDLoc, "too few operands for instruction"); 767 768 ErrorLoc = ((VEOperand &)*Operands[ErrorInfo]).getStartLoc(); 769 if (ErrorLoc == SMLoc()) 770 ErrorLoc = IDLoc; 771 } 772 773 return Error(ErrorLoc, "invalid operand for instruction"); 774 } 775 case Match_MnemonicFail: 776 return Error(IDLoc, "invalid instruction mnemonic"); 777 } 778 llvm_unreachable("Implement any new match types added!"); 779 } 780 781 bool VEAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 782 SMLoc &EndLoc) { 783 if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success) 784 return Error(StartLoc, "invalid register name"); 785 return false; 786 } 787 788 /// Parses a register name using a given matching function. 789 /// Checks for lowercase or uppercase if necessary. 790 int VEAsmParser::parseRegisterName(unsigned (*matchFn)(StringRef)) { 791 StringRef Name = Parser.getTok().getString(); 792 793 int RegNum = matchFn(Name); 794 795 // GCC supports case insensitive register names. All of the VE registers 796 // are all lower case. 797 if (RegNum == VE::NoRegister) { 798 RegNum = matchFn(Name.lower()); 799 } 800 801 return RegNum; 802 } 803 804 /// Maps from the set of all register names to a register number. 805 /// \note Generated by TableGen. 806 static unsigned MatchRegisterName(StringRef Name); 807 808 /// Maps from the set of all alternative registernames to a register number. 809 /// \note Generated by TableGen. 810 static unsigned MatchRegisterAltName(StringRef Name); 811 812 OperandMatchResultTy 813 VEAsmParser::tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { 814 const AsmToken Tok = Parser.getTok(); 815 StartLoc = Tok.getLoc(); 816 EndLoc = Tok.getEndLoc(); 817 RegNo = 0; 818 if (getLexer().getKind() != AsmToken::Percent) 819 return MatchOperand_NoMatch; 820 Parser.Lex(); 821 822 RegNo = parseRegisterName(&MatchRegisterName); 823 if (RegNo == VE::NoRegister) 824 RegNo = parseRegisterName(&MatchRegisterAltName); 825 826 if (RegNo != VE::NoRegister) { 827 Parser.Lex(); 828 return MatchOperand_Success; 829 } 830 831 getLexer().UnLex(Tok); 832 return MatchOperand_NoMatch; 833 } 834 835 static StringRef parseCC(StringRef Name, unsigned Prefix, unsigned Suffix, 836 bool IntegerCC, bool OmitCC, SMLoc NameLoc, 837 OperandVector *Operands) { 838 // Parse instructions with a conditional code. For example, 'bne' is 839 // converted into two operands 'b' and 'ne'. 840 StringRef Cond = Name.slice(Prefix, Suffix); 841 VECC::CondCode CondCode = 842 IntegerCC ? stringToVEICondCode(Cond) : stringToVEFCondCode(Cond); 843 844 // If OmitCC is enabled, CC_AT and CC_AF is treated as a part of mnemonic. 845 if (CondCode != VECC::UNKNOWN && 846 (!OmitCC || (CondCode != VECC::CC_AT && CondCode != VECC::CC_AF))) { 847 StringRef SuffixStr = Name.substr(Suffix); 848 // Push "b". 849 Name = Name.slice(0, Prefix); 850 Operands->push_back(VEOperand::CreateToken(Name, NameLoc)); 851 // Push $cond part. 852 SMLoc CondLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Prefix); 853 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Suffix); 854 Operands->push_back(VEOperand::CreateCCOp(CondCode, CondLoc, SuffixLoc)); 855 // push suffix like ".l.t" 856 if (!SuffixStr.empty()) 857 Operands->push_back(VEOperand::CreateToken(SuffixStr, SuffixLoc)); 858 } else { 859 Operands->push_back(VEOperand::CreateToken(Name, NameLoc)); 860 } 861 return Name; 862 } 863 864 static StringRef parseRD(StringRef Name, unsigned Prefix, SMLoc NameLoc, 865 OperandVector *Operands) { 866 // Parse instructions with a conditional code. For example, 'cvt.w.d.sx.rz' 867 // is converted into two operands 'cvt.w.d.sx' and '.rz'. 868 StringRef RD = Name.substr(Prefix); 869 VERD::RoundingMode RoundingMode = stringToVERD(RD); 870 871 if (RoundingMode != VERD::UNKNOWN) { 872 Name = Name.slice(0, Prefix); 873 // push 1st like `cvt.w.d.sx` 874 Operands->push_back(VEOperand::CreateToken(Name, NameLoc)); 875 SMLoc SuffixLoc = 876 SMLoc::getFromPointer(NameLoc.getPointer() + (RD.data() - Name.data())); 877 SMLoc SuffixEnd = 878 SMLoc::getFromPointer(NameLoc.getPointer() + (RD.end() - Name.data())); 879 // push $round if it has rounding mode 880 Operands->push_back( 881 VEOperand::CreateRDOp(RoundingMode, SuffixLoc, SuffixEnd)); 882 } else { 883 Operands->push_back(VEOperand::CreateToken(Name, NameLoc)); 884 } 885 return Name; 886 } 887 888 // Split the mnemonic into ASM operand, conditional code and instruction 889 // qualifier (half-word, byte). 890 StringRef VEAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc, 891 OperandVector *Operands) { 892 // Create the leading tokens for the mnemonic 893 StringRef Mnemonic = Name; 894 895 if (Name[0] == 'b') { 896 // Match b?? or br??. 897 size_t Start = 1; 898 size_t Next = Name.find('.'); 899 // Adjust position of CondCode. 900 if (Name.size() > 1 && Name[1] == 'r') 901 Start = 2; 902 // Check suffix. 903 bool ICC = true; 904 if (Next + 1 < Name.size() && 905 (Name[Next + 1] == 'd' || Name[Next + 1] == 's')) 906 ICC = false; 907 Mnemonic = parseCC(Name, Start, Next, ICC, true, NameLoc, Operands); 908 } else if (Name.startswith("cmov.l.") || Name.startswith("cmov.w.") || 909 Name.startswith("cmov.d.") || Name.startswith("cmov.s.")) { 910 bool ICC = Name[5] == 'l' || Name[5] == 'w'; 911 Mnemonic = parseCC(Name, 7, Name.size(), ICC, false, NameLoc, Operands); 912 } else if (Name.startswith("cvt.w.d.sx") || Name.startswith("cvt.w.d.zx") || 913 Name.startswith("cvt.w.s.sx") || Name.startswith("cvt.w.s.zx")) { 914 Mnemonic = parseRD(Name, 10, NameLoc, Operands); 915 } else if (Name.startswith("cvt.l.d")) { 916 Mnemonic = parseRD(Name, 7, NameLoc, Operands); 917 } else if (Name.startswith("vcvt.w.d.sx") || Name.startswith("vcvt.w.d.zx") || 918 Name.startswith("vcvt.w.s.sx") || Name.startswith("vcvt.w.s.zx")) { 919 Mnemonic = parseRD(Name, 11, NameLoc, Operands); 920 } else if (Name.startswith("vcvt.l.d")) { 921 Mnemonic = parseRD(Name, 8, NameLoc, Operands); 922 } else if (Name.startswith("pvcvt.w.s.lo") || 923 Name.startswith("pvcvt.w.s.up")) { 924 Mnemonic = parseRD(Name, 12, NameLoc, Operands); 925 } else if (Name.startswith("pvcvt.w.s")) { 926 Mnemonic = parseRD(Name, 9, NameLoc, Operands); 927 } else { 928 Operands->push_back(VEOperand::CreateToken(Mnemonic, NameLoc)); 929 } 930 931 return Mnemonic; 932 } 933 934 static void applyMnemonicAliases(StringRef &Mnemonic, 935 const FeatureBitset &Features, 936 unsigned VariantID); 937 938 bool VEAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 939 SMLoc NameLoc, OperandVector &Operands) { 940 // If the target architecture uses MnemonicAlias, call it here to parse 941 // operands correctly. 942 applyMnemonicAliases(Name, getAvailableFeatures(), 0); 943 944 // Split name to first token and the rest, e.g. "bgt.l.t" to "b", "gt", and 945 // ".l.t". We treat "b" as a mnemonic, "gt" as first operand, and ".l.t" 946 // as second operand. 947 StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands); 948 949 if (getLexer().isNot(AsmToken::EndOfStatement)) { 950 // Read the first operand. 951 if (parseOperand(Operands, Mnemonic) != MatchOperand_Success) { 952 SMLoc Loc = getLexer().getLoc(); 953 return Error(Loc, "unexpected token"); 954 } 955 956 while (getLexer().is(AsmToken::Comma)) { 957 Parser.Lex(); // Eat the comma. 958 // Parse and remember the operand. 959 if (parseOperand(Operands, Mnemonic) != MatchOperand_Success) { 960 SMLoc Loc = getLexer().getLoc(); 961 return Error(Loc, "unexpected token"); 962 } 963 } 964 } 965 if (getLexer().isNot(AsmToken::EndOfStatement)) { 966 SMLoc Loc = getLexer().getLoc(); 967 return Error(Loc, "unexpected token"); 968 } 969 Parser.Lex(); // Consume the EndOfStatement. 970 return false; 971 } 972 973 bool VEAsmParser::ParseDirective(AsmToken DirectiveID) { 974 // Let the MC layer to handle other directives. 975 return true; 976 } 977 978 /// Extract \code @lo32/@hi32/etc \endcode modifier from expression. 979 /// Recursively scan the expression and check for VK_VE_HI32/LO32/etc 980 /// symbol variants. If all symbols with modifier use the same 981 /// variant, return the corresponding VEMCExpr::VariantKind, 982 /// and a modified expression using the default symbol variant. 983 /// Otherwise, return NULL. 984 const MCExpr * 985 VEAsmParser::extractModifierFromExpr(const MCExpr *E, 986 VEMCExpr::VariantKind &Variant) { 987 MCContext &Context = getParser().getContext(); 988 Variant = VEMCExpr::VK_VE_None; 989 990 switch (E->getKind()) { 991 case MCExpr::Target: 992 case MCExpr::Constant: 993 return nullptr; 994 995 case MCExpr::SymbolRef: { 996 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 997 998 switch (SRE->getKind()) { 999 case MCSymbolRefExpr::VK_None: 1000 // Use VK_VE_REFLONG to a symbol without modifiers. 1001 Variant = VEMCExpr::VK_VE_REFLONG; 1002 break; 1003 case MCSymbolRefExpr::VK_VE_HI32: 1004 Variant = VEMCExpr::VK_VE_HI32; 1005 break; 1006 case MCSymbolRefExpr::VK_VE_LO32: 1007 Variant = VEMCExpr::VK_VE_LO32; 1008 break; 1009 case MCSymbolRefExpr::VK_VE_PC_HI32: 1010 Variant = VEMCExpr::VK_VE_PC_HI32; 1011 break; 1012 case MCSymbolRefExpr::VK_VE_PC_LO32: 1013 Variant = VEMCExpr::VK_VE_PC_LO32; 1014 break; 1015 case MCSymbolRefExpr::VK_VE_GOT_HI32: 1016 Variant = VEMCExpr::VK_VE_GOT_HI32; 1017 break; 1018 case MCSymbolRefExpr::VK_VE_GOT_LO32: 1019 Variant = VEMCExpr::VK_VE_GOT_LO32; 1020 break; 1021 case MCSymbolRefExpr::VK_VE_GOTOFF_HI32: 1022 Variant = VEMCExpr::VK_VE_GOTOFF_HI32; 1023 break; 1024 case MCSymbolRefExpr::VK_VE_GOTOFF_LO32: 1025 Variant = VEMCExpr::VK_VE_GOTOFF_LO32; 1026 break; 1027 case MCSymbolRefExpr::VK_VE_PLT_HI32: 1028 Variant = VEMCExpr::VK_VE_PLT_HI32; 1029 break; 1030 case MCSymbolRefExpr::VK_VE_PLT_LO32: 1031 Variant = VEMCExpr::VK_VE_PLT_LO32; 1032 break; 1033 case MCSymbolRefExpr::VK_VE_TLS_GD_HI32: 1034 Variant = VEMCExpr::VK_VE_TLS_GD_HI32; 1035 break; 1036 case MCSymbolRefExpr::VK_VE_TLS_GD_LO32: 1037 Variant = VEMCExpr::VK_VE_TLS_GD_LO32; 1038 break; 1039 case MCSymbolRefExpr::VK_VE_TPOFF_HI32: 1040 Variant = VEMCExpr::VK_VE_TPOFF_HI32; 1041 break; 1042 case MCSymbolRefExpr::VK_VE_TPOFF_LO32: 1043 Variant = VEMCExpr::VK_VE_TPOFF_LO32; 1044 break; 1045 default: 1046 return nullptr; 1047 } 1048 1049 return MCSymbolRefExpr::create(&SRE->getSymbol(), Context); 1050 } 1051 1052 case MCExpr::Unary: { 1053 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); 1054 const MCExpr *Sub = extractModifierFromExpr(UE->getSubExpr(), Variant); 1055 if (!Sub) 1056 return nullptr; 1057 return MCUnaryExpr::create(UE->getOpcode(), Sub, Context); 1058 } 1059 1060 case MCExpr::Binary: { 1061 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 1062 VEMCExpr::VariantKind LHSVariant, RHSVariant; 1063 const MCExpr *LHS = extractModifierFromExpr(BE->getLHS(), LHSVariant); 1064 const MCExpr *RHS = extractModifierFromExpr(BE->getRHS(), RHSVariant); 1065 1066 if (!LHS && !RHS) 1067 return nullptr; 1068 1069 if (!LHS) 1070 LHS = BE->getLHS(); 1071 if (!RHS) 1072 RHS = BE->getRHS(); 1073 1074 if (LHSVariant == VEMCExpr::VK_VE_None) 1075 Variant = RHSVariant; 1076 else if (RHSVariant == VEMCExpr::VK_VE_None) 1077 Variant = LHSVariant; 1078 else if (LHSVariant == RHSVariant) 1079 Variant = LHSVariant; 1080 else 1081 return nullptr; 1082 1083 return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context); 1084 } 1085 } 1086 1087 llvm_unreachable("Invalid expression kind!"); 1088 } 1089 1090 const MCExpr *VEAsmParser::fixupVariantKind(const MCExpr *E) { 1091 MCContext &Context = getParser().getContext(); 1092 1093 switch (E->getKind()) { 1094 case MCExpr::Target: 1095 case MCExpr::Constant: 1096 case MCExpr::SymbolRef: 1097 return E; 1098 1099 case MCExpr::Unary: { 1100 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); 1101 const MCExpr *Sub = fixupVariantKind(UE->getSubExpr()); 1102 if (Sub == UE->getSubExpr()) 1103 return E; 1104 return MCUnaryExpr::create(UE->getOpcode(), Sub, Context); 1105 } 1106 1107 case MCExpr::Binary: { 1108 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 1109 const MCExpr *LHS = fixupVariantKind(BE->getLHS()); 1110 const MCExpr *RHS = fixupVariantKind(BE->getRHS()); 1111 if (LHS == BE->getLHS() && RHS == BE->getRHS()) 1112 return E; 1113 return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context); 1114 } 1115 } 1116 1117 llvm_unreachable("Invalid expression kind!"); 1118 } 1119 1120 /// ParseExpression. This differs from the default "parseExpression" in that 1121 /// it handles modifiers. 1122 bool VEAsmParser::parseExpression(const MCExpr *&EVal) { 1123 // Handle \code symbol @lo32/@hi32/etc \endcode. 1124 if (getParser().parseExpression(EVal)) 1125 return true; 1126 1127 // Convert MCSymbolRefExpr with VK_* to MCExpr with VK_*. 1128 EVal = fixupVariantKind(EVal); 1129 VEMCExpr::VariantKind Variant; 1130 const MCExpr *E = extractModifierFromExpr(EVal, Variant); 1131 if (E) 1132 EVal = VEMCExpr::create(Variant, E, getParser().getContext()); 1133 1134 return false; 1135 } 1136 1137 OperandMatchResultTy VEAsmParser::parseMEMOperand(OperandVector &Operands) { 1138 LLVM_DEBUG(dbgs() << "parseMEMOperand\n"); 1139 const AsmToken &Tok = Parser.getTok(); 1140 SMLoc S = Tok.getLoc(); 1141 SMLoc E = Tok.getEndLoc(); 1142 // Parse ASX format 1143 // disp 1144 // disp(, base) 1145 // disp(index) 1146 // disp(index, base) 1147 // (, base) 1148 // (index) 1149 // (index, base) 1150 1151 std::unique_ptr<VEOperand> Offset; 1152 switch (getLexer().getKind()) { 1153 default: 1154 return MatchOperand_NoMatch; 1155 1156 case AsmToken::Minus: 1157 case AsmToken::Integer: 1158 case AsmToken::Dot: 1159 case AsmToken::Identifier: { 1160 const MCExpr *EVal; 1161 if (!parseExpression(EVal)) 1162 Offset = VEOperand::CreateImm(EVal, S, E); 1163 else 1164 return MatchOperand_NoMatch; 1165 break; 1166 } 1167 1168 case AsmToken::LParen: 1169 // empty disp (= 0) 1170 Offset = 1171 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E); 1172 break; 1173 } 1174 1175 switch (getLexer().getKind()) { 1176 default: 1177 return MatchOperand_ParseFail; 1178 1179 case AsmToken::EndOfStatement: 1180 Operands.push_back(VEOperand::MorphToMEMzii( 1181 MCConstantExpr::create(0, getContext()), std::move(Offset))); 1182 return MatchOperand_Success; 1183 1184 case AsmToken::LParen: 1185 Parser.Lex(); // Eat the ( 1186 break; 1187 } 1188 1189 const MCExpr *IndexValue = nullptr; 1190 unsigned IndexReg = 0; 1191 1192 switch (getLexer().getKind()) { 1193 default: 1194 if (ParseRegister(IndexReg, S, E)) 1195 return MatchOperand_ParseFail; 1196 break; 1197 1198 case AsmToken::Minus: 1199 case AsmToken::Integer: 1200 case AsmToken::Dot: 1201 if (getParser().parseExpression(IndexValue, E)) 1202 return MatchOperand_ParseFail; 1203 break; 1204 1205 case AsmToken::Comma: 1206 // empty index 1207 IndexValue = MCConstantExpr::create(0, getContext()); 1208 break; 1209 } 1210 1211 switch (getLexer().getKind()) { 1212 default: 1213 return MatchOperand_ParseFail; 1214 1215 case AsmToken::RParen: 1216 Parser.Lex(); // Eat the ) 1217 Operands.push_back( 1218 IndexValue ? VEOperand::MorphToMEMzii(IndexValue, std::move(Offset)) 1219 : VEOperand::MorphToMEMzri(IndexReg, std::move(Offset))); 1220 return MatchOperand_Success; 1221 1222 case AsmToken::Comma: 1223 Parser.Lex(); // Eat the , 1224 break; 1225 } 1226 1227 unsigned BaseReg = 0; 1228 if (ParseRegister(BaseReg, S, E)) 1229 return MatchOperand_ParseFail; 1230 1231 if (!Parser.getTok().is(AsmToken::RParen)) 1232 return MatchOperand_ParseFail; 1233 1234 Parser.Lex(); // Eat the ) 1235 Operands.push_back( 1236 IndexValue 1237 ? VEOperand::MorphToMEMrii(BaseReg, IndexValue, std::move(Offset)) 1238 : VEOperand::MorphToMEMrri(BaseReg, IndexReg, std::move(Offset))); 1239 1240 return MatchOperand_Success; 1241 } 1242 1243 OperandMatchResultTy VEAsmParser::parseMEMAsOperand(OperandVector &Operands) { 1244 LLVM_DEBUG(dbgs() << "parseMEMAsOperand\n"); 1245 const AsmToken &Tok = Parser.getTok(); 1246 SMLoc S = Tok.getLoc(); 1247 SMLoc E = Tok.getEndLoc(); 1248 // Parse AS format 1249 // disp 1250 // disp(, base) 1251 // disp(base) 1252 // disp() 1253 // (, base) 1254 // (base) 1255 // base 1256 1257 unsigned BaseReg = VE::NoRegister; 1258 std::unique_ptr<VEOperand> Offset; 1259 switch (getLexer().getKind()) { 1260 default: 1261 return MatchOperand_NoMatch; 1262 1263 case AsmToken::Minus: 1264 case AsmToken::Integer: 1265 case AsmToken::Dot: 1266 case AsmToken::Identifier: { 1267 const MCExpr *EVal; 1268 if (!parseExpression(EVal)) 1269 Offset = VEOperand::CreateImm(EVal, S, E); 1270 else 1271 return MatchOperand_NoMatch; 1272 break; 1273 } 1274 1275 case AsmToken::Percent: 1276 if (ParseRegister(BaseReg, S, E)) 1277 return MatchOperand_NoMatch; 1278 Offset = 1279 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E); 1280 break; 1281 1282 case AsmToken::LParen: 1283 // empty disp (= 0) 1284 Offset = 1285 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E); 1286 break; 1287 } 1288 1289 switch (getLexer().getKind()) { 1290 default: 1291 return MatchOperand_ParseFail; 1292 1293 case AsmToken::EndOfStatement: 1294 case AsmToken::Comma: 1295 Operands.push_back(BaseReg != VE::NoRegister 1296 ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset)) 1297 : VEOperand::MorphToMEMzi(std::move(Offset))); 1298 return MatchOperand_Success; 1299 1300 case AsmToken::LParen: 1301 if (BaseReg != VE::NoRegister) 1302 return MatchOperand_ParseFail; 1303 Parser.Lex(); // Eat the ( 1304 break; 1305 } 1306 1307 switch (getLexer().getKind()) { 1308 default: 1309 if (ParseRegister(BaseReg, S, E)) 1310 return MatchOperand_ParseFail; 1311 break; 1312 1313 case AsmToken::Comma: 1314 Parser.Lex(); // Eat the , 1315 if (ParseRegister(BaseReg, S, E)) 1316 return MatchOperand_ParseFail; 1317 break; 1318 1319 case AsmToken::RParen: 1320 break; 1321 } 1322 1323 if (!Parser.getTok().is(AsmToken::RParen)) 1324 return MatchOperand_ParseFail; 1325 1326 Parser.Lex(); // Eat the ) 1327 Operands.push_back(BaseReg != VE::NoRegister 1328 ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset)) 1329 : VEOperand::MorphToMEMzi(std::move(Offset))); 1330 1331 return MatchOperand_Success; 1332 } 1333 1334 OperandMatchResultTy VEAsmParser::parseMImmOperand(OperandVector &Operands) { 1335 LLVM_DEBUG(dbgs() << "parseMImmOperand\n"); 1336 1337 // Parsing "(" + number + ")0/1" 1338 const AsmToken Tok1 = Parser.getTok(); 1339 if (!Tok1.is(AsmToken::LParen)) 1340 return MatchOperand_NoMatch; 1341 1342 Parser.Lex(); // Eat the '('. 1343 1344 const AsmToken Tok2 = Parser.getTok(); 1345 SMLoc E; 1346 const MCExpr *EVal; 1347 if (!Tok2.is(AsmToken::Integer) || getParser().parseExpression(EVal, E)) { 1348 getLexer().UnLex(Tok1); 1349 return MatchOperand_NoMatch; 1350 } 1351 1352 const AsmToken Tok3 = Parser.getTok(); 1353 if (!Tok3.is(AsmToken::RParen)) { 1354 getLexer().UnLex(Tok2); 1355 getLexer().UnLex(Tok1); 1356 return MatchOperand_NoMatch; 1357 } 1358 Parser.Lex(); // Eat the ')'. 1359 1360 const AsmToken &Tok4 = Parser.getTok(); 1361 StringRef Suffix = Tok4.getString(); 1362 if (Suffix != "1" && Suffix != "0") { 1363 getLexer().UnLex(Tok3); 1364 getLexer().UnLex(Tok2); 1365 getLexer().UnLex(Tok1); 1366 return MatchOperand_NoMatch; 1367 } 1368 Parser.Lex(); // Eat the value. 1369 SMLoc EndLoc = SMLoc::getFromPointer(Suffix.end()); 1370 Operands.push_back( 1371 VEOperand::CreateMImm(EVal, Suffix == "0", Tok1.getLoc(), EndLoc)); 1372 return MatchOperand_Success; 1373 } 1374 1375 OperandMatchResultTy VEAsmParser::parseOperand(OperandVector &Operands, 1376 StringRef Mnemonic) { 1377 LLVM_DEBUG(dbgs() << "parseOperand\n"); 1378 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1379 1380 // If there wasn't a custom match, try the generic matcher below. Otherwise, 1381 // there was a match, but an error occurred, in which case, just return that 1382 // the operand parsing failed. 1383 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail) 1384 return ResTy; 1385 1386 switch (getLexer().getKind()) { 1387 case AsmToken::LParen: { 1388 // Parsing "(" + %vreg + ", " + %vreg + ")" 1389 const AsmToken Tok1 = Parser.getTok(); 1390 Parser.Lex(); // Eat the '('. 1391 1392 unsigned RegNo1; 1393 SMLoc S1, E1; 1394 if (tryParseRegister(RegNo1, S1, E1) != MatchOperand_Success) { 1395 getLexer().UnLex(Tok1); 1396 return MatchOperand_NoMatch; 1397 } 1398 1399 if (!Parser.getTok().is(AsmToken::Comma)) 1400 return MatchOperand_ParseFail; 1401 Parser.Lex(); // Eat the ','. 1402 1403 unsigned RegNo2; 1404 SMLoc S2, E2; 1405 if (tryParseRegister(RegNo2, S2, E2) != MatchOperand_Success) 1406 return MatchOperand_ParseFail; 1407 1408 if (!Parser.getTok().is(AsmToken::RParen)) 1409 return MatchOperand_ParseFail; 1410 1411 Operands.push_back(VEOperand::CreateToken(Tok1.getString(), Tok1.getLoc())); 1412 Operands.push_back(VEOperand::CreateReg(RegNo1, S1, E1)); 1413 Operands.push_back(VEOperand::CreateReg(RegNo2, S2, E2)); 1414 Operands.push_back(VEOperand::CreateToken(Parser.getTok().getString(), 1415 Parser.getTok().getLoc())); 1416 Parser.Lex(); // Eat the ')'. 1417 break; 1418 } 1419 default: { 1420 std::unique_ptr<VEOperand> Op; 1421 ResTy = parseVEAsmOperand(Op); 1422 if (ResTy != MatchOperand_Success || !Op) 1423 return MatchOperand_ParseFail; 1424 1425 // Push the parsed operand into the list of operands 1426 Operands.push_back(std::move(Op)); 1427 1428 if (!Parser.getTok().is(AsmToken::LParen)) 1429 break; 1430 1431 // Parsing %vec-reg + "(" + %sclar-reg/number + ")" 1432 std::unique_ptr<VEOperand> Op1 = VEOperand::CreateToken( 1433 Parser.getTok().getString(), Parser.getTok().getLoc()); 1434 Parser.Lex(); // Eat the '('. 1435 1436 std::unique_ptr<VEOperand> Op2; 1437 ResTy = parseVEAsmOperand(Op2); 1438 if (ResTy != MatchOperand_Success || !Op2) 1439 return MatchOperand_ParseFail; 1440 1441 if (!Parser.getTok().is(AsmToken::RParen)) 1442 return MatchOperand_ParseFail; 1443 1444 Operands.push_back(std::move(Op1)); 1445 Operands.push_back(std::move(Op2)); 1446 Operands.push_back(VEOperand::CreateToken(Parser.getTok().getString(), 1447 Parser.getTok().getLoc())); 1448 Parser.Lex(); // Eat the ')'. 1449 break; 1450 } 1451 } 1452 1453 return MatchOperand_Success; 1454 } 1455 1456 OperandMatchResultTy 1457 VEAsmParser::parseVEAsmOperand(std::unique_ptr<VEOperand> &Op) { 1458 LLVM_DEBUG(dbgs() << "parseVEAsmOperand\n"); 1459 SMLoc S = Parser.getTok().getLoc(); 1460 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1461 const MCExpr *EVal; 1462 1463 Op = nullptr; 1464 switch (getLexer().getKind()) { 1465 default: 1466 break; 1467 1468 case AsmToken::Percent: 1469 unsigned RegNo; 1470 if (tryParseRegister(RegNo, S, E) == MatchOperand_Success) 1471 Op = VEOperand::CreateReg(RegNo, S, E); 1472 break; 1473 1474 case AsmToken::Minus: 1475 case AsmToken::Integer: 1476 case AsmToken::Dot: 1477 case AsmToken::Identifier: 1478 if (!parseExpression(EVal)) 1479 Op = VEOperand::CreateImm(EVal, S, E); 1480 break; 1481 } 1482 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail; 1483 } 1484 1485 // Force static initialization. 1486 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmParser() { 1487 RegisterMCAsmParser<VEAsmParser> A(getTheVETarget()); 1488 } 1489 1490 #define GET_REGISTER_MATCHER 1491 #define GET_MATCHER_IMPLEMENTATION 1492 #include "VEGenAsmMatcher.inc" 1493 1494 unsigned VEAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp, 1495 unsigned Kind) { 1496 VEOperand &Op = (VEOperand &)GOp; 1497 1498 // VE uses identical register name for all registers like both 1499 // F32 and I32 uses "%s23". Need to convert the name of them 1500 // for validation. 1501 switch (Kind) { 1502 default: 1503 break; 1504 case MCK_F32: 1505 if (Op.isReg() && VEOperand::MorphToF32Reg(Op)) 1506 return MCTargetAsmParser::Match_Success; 1507 break; 1508 case MCK_I32: 1509 if (Op.isReg() && VEOperand::MorphToI32Reg(Op)) 1510 return MCTargetAsmParser::Match_Success; 1511 break; 1512 case MCK_F128: 1513 if (Op.isReg() && VEOperand::MorphToF128Reg(Op)) 1514 return MCTargetAsmParser::Match_Success; 1515 break; 1516 case MCK_VM512: 1517 if (Op.isReg() && VEOperand::MorphToVM512Reg(Op)) 1518 return MCTargetAsmParser::Match_Success; 1519 break; 1520 case MCK_MISC: 1521 if (Op.isImm() && VEOperand::MorphToMISCReg(Op)) 1522 return MCTargetAsmParser::Match_Success; 1523 break; 1524 } 1525 return Match_InvalidOperand; 1526 } 1527