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