1 //===-- AMDGPUAsmParser.cpp - Parse SI asm to MCInst instructions ----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "AMDKernelCodeT.h" 11 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 12 #include "MCTargetDesc/AMDGPUTargetStreamer.h" 13 #include "SIDefines.h" 14 #include "Utils/AMDGPUBaseInfo.h" 15 #include "llvm/ADT/APFloat.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/SmallString.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/ADT/StringSwitch.h" 20 #include "llvm/ADT/Twine.h" 21 #include "llvm/MC/MCContext.h" 22 #include "llvm/MC/MCExpr.h" 23 #include "llvm/MC/MCInst.h" 24 #include "llvm/MC/MCInstrInfo.h" 25 #include "llvm/MC/MCParser/MCAsmLexer.h" 26 #include "llvm/MC/MCParser/MCAsmParser.h" 27 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 28 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 29 #include "llvm/MC/MCRegisterInfo.h" 30 #include "llvm/MC/MCStreamer.h" 31 #include "llvm/MC/MCSubtargetInfo.h" 32 #include "llvm/MC/MCSymbolELF.h" 33 #include "llvm/Support/Debug.h" 34 #include "llvm/Support/ELF.h" 35 #include "llvm/Support/SourceMgr.h" 36 #include "llvm/Support/TargetRegistry.h" 37 #include "llvm/Support/raw_ostream.h" 38 39 using namespace llvm; 40 41 namespace { 42 43 struct OptionalOperand; 44 45 class AMDGPUOperand : public MCParsedAsmOperand { 46 enum KindTy { 47 Token, 48 Immediate, 49 Register, 50 Expression 51 } Kind; 52 53 SMLoc StartLoc, EndLoc; 54 55 public: 56 AMDGPUOperand(enum KindTy K) : MCParsedAsmOperand(), Kind(K) {} 57 58 MCContext *Ctx; 59 60 enum ImmTy { 61 ImmTyNone, 62 ImmTyDSOffset0, 63 ImmTyDSOffset1, 64 ImmTyGDS, 65 ImmTyOffset, 66 ImmTyGLC, 67 ImmTySLC, 68 ImmTyTFE, 69 ImmTyClamp, 70 ImmTyOMod 71 }; 72 73 struct TokOp { 74 const char *Data; 75 unsigned Length; 76 }; 77 78 struct ImmOp { 79 bool IsFPImm; 80 ImmTy Type; 81 int64_t Val; 82 }; 83 84 struct RegOp { 85 unsigned RegNo; 86 int Modifiers; 87 const MCRegisterInfo *TRI; 88 const MCSubtargetInfo *STI; 89 bool IsForcedVOP3; 90 }; 91 92 union { 93 TokOp Tok; 94 ImmOp Imm; 95 RegOp Reg; 96 const MCExpr *Expr; 97 }; 98 99 void addImmOperands(MCInst &Inst, unsigned N) const { 100 Inst.addOperand(MCOperand::createImm(getImm())); 101 } 102 103 StringRef getToken() const { 104 return StringRef(Tok.Data, Tok.Length); 105 } 106 107 void addRegOperands(MCInst &Inst, unsigned N) const { 108 Inst.addOperand(MCOperand::createReg(AMDGPU::getMCReg(getReg(), *Reg.STI))); 109 } 110 111 void addRegOrImmOperands(MCInst &Inst, unsigned N) const { 112 if (isReg()) 113 addRegOperands(Inst, N); 114 else 115 addImmOperands(Inst, N); 116 } 117 118 void addRegWithInputModsOperands(MCInst &Inst, unsigned N) const { 119 Inst.addOperand(MCOperand::createImm(Reg.Modifiers)); 120 addRegOperands(Inst, N); 121 } 122 123 void addSoppBrTargetOperands(MCInst &Inst, unsigned N) const { 124 if (isImm()) 125 addImmOperands(Inst, N); 126 else { 127 assert(isExpr()); 128 Inst.addOperand(MCOperand::createExpr(Expr)); 129 } 130 } 131 132 bool defaultTokenHasSuffix() const { 133 StringRef Token(Tok.Data, Tok.Length); 134 135 return Token.endswith("_e32") || Token.endswith("_e64"); 136 } 137 138 bool isToken() const override { 139 return Kind == Token; 140 } 141 142 bool isImm() const override { 143 return Kind == Immediate; 144 } 145 146 bool isInlineImm() const { 147 float F = BitsToFloat(Imm.Val); 148 // TODO: Add 0.5pi for VI 149 return isImm() && ((Imm.Val <= 64 && Imm.Val >= -16) || 150 (F == 0.0 || F == 0.5 || F == -0.5 || F == 1.0 || F == -1.0 || 151 F == 2.0 || F == -2.0 || F == 4.0 || F == -4.0)); 152 } 153 154 bool isDSOffset0() const { 155 assert(isImm()); 156 return Imm.Type == ImmTyDSOffset0; 157 } 158 159 bool isDSOffset1() const { 160 assert(isImm()); 161 return Imm.Type == ImmTyDSOffset1; 162 } 163 164 int64_t getImm() const { 165 return Imm.Val; 166 } 167 168 enum ImmTy getImmTy() const { 169 assert(isImm()); 170 return Imm.Type; 171 } 172 173 bool isRegKind() const { 174 return Kind == Register; 175 } 176 177 bool isReg() const override { 178 return Kind == Register && Reg.Modifiers == 0; 179 } 180 181 bool isRegWithInputMods() const { 182 return Kind == Register; 183 } 184 185 bool isClamp() const { 186 return isImm() && Imm.Type == ImmTyClamp; 187 } 188 189 bool isOMod() const { 190 return isImm() && Imm.Type == ImmTyOMod; 191 } 192 193 bool isMod() const { 194 return isClamp() || isOMod(); 195 } 196 197 void setModifiers(unsigned Mods) { 198 assert(isReg()); 199 Reg.Modifiers = Mods; 200 } 201 202 bool hasModifiers() const { 203 assert(isRegKind()); 204 return Reg.Modifiers != 0; 205 } 206 207 unsigned getReg() const override { 208 return Reg.RegNo; 209 } 210 211 bool isRegOrImm() const { 212 return isReg() || isImm(); 213 } 214 215 bool isRegClass(unsigned RCID) const { 216 return isReg() && Reg.TRI->getRegClass(RCID).contains(getReg()); 217 } 218 219 bool isSCSrc32() const { 220 return isInlineImm() || (isReg() && isRegClass(AMDGPU::SReg_32RegClassID)); 221 } 222 223 bool isSSrc32() const { 224 return isImm() || (isReg() && isRegClass(AMDGPU::SReg_32RegClassID)); 225 } 226 227 bool isSSrc64() const { 228 return isImm() || isInlineImm() || 229 (isReg() && isRegClass(AMDGPU::SReg_64RegClassID)); 230 } 231 232 bool isSCSrc64() const { 233 return (isReg() && isRegClass(AMDGPU::SReg_64RegClassID)) || isInlineImm(); 234 } 235 236 bool isVCSrc32() const { 237 return isInlineImm() || (isReg() && isRegClass(AMDGPU::VS_32RegClassID)); 238 } 239 240 bool isVCSrc64() const { 241 return isInlineImm() || (isReg() && isRegClass(AMDGPU::VS_64RegClassID)); 242 } 243 244 bool isVSrc32() const { 245 return isImm() || (isReg() && isRegClass(AMDGPU::VS_32RegClassID)); 246 } 247 248 bool isVSrc64() const { 249 return isImm() || (isReg() && isRegClass(AMDGPU::VS_64RegClassID)); 250 } 251 252 bool isMem() const override { 253 return false; 254 } 255 256 bool isExpr() const { 257 return Kind == Expression; 258 } 259 260 bool isSoppBrTarget() const { 261 return isExpr() || isImm(); 262 } 263 264 SMLoc getStartLoc() const override { 265 return StartLoc; 266 } 267 268 SMLoc getEndLoc() const override { 269 return EndLoc; 270 } 271 272 void print(raw_ostream &OS) const override { 273 switch (Kind) { 274 case Register: 275 OS << "<register " << getReg() << " mods: " << Reg.Modifiers << '>'; 276 break; 277 case Immediate: 278 OS << getImm(); 279 break; 280 case Token: 281 OS << '\'' << getToken() << '\''; 282 break; 283 case Expression: 284 OS << "<expr " << *Expr << '>'; 285 break; 286 } 287 } 288 289 static std::unique_ptr<AMDGPUOperand> CreateImm(int64_t Val, SMLoc Loc, 290 enum ImmTy Type = ImmTyNone, 291 bool IsFPImm = false) { 292 auto Op = llvm::make_unique<AMDGPUOperand>(Immediate); 293 Op->Imm.Val = Val; 294 Op->Imm.IsFPImm = IsFPImm; 295 Op->Imm.Type = Type; 296 Op->StartLoc = Loc; 297 Op->EndLoc = Loc; 298 return Op; 299 } 300 301 static std::unique_ptr<AMDGPUOperand> CreateToken(StringRef Str, SMLoc Loc, 302 bool HasExplicitEncodingSize = true) { 303 auto Res = llvm::make_unique<AMDGPUOperand>(Token); 304 Res->Tok.Data = Str.data(); 305 Res->Tok.Length = Str.size(); 306 Res->StartLoc = Loc; 307 Res->EndLoc = Loc; 308 return Res; 309 } 310 311 static std::unique_ptr<AMDGPUOperand> CreateReg(unsigned RegNo, SMLoc S, 312 SMLoc E, 313 const MCRegisterInfo *TRI, 314 const MCSubtargetInfo *STI, 315 bool ForceVOP3) { 316 auto Op = llvm::make_unique<AMDGPUOperand>(Register); 317 Op->Reg.RegNo = RegNo; 318 Op->Reg.TRI = TRI; 319 Op->Reg.STI = STI; 320 Op->Reg.Modifiers = 0; 321 Op->Reg.IsForcedVOP3 = ForceVOP3; 322 Op->StartLoc = S; 323 Op->EndLoc = E; 324 return Op; 325 } 326 327 static std::unique_ptr<AMDGPUOperand> CreateExpr(const class MCExpr *Expr, SMLoc S) { 328 auto Op = llvm::make_unique<AMDGPUOperand>(Expression); 329 Op->Expr = Expr; 330 Op->StartLoc = S; 331 Op->EndLoc = S; 332 return Op; 333 } 334 335 bool isDSOffset() const; 336 bool isDSOffset01() const; 337 bool isSWaitCnt() const; 338 bool isMubufOffset() const; 339 bool isSMRDOffset() const; 340 bool isSMRDLiteralOffset() const; 341 }; 342 343 class AMDGPUAsmParser : public MCTargetAsmParser { 344 const MCInstrInfo &MII; 345 MCAsmParser &Parser; 346 347 unsigned ForcedEncodingSize; 348 349 bool isSI() const { 350 return AMDGPU::isSI(getSTI()); 351 } 352 353 bool isCI() const { 354 return AMDGPU::isCI(getSTI()); 355 } 356 357 bool isVI() const { 358 return AMDGPU::isVI(getSTI()); 359 } 360 361 bool hasSGPR102_SGPR103() const { 362 return !isVI(); 363 } 364 365 /// @name Auto-generated Match Functions 366 /// { 367 368 #define GET_ASSEMBLER_HEADER 369 #include "AMDGPUGenAsmMatcher.inc" 370 371 /// } 372 373 private: 374 bool ParseDirectiveMajorMinor(uint32_t &Major, uint32_t &Minor); 375 bool ParseDirectiveHSACodeObjectVersion(); 376 bool ParseDirectiveHSACodeObjectISA(); 377 bool ParseAMDKernelCodeTValue(StringRef ID, amd_kernel_code_t &Header); 378 bool ParseDirectiveAMDKernelCodeT(); 379 bool ParseSectionDirectiveHSAText(); 380 bool subtargetHasRegister(const MCRegisterInfo &MRI, unsigned RegNo) const; 381 bool ParseDirectiveAMDGPUHsaKernel(); 382 bool ParseDirectiveAMDGPUHsaModuleGlobal(); 383 bool ParseDirectiveAMDGPUHsaProgramGlobal(); 384 bool ParseSectionDirectiveHSADataGlobalAgent(); 385 bool ParseSectionDirectiveHSADataGlobalProgram(); 386 bool ParseSectionDirectiveHSARodataReadonlyAgent(); 387 388 public: 389 public: 390 enum AMDGPUMatchResultTy { 391 Match_PreferE32 = FIRST_TARGET_MATCH_RESULT_TY 392 }; 393 394 AMDGPUAsmParser(const MCSubtargetInfo &STI, MCAsmParser &_Parser, 395 const MCInstrInfo &MII, 396 const MCTargetOptions &Options) 397 : MCTargetAsmParser(Options, STI), MII(MII), Parser(_Parser), 398 ForcedEncodingSize(0) { 399 MCAsmParserExtension::Initialize(Parser); 400 401 if (getSTI().getFeatureBits().none()) { 402 // Set default features. 403 copySTI().ToggleFeature("SOUTHERN_ISLANDS"); 404 } 405 406 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); 407 } 408 409 AMDGPUTargetStreamer &getTargetStreamer() { 410 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 411 return static_cast<AMDGPUTargetStreamer &>(TS); 412 } 413 414 unsigned getForcedEncodingSize() const { 415 return ForcedEncodingSize; 416 } 417 418 void setForcedEncodingSize(unsigned Size) { 419 ForcedEncodingSize = Size; 420 } 421 422 bool isForcedVOP3() const { 423 return ForcedEncodingSize == 64; 424 } 425 426 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 427 unsigned checkTargetMatchPredicate(MCInst &Inst) override; 428 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 429 OperandVector &Operands, MCStreamer &Out, 430 uint64_t &ErrorInfo, 431 bool MatchingInlineAsm) override; 432 bool ParseDirective(AsmToken DirectiveID) override; 433 OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Mnemonic); 434 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 435 SMLoc NameLoc, OperandVector &Operands) override; 436 437 OperandMatchResultTy parseIntWithPrefix(const char *Prefix, int64_t &Int, 438 int64_t Default = 0); 439 OperandMatchResultTy parseIntWithPrefix(const char *Prefix, 440 OperandVector &Operands, 441 enum AMDGPUOperand::ImmTy ImmTy = 442 AMDGPUOperand::ImmTyNone); 443 OperandMatchResultTy parseNamedBit(const char *Name, OperandVector &Operands, 444 enum AMDGPUOperand::ImmTy ImmTy = 445 AMDGPUOperand::ImmTyNone); 446 OperandMatchResultTy parseOptionalOps( 447 const ArrayRef<OptionalOperand> &OptionalOps, 448 OperandVector &Operands); 449 450 451 void cvtDSOffset01(MCInst &Inst, const OperandVector &Operands); 452 void cvtDS(MCInst &Inst, const OperandVector &Operands); 453 OperandMatchResultTy parseDSOptionalOps(OperandVector &Operands); 454 OperandMatchResultTy parseDSOff01OptionalOps(OperandVector &Operands); 455 OperandMatchResultTy parseDSOffsetOptional(OperandVector &Operands); 456 457 bool parseCnt(int64_t &IntVal); 458 OperandMatchResultTy parseSWaitCntOps(OperandVector &Operands); 459 OperandMatchResultTy parseSOppBrTarget(OperandVector &Operands); 460 461 OperandMatchResultTy parseFlatOptionalOps(OperandVector &Operands); 462 OperandMatchResultTy parseFlatAtomicOptionalOps(OperandVector &Operands); 463 void cvtFlat(MCInst &Inst, const OperandVector &Operands); 464 465 void cvtMubuf(MCInst &Inst, const OperandVector &Operands); 466 OperandMatchResultTy parseOffset(OperandVector &Operands); 467 OperandMatchResultTy parseMubufOptionalOps(OperandVector &Operands); 468 OperandMatchResultTy parseGLC(OperandVector &Operands); 469 OperandMatchResultTy parseSLC(OperandVector &Operands); 470 OperandMatchResultTy parseTFE(OperandVector &Operands); 471 472 OperandMatchResultTy parseDMask(OperandVector &Operands); 473 OperandMatchResultTy parseUNorm(OperandVector &Operands); 474 OperandMatchResultTy parseR128(OperandVector &Operands); 475 476 void cvtId(MCInst &Inst, const OperandVector &Operands); 477 void cvtVOP3_2_mod(MCInst &Inst, const OperandVector &Operands); 478 void cvtVOP3_2_nomod(MCInst &Inst, const OperandVector &Operands); 479 void cvtVOP3_only(MCInst &Inst, const OperandVector &Operands); 480 void cvtVOP3(MCInst &Inst, const OperandVector &Operands); 481 OperandMatchResultTy parseVOP3OptionalOps(OperandVector &Operands); 482 }; 483 484 struct OptionalOperand { 485 const char *Name; 486 AMDGPUOperand::ImmTy Type; 487 bool IsBit; 488 int64_t Default; 489 bool (*ConvertResult)(int64_t&); 490 }; 491 492 } 493 494 static int getRegClass(bool IsVgpr, unsigned RegWidth) { 495 if (IsVgpr) { 496 switch (RegWidth) { 497 default: return -1; 498 case 1: return AMDGPU::VGPR_32RegClassID; 499 case 2: return AMDGPU::VReg_64RegClassID; 500 case 3: return AMDGPU::VReg_96RegClassID; 501 case 4: return AMDGPU::VReg_128RegClassID; 502 case 8: return AMDGPU::VReg_256RegClassID; 503 case 16: return AMDGPU::VReg_512RegClassID; 504 } 505 } 506 507 switch (RegWidth) { 508 default: return -1; 509 case 1: return AMDGPU::SGPR_32RegClassID; 510 case 2: return AMDGPU::SGPR_64RegClassID; 511 case 4: return AMDGPU::SReg_128RegClassID; 512 case 8: return AMDGPU::SReg_256RegClassID; 513 case 16: return AMDGPU::SReg_512RegClassID; 514 } 515 } 516 517 static unsigned getRegForName(StringRef RegName) { 518 519 return StringSwitch<unsigned>(RegName) 520 .Case("exec", AMDGPU::EXEC) 521 .Case("vcc", AMDGPU::VCC) 522 .Case("flat_scratch", AMDGPU::FLAT_SCR) 523 .Case("m0", AMDGPU::M0) 524 .Case("scc", AMDGPU::SCC) 525 .Case("flat_scratch_lo", AMDGPU::FLAT_SCR_LO) 526 .Case("flat_scratch_hi", AMDGPU::FLAT_SCR_HI) 527 .Case("vcc_lo", AMDGPU::VCC_LO) 528 .Case("vcc_hi", AMDGPU::VCC_HI) 529 .Case("exec_lo", AMDGPU::EXEC_LO) 530 .Case("exec_hi", AMDGPU::EXEC_HI) 531 .Default(0); 532 } 533 534 bool AMDGPUAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { 535 const AsmToken Tok = Parser.getTok(); 536 StartLoc = Tok.getLoc(); 537 EndLoc = Tok.getEndLoc(); 538 const MCRegisterInfo *TRI = getContext().getRegisterInfo(); 539 540 StringRef RegName = Tok.getString(); 541 RegNo = getRegForName(RegName); 542 543 if (RegNo) { 544 Parser.Lex(); 545 return !subtargetHasRegister(*TRI, RegNo); 546 } 547 548 // Match vgprs and sgprs 549 if (RegName[0] != 's' && RegName[0] != 'v') 550 return true; 551 552 bool IsVgpr = RegName[0] == 'v'; 553 unsigned RegWidth; 554 unsigned RegIndexInClass; 555 if (RegName.size() > 1) { 556 // We have a 32-bit register 557 RegWidth = 1; 558 if (RegName.substr(1).getAsInteger(10, RegIndexInClass)) 559 return true; 560 Parser.Lex(); 561 } else { 562 // We have a register greater than 32-bits. 563 564 int64_t RegLo, RegHi; 565 Parser.Lex(); 566 if (getLexer().isNot(AsmToken::LBrac)) 567 return true; 568 569 Parser.Lex(); 570 if (getParser().parseAbsoluteExpression(RegLo)) 571 return true; 572 573 if (getLexer().isNot(AsmToken::Colon)) 574 return true; 575 576 Parser.Lex(); 577 if (getParser().parseAbsoluteExpression(RegHi)) 578 return true; 579 580 if (getLexer().isNot(AsmToken::RBrac)) 581 return true; 582 583 Parser.Lex(); 584 RegWidth = (RegHi - RegLo) + 1; 585 if (IsVgpr) { 586 // VGPR registers aren't aligned. 587 RegIndexInClass = RegLo; 588 } else { 589 // SGPR registers are aligned. Max alignment is 4 dwords. 590 unsigned Size = std::min(RegWidth, 4u); 591 if (RegLo % Size != 0) 592 return true; 593 594 RegIndexInClass = RegLo / Size; 595 } 596 } 597 598 int RCID = getRegClass(IsVgpr, RegWidth); 599 if (RCID == -1) 600 return true; 601 602 const MCRegisterClass RC = TRI->getRegClass(RCID); 603 if (RegIndexInClass >= RC.getNumRegs()) 604 return true; 605 606 RegNo = RC.getRegister(RegIndexInClass); 607 return !subtargetHasRegister(*TRI, RegNo); 608 } 609 610 unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 611 612 uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags; 613 614 if ((getForcedEncodingSize() == 32 && (TSFlags & SIInstrFlags::VOP3)) || 615 (getForcedEncodingSize() == 64 && !(TSFlags & SIInstrFlags::VOP3))) 616 return Match_InvalidOperand; 617 618 if ((TSFlags & SIInstrFlags::VOP3) && 619 (TSFlags & SIInstrFlags::VOPAsmPrefer32Bit) && 620 getForcedEncodingSize() != 64) 621 return Match_PreferE32; 622 623 return Match_Success; 624 } 625 626 627 bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 628 OperandVector &Operands, 629 MCStreamer &Out, 630 uint64_t &ErrorInfo, 631 bool MatchingInlineAsm) { 632 MCInst Inst; 633 634 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) { 635 default: break; 636 case Match_Success: 637 Inst.setLoc(IDLoc); 638 Out.EmitInstruction(Inst, getSTI()); 639 return false; 640 case Match_MissingFeature: 641 return Error(IDLoc, "instruction not supported on this GPU"); 642 643 case Match_MnemonicFail: 644 return Error(IDLoc, "unrecognized instruction mnemonic"); 645 646 case Match_InvalidOperand: { 647 SMLoc ErrorLoc = IDLoc; 648 if (ErrorInfo != ~0ULL) { 649 if (ErrorInfo >= Operands.size()) { 650 if (isForcedVOP3()) { 651 // If 64-bit encoding has been forced we can end up with no 652 // clamp or omod operands if none of the registers have modifiers, 653 // so we need to add these to the operand list. 654 AMDGPUOperand &LastOp = 655 ((AMDGPUOperand &)*Operands[Operands.size() - 1]); 656 if (LastOp.isRegKind() || 657 (LastOp.isImm() && 658 LastOp.getImmTy() != AMDGPUOperand::ImmTyNone)) { 659 SMLoc S = Parser.getTok().getLoc(); 660 Operands.push_back(AMDGPUOperand::CreateImm(0, S, 661 AMDGPUOperand::ImmTyClamp)); 662 Operands.push_back(AMDGPUOperand::CreateImm(0, S, 663 AMDGPUOperand::ImmTyOMod)); 664 bool Res = MatchAndEmitInstruction(IDLoc, Opcode, Operands, 665 Out, ErrorInfo, 666 MatchingInlineAsm); 667 if (!Res) 668 return Res; 669 } 670 671 } 672 return Error(IDLoc, "too few operands for instruction"); 673 } 674 675 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc(); 676 if (ErrorLoc == SMLoc()) 677 ErrorLoc = IDLoc; 678 } 679 return Error(ErrorLoc, "invalid operand for instruction"); 680 } 681 case Match_PreferE32: 682 return Error(IDLoc, "internal error: instruction without _e64 suffix " 683 "should be encoded as e32"); 684 } 685 llvm_unreachable("Implement any new match types added!"); 686 } 687 688 bool AMDGPUAsmParser::ParseDirectiveMajorMinor(uint32_t &Major, 689 uint32_t &Minor) { 690 if (getLexer().isNot(AsmToken::Integer)) 691 return TokError("invalid major version"); 692 693 Major = getLexer().getTok().getIntVal(); 694 Lex(); 695 696 if (getLexer().isNot(AsmToken::Comma)) 697 return TokError("minor version number required, comma expected"); 698 Lex(); 699 700 if (getLexer().isNot(AsmToken::Integer)) 701 return TokError("invalid minor version"); 702 703 Minor = getLexer().getTok().getIntVal(); 704 Lex(); 705 706 return false; 707 } 708 709 bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectVersion() { 710 711 uint32_t Major; 712 uint32_t Minor; 713 714 if (ParseDirectiveMajorMinor(Major, Minor)) 715 return true; 716 717 getTargetStreamer().EmitDirectiveHSACodeObjectVersion(Major, Minor); 718 return false; 719 } 720 721 bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectISA() { 722 723 uint32_t Major; 724 uint32_t Minor; 725 uint32_t Stepping; 726 StringRef VendorName; 727 StringRef ArchName; 728 729 // If this directive has no arguments, then use the ISA version for the 730 // targeted GPU. 731 if (getLexer().is(AsmToken::EndOfStatement)) { 732 AMDGPU::IsaVersion Isa = AMDGPU::getIsaVersion(getSTI().getFeatureBits()); 733 getTargetStreamer().EmitDirectiveHSACodeObjectISA(Isa.Major, Isa.Minor, 734 Isa.Stepping, 735 "AMD", "AMDGPU"); 736 return false; 737 } 738 739 740 if (ParseDirectiveMajorMinor(Major, Minor)) 741 return true; 742 743 if (getLexer().isNot(AsmToken::Comma)) 744 return TokError("stepping version number required, comma expected"); 745 Lex(); 746 747 if (getLexer().isNot(AsmToken::Integer)) 748 return TokError("invalid stepping version"); 749 750 Stepping = getLexer().getTok().getIntVal(); 751 Lex(); 752 753 if (getLexer().isNot(AsmToken::Comma)) 754 return TokError("vendor name required, comma expected"); 755 Lex(); 756 757 if (getLexer().isNot(AsmToken::String)) 758 return TokError("invalid vendor name"); 759 760 VendorName = getLexer().getTok().getStringContents(); 761 Lex(); 762 763 if (getLexer().isNot(AsmToken::Comma)) 764 return TokError("arch name required, comma expected"); 765 Lex(); 766 767 if (getLexer().isNot(AsmToken::String)) 768 return TokError("invalid arch name"); 769 770 ArchName = getLexer().getTok().getStringContents(); 771 Lex(); 772 773 getTargetStreamer().EmitDirectiveHSACodeObjectISA(Major, Minor, Stepping, 774 VendorName, ArchName); 775 return false; 776 } 777 778 bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef ID, 779 amd_kernel_code_t &Header) { 780 781 if (getLexer().isNot(AsmToken::Equal)) 782 return TokError("expected '='"); 783 Lex(); 784 785 if (getLexer().isNot(AsmToken::Integer)) 786 return TokError("amd_kernel_code_t values must be integers"); 787 788 uint64_t Value = getLexer().getTok().getIntVal(); 789 Lex(); 790 791 if (ID == "kernel_code_version_major") 792 Header.amd_kernel_code_version_major = Value; 793 else if (ID == "kernel_code_version_minor") 794 Header.amd_kernel_code_version_minor = Value; 795 else if (ID == "machine_kind") 796 Header.amd_machine_kind = Value; 797 else if (ID == "machine_version_major") 798 Header.amd_machine_version_major = Value; 799 else if (ID == "machine_version_minor") 800 Header.amd_machine_version_minor = Value; 801 else if (ID == "machine_version_stepping") 802 Header.amd_machine_version_stepping = Value; 803 else if (ID == "kernel_code_entry_byte_offset") 804 Header.kernel_code_entry_byte_offset = Value; 805 else if (ID == "kernel_code_prefetch_byte_size") 806 Header.kernel_code_prefetch_byte_size = Value; 807 else if (ID == "max_scratch_backing_memory_byte_size") 808 Header.max_scratch_backing_memory_byte_size = Value; 809 else if (ID == "compute_pgm_rsrc1_vgprs") 810 Header.compute_pgm_resource_registers |= S_00B848_VGPRS(Value); 811 else if (ID == "compute_pgm_rsrc1_sgprs") 812 Header.compute_pgm_resource_registers |= S_00B848_SGPRS(Value); 813 else if (ID == "compute_pgm_rsrc1_priority") 814 Header.compute_pgm_resource_registers |= S_00B848_PRIORITY(Value); 815 else if (ID == "compute_pgm_rsrc1_float_mode") 816 Header.compute_pgm_resource_registers |= S_00B848_FLOAT_MODE(Value); 817 else if (ID == "compute_pgm_rsrc1_priv") 818 Header.compute_pgm_resource_registers |= S_00B848_PRIV(Value); 819 else if (ID == "compute_pgm_rsrc1_dx10_clamp") 820 Header.compute_pgm_resource_registers |= S_00B848_DX10_CLAMP(Value); 821 else if (ID == "compute_pgm_rsrc1_debug_mode") 822 Header.compute_pgm_resource_registers |= S_00B848_DEBUG_MODE(Value); 823 else if (ID == "compute_pgm_rsrc1_ieee_mode") 824 Header.compute_pgm_resource_registers |= S_00B848_IEEE_MODE(Value); 825 else if (ID == "compute_pgm_rsrc2_scratch_en") 826 Header.compute_pgm_resource_registers |= (S_00B84C_SCRATCH_EN(Value) << 32); 827 else if (ID == "compute_pgm_rsrc2_user_sgpr") 828 Header.compute_pgm_resource_registers |= (S_00B84C_USER_SGPR(Value) << 32); 829 else if (ID == "compute_pgm_rsrc2_tgid_x_en") 830 Header.compute_pgm_resource_registers |= (S_00B84C_TGID_X_EN(Value) << 32); 831 else if (ID == "compute_pgm_rsrc2_tgid_y_en") 832 Header.compute_pgm_resource_registers |= (S_00B84C_TGID_Y_EN(Value) << 32); 833 else if (ID == "compute_pgm_rsrc2_tgid_z_en") 834 Header.compute_pgm_resource_registers |= (S_00B84C_TGID_Z_EN(Value) << 32); 835 else if (ID == "compute_pgm_rsrc2_tg_size_en") 836 Header.compute_pgm_resource_registers |= (S_00B84C_TG_SIZE_EN(Value) << 32); 837 else if (ID == "compute_pgm_rsrc2_tidig_comp_cnt") 838 Header.compute_pgm_resource_registers |= 839 (S_00B84C_TIDIG_COMP_CNT(Value) << 32); 840 else if (ID == "compute_pgm_rsrc2_excp_en_msb") 841 Header.compute_pgm_resource_registers |= 842 (S_00B84C_EXCP_EN_MSB(Value) << 32); 843 else if (ID == "compute_pgm_rsrc2_lds_size") 844 Header.compute_pgm_resource_registers |= (S_00B84C_LDS_SIZE(Value) << 32); 845 else if (ID == "compute_pgm_rsrc2_excp_en") 846 Header.compute_pgm_resource_registers |= (S_00B84C_EXCP_EN(Value) << 32); 847 else if (ID == "compute_pgm_resource_registers") 848 Header.compute_pgm_resource_registers = Value; 849 else if (ID == "enable_sgpr_private_segment_buffer") 850 Header.code_properties |= 851 (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER_SHIFT); 852 else if (ID == "enable_sgpr_dispatch_ptr") 853 Header.code_properties |= 854 (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR_SHIFT); 855 else if (ID == "enable_sgpr_queue_ptr") 856 Header.code_properties |= 857 (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR_SHIFT); 858 else if (ID == "enable_sgpr_kernarg_segment_ptr") 859 Header.code_properties |= 860 (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR_SHIFT); 861 else if (ID == "enable_sgpr_dispatch_id") 862 Header.code_properties |= 863 (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID_SHIFT); 864 else if (ID == "enable_sgpr_flat_scratch_init") 865 Header.code_properties |= 866 (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT_SHIFT); 867 else if (ID == "enable_sgpr_private_segment_size") 868 Header.code_properties |= 869 (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE_SHIFT); 870 else if (ID == "enable_sgpr_grid_workgroup_count_x") 871 Header.code_properties |= 872 (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_GRID_WORKGROUP_COUNT_X_SHIFT); 873 else if (ID == "enable_sgpr_grid_workgroup_count_y") 874 Header.code_properties |= 875 (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_GRID_WORKGROUP_COUNT_Y_SHIFT); 876 else if (ID == "enable_sgpr_grid_workgroup_count_z") 877 Header.code_properties |= 878 (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_GRID_WORKGROUP_COUNT_Z_SHIFT); 879 else if (ID == "enable_ordered_append_gds") 880 Header.code_properties |= 881 (Value << AMD_CODE_PROPERTY_ENABLE_ORDERED_APPEND_GDS_SHIFT); 882 else if (ID == "private_element_size") 883 Header.code_properties |= 884 (Value << AMD_CODE_PROPERTY_PRIVATE_ELEMENT_SIZE_SHIFT); 885 else if (ID == "is_ptr64") 886 Header.code_properties |= 887 (Value << AMD_CODE_PROPERTY_IS_PTR64_SHIFT); 888 else if (ID == "is_dynamic_callstack") 889 Header.code_properties |= 890 (Value << AMD_CODE_PROPERTY_IS_DYNAMIC_CALLSTACK_SHIFT); 891 else if (ID == "is_debug_enabled") 892 Header.code_properties |= 893 (Value << AMD_CODE_PROPERTY_IS_DEBUG_SUPPORTED_SHIFT); 894 else if (ID == "is_xnack_enabled") 895 Header.code_properties |= 896 (Value << AMD_CODE_PROPERTY_IS_XNACK_SUPPORTED_SHIFT); 897 else if (ID == "workitem_private_segment_byte_size") 898 Header.workitem_private_segment_byte_size = Value; 899 else if (ID == "workgroup_group_segment_byte_size") 900 Header.workgroup_group_segment_byte_size = Value; 901 else if (ID == "gds_segment_byte_size") 902 Header.gds_segment_byte_size = Value; 903 else if (ID == "kernarg_segment_byte_size") 904 Header.kernarg_segment_byte_size = Value; 905 else if (ID == "workgroup_fbarrier_count") 906 Header.workgroup_fbarrier_count = Value; 907 else if (ID == "wavefront_sgpr_count") 908 Header.wavefront_sgpr_count = Value; 909 else if (ID == "workitem_vgpr_count") 910 Header.workitem_vgpr_count = Value; 911 else if (ID == "reserved_vgpr_first") 912 Header.reserved_vgpr_first = Value; 913 else if (ID == "reserved_vgpr_count") 914 Header.reserved_vgpr_count = Value; 915 else if (ID == "reserved_sgpr_first") 916 Header.reserved_sgpr_first = Value; 917 else if (ID == "reserved_sgpr_count") 918 Header.reserved_sgpr_count = Value; 919 else if (ID == "debug_wavefront_private_segment_offset_sgpr") 920 Header.debug_wavefront_private_segment_offset_sgpr = Value; 921 else if (ID == "debug_private_segment_buffer_sgpr") 922 Header.debug_private_segment_buffer_sgpr = Value; 923 else if (ID == "kernarg_segment_alignment") 924 Header.kernarg_segment_alignment = Value; 925 else if (ID == "group_segment_alignment") 926 Header.group_segment_alignment = Value; 927 else if (ID == "private_segment_alignment") 928 Header.private_segment_alignment = Value; 929 else if (ID == "wavefront_size") 930 Header.wavefront_size = Value; 931 else if (ID == "call_convention") 932 Header.call_convention = Value; 933 else if (ID == "runtime_loader_kernel_symbol") 934 Header.runtime_loader_kernel_symbol = Value; 935 else 936 return TokError("amd_kernel_code_t value not recognized."); 937 938 return false; 939 } 940 941 bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() { 942 943 amd_kernel_code_t Header; 944 AMDGPU::initDefaultAMDKernelCodeT(Header, getSTI().getFeatureBits()); 945 946 while (true) { 947 948 if (getLexer().isNot(AsmToken::EndOfStatement)) 949 return TokError("amd_kernel_code_t values must begin on a new line"); 950 951 // Lex EndOfStatement. This is in a while loop, because lexing a comment 952 // will set the current token to EndOfStatement. 953 while(getLexer().is(AsmToken::EndOfStatement)) 954 Lex(); 955 956 if (getLexer().isNot(AsmToken::Identifier)) 957 return TokError("expected value identifier or .end_amd_kernel_code_t"); 958 959 StringRef ID = getLexer().getTok().getIdentifier(); 960 Lex(); 961 962 if (ID == ".end_amd_kernel_code_t") 963 break; 964 965 if (ParseAMDKernelCodeTValue(ID, Header)) 966 return true; 967 } 968 969 getTargetStreamer().EmitAMDKernelCodeT(Header); 970 971 return false; 972 } 973 974 bool AMDGPUAsmParser::ParseSectionDirectiveHSAText() { 975 getParser().getStreamer().SwitchSection( 976 AMDGPU::getHSATextSection(getContext())); 977 return false; 978 } 979 980 bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() { 981 if (getLexer().isNot(AsmToken::Identifier)) 982 return TokError("expected symbol name"); 983 984 StringRef KernelName = Parser.getTok().getString(); 985 986 getTargetStreamer().EmitAMDGPUSymbolType(KernelName, 987 ELF::STT_AMDGPU_HSA_KERNEL); 988 Lex(); 989 return false; 990 } 991 992 bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaModuleGlobal() { 993 if (getLexer().isNot(AsmToken::Identifier)) 994 return TokError("expected symbol name"); 995 996 StringRef GlobalName = Parser.getTok().getIdentifier(); 997 998 getTargetStreamer().EmitAMDGPUHsaModuleScopeGlobal(GlobalName); 999 Lex(); 1000 return false; 1001 } 1002 1003 bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaProgramGlobal() { 1004 if (getLexer().isNot(AsmToken::Identifier)) 1005 return TokError("expected symbol name"); 1006 1007 StringRef GlobalName = Parser.getTok().getIdentifier(); 1008 1009 getTargetStreamer().EmitAMDGPUHsaProgramScopeGlobal(GlobalName); 1010 Lex(); 1011 return false; 1012 } 1013 1014 bool AMDGPUAsmParser::ParseSectionDirectiveHSADataGlobalAgent() { 1015 getParser().getStreamer().SwitchSection( 1016 AMDGPU::getHSADataGlobalAgentSection(getContext())); 1017 return false; 1018 } 1019 1020 bool AMDGPUAsmParser::ParseSectionDirectiveHSADataGlobalProgram() { 1021 getParser().getStreamer().SwitchSection( 1022 AMDGPU::getHSADataGlobalProgramSection(getContext())); 1023 return false; 1024 } 1025 1026 bool AMDGPUAsmParser::ParseSectionDirectiveHSARodataReadonlyAgent() { 1027 getParser().getStreamer().SwitchSection( 1028 AMDGPU::getHSARodataReadonlyAgentSection(getContext())); 1029 return false; 1030 } 1031 1032 bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) { 1033 StringRef IDVal = DirectiveID.getString(); 1034 1035 if (IDVal == ".hsa_code_object_version") 1036 return ParseDirectiveHSACodeObjectVersion(); 1037 1038 if (IDVal == ".hsa_code_object_isa") 1039 return ParseDirectiveHSACodeObjectISA(); 1040 1041 if (IDVal == ".amd_kernel_code_t") 1042 return ParseDirectiveAMDKernelCodeT(); 1043 1044 if (IDVal == ".hsatext" || IDVal == ".text") 1045 return ParseSectionDirectiveHSAText(); 1046 1047 if (IDVal == ".amdgpu_hsa_kernel") 1048 return ParseDirectiveAMDGPUHsaKernel(); 1049 1050 if (IDVal == ".amdgpu_hsa_module_global") 1051 return ParseDirectiveAMDGPUHsaModuleGlobal(); 1052 1053 if (IDVal == ".amdgpu_hsa_program_global") 1054 return ParseDirectiveAMDGPUHsaProgramGlobal(); 1055 1056 if (IDVal == ".hsadata_global_agent") 1057 return ParseSectionDirectiveHSADataGlobalAgent(); 1058 1059 if (IDVal == ".hsadata_global_program") 1060 return ParseSectionDirectiveHSADataGlobalProgram(); 1061 1062 if (IDVal == ".hsarodata_readonly_agent") 1063 return ParseSectionDirectiveHSARodataReadonlyAgent(); 1064 1065 return true; 1066 } 1067 1068 bool AMDGPUAsmParser::subtargetHasRegister(const MCRegisterInfo &MRI, 1069 unsigned RegNo) const { 1070 if (isCI()) 1071 return true; 1072 1073 if (isSI()) { 1074 // No flat_scr 1075 switch (RegNo) { 1076 case AMDGPU::FLAT_SCR: 1077 case AMDGPU::FLAT_SCR_LO: 1078 case AMDGPU::FLAT_SCR_HI: 1079 return false; 1080 default: 1081 return true; 1082 } 1083 } 1084 1085 // VI only has 102 SGPRs, so make sure we aren't trying to use the 2 more that 1086 // SI/CI have. 1087 for (MCRegAliasIterator R(AMDGPU::SGPR102_SGPR103, &MRI, true); 1088 R.isValid(); ++R) { 1089 if (*R == RegNo) 1090 return false; 1091 } 1092 1093 return true; 1094 } 1095 1096 static bool operandsHaveModifiers(const OperandVector &Operands) { 1097 1098 for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 1099 const AMDGPUOperand &Op = ((AMDGPUOperand&)*Operands[i]); 1100 if (Op.isRegKind() && Op.hasModifiers()) 1101 return true; 1102 if (Op.isImm() && (Op.getImmTy() == AMDGPUOperand::ImmTyOMod || 1103 Op.getImmTy() == AMDGPUOperand::ImmTyClamp)) 1104 return true; 1105 } 1106 return false; 1107 } 1108 1109 AMDGPUAsmParser::OperandMatchResultTy 1110 AMDGPUAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1111 1112 // Try to parse with a custom parser 1113 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1114 1115 // If we successfully parsed the operand or if there as an error parsing, 1116 // we are done. 1117 // 1118 // If we are parsing after we reach EndOfStatement then this means we 1119 // are appending default values to the Operands list. This is only done 1120 // by custom parser, so we shouldn't continue on to the generic parsing. 1121 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail|| 1122 getLexer().is(AsmToken::EndOfStatement)) 1123 return ResTy; 1124 1125 bool Negate = false, Abs = false; 1126 if (getLexer().getKind()== AsmToken::Minus) { 1127 Parser.Lex(); 1128 Negate = true; 1129 } 1130 1131 if (getLexer().getKind() == AsmToken::Pipe) { 1132 Parser.Lex(); 1133 Abs = true; 1134 } 1135 1136 switch(getLexer().getKind()) { 1137 case AsmToken::Integer: { 1138 SMLoc S = Parser.getTok().getLoc(); 1139 int64_t IntVal; 1140 if (getParser().parseAbsoluteExpression(IntVal)) 1141 return MatchOperand_ParseFail; 1142 if (!isInt<32>(IntVal) && !isUInt<32>(IntVal)) { 1143 Error(S, "invalid immediate: only 32-bit values are legal"); 1144 return MatchOperand_ParseFail; 1145 } 1146 1147 if (Negate) 1148 IntVal *= -1; 1149 Operands.push_back(AMDGPUOperand::CreateImm(IntVal, S)); 1150 return MatchOperand_Success; 1151 } 1152 case AsmToken::Real: { 1153 // FIXME: We should emit an error if a double precisions floating-point 1154 // value is used. I'm not sure the best way to detect this. 1155 SMLoc S = Parser.getTok().getLoc(); 1156 int64_t IntVal; 1157 if (getParser().parseAbsoluteExpression(IntVal)) 1158 return MatchOperand_ParseFail; 1159 1160 APFloat F((float)BitsToDouble(IntVal)); 1161 if (Negate) 1162 F.changeSign(); 1163 Operands.push_back( 1164 AMDGPUOperand::CreateImm(F.bitcastToAPInt().getZExtValue(), S)); 1165 return MatchOperand_Success; 1166 } 1167 case AsmToken::Identifier: { 1168 SMLoc S, E; 1169 unsigned RegNo; 1170 if (!ParseRegister(RegNo, S, E)) { 1171 unsigned Modifiers = 0; 1172 1173 if (Negate) 1174 Modifiers |= 0x1; 1175 1176 if (Abs) { 1177 if (getLexer().getKind() != AsmToken::Pipe) 1178 return MatchOperand_ParseFail; 1179 Parser.Lex(); 1180 Modifiers |= 0x2; 1181 } 1182 1183 Operands.push_back(AMDGPUOperand::CreateReg( 1184 RegNo, S, E, getContext().getRegisterInfo(), &getSTI(), 1185 isForcedVOP3())); 1186 1187 if (Modifiers) { 1188 AMDGPUOperand &RegOp = ((AMDGPUOperand&)*Operands[Operands.size() - 1]); 1189 RegOp.setModifiers(Modifiers); 1190 } 1191 } else { 1192 ResTy = parseVOP3OptionalOps(Operands); 1193 if (ResTy == MatchOperand_NoMatch) { 1194 Operands.push_back(AMDGPUOperand::CreateToken(Parser.getTok().getString(), 1195 S)); 1196 Parser.Lex(); 1197 } 1198 } 1199 return MatchOperand_Success; 1200 } 1201 default: 1202 return MatchOperand_NoMatch; 1203 } 1204 } 1205 1206 bool AMDGPUAsmParser::ParseInstruction(ParseInstructionInfo &Info, 1207 StringRef Name, 1208 SMLoc NameLoc, OperandVector &Operands) { 1209 1210 // Clear any forced encodings from the previous instruction. 1211 setForcedEncodingSize(0); 1212 1213 if (Name.endswith("_e64")) 1214 setForcedEncodingSize(64); 1215 else if (Name.endswith("_e32")) 1216 setForcedEncodingSize(32); 1217 1218 // Add the instruction mnemonic 1219 Operands.push_back(AMDGPUOperand::CreateToken(Name, NameLoc)); 1220 1221 while (!getLexer().is(AsmToken::EndOfStatement)) { 1222 AMDGPUAsmParser::OperandMatchResultTy Res = parseOperand(Operands, Name); 1223 1224 // Eat the comma or space if there is one. 1225 if (getLexer().is(AsmToken::Comma)) 1226 Parser.Lex(); 1227 1228 switch (Res) { 1229 case MatchOperand_Success: break; 1230 case MatchOperand_ParseFail: return Error(getLexer().getLoc(), 1231 "failed parsing operand."); 1232 case MatchOperand_NoMatch: return Error(getLexer().getLoc(), 1233 "not a valid operand."); 1234 } 1235 } 1236 1237 // Once we reach end of statement, continue parsing so we can add default 1238 // values for optional arguments. 1239 AMDGPUAsmParser::OperandMatchResultTy Res; 1240 while ((Res = parseOperand(Operands, Name)) != MatchOperand_NoMatch) { 1241 if (Res != MatchOperand_Success) 1242 return Error(getLexer().getLoc(), "failed parsing operand."); 1243 } 1244 return false; 1245 } 1246 1247 //===----------------------------------------------------------------------===// 1248 // Utility functions 1249 //===----------------------------------------------------------------------===// 1250 1251 AMDGPUAsmParser::OperandMatchResultTy 1252 AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix, int64_t &Int, 1253 int64_t Default) { 1254 1255 // We are at the end of the statement, and this is a default argument, so 1256 // use a default value. 1257 if (getLexer().is(AsmToken::EndOfStatement)) { 1258 Int = Default; 1259 return MatchOperand_Success; 1260 } 1261 1262 switch(getLexer().getKind()) { 1263 default: return MatchOperand_NoMatch; 1264 case AsmToken::Identifier: { 1265 StringRef OffsetName = Parser.getTok().getString(); 1266 if (!OffsetName.equals(Prefix)) 1267 return MatchOperand_NoMatch; 1268 1269 Parser.Lex(); 1270 if (getLexer().isNot(AsmToken::Colon)) 1271 return MatchOperand_ParseFail; 1272 1273 Parser.Lex(); 1274 if (getLexer().isNot(AsmToken::Integer)) 1275 return MatchOperand_ParseFail; 1276 1277 if (getParser().parseAbsoluteExpression(Int)) 1278 return MatchOperand_ParseFail; 1279 break; 1280 } 1281 } 1282 return MatchOperand_Success; 1283 } 1284 1285 AMDGPUAsmParser::OperandMatchResultTy 1286 AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix, OperandVector &Operands, 1287 enum AMDGPUOperand::ImmTy ImmTy) { 1288 1289 SMLoc S = Parser.getTok().getLoc(); 1290 int64_t Offset = 0; 1291 1292 AMDGPUAsmParser::OperandMatchResultTy Res = parseIntWithPrefix(Prefix, Offset); 1293 if (Res != MatchOperand_Success) 1294 return Res; 1295 1296 Operands.push_back(AMDGPUOperand::CreateImm(Offset, S, ImmTy)); 1297 return MatchOperand_Success; 1298 } 1299 1300 AMDGPUAsmParser::OperandMatchResultTy 1301 AMDGPUAsmParser::parseNamedBit(const char *Name, OperandVector &Operands, 1302 enum AMDGPUOperand::ImmTy ImmTy) { 1303 int64_t Bit = 0; 1304 SMLoc S = Parser.getTok().getLoc(); 1305 1306 // We are at the end of the statement, and this is a default argument, so 1307 // use a default value. 1308 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1309 switch(getLexer().getKind()) { 1310 case AsmToken::Identifier: { 1311 StringRef Tok = Parser.getTok().getString(); 1312 if (Tok == Name) { 1313 Bit = 1; 1314 Parser.Lex(); 1315 } else if (Tok.startswith("no") && Tok.endswith(Name)) { 1316 Bit = 0; 1317 Parser.Lex(); 1318 } else { 1319 return MatchOperand_NoMatch; 1320 } 1321 break; 1322 } 1323 default: 1324 return MatchOperand_NoMatch; 1325 } 1326 } 1327 1328 Operands.push_back(AMDGPUOperand::CreateImm(Bit, S, ImmTy)); 1329 return MatchOperand_Success; 1330 } 1331 1332 static bool operandsHasOptionalOp(const OperandVector &Operands, 1333 const OptionalOperand &OOp) { 1334 for (unsigned i = 0; i < Operands.size(); i++) { 1335 const AMDGPUOperand &ParsedOp = ((const AMDGPUOperand &)*Operands[i]); 1336 if ((ParsedOp.isImm() && ParsedOp.getImmTy() == OOp.Type) || 1337 (ParsedOp.isToken() && ParsedOp.getToken() == OOp.Name)) 1338 return true; 1339 1340 } 1341 return false; 1342 } 1343 1344 AMDGPUAsmParser::OperandMatchResultTy 1345 AMDGPUAsmParser::parseOptionalOps(const ArrayRef<OptionalOperand> &OptionalOps, 1346 OperandVector &Operands) { 1347 SMLoc S = Parser.getTok().getLoc(); 1348 for (const OptionalOperand &Op : OptionalOps) { 1349 if (operandsHasOptionalOp(Operands, Op)) 1350 continue; 1351 AMDGPUAsmParser::OperandMatchResultTy Res; 1352 int64_t Value; 1353 if (Op.IsBit) { 1354 Res = parseNamedBit(Op.Name, Operands, Op.Type); 1355 if (Res == MatchOperand_NoMatch) 1356 continue; 1357 return Res; 1358 } 1359 1360 Res = parseIntWithPrefix(Op.Name, Value, Op.Default); 1361 1362 if (Res == MatchOperand_NoMatch) 1363 continue; 1364 1365 if (Res != MatchOperand_Success) 1366 return Res; 1367 1368 if (Op.ConvertResult && !Op.ConvertResult(Value)) { 1369 return MatchOperand_ParseFail; 1370 } 1371 1372 Operands.push_back(AMDGPUOperand::CreateImm(Value, S, Op.Type)); 1373 return MatchOperand_Success; 1374 } 1375 return MatchOperand_NoMatch; 1376 } 1377 1378 //===----------------------------------------------------------------------===// 1379 // ds 1380 //===----------------------------------------------------------------------===// 1381 1382 static const OptionalOperand DSOptionalOps [] = { 1383 {"offset", AMDGPUOperand::ImmTyOffset, false, 0, nullptr}, 1384 {"gds", AMDGPUOperand::ImmTyGDS, true, 0, nullptr} 1385 }; 1386 1387 static const OptionalOperand DSOptionalOpsOff01 [] = { 1388 {"offset0", AMDGPUOperand::ImmTyDSOffset0, false, 0, nullptr}, 1389 {"offset1", AMDGPUOperand::ImmTyDSOffset1, false, 0, nullptr}, 1390 {"gds", AMDGPUOperand::ImmTyGDS, true, 0, nullptr} 1391 }; 1392 1393 AMDGPUAsmParser::OperandMatchResultTy 1394 AMDGPUAsmParser::parseDSOptionalOps(OperandVector &Operands) { 1395 return parseOptionalOps(DSOptionalOps, Operands); 1396 } 1397 AMDGPUAsmParser::OperandMatchResultTy 1398 AMDGPUAsmParser::parseDSOff01OptionalOps(OperandVector &Operands) { 1399 return parseOptionalOps(DSOptionalOpsOff01, Operands); 1400 } 1401 1402 AMDGPUAsmParser::OperandMatchResultTy 1403 AMDGPUAsmParser::parseDSOffsetOptional(OperandVector &Operands) { 1404 SMLoc S = Parser.getTok().getLoc(); 1405 AMDGPUAsmParser::OperandMatchResultTy Res = 1406 parseIntWithPrefix("offset", Operands, AMDGPUOperand::ImmTyOffset); 1407 if (Res == MatchOperand_NoMatch) { 1408 Operands.push_back(AMDGPUOperand::CreateImm(0, S, 1409 AMDGPUOperand::ImmTyOffset)); 1410 Res = MatchOperand_Success; 1411 } 1412 return Res; 1413 } 1414 1415 bool AMDGPUOperand::isDSOffset() const { 1416 return isImm() && isUInt<16>(getImm()); 1417 } 1418 1419 bool AMDGPUOperand::isDSOffset01() const { 1420 return isImm() && isUInt<8>(getImm()); 1421 } 1422 1423 void AMDGPUAsmParser::cvtDSOffset01(MCInst &Inst, 1424 const OperandVector &Operands) { 1425 1426 std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx; 1427 1428 for (unsigned i = 1, e = Operands.size(); i != e; ++i) { 1429 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]); 1430 1431 // Add the register arguments 1432 if (Op.isReg()) { 1433 Op.addRegOperands(Inst, 1); 1434 continue; 1435 } 1436 1437 // Handle optional arguments 1438 OptionalIdx[Op.getImmTy()] = i; 1439 } 1440 1441 unsigned Offset0Idx = OptionalIdx[AMDGPUOperand::ImmTyDSOffset0]; 1442 unsigned Offset1Idx = OptionalIdx[AMDGPUOperand::ImmTyDSOffset1]; 1443 unsigned GDSIdx = OptionalIdx[AMDGPUOperand::ImmTyGDS]; 1444 1445 ((AMDGPUOperand &)*Operands[Offset0Idx]).addImmOperands(Inst, 1); // offset0 1446 ((AMDGPUOperand &)*Operands[Offset1Idx]).addImmOperands(Inst, 1); // offset1 1447 ((AMDGPUOperand &)*Operands[GDSIdx]).addImmOperands(Inst, 1); // gds 1448 Inst.addOperand(MCOperand::createReg(AMDGPU::M0)); // m0 1449 } 1450 1451 void AMDGPUAsmParser::cvtDS(MCInst &Inst, const OperandVector &Operands) { 1452 1453 std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx; 1454 bool GDSOnly = false; 1455 1456 for (unsigned i = 1, e = Operands.size(); i != e; ++i) { 1457 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]); 1458 1459 // Add the register arguments 1460 if (Op.isReg()) { 1461 Op.addRegOperands(Inst, 1); 1462 continue; 1463 } 1464 1465 if (Op.isToken() && Op.getToken() == "gds") { 1466 GDSOnly = true; 1467 continue; 1468 } 1469 1470 // Handle optional arguments 1471 OptionalIdx[Op.getImmTy()] = i; 1472 } 1473 1474 unsigned OffsetIdx = OptionalIdx[AMDGPUOperand::ImmTyOffset]; 1475 ((AMDGPUOperand &)*Operands[OffsetIdx]).addImmOperands(Inst, 1); // offset 1476 1477 if (!GDSOnly) { 1478 unsigned GDSIdx = OptionalIdx[AMDGPUOperand::ImmTyGDS]; 1479 ((AMDGPUOperand &)*Operands[GDSIdx]).addImmOperands(Inst, 1); // gds 1480 } 1481 Inst.addOperand(MCOperand::createReg(AMDGPU::M0)); // m0 1482 } 1483 1484 1485 //===----------------------------------------------------------------------===// 1486 // s_waitcnt 1487 //===----------------------------------------------------------------------===// 1488 1489 bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) { 1490 StringRef CntName = Parser.getTok().getString(); 1491 int64_t CntVal; 1492 1493 Parser.Lex(); 1494 if (getLexer().isNot(AsmToken::LParen)) 1495 return true; 1496 1497 Parser.Lex(); 1498 if (getLexer().isNot(AsmToken::Integer)) 1499 return true; 1500 1501 if (getParser().parseAbsoluteExpression(CntVal)) 1502 return true; 1503 1504 if (getLexer().isNot(AsmToken::RParen)) 1505 return true; 1506 1507 Parser.Lex(); 1508 if (getLexer().is(AsmToken::Amp) || getLexer().is(AsmToken::Comma)) 1509 Parser.Lex(); 1510 1511 int CntShift; 1512 int CntMask; 1513 1514 if (CntName == "vmcnt") { 1515 CntMask = 0xf; 1516 CntShift = 0; 1517 } else if (CntName == "expcnt") { 1518 CntMask = 0x7; 1519 CntShift = 4; 1520 } else if (CntName == "lgkmcnt") { 1521 CntMask = 0xf; 1522 CntShift = 8; 1523 } else { 1524 return true; 1525 } 1526 1527 IntVal &= ~(CntMask << CntShift); 1528 IntVal |= (CntVal << CntShift); 1529 return false; 1530 } 1531 1532 AMDGPUAsmParser::OperandMatchResultTy 1533 AMDGPUAsmParser::parseSWaitCntOps(OperandVector &Operands) { 1534 // Disable all counters by default. 1535 // vmcnt [3:0] 1536 // expcnt [6:4] 1537 // lgkmcnt [11:8] 1538 int64_t CntVal = 0xf7f; 1539 SMLoc S = Parser.getTok().getLoc(); 1540 1541 switch(getLexer().getKind()) { 1542 default: return MatchOperand_ParseFail; 1543 case AsmToken::Integer: 1544 // The operand can be an integer value. 1545 if (getParser().parseAbsoluteExpression(CntVal)) 1546 return MatchOperand_ParseFail; 1547 break; 1548 1549 case AsmToken::Identifier: 1550 do { 1551 if (parseCnt(CntVal)) 1552 return MatchOperand_ParseFail; 1553 } while(getLexer().isNot(AsmToken::EndOfStatement)); 1554 break; 1555 } 1556 Operands.push_back(AMDGPUOperand::CreateImm(CntVal, S)); 1557 return MatchOperand_Success; 1558 } 1559 1560 bool AMDGPUOperand::isSWaitCnt() const { 1561 return isImm(); 1562 } 1563 1564 //===----------------------------------------------------------------------===// 1565 // sopp branch targets 1566 //===----------------------------------------------------------------------===// 1567 1568 AMDGPUAsmParser::OperandMatchResultTy 1569 AMDGPUAsmParser::parseSOppBrTarget(OperandVector &Operands) { 1570 SMLoc S = Parser.getTok().getLoc(); 1571 1572 switch (getLexer().getKind()) { 1573 default: return MatchOperand_ParseFail; 1574 case AsmToken::Integer: { 1575 int64_t Imm; 1576 if (getParser().parseAbsoluteExpression(Imm)) 1577 return MatchOperand_ParseFail; 1578 Operands.push_back(AMDGPUOperand::CreateImm(Imm, S)); 1579 return MatchOperand_Success; 1580 } 1581 1582 case AsmToken::Identifier: 1583 Operands.push_back(AMDGPUOperand::CreateExpr( 1584 MCSymbolRefExpr::create(getContext().getOrCreateSymbol( 1585 Parser.getTok().getString()), getContext()), S)); 1586 Parser.Lex(); 1587 return MatchOperand_Success; 1588 } 1589 } 1590 1591 //===----------------------------------------------------------------------===// 1592 // flat 1593 //===----------------------------------------------------------------------===// 1594 1595 static const OptionalOperand FlatOptionalOps [] = { 1596 {"glc", AMDGPUOperand::ImmTyGLC, true, 0, nullptr}, 1597 {"slc", AMDGPUOperand::ImmTySLC, true, 0, nullptr}, 1598 {"tfe", AMDGPUOperand::ImmTyTFE, true, 0, nullptr} 1599 }; 1600 1601 static const OptionalOperand FlatAtomicOptionalOps [] = { 1602 {"slc", AMDGPUOperand::ImmTySLC, true, 0, nullptr}, 1603 {"tfe", AMDGPUOperand::ImmTyTFE, true, 0, nullptr} 1604 }; 1605 1606 AMDGPUAsmParser::OperandMatchResultTy 1607 AMDGPUAsmParser::parseFlatOptionalOps(OperandVector &Operands) { 1608 return parseOptionalOps(FlatOptionalOps, Operands); 1609 } 1610 1611 AMDGPUAsmParser::OperandMatchResultTy 1612 AMDGPUAsmParser::parseFlatAtomicOptionalOps(OperandVector &Operands) { 1613 return parseOptionalOps(FlatAtomicOptionalOps, Operands); 1614 } 1615 1616 void AMDGPUAsmParser::cvtFlat(MCInst &Inst, 1617 const OperandVector &Operands) { 1618 std::map<AMDGPUOperand::ImmTy, unsigned> OptionalIdx; 1619 1620 for (unsigned i = 1, e = Operands.size(); i != e; ++i) { 1621 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]); 1622 1623 // Add the register arguments 1624 if (Op.isReg()) { 1625 Op.addRegOperands(Inst, 1); 1626 continue; 1627 } 1628 1629 // Handle 'glc' token which is sometimes hard-coded into the 1630 // asm string. There are no MCInst operands for these. 1631 if (Op.isToken()) 1632 continue; 1633 1634 // Handle optional arguments 1635 OptionalIdx[Op.getImmTy()] = i; 1636 1637 } 1638 1639 // flat atomic instructions don't have a glc argument. 1640 if (OptionalIdx.count(AMDGPUOperand::ImmTyGLC)) { 1641 unsigned GLCIdx = OptionalIdx[AMDGPUOperand::ImmTyGLC]; 1642 ((AMDGPUOperand &)*Operands[GLCIdx]).addImmOperands(Inst, 1); 1643 } 1644 1645 unsigned SLCIdx = OptionalIdx[AMDGPUOperand::ImmTySLC]; 1646 unsigned TFEIdx = OptionalIdx[AMDGPUOperand::ImmTyTFE]; 1647 1648 ((AMDGPUOperand &)*Operands[SLCIdx]).addImmOperands(Inst, 1); 1649 ((AMDGPUOperand &)*Operands[TFEIdx]).addImmOperands(Inst, 1); 1650 } 1651 1652 //===----------------------------------------------------------------------===// 1653 // mubuf 1654 //===----------------------------------------------------------------------===// 1655 1656 static const OptionalOperand MubufOptionalOps [] = { 1657 {"offset", AMDGPUOperand::ImmTyOffset, false, 0, nullptr}, 1658 {"glc", AMDGPUOperand::ImmTyGLC, true, 0, nullptr}, 1659 {"slc", AMDGPUOperand::ImmTySLC, true, 0, nullptr}, 1660 {"tfe", AMDGPUOperand::ImmTyTFE, true, 0, nullptr} 1661 }; 1662 1663 AMDGPUAsmParser::OperandMatchResultTy 1664 AMDGPUAsmParser::parseMubufOptionalOps(OperandVector &Operands) { 1665 return parseOptionalOps(MubufOptionalOps, Operands); 1666 } 1667 1668 AMDGPUAsmParser::OperandMatchResultTy 1669 AMDGPUAsmParser::parseOffset(OperandVector &Operands) { 1670 return parseIntWithPrefix("offset", Operands); 1671 } 1672 1673 AMDGPUAsmParser::OperandMatchResultTy 1674 AMDGPUAsmParser::parseGLC(OperandVector &Operands) { 1675 return parseNamedBit("glc", Operands); 1676 } 1677 1678 AMDGPUAsmParser::OperandMatchResultTy 1679 AMDGPUAsmParser::parseSLC(OperandVector &Operands) { 1680 return parseNamedBit("slc", Operands); 1681 } 1682 1683 AMDGPUAsmParser::OperandMatchResultTy 1684 AMDGPUAsmParser::parseTFE(OperandVector &Operands) { 1685 return parseNamedBit("tfe", Operands); 1686 } 1687 1688 bool AMDGPUOperand::isMubufOffset() const { 1689 return isImm() && isUInt<12>(getImm()); 1690 } 1691 1692 void AMDGPUAsmParser::cvtMubuf(MCInst &Inst, 1693 const OperandVector &Operands) { 1694 std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx; 1695 1696 for (unsigned i = 1, e = Operands.size(); i != e; ++i) { 1697 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]); 1698 1699 // Add the register arguments 1700 if (Op.isReg()) { 1701 Op.addRegOperands(Inst, 1); 1702 continue; 1703 } 1704 1705 // Handle the case where soffset is an immediate 1706 if (Op.isImm() && Op.getImmTy() == AMDGPUOperand::ImmTyNone) { 1707 Op.addImmOperands(Inst, 1); 1708 continue; 1709 } 1710 1711 // Handle tokens like 'offen' which are sometimes hard-coded into the 1712 // asm string. There are no MCInst operands for these. 1713 if (Op.isToken()) { 1714 continue; 1715 } 1716 assert(Op.isImm()); 1717 1718 // Handle optional arguments 1719 OptionalIdx[Op.getImmTy()] = i; 1720 } 1721 1722 assert(OptionalIdx.size() == 4); 1723 1724 unsigned OffsetIdx = OptionalIdx[AMDGPUOperand::ImmTyOffset]; 1725 unsigned GLCIdx = OptionalIdx[AMDGPUOperand::ImmTyGLC]; 1726 unsigned SLCIdx = OptionalIdx[AMDGPUOperand::ImmTySLC]; 1727 unsigned TFEIdx = OptionalIdx[AMDGPUOperand::ImmTyTFE]; 1728 1729 ((AMDGPUOperand &)*Operands[OffsetIdx]).addImmOperands(Inst, 1); 1730 ((AMDGPUOperand &)*Operands[GLCIdx]).addImmOperands(Inst, 1); 1731 ((AMDGPUOperand &)*Operands[SLCIdx]).addImmOperands(Inst, 1); 1732 ((AMDGPUOperand &)*Operands[TFEIdx]).addImmOperands(Inst, 1); 1733 } 1734 1735 //===----------------------------------------------------------------------===// 1736 // mimg 1737 //===----------------------------------------------------------------------===// 1738 1739 AMDGPUAsmParser::OperandMatchResultTy 1740 AMDGPUAsmParser::parseDMask(OperandVector &Operands) { 1741 return parseIntWithPrefix("dmask", Operands); 1742 } 1743 1744 AMDGPUAsmParser::OperandMatchResultTy 1745 AMDGPUAsmParser::parseUNorm(OperandVector &Operands) { 1746 return parseNamedBit("unorm", Operands); 1747 } 1748 1749 AMDGPUAsmParser::OperandMatchResultTy 1750 AMDGPUAsmParser::parseR128(OperandVector &Operands) { 1751 return parseNamedBit("r128", Operands); 1752 } 1753 1754 //===----------------------------------------------------------------------===// 1755 // smrd 1756 //===----------------------------------------------------------------------===// 1757 1758 bool AMDGPUOperand::isSMRDOffset() const { 1759 1760 // FIXME: Support 20-bit offsets on VI. We need to to pass subtarget 1761 // information here. 1762 return isImm() && isUInt<8>(getImm()); 1763 } 1764 1765 bool AMDGPUOperand::isSMRDLiteralOffset() const { 1766 // 32-bit literals are only supported on CI and we only want to use them 1767 // when the offset is > 8-bits. 1768 return isImm() && !isUInt<8>(getImm()) && isUInt<32>(getImm()); 1769 } 1770 1771 //===----------------------------------------------------------------------===// 1772 // vop3 1773 //===----------------------------------------------------------------------===// 1774 1775 static bool ConvertOmodMul(int64_t &Mul) { 1776 if (Mul != 1 && Mul != 2 && Mul != 4) 1777 return false; 1778 1779 Mul >>= 1; 1780 return true; 1781 } 1782 1783 static bool ConvertOmodDiv(int64_t &Div) { 1784 if (Div == 1) { 1785 Div = 0; 1786 return true; 1787 } 1788 1789 if (Div == 2) { 1790 Div = 3; 1791 return true; 1792 } 1793 1794 return false; 1795 } 1796 1797 static const OptionalOperand VOP3OptionalOps [] = { 1798 {"clamp", AMDGPUOperand::ImmTyClamp, true, 0, nullptr}, 1799 {"mul", AMDGPUOperand::ImmTyOMod, false, 1, ConvertOmodMul}, 1800 {"div", AMDGPUOperand::ImmTyOMod, false, 1, ConvertOmodDiv}, 1801 }; 1802 1803 static bool isVOP3(OperandVector &Operands) { 1804 if (operandsHaveModifiers(Operands)) 1805 return true; 1806 1807 if (Operands.size() >= 2) { 1808 AMDGPUOperand &DstOp = ((AMDGPUOperand&)*Operands[1]); 1809 1810 if (DstOp.isReg() && DstOp.isRegClass(AMDGPU::SGPR_64RegClassID)) 1811 return true; 1812 } 1813 1814 if (Operands.size() >= 5) 1815 return true; 1816 1817 if (Operands.size() > 3) { 1818 AMDGPUOperand &Src1Op = ((AMDGPUOperand&)*Operands[3]); 1819 if (Src1Op.isReg() && (Src1Op.isRegClass(AMDGPU::SReg_32RegClassID) || 1820 Src1Op.isRegClass(AMDGPU::SReg_64RegClassID))) 1821 return true; 1822 } 1823 return false; 1824 } 1825 1826 AMDGPUAsmParser::OperandMatchResultTy 1827 AMDGPUAsmParser::parseVOP3OptionalOps(OperandVector &Operands) { 1828 1829 // The value returned by this function may change after parsing 1830 // an operand so store the original value here. 1831 bool HasModifiers = operandsHaveModifiers(Operands); 1832 1833 bool IsVOP3 = isVOP3(Operands); 1834 if (HasModifiers || IsVOP3 || 1835 getLexer().isNot(AsmToken::EndOfStatement) || 1836 getForcedEncodingSize() == 64) { 1837 1838 AMDGPUAsmParser::OperandMatchResultTy Res = 1839 parseOptionalOps(VOP3OptionalOps, Operands); 1840 1841 if (!HasModifiers && Res == MatchOperand_Success) { 1842 // We have added a modifier operation, so we need to make sure all 1843 // previous register operands have modifiers 1844 for (unsigned i = 2, e = Operands.size(); i != e; ++i) { 1845 AMDGPUOperand &Op = ((AMDGPUOperand&)*Operands[i]); 1846 if (Op.isReg()) 1847 Op.setModifiers(0); 1848 } 1849 } 1850 return Res; 1851 } 1852 return MatchOperand_NoMatch; 1853 } 1854 1855 void AMDGPUAsmParser::cvtId(MCInst &Inst, const OperandVector &Operands) { 1856 unsigned I = 1; 1857 const MCInstrDesc &Desc = MII.get(Inst.getOpcode()); 1858 for (unsigned J = 0; J < Desc.getNumDefs(); ++J) { 1859 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1); 1860 } 1861 for (unsigned E = Operands.size(); I != E; ++I) 1862 ((AMDGPUOperand &)*Operands[I]).addRegOrImmOperands(Inst, 1); 1863 } 1864 1865 void AMDGPUAsmParser::cvtVOP3_2_mod(MCInst &Inst, const OperandVector &Operands) { 1866 if (operandsHaveModifiers(Operands) || isForcedVOP3()) { 1867 cvtVOP3(Inst, Operands); 1868 } else { 1869 cvtId(Inst, Operands); 1870 } 1871 } 1872 1873 void AMDGPUAsmParser::cvtVOP3_2_nomod(MCInst &Inst, const OperandVector &Operands) { 1874 if (operandsHaveModifiers(Operands)) { 1875 cvtVOP3(Inst, Operands); 1876 } else { 1877 cvtId(Inst, Operands); 1878 } 1879 } 1880 1881 void AMDGPUAsmParser::cvtVOP3_only(MCInst &Inst, const OperandVector &Operands) { 1882 cvtVOP3(Inst, Operands); 1883 } 1884 1885 void AMDGPUAsmParser::cvtVOP3(MCInst &Inst, const OperandVector &Operands) { 1886 unsigned I = 1; 1887 const MCInstrDesc &Desc = MII.get(Inst.getOpcode()); 1888 for (unsigned J = 0; J < Desc.getNumDefs(); ++J) { 1889 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1); 1890 } 1891 1892 unsigned ClampIdx = 0, OModIdx = 0; 1893 for (unsigned E = Operands.size(); I != E; ++I) { 1894 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]); 1895 if (Op.isRegWithInputMods()) { 1896 Op.addRegWithInputModsOperands(Inst, 2); 1897 } else if (Op.isClamp()) { 1898 ClampIdx = I; 1899 } else if (Op.isOMod()) { 1900 OModIdx = I; 1901 } else if (Op.isImm()) { 1902 Op.addImmOperands(Inst, 1); 1903 } else { 1904 assert(false); 1905 } 1906 } 1907 1908 if (ClampIdx) { 1909 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[ClampIdx]); 1910 Op.addImmOperands(Inst, 1); 1911 } else { 1912 Inst.addOperand(MCOperand::createImm(0)); 1913 } 1914 if (OModIdx) { 1915 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[OModIdx]); 1916 Op.addImmOperands(Inst, 1); 1917 } else { 1918 Inst.addOperand(MCOperand::createImm(0)); 1919 } 1920 } 1921 1922 /// Force static initialization. 1923 extern "C" void LLVMInitializeAMDGPUAsmParser() { 1924 RegisterMCAsmParser<AMDGPUAsmParser> A(TheAMDGPUTarget); 1925 RegisterMCAsmParser<AMDGPUAsmParser> B(TheGCNTarget); 1926 } 1927 1928 #define GET_REGISTER_MATCHER 1929 #define GET_MATCHER_IMPLEMENTATION 1930 #include "AMDGPUGenAsmMatcher.inc" 1931 1932