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