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