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