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