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