LLVM  3.7.0
AMDGPUAsmParser.cpp
Go to the documentation of this file.
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 
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"
28 #include "llvm/MC/MCRegisterInfo.h"
29 #include "llvm/MC/MCStreamer.h"
32 #include "llvm/Support/SourceMgr.h"
35 #include "llvm/Support/Debug.h"
36 
37 using namespace llvm;
38 
39 namespace {
40 
41 struct OptionalOperand;
42 
43 class AMDGPUOperand : public MCParsedAsmOperand {
44  enum KindTy {
45  Token,
46  Immediate,
47  Register,
48  Expression
49  } Kind;
50 
51  SMLoc StartLoc, EndLoc;
52 
53 public:
54  AMDGPUOperand(enum KindTy K) : MCParsedAsmOperand(), Kind(K) {}
55 
56  MCContext *Ctx;
57 
58  enum ImmTy {
59  ImmTyNone,
60  ImmTyDSOffset0,
61  ImmTyDSOffset1,
62  ImmTyGDS,
63  ImmTyOffset,
64  ImmTyGLC,
65  ImmTySLC,
66  ImmTyTFE,
67  ImmTyClamp,
68  ImmTyOMod
69  };
70 
71  struct TokOp {
72  const char *Data;
73  unsigned Length;
74  };
75 
76  struct ImmOp {
77  bool IsFPImm;
78  ImmTy Type;
79  int64_t Val;
80  };
81 
82  struct RegOp {
83  unsigned RegNo;
84  int Modifiers;
85  const MCRegisterInfo *TRI;
86  bool IsForcedVOP3;
87  };
88 
89  union {
90  TokOp Tok;
91  ImmOp Imm;
92  RegOp Reg;
93  const MCExpr *Expr;
94  };
95 
96  void addImmOperands(MCInst &Inst, unsigned N) const {
97  Inst.addOperand(MCOperand::createImm(getImm()));
98  }
99 
100  StringRef getToken() const {
101  return StringRef(Tok.Data, Tok.Length);
102  }
103 
104  void addRegOperands(MCInst &Inst, unsigned N) const {
106  }
107 
108  void addRegOrImmOperands(MCInst &Inst, unsigned N) const {
109  if (isReg())
110  addRegOperands(Inst, N);
111  else
112  addImmOperands(Inst, N);
113  }
114 
115  void addRegWithInputModsOperands(MCInst &Inst, unsigned N) const {
117  Reg.Modifiers == -1 ? 0 : Reg.Modifiers));
118  addRegOperands(Inst, N);
119  }
120 
121  void addSoppBrTargetOperands(MCInst &Inst, unsigned N) const {
122  if (isImm())
123  addImmOperands(Inst, N);
124  else {
125  assert(isExpr());
126  Inst.addOperand(MCOperand::createExpr(Expr));
127  }
128  }
129 
130  bool defaultTokenHasSuffix() const {
131  StringRef Token(Tok.Data, Tok.Length);
132 
133  return Token.endswith("_e32") || Token.endswith("_e64");
134  }
135 
136  bool isToken() const override {
137  return Kind == Token;
138  }
139 
140  bool isImm() const override {
141  return Kind == Immediate;
142  }
143 
144  bool isInlineImm() const {
145  float F = BitsToFloat(Imm.Val);
146  // TODO: Add 0.5pi for VI
147  return isImm() && ((Imm.Val <= 64 && Imm.Val >= -16) ||
148  (F == 0.0 || F == 0.5 || F == -0.5 || F == 1.0 || F == -1.0 ||
149  F == 2.0 || F == -2.0 || F == 4.0 || F == -4.0));
150  }
151 
152  bool isDSOffset0() const {
153  assert(isImm());
154  return Imm.Type == ImmTyDSOffset0;
155  }
156 
157  bool isDSOffset1() const {
158  assert(isImm());
159  return Imm.Type == ImmTyDSOffset1;
160  }
161 
162  int64_t getImm() const {
163  return Imm.Val;
164  }
165 
166  enum ImmTy getImmTy() const {
167  assert(isImm());
168  return Imm.Type;
169  }
170 
171  bool isRegKind() const {
172  return Kind == Register;
173  }
174 
175  bool isReg() const override {
176  return Kind == Register && Reg.Modifiers == -1;
177  }
178 
179  bool isRegWithInputMods() const {
180  return Kind == Register && (Reg.IsForcedVOP3 || Reg.Modifiers != -1);
181  }
182 
183  void setModifiers(unsigned Mods) {
184  assert(isReg());
185  Reg.Modifiers = Mods;
186  }
187 
188  bool hasModifiers() const {
189  assert(isRegKind());
190  return Reg.Modifiers != -1;
191  }
192 
193  unsigned getReg() const override {
194  return Reg.RegNo;
195  }
196 
197  bool isRegOrImm() const {
198  return isReg() || isImm();
199  }
200 
201  bool isRegClass(unsigned RCID) const {
202  return Reg.TRI->getRegClass(RCID).contains(getReg());
203  }
204 
205  bool isSCSrc32() const {
206  return isInlineImm() || (isReg() && isRegClass(AMDGPU::SReg_32RegClassID));
207  }
208 
209  bool isSSrc32() const {
210  return isImm() || (isReg() && isRegClass(AMDGPU::SReg_32RegClassID));
211  }
212 
213  bool isSSrc64() const {
214  return isImm() || isInlineImm() ||
215  (isReg() && isRegClass(AMDGPU::SReg_64RegClassID));
216  }
217 
218  bool isVCSrc32() const {
219  return isInlineImm() || (isReg() && isRegClass(AMDGPU::VS_32RegClassID));
220  }
221 
222  bool isVCSrc64() const {
223  return isInlineImm() || (isReg() && isRegClass(AMDGPU::VS_64RegClassID));
224  }
225 
226  bool isVSrc32() const {
227  return isImm() || (isReg() && isRegClass(AMDGPU::VS_32RegClassID));
228  }
229 
230  bool isVSrc64() const {
231  return isImm() || (isReg() && isRegClass(AMDGPU::VS_64RegClassID));
232  }
233 
234  bool isMem() const override {
235  return false;
236  }
237 
238  bool isExpr() const {
239  return Kind == Expression;
240  }
241 
242  bool isSoppBrTarget() const {
243  return isExpr() || isImm();
244  }
245 
246  SMLoc getStartLoc() const override {
247  return StartLoc;
248  }
249 
250  SMLoc getEndLoc() const override {
251  return EndLoc;
252  }
253 
254  void print(raw_ostream &OS) const override { }
255 
256  static std::unique_ptr<AMDGPUOperand> CreateImm(int64_t Val, SMLoc Loc,
257  enum ImmTy Type = ImmTyNone,
258  bool IsFPImm = false) {
259  auto Op = llvm::make_unique<AMDGPUOperand>(Immediate);
260  Op->Imm.Val = Val;
261  Op->Imm.IsFPImm = IsFPImm;
262  Op->Imm.Type = Type;
263  Op->StartLoc = Loc;
264  Op->EndLoc = Loc;
265  return Op;
266  }
267 
268  static std::unique_ptr<AMDGPUOperand> CreateToken(StringRef Str, SMLoc Loc,
269  bool HasExplicitEncodingSize = true) {
270  auto Res = llvm::make_unique<AMDGPUOperand>(Token);
271  Res->Tok.Data = Str.data();
272  Res->Tok.Length = Str.size();
273  Res->StartLoc = Loc;
274  Res->EndLoc = Loc;
275  return Res;
276  }
277 
278  static std::unique_ptr<AMDGPUOperand> CreateReg(unsigned RegNo, SMLoc S,
279  SMLoc E,
280  const MCRegisterInfo *TRI,
281  bool ForceVOP3) {
282  auto Op = llvm::make_unique<AMDGPUOperand>(Register);
283  Op->Reg.RegNo = RegNo;
284  Op->Reg.TRI = TRI;
285  Op->Reg.Modifiers = -1;
286  Op->Reg.IsForcedVOP3 = ForceVOP3;
287  Op->StartLoc = S;
288  Op->EndLoc = E;
289  return Op;
290  }
291 
292  static std::unique_ptr<AMDGPUOperand> CreateExpr(const class MCExpr *Expr, SMLoc S) {
293  auto Op = llvm::make_unique<AMDGPUOperand>(Expression);
294  Op->Expr = Expr;
295  Op->StartLoc = S;
296  Op->EndLoc = S;
297  return Op;
298  }
299 
300  bool isDSOffset() const;
301  bool isDSOffset01() const;
302  bool isSWaitCnt() const;
303  bool isMubufOffset() const;
304 };
305 
306 class AMDGPUAsmParser : public MCTargetAsmParser {
307  MCSubtargetInfo &STI;
308  const MCInstrInfo &MII;
309  MCAsmParser &Parser;
310 
311  unsigned ForcedEncodingSize;
312  /// @name Auto-generated Match Functions
313  /// {
314 
315 #define GET_ASSEMBLER_HEADER
316 #include "AMDGPUGenAsmMatcher.inc"
317 
318  /// }
319 
320 private:
321  bool ParseDirectiveMajorMinor(uint32_t &Major, uint32_t &Minor);
322  bool ParseDirectiveHSACodeObjectVersion();
323  bool ParseDirectiveHSACodeObjectISA();
324  bool ParseAMDKernelCodeTValue(StringRef ID, amd_kernel_code_t &Header);
325  bool ParseDirectiveAMDKernelCodeT();
326 
327 public:
328  AMDGPUAsmParser(MCSubtargetInfo &STI, MCAsmParser &_Parser,
329  const MCInstrInfo &MII,
330  const MCTargetOptions &Options)
331  : MCTargetAsmParser(), STI(STI), MII(MII), Parser(_Parser),
332  ForcedEncodingSize(0){
333 
334  if (STI.getFeatureBits().none()) {
335  // Set default features.
336  STI.ToggleFeature("SOUTHERN_ISLANDS");
337  }
338 
339  setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
340  }
341 
342  AMDGPUTargetStreamer &getTargetStreamer() {
343  MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
344  return static_cast<AMDGPUTargetStreamer &>(TS);
345  }
346 
347  unsigned getForcedEncodingSize() const {
348  return ForcedEncodingSize;
349  }
350 
351  void setForcedEncodingSize(unsigned Size) {
352  ForcedEncodingSize = Size;
353  }
354 
355  bool isForcedVOP3() const {
356  return ForcedEncodingSize == 64;
357  }
358 
359  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
360  unsigned checkTargetMatchPredicate(MCInst &Inst) override;
361  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
363  uint64_t &ErrorInfo,
364  bool MatchingInlineAsm) override;
365  bool ParseDirective(AsmToken DirectiveID) override;
366  OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Mnemonic);
367  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
368  SMLoc NameLoc, OperandVector &Operands) override;
369 
370  OperandMatchResultTy parseIntWithPrefix(const char *Prefix, int64_t &Int,
371  int64_t Default = 0);
372  OperandMatchResultTy parseIntWithPrefix(const char *Prefix,
374  enum AMDGPUOperand::ImmTy ImmTy =
375  AMDGPUOperand::ImmTyNone);
376  OperandMatchResultTy parseNamedBit(const char *Name, OperandVector &Operands,
377  enum AMDGPUOperand::ImmTy ImmTy =
378  AMDGPUOperand::ImmTyNone);
379  OperandMatchResultTy parseOptionalOps(
380  const ArrayRef<OptionalOperand> &OptionalOps,
382 
383 
384  void cvtDSOffset01(MCInst &Inst, const OperandVector &Operands);
385  void cvtDS(MCInst &Inst, const OperandVector &Operands);
386  OperandMatchResultTy parseDSOptionalOps(OperandVector &Operands);
387  OperandMatchResultTy parseDSOff01OptionalOps(OperandVector &Operands);
388  OperandMatchResultTy parseDSOffsetOptional(OperandVector &Operands);
389 
390  bool parseCnt(int64_t &IntVal);
391  OperandMatchResultTy parseSWaitCntOps(OperandVector &Operands);
392  OperandMatchResultTy parseSOppBrTarget(OperandVector &Operands);
393 
394  OperandMatchResultTy parseFlatOptionalOps(OperandVector &Operands);
395  OperandMatchResultTy parseFlatAtomicOptionalOps(OperandVector &Operands);
396  void cvtFlat(MCInst &Inst, const OperandVector &Operands);
397 
398  void cvtMubuf(MCInst &Inst, const OperandVector &Operands);
399  OperandMatchResultTy parseOffset(OperandVector &Operands);
400  OperandMatchResultTy parseMubufOptionalOps(OperandVector &Operands);
401  OperandMatchResultTy parseGLC(OperandVector &Operands);
402  OperandMatchResultTy parseSLC(OperandVector &Operands);
403  OperandMatchResultTy parseTFE(OperandVector &Operands);
404 
405  OperandMatchResultTy parseDMask(OperandVector &Operands);
406  OperandMatchResultTy parseUNorm(OperandVector &Operands);
407  OperandMatchResultTy parseR128(OperandVector &Operands);
408 
409  void cvtVOP3(MCInst &Inst, const OperandVector &Operands);
410  OperandMatchResultTy parseVOP3OptionalOps(OperandVector &Operands);
411 };
412 
413 struct OptionalOperand {
414  const char *Name;
415  AMDGPUOperand::ImmTy Type;
416  bool IsBit;
417  int64_t Default;
418  bool (*ConvertResult)(int64_t&);
419 };
420 
421 }
422 
423 static unsigned getRegClass(bool IsVgpr, unsigned RegWidth) {
424  if (IsVgpr) {
425  switch (RegWidth) {
426  default: llvm_unreachable("Unknown register width");
427  case 1: return AMDGPU::VGPR_32RegClassID;
428  case 2: return AMDGPU::VReg_64RegClassID;
429  case 3: return AMDGPU::VReg_96RegClassID;
430  case 4: return AMDGPU::VReg_128RegClassID;
431  case 8: return AMDGPU::VReg_256RegClassID;
432  case 16: return AMDGPU::VReg_512RegClassID;
433  }
434  }
435 
436  switch (RegWidth) {
437  default: llvm_unreachable("Unknown register width");
438  case 1: return AMDGPU::SGPR_32RegClassID;
439  case 2: return AMDGPU::SGPR_64RegClassID;
440  case 4: return AMDGPU::SReg_128RegClassID;
441  case 8: return AMDGPU::SReg_256RegClassID;
442  case 16: return AMDGPU::SReg_512RegClassID;
443  }
444 }
445 
446 static unsigned getRegForName(const StringRef &RegName) {
447 
448  return StringSwitch<unsigned>(RegName)
449  .Case("exec", AMDGPU::EXEC)
450  .Case("vcc", AMDGPU::VCC)
451  .Case("flat_scr", AMDGPU::FLAT_SCR)
452  .Case("m0", AMDGPU::M0)
453  .Case("scc", AMDGPU::SCC)
454  .Case("flat_scr_lo", AMDGPU::FLAT_SCR_LO)
455  .Case("flat_scr_hi", AMDGPU::FLAT_SCR_HI)
456  .Case("vcc_lo", AMDGPU::VCC_LO)
457  .Case("vcc_hi", AMDGPU::VCC_HI)
458  .Case("exec_lo", AMDGPU::EXEC_LO)
459  .Case("exec_hi", AMDGPU::EXEC_HI)
460  .Default(0);
461 }
462 
463 bool AMDGPUAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
464  const AsmToken Tok = Parser.getTok();
465  StartLoc = Tok.getLoc();
466  EndLoc = Tok.getEndLoc();
467  const StringRef &RegName = Tok.getString();
468  RegNo = getRegForName(RegName);
469 
470  if (RegNo) {
471  Parser.Lex();
472  return false;
473  }
474 
475  // Match vgprs and sgprs
476  if (RegName[0] != 's' && RegName[0] != 'v')
477  return true;
478 
479  bool IsVgpr = RegName[0] == 'v';
480  unsigned RegWidth;
481  unsigned RegIndexInClass;
482  if (RegName.size() > 1) {
483  // We have a 32-bit register
484  RegWidth = 1;
485  if (RegName.substr(1).getAsInteger(10, RegIndexInClass))
486  return true;
487  Parser.Lex();
488  } else {
489  // We have a register greater than 32-bits.
490 
491  int64_t RegLo, RegHi;
492  Parser.Lex();
493  if (getLexer().isNot(AsmToken::LBrac))
494  return true;
495 
496  Parser.Lex();
497  if (getParser().parseAbsoluteExpression(RegLo))
498  return true;
499 
500  if (getLexer().isNot(AsmToken::Colon))
501  return true;
502 
503  Parser.Lex();
504  if (getParser().parseAbsoluteExpression(RegHi))
505  return true;
506 
507  if (getLexer().isNot(AsmToken::RBrac))
508  return true;
509 
510  Parser.Lex();
511  RegWidth = (RegHi - RegLo) + 1;
512  if (IsVgpr) {
513  // VGPR registers aren't aligned.
514  RegIndexInClass = RegLo;
515  } else {
516  // SGPR registers are aligned. Max alignment is 4 dwords.
517  RegIndexInClass = RegLo / std::min(RegWidth, 4u);
518  }
519  }
520 
521  const MCRegisterInfo *TRC = getContext().getRegisterInfo();
522  unsigned RC = getRegClass(IsVgpr, RegWidth);
523  if (RegIndexInClass > TRC->getRegClass(RC).getNumRegs())
524  return true;
525  RegNo = TRC->getRegClass(RC).getRegister(RegIndexInClass);
526  return false;
527 }
528 
529 unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
530 
531  uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
532 
533  if ((getForcedEncodingSize() == 32 && (TSFlags & SIInstrFlags::VOP3)) ||
534  (getForcedEncodingSize() == 64 && !(TSFlags & SIInstrFlags::VOP3)))
535  return Match_InvalidOperand;
536 
537  return Match_Success;
538 }
539 
540 
541 bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
543  MCStreamer &Out,
544  uint64_t &ErrorInfo,
545  bool MatchingInlineAsm) {
546  MCInst Inst;
547 
548  switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
549  default: break;
550  case Match_Success:
551  Inst.setLoc(IDLoc);
552  Out.EmitInstruction(Inst, STI);
553  return false;
554  case Match_MissingFeature:
555  return Error(IDLoc, "instruction not supported on this GPU");
556 
557  case Match_MnemonicFail:
558  return Error(IDLoc, "unrecognized instruction mnemonic");
559 
560  case Match_InvalidOperand: {
561  SMLoc ErrorLoc = IDLoc;
562  if (ErrorInfo != ~0ULL) {
563  if (ErrorInfo >= Operands.size()) {
564  if (isForcedVOP3()) {
565  // If 64-bit encoding has been forced we can end up with no
566  // clamp or omod operands if none of the registers have modifiers,
567  // so we need to add these to the operand list.
568  AMDGPUOperand &LastOp =
569  ((AMDGPUOperand &)*Operands[Operands.size() - 1]);
570  if (LastOp.isRegKind() ||
571  (LastOp.isImm() &&
572  LastOp.getImmTy() != AMDGPUOperand::ImmTyNone)) {
573  SMLoc S = Parser.getTok().getLoc();
574  Operands.push_back(AMDGPUOperand::CreateImm(0, S,
575  AMDGPUOperand::ImmTyClamp));
576  Operands.push_back(AMDGPUOperand::CreateImm(0, S,
577  AMDGPUOperand::ImmTyOMod));
578  bool Res = MatchAndEmitInstruction(IDLoc, Opcode, Operands,
579  Out, ErrorInfo,
580  MatchingInlineAsm);
581  if (!Res)
582  return Res;
583  }
584 
585  }
586  return Error(IDLoc, "too few operands for instruction");
587  }
588 
589  ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
590  if (ErrorLoc == SMLoc())
591  ErrorLoc = IDLoc;
592  }
593  return Error(ErrorLoc, "invalid operand for instruction");
594  }
595  }
596  llvm_unreachable("Implement any new match types added!");
597 }
598 
599 bool AMDGPUAsmParser::ParseDirectiveMajorMinor(uint32_t &Major,
600  uint32_t &Minor) {
601  if (getLexer().isNot(AsmToken::Integer))
602  return TokError("invalid major version");
603 
604  Major = getLexer().getTok().getIntVal();
605  Lex();
606 
607  if (getLexer().isNot(AsmToken::Comma))
608  return TokError("minor version number required, comma expected");
609  Lex();
610 
611  if (getLexer().isNot(AsmToken::Integer))
612  return TokError("invalid minor version");
613 
614  Minor = getLexer().getTok().getIntVal();
615  Lex();
616 
617  return false;
618 }
619 
620 bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectVersion() {
621 
622  uint32_t Major;
623  uint32_t Minor;
624 
625  if (ParseDirectiveMajorMinor(Major, Minor))
626  return true;
627 
628  getTargetStreamer().EmitDirectiveHSACodeObjectVersion(Major, Minor);
629  return false;
630 }
631 
632 bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectISA() {
633 
634  uint32_t Major;
635  uint32_t Minor;
636  uint32_t Stepping;
637  StringRef VendorName;
638  StringRef ArchName;
639 
640  // If this directive has no arguments, then use the ISA version for the
641  // targeted GPU.
642  if (getLexer().is(AsmToken::EndOfStatement)) {
644  getTargetStreamer().EmitDirectiveHSACodeObjectISA(Isa.Major, Isa.Minor,
645  Isa.Stepping,
646  "AMD", "AMDGPU");
647  return false;
648  }
649 
650 
651  if (ParseDirectiveMajorMinor(Major, Minor))
652  return true;
653 
654  if (getLexer().isNot(AsmToken::Comma))
655  return TokError("stepping version number required, comma expected");
656  Lex();
657 
658  if (getLexer().isNot(AsmToken::Integer))
659  return TokError("invalid stepping version");
660 
661  Stepping = getLexer().getTok().getIntVal();
662  Lex();
663 
664  if (getLexer().isNot(AsmToken::Comma))
665  return TokError("vendor name required, comma expected");
666  Lex();
667 
668  if (getLexer().isNot(AsmToken::String))
669  return TokError("invalid vendor name");
670 
671  VendorName = getLexer().getTok().getStringContents();
672  Lex();
673 
674  if (getLexer().isNot(AsmToken::Comma))
675  return TokError("arch name required, comma expected");
676  Lex();
677 
678  if (getLexer().isNot(AsmToken::String))
679  return TokError("invalid arch name");
680 
681  ArchName = getLexer().getTok().getStringContents();
682  Lex();
683 
684  getTargetStreamer().EmitDirectiveHSACodeObjectISA(Major, Minor, Stepping,
685  VendorName, ArchName);
686  return false;
687 }
688 
689 bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef ID,
690  amd_kernel_code_t &Header) {
691 
692  if (getLexer().isNot(AsmToken::Equal))
693  return TokError("expected '='");
694  Lex();
695 
696  if (getLexer().isNot(AsmToken::Integer))
697  return TokError("amd_kernel_code_t values must be integers");
698 
699  uint64_t Value = getLexer().getTok().getIntVal();
700  Lex();
701 
702  if (ID == "kernel_code_version_major")
703  Header.amd_kernel_code_version_major = Value;
704  else if (ID == "kernel_code_version_minor")
705  Header.amd_kernel_code_version_minor = Value;
706  else if (ID == "machine_kind")
707  Header.amd_machine_kind = Value;
708  else if (ID == "machine_version_major")
709  Header.amd_machine_version_major = Value;
710  else if (ID == "machine_version_minor")
711  Header.amd_machine_version_minor = Value;
712  else if (ID == "machine_version_stepping")
713  Header.amd_machine_version_stepping = Value;
714  else if (ID == "kernel_code_entry_byte_offset")
715  Header.kernel_code_entry_byte_offset = Value;
716  else if (ID == "kernel_code_prefetch_byte_size")
717  Header.kernel_code_prefetch_byte_size = Value;
718  else if (ID == "max_scratch_backing_memory_byte_size")
720  else if (ID == "compute_pgm_rsrc1_vgprs")
722  else if (ID == "compute_pgm_rsrc1_sgprs")
724  else if (ID == "compute_pgm_rsrc1_priority")
726  else if (ID == "compute_pgm_rsrc1_float_mode")
728  else if (ID == "compute_pgm_rsrc1_priv")
730  else if (ID == "compute_pgm_rsrc1_dx10_clamp")
732  else if (ID == "compute_pgm_rsrc1_debug_mode")
734  else if (ID == "compute_pgm_rsrc1_ieee_mode")
736  else if (ID == "compute_pgm_rsrc2_scratch_en")
737  Header.compute_pgm_resource_registers |= (S_00B84C_SCRATCH_EN(Value) << 32);
738  else if (ID == "compute_pgm_rsrc2_user_sgpr")
739  Header.compute_pgm_resource_registers |= (S_00B84C_USER_SGPR(Value) << 32);
740  else if (ID == "compute_pgm_rsrc2_tgid_x_en")
741  Header.compute_pgm_resource_registers |= (S_00B84C_TGID_X_EN(Value) << 32);
742  else if (ID == "compute_pgm_rsrc2_tgid_y_en")
743  Header.compute_pgm_resource_registers |= (S_00B84C_TGID_Y_EN(Value) << 32);
744  else if (ID == "compute_pgm_rsrc2_tgid_z_en")
745  Header.compute_pgm_resource_registers |= (S_00B84C_TGID_Z_EN(Value) << 32);
746  else if (ID == "compute_pgm_rsrc2_tg_size_en")
747  Header.compute_pgm_resource_registers |= (S_00B84C_TG_SIZE_EN(Value) << 32);
748  else if (ID == "compute_pgm_rsrc2_tidig_comp_cnt")
750  (S_00B84C_TIDIG_COMP_CNT(Value) << 32);
751  else if (ID == "compute_pgm_rsrc2_excp_en_msb")
753  (S_00B84C_EXCP_EN_MSB(Value) << 32);
754  else if (ID == "compute_pgm_rsrc2_lds_size")
755  Header.compute_pgm_resource_registers |= (S_00B84C_LDS_SIZE(Value) << 32);
756  else if (ID == "compute_pgm_rsrc2_excp_en")
757  Header.compute_pgm_resource_registers |= (S_00B84C_EXCP_EN(Value) << 32);
758  else if (ID == "compute_pgm_resource_registers")
759  Header.compute_pgm_resource_registers = Value;
760  else if (ID == "enable_sgpr_private_segment_buffer")
761  Header.code_properties |=
763  else if (ID == "enable_sgpr_dispatch_ptr")
764  Header.code_properties |=
766  else if (ID == "enable_sgpr_queue_ptr")
767  Header.code_properties |=
769  else if (ID == "enable_sgpr_kernarg_segment_ptr")
770  Header.code_properties |=
772  else if (ID == "enable_sgpr_dispatch_id")
773  Header.code_properties |=
775  else if (ID == "enable_sgpr_flat_scratch_init")
776  Header.code_properties |=
778  else if (ID == "enable_sgpr_private_segment_size")
779  Header.code_properties |=
781  else if (ID == "enable_sgpr_grid_workgroup_count_x")
782  Header.code_properties |=
784  else if (ID == "enable_sgpr_grid_workgroup_count_y")
785  Header.code_properties |=
787  else if (ID == "enable_sgpr_grid_workgroup_count_z")
788  Header.code_properties |=
790  else if (ID == "enable_ordered_append_gds")
791  Header.code_properties |=
793  else if (ID == "private_element_size")
794  Header.code_properties |=
796  else if (ID == "is_ptr64")
797  Header.code_properties |=
799  else if (ID == "is_dynamic_callstack")
800  Header.code_properties |=
802  else if (ID == "is_debug_enabled")
803  Header.code_properties |=
805  else if (ID == "is_xnack_enabled")
806  Header.code_properties |=
808  else if (ID == "workitem_private_segment_byte_size")
809  Header.workitem_private_segment_byte_size = Value;
810  else if (ID == "workgroup_group_segment_byte_size")
811  Header.workgroup_group_segment_byte_size = Value;
812  else if (ID == "gds_segment_byte_size")
813  Header.gds_segment_byte_size = Value;
814  else if (ID == "kernarg_segment_byte_size")
815  Header.kernarg_segment_byte_size = Value;
816  else if (ID == "workgroup_fbarrier_count")
817  Header.workgroup_fbarrier_count = Value;
818  else if (ID == "wavefront_sgpr_count")
819  Header.wavefront_sgpr_count = Value;
820  else if (ID == "workitem_vgpr_count")
821  Header.workitem_vgpr_count = Value;
822  else if (ID == "reserved_vgpr_first")
823  Header.reserved_vgpr_first = Value;
824  else if (ID == "reserved_vgpr_count")
825  Header.reserved_vgpr_count = Value;
826  else if (ID == "reserved_sgpr_first")
827  Header.reserved_sgpr_first = Value;
828  else if (ID == "reserved_sgpr_count")
829  Header.reserved_sgpr_count = Value;
830  else if (ID == "debug_wavefront_private_segment_offset_sgpr")
832  else if (ID == "debug_private_segment_buffer_sgpr")
833  Header.debug_private_segment_buffer_sgpr = Value;
834  else if (ID == "kernarg_segment_alignment")
835  Header.kernarg_segment_alignment = Value;
836  else if (ID == "group_segment_alignment")
837  Header.group_segment_alignment = Value;
838  else if (ID == "private_segment_alignment")
839  Header.private_segment_alignment = Value;
840  else if (ID == "wavefront_size")
841  Header.wavefront_size = Value;
842  else if (ID == "call_convention")
843  Header.call_convention = Value;
844  else if (ID == "runtime_loader_kernel_symbol")
845  Header.runtime_loader_kernel_symbol = Value;
846  else
847  return TokError("amd_kernel_code_t value not recognized.");
848 
849  return false;
850 }
851 
852 bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
853 
854  amd_kernel_code_t Header;
856 
857  while (true) {
858 
859  if (getLexer().isNot(AsmToken::EndOfStatement))
860  return TokError("amd_kernel_code_t values must begin on a new line");
861 
862  // Lex EndOfStatement. This is in a while loop, because lexing a comment
863  // will set the current token to EndOfStatement.
864  while(getLexer().is(AsmToken::EndOfStatement))
865  Lex();
866 
867  if (getLexer().isNot(AsmToken::Identifier))
868  return TokError("expected value identifier or .end_amd_kernel_code_t");
869 
870  StringRef ID = getLexer().getTok().getIdentifier();
871  Lex();
872 
873  if (ID == ".end_amd_kernel_code_t")
874  break;
875 
876  if (ParseAMDKernelCodeTValue(ID, Header))
877  return true;
878  }
879 
880  getTargetStreamer().EmitAMDKernelCodeT(Header);
881 
882  return false;
883 }
884 
885 bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
886  StringRef IDVal = DirectiveID.getString();
887 
888  if (IDVal == ".hsa_code_object_version")
889  return ParseDirectiveHSACodeObjectVersion();
890 
891  if (IDVal == ".hsa_code_object_isa")
892  return ParseDirectiveHSACodeObjectISA();
893 
894  if (IDVal == ".amd_kernel_code_t")
895  return ParseDirectiveAMDKernelCodeT();
896 
897  return true;
898 }
899 
900 static bool operandsHaveModifiers(const OperandVector &Operands) {
901 
902  for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
903  const AMDGPUOperand &Op = ((AMDGPUOperand&)*Operands[i]);
904  if (Op.isRegKind() && Op.hasModifiers())
905  return true;
906  if (Op.isImm() && (Op.getImmTy() == AMDGPUOperand::ImmTyOMod ||
907  Op.getImmTy() == AMDGPUOperand::ImmTyClamp))
908  return true;
909  }
910  return false;
911 }
912 
913 AMDGPUAsmParser::OperandMatchResultTy
914 AMDGPUAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
915 
916  // Try to parse with a custom parser
917  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
918 
919  // If we successfully parsed the operand or if there as an error parsing,
920  // we are done.
921  //
922  // If we are parsing after we reach EndOfStatement then this means we
923  // are appending default values to the Operands list. This is only done
924  // by custom parser, so we shouldn't continue on to the generic parsing.
925  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail ||
926  getLexer().is(AsmToken::EndOfStatement))
927  return ResTy;
928 
929  bool Negate = false, Abs = false;
930  if (getLexer().getKind()== AsmToken::Minus) {
931  Parser.Lex();
932  Negate = true;
933  }
934 
935  if (getLexer().getKind() == AsmToken::Pipe) {
936  Parser.Lex();
937  Abs = true;
938  }
939 
940  switch(getLexer().getKind()) {
941  case AsmToken::Integer: {
942  SMLoc S = Parser.getTok().getLoc();
943  int64_t IntVal;
944  if (getParser().parseAbsoluteExpression(IntVal))
945  return MatchOperand_ParseFail;
946  APInt IntVal32(32, IntVal);
947  if (IntVal32.getSExtValue() != IntVal) {
948  Error(S, "invalid immediate: only 32-bit values are legal");
949  return MatchOperand_ParseFail;
950  }
951 
952  IntVal = IntVal32.getSExtValue();
953  if (Negate)
954  IntVal *= -1;
955  Operands.push_back(AMDGPUOperand::CreateImm(IntVal, S));
956  return MatchOperand_Success;
957  }
958  case AsmToken::Real: {
959  // FIXME: We should emit an error if a double precisions floating-point
960  // value is used. I'm not sure the best way to detect this.
961  SMLoc S = Parser.getTok().getLoc();
962  int64_t IntVal;
963  if (getParser().parseAbsoluteExpression(IntVal))
964  return MatchOperand_ParseFail;
965 
966  APFloat F((float)BitsToDouble(IntVal));
967  if (Negate)
968  F.changeSign();
969  Operands.push_back(
970  AMDGPUOperand::CreateImm(F.bitcastToAPInt().getZExtValue(), S));
971  return MatchOperand_Success;
972  }
973  case AsmToken::Identifier: {
974  SMLoc S, E;
975  unsigned RegNo;
976  if (!ParseRegister(RegNo, S, E)) {
977 
978  bool HasModifiers = operandsHaveModifiers(Operands);
979  unsigned Modifiers = 0;
980 
981  if (Negate)
982  Modifiers |= 0x1;
983 
984  if (Abs) {
985  if (getLexer().getKind() != AsmToken::Pipe)
986  return MatchOperand_ParseFail;
987  Parser.Lex();
988  Modifiers |= 0x2;
989  }
990 
991  if (Modifiers && !HasModifiers) {
992  // We are adding a modifier to src1 or src2 and previous sources
993  // don't have modifiers, so we need to go back and empty modifers
994  // for each previous source.
995  for (unsigned PrevRegIdx = Operands.size() - 1; PrevRegIdx > 1;
996  --PrevRegIdx) {
997 
998  AMDGPUOperand &RegOp = ((AMDGPUOperand&)*Operands[PrevRegIdx]);
999  RegOp.setModifiers(0);
1000  }
1001  }
1002 
1003 
1004  Operands.push_back(AMDGPUOperand::CreateReg(
1005  RegNo, S, E, getContext().getRegisterInfo(),
1006  isForcedVOP3()));
1007 
1008  if (HasModifiers || Modifiers) {
1009  AMDGPUOperand &RegOp = ((AMDGPUOperand&)*Operands[Operands.size() - 1]);
1010  RegOp.setModifiers(Modifiers);
1011 
1012  }
1013  } else {
1014  Operands.push_back(AMDGPUOperand::CreateToken(Parser.getTok().getString(),
1015  S));
1016  Parser.Lex();
1017  }
1018  return MatchOperand_Success;
1019  }
1020  default:
1021  return MatchOperand_NoMatch;
1022  }
1023 }
1024 
1025 bool AMDGPUAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1026  StringRef Name,
1027  SMLoc NameLoc, OperandVector &Operands) {
1028 
1029  // Clear any forced encodings from the previous instruction.
1030  setForcedEncodingSize(0);
1031 
1032  if (Name.endswith("_e64"))
1033  setForcedEncodingSize(64);
1034  else if (Name.endswith("_e32"))
1035  setForcedEncodingSize(32);
1036 
1037  // Add the instruction mnemonic
1038  Operands.push_back(AMDGPUOperand::CreateToken(Name, NameLoc));
1039 
1040  while (!getLexer().is(AsmToken::EndOfStatement)) {
1041  AMDGPUAsmParser::OperandMatchResultTy Res = parseOperand(Operands, Name);
1042 
1043  // Eat the comma or space if there is one.
1044  if (getLexer().is(AsmToken::Comma))
1045  Parser.Lex();
1046 
1047  switch (Res) {
1048  case MatchOperand_Success: break;
1049  case MatchOperand_ParseFail: return Error(getLexer().getLoc(),
1050  "failed parsing operand.");
1051  case MatchOperand_NoMatch: return Error(getLexer().getLoc(),
1052  "not a valid operand.");
1053  }
1054  }
1055 
1056  // Once we reach end of statement, continue parsing so we can add default
1057  // values for optional arguments.
1058  AMDGPUAsmParser::OperandMatchResultTy Res;
1059  while ((Res = parseOperand(Operands, Name)) != MatchOperand_NoMatch) {
1060  if (Res != MatchOperand_Success)
1061  return Error(getLexer().getLoc(), "failed parsing operand.");
1062  }
1063  return false;
1064 }
1065 
1066 //===----------------------------------------------------------------------===//
1067 // Utility functions
1068 //===----------------------------------------------------------------------===//
1069 
1070 AMDGPUAsmParser::OperandMatchResultTy
1071 AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix, int64_t &Int,
1072  int64_t Default) {
1073 
1074  // We are at the end of the statement, and this is a default argument, so
1075  // use a default value.
1076  if (getLexer().is(AsmToken::EndOfStatement)) {
1077  Int = Default;
1078  return MatchOperand_Success;
1079  }
1080 
1081  switch(getLexer().getKind()) {
1082  default: return MatchOperand_NoMatch;
1083  case AsmToken::Identifier: {
1084  StringRef OffsetName = Parser.getTok().getString();
1085  if (!OffsetName.equals(Prefix))
1086  return MatchOperand_NoMatch;
1087 
1088  Parser.Lex();
1089  if (getLexer().isNot(AsmToken::Colon))
1090  return MatchOperand_ParseFail;
1091 
1092  Parser.Lex();
1093  if (getLexer().isNot(AsmToken::Integer))
1094  return MatchOperand_ParseFail;
1095 
1096  if (getParser().parseAbsoluteExpression(Int))
1097  return MatchOperand_ParseFail;
1098  break;
1099  }
1100  }
1101  return MatchOperand_Success;
1102 }
1103 
1104 AMDGPUAsmParser::OperandMatchResultTy
1105 AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix, OperandVector &Operands,
1106  enum AMDGPUOperand::ImmTy ImmTy) {
1107 
1108  SMLoc S = Parser.getTok().getLoc();
1109  int64_t Offset = 0;
1110 
1111  AMDGPUAsmParser::OperandMatchResultTy Res = parseIntWithPrefix(Prefix, Offset);
1112  if (Res != MatchOperand_Success)
1113  return Res;
1114 
1115  Operands.push_back(AMDGPUOperand::CreateImm(Offset, S, ImmTy));
1116  return MatchOperand_Success;
1117 }
1118 
1119 AMDGPUAsmParser::OperandMatchResultTy
1120 AMDGPUAsmParser::parseNamedBit(const char *Name, OperandVector &Operands,
1121  enum AMDGPUOperand::ImmTy ImmTy) {
1122  int64_t Bit = 0;
1123  SMLoc S = Parser.getTok().getLoc();
1124 
1125  // We are at the end of the statement, and this is a default argument, so
1126  // use a default value.
1127  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1128  switch(getLexer().getKind()) {
1129  case AsmToken::Identifier: {
1130  StringRef Tok = Parser.getTok().getString();
1131  if (Tok == Name) {
1132  Bit = 1;
1133  Parser.Lex();
1134  } else if (Tok.startswith("no") && Tok.endswith(Name)) {
1135  Bit = 0;
1136  Parser.Lex();
1137  } else {
1138  return MatchOperand_NoMatch;
1139  }
1140  break;
1141  }
1142  default:
1143  return MatchOperand_NoMatch;
1144  }
1145  }
1146 
1147  Operands.push_back(AMDGPUOperand::CreateImm(Bit, S, ImmTy));
1148  return MatchOperand_Success;
1149 }
1150 
1151 static bool operandsHasOptionalOp(const OperandVector &Operands,
1152  const OptionalOperand &OOp) {
1153  for (unsigned i = 0; i < Operands.size(); i++) {
1154  const AMDGPUOperand &ParsedOp = ((const AMDGPUOperand &)*Operands[i]);
1155  if ((ParsedOp.isImm() && ParsedOp.getImmTy() == OOp.Type) ||
1156  (ParsedOp.isToken() && ParsedOp.getToken() == OOp.Name))
1157  return true;
1158 
1159  }
1160  return false;
1161 }
1162 
1163 AMDGPUAsmParser::OperandMatchResultTy
1164 AMDGPUAsmParser::parseOptionalOps(const ArrayRef<OptionalOperand> &OptionalOps,
1165  OperandVector &Operands) {
1166  SMLoc S = Parser.getTok().getLoc();
1167  for (const OptionalOperand &Op : OptionalOps) {
1168  if (operandsHasOptionalOp(Operands, Op))
1169  continue;
1170  AMDGPUAsmParser::OperandMatchResultTy Res;
1171  int64_t Value;
1172  if (Op.IsBit) {
1173  Res = parseNamedBit(Op.Name, Operands, Op.Type);
1174  if (Res == MatchOperand_NoMatch)
1175  continue;
1176  return Res;
1177  }
1178 
1179  Res = parseIntWithPrefix(Op.Name, Value, Op.Default);
1180 
1181  if (Res == MatchOperand_NoMatch)
1182  continue;
1183 
1184  if (Res != MatchOperand_Success)
1185  return Res;
1186 
1187  if (Op.ConvertResult && !Op.ConvertResult(Value)) {
1188  return MatchOperand_ParseFail;
1189  }
1190 
1191  Operands.push_back(AMDGPUOperand::CreateImm(Value, S, Op.Type));
1192  return MatchOperand_Success;
1193  }
1194  return MatchOperand_NoMatch;
1195 }
1196 
1197 //===----------------------------------------------------------------------===//
1198 // ds
1199 //===----------------------------------------------------------------------===//
1200 
1201 static const OptionalOperand DSOptionalOps [] = {
1202  {"offset", AMDGPUOperand::ImmTyOffset, false, 0, nullptr},
1203  {"gds", AMDGPUOperand::ImmTyGDS, true, 0, nullptr}
1204 };
1205 
1206 static const OptionalOperand DSOptionalOpsOff01 [] = {
1207  {"offset0", AMDGPUOperand::ImmTyDSOffset0, false, 0, nullptr},
1208  {"offset1", AMDGPUOperand::ImmTyDSOffset1, false, 0, nullptr},
1209  {"gds", AMDGPUOperand::ImmTyGDS, true, 0, nullptr}
1210 };
1211 
1212 AMDGPUAsmParser::OperandMatchResultTy
1213 AMDGPUAsmParser::parseDSOptionalOps(OperandVector &Operands) {
1214  return parseOptionalOps(DSOptionalOps, Operands);
1215 }
1216 AMDGPUAsmParser::OperandMatchResultTy
1217 AMDGPUAsmParser::parseDSOff01OptionalOps(OperandVector &Operands) {
1218  return parseOptionalOps(DSOptionalOpsOff01, Operands);
1219 }
1220 
1221 AMDGPUAsmParser::OperandMatchResultTy
1222 AMDGPUAsmParser::parseDSOffsetOptional(OperandVector &Operands) {
1223  SMLoc S = Parser.getTok().getLoc();
1224  AMDGPUAsmParser::OperandMatchResultTy Res =
1225  parseIntWithPrefix("offset", Operands, AMDGPUOperand::ImmTyOffset);
1226  if (Res == MatchOperand_NoMatch) {
1227  Operands.push_back(AMDGPUOperand::CreateImm(0, S,
1228  AMDGPUOperand::ImmTyOffset));
1229  Res = MatchOperand_Success;
1230  }
1231  return Res;
1232 }
1233 
1234 bool AMDGPUOperand::isDSOffset() const {
1235  return isImm() && isUInt<16>(getImm());
1236 }
1237 
1238 bool AMDGPUOperand::isDSOffset01() const {
1239  return isImm() && isUInt<8>(getImm());
1240 }
1241 
1242 void AMDGPUAsmParser::cvtDSOffset01(MCInst &Inst,
1243  const OperandVector &Operands) {
1244 
1245  std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
1246 
1247  for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
1248  AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
1249 
1250  // Add the register arguments
1251  if (Op.isReg()) {
1252  Op.addRegOperands(Inst, 1);
1253  continue;
1254  }
1255 
1256  // Handle optional arguments
1257  OptionalIdx[Op.getImmTy()] = i;
1258  }
1259 
1260  unsigned Offset0Idx = OptionalIdx[AMDGPUOperand::ImmTyDSOffset0];
1261  unsigned Offset1Idx = OptionalIdx[AMDGPUOperand::ImmTyDSOffset1];
1262  unsigned GDSIdx = OptionalIdx[AMDGPUOperand::ImmTyGDS];
1263 
1264  ((AMDGPUOperand &)*Operands[Offset0Idx]).addImmOperands(Inst, 1); // offset0
1265  ((AMDGPUOperand &)*Operands[Offset1Idx]).addImmOperands(Inst, 1); // offset1
1266  ((AMDGPUOperand &)*Operands[GDSIdx]).addImmOperands(Inst, 1); // gds
1267  Inst.addOperand(MCOperand::createReg(AMDGPU::M0)); // m0
1268 }
1269 
1270 void AMDGPUAsmParser::cvtDS(MCInst &Inst, const OperandVector &Operands) {
1271 
1272  std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
1273  bool GDSOnly = false;
1274 
1275  for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
1276  AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
1277 
1278  // Add the register arguments
1279  if (Op.isReg()) {
1280  Op.addRegOperands(Inst, 1);
1281  continue;
1282  }
1283 
1284  if (Op.isToken() && Op.getToken() == "gds") {
1285  GDSOnly = true;
1286  continue;
1287  }
1288 
1289  // Handle optional arguments
1290  OptionalIdx[Op.getImmTy()] = i;
1291  }
1292 
1293  unsigned OffsetIdx = OptionalIdx[AMDGPUOperand::ImmTyOffset];
1294  ((AMDGPUOperand &)*Operands[OffsetIdx]).addImmOperands(Inst, 1); // offset
1295 
1296  if (!GDSOnly) {
1297  unsigned GDSIdx = OptionalIdx[AMDGPUOperand::ImmTyGDS];
1298  ((AMDGPUOperand &)*Operands[GDSIdx]).addImmOperands(Inst, 1); // gds
1299  }
1300  Inst.addOperand(MCOperand::createReg(AMDGPU::M0)); // m0
1301 }
1302 
1303 
1304 //===----------------------------------------------------------------------===//
1305 // s_waitcnt
1306 //===----------------------------------------------------------------------===//
1307 
1308 bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
1309  StringRef CntName = Parser.getTok().getString();
1310  int64_t CntVal;
1311 
1312  Parser.Lex();
1313  if (getLexer().isNot(AsmToken::LParen))
1314  return true;
1315 
1316  Parser.Lex();
1317  if (getLexer().isNot(AsmToken::Integer))
1318  return true;
1319 
1320  if (getParser().parseAbsoluteExpression(CntVal))
1321  return true;
1322 
1323  if (getLexer().isNot(AsmToken::RParen))
1324  return true;
1325 
1326  Parser.Lex();
1327  if (getLexer().is(AsmToken::Amp) || getLexer().is(AsmToken::Comma))
1328  Parser.Lex();
1329 
1330  int CntShift;
1331  int CntMask;
1332 
1333  if (CntName == "vmcnt") {
1334  CntMask = 0xf;
1335  CntShift = 0;
1336  } else if (CntName == "expcnt") {
1337  CntMask = 0x7;
1338  CntShift = 4;
1339  } else if (CntName == "lgkmcnt") {
1340  CntMask = 0x7;
1341  CntShift = 8;
1342  } else {
1343  return true;
1344  }
1345 
1346  IntVal &= ~(CntMask << CntShift);
1347  IntVal |= (CntVal << CntShift);
1348  return false;
1349 }
1350 
1351 AMDGPUAsmParser::OperandMatchResultTy
1352 AMDGPUAsmParser::parseSWaitCntOps(OperandVector &Operands) {
1353  // Disable all counters by default.
1354  // vmcnt [3:0]
1355  // expcnt [6:4]
1356  // lgkmcnt [10:8]
1357  int64_t CntVal = 0x77f;
1358  SMLoc S = Parser.getTok().getLoc();
1359 
1360  switch(getLexer().getKind()) {
1361  default: return MatchOperand_ParseFail;
1362  case AsmToken::Integer:
1363  // The operand can be an integer value.
1364  if (getParser().parseAbsoluteExpression(CntVal))
1365  return MatchOperand_ParseFail;
1366  break;
1367 
1368  case AsmToken::Identifier:
1369  do {
1370  if (parseCnt(CntVal))
1371  return MatchOperand_ParseFail;
1372  } while(getLexer().isNot(AsmToken::EndOfStatement));
1373  break;
1374  }
1375  Operands.push_back(AMDGPUOperand::CreateImm(CntVal, S));
1376  return MatchOperand_Success;
1377 }
1378 
1379 bool AMDGPUOperand::isSWaitCnt() const {
1380  return isImm();
1381 }
1382 
1383 //===----------------------------------------------------------------------===//
1384 // sopp branch targets
1385 //===----------------------------------------------------------------------===//
1386 
1387 AMDGPUAsmParser::OperandMatchResultTy
1388 AMDGPUAsmParser::parseSOppBrTarget(OperandVector &Operands) {
1389  SMLoc S = Parser.getTok().getLoc();
1390 
1391  switch (getLexer().getKind()) {
1392  default: return MatchOperand_ParseFail;
1393  case AsmToken::Integer: {
1394  int64_t Imm;
1395  if (getParser().parseAbsoluteExpression(Imm))
1396  return MatchOperand_ParseFail;
1397  Operands.push_back(AMDGPUOperand::CreateImm(Imm, S));
1398  return MatchOperand_Success;
1399  }
1400 
1401  case AsmToken::Identifier:
1402  Operands.push_back(AMDGPUOperand::CreateExpr(
1403  MCSymbolRefExpr::create(getContext().getOrCreateSymbol(
1404  Parser.getTok().getString()), getContext()), S));
1405  Parser.Lex();
1406  return MatchOperand_Success;
1407  }
1408 }
1409 
1410 //===----------------------------------------------------------------------===//
1411 // flat
1412 //===----------------------------------------------------------------------===//
1413 
1414 static const OptionalOperand FlatOptionalOps [] = {
1415  {"glc", AMDGPUOperand::ImmTyGLC, true, 0, nullptr},
1416  {"slc", AMDGPUOperand::ImmTySLC, true, 0, nullptr},
1417  {"tfe", AMDGPUOperand::ImmTyTFE, true, 0, nullptr}
1418 };
1419 
1420 static const OptionalOperand FlatAtomicOptionalOps [] = {
1421  {"slc", AMDGPUOperand::ImmTySLC, true, 0, nullptr},
1422  {"tfe", AMDGPUOperand::ImmTyTFE, true, 0, nullptr}
1423 };
1424 
1425 AMDGPUAsmParser::OperandMatchResultTy
1426 AMDGPUAsmParser::parseFlatOptionalOps(OperandVector &Operands) {
1427  return parseOptionalOps(FlatOptionalOps, Operands);
1428 }
1429 
1430 AMDGPUAsmParser::OperandMatchResultTy
1431 AMDGPUAsmParser::parseFlatAtomicOptionalOps(OperandVector &Operands) {
1432  return parseOptionalOps(FlatAtomicOptionalOps, Operands);
1433 }
1434 
1435 void AMDGPUAsmParser::cvtFlat(MCInst &Inst,
1436  const OperandVector &Operands) {
1437  std::map<AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
1438 
1439  for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
1440  AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
1441 
1442  // Add the register arguments
1443  if (Op.isReg()) {
1444  Op.addRegOperands(Inst, 1);
1445  continue;
1446  }
1447 
1448  // Handle 'glc' token which is sometimes hard-coded into the
1449  // asm string. There are no MCInst operands for these.
1450  if (Op.isToken())
1451  continue;
1452 
1453  // Handle optional arguments
1454  OptionalIdx[Op.getImmTy()] = i;
1455 
1456  }
1457 
1458  // flat atomic instructions don't have a glc argument.
1459  if (OptionalIdx.count(AMDGPUOperand::ImmTyGLC)) {
1460  unsigned GLCIdx = OptionalIdx[AMDGPUOperand::ImmTyGLC];
1461  ((AMDGPUOperand &)*Operands[GLCIdx]).addImmOperands(Inst, 1);
1462  }
1463 
1464  unsigned SLCIdx = OptionalIdx[AMDGPUOperand::ImmTySLC];
1465  unsigned TFEIdx = OptionalIdx[AMDGPUOperand::ImmTyTFE];
1466 
1467  ((AMDGPUOperand &)*Operands[SLCIdx]).addImmOperands(Inst, 1);
1468  ((AMDGPUOperand &)*Operands[TFEIdx]).addImmOperands(Inst, 1);
1469 }
1470 
1471 //===----------------------------------------------------------------------===//
1472 // mubuf
1473 //===----------------------------------------------------------------------===//
1474 
1475 static const OptionalOperand MubufOptionalOps [] = {
1476  {"offset", AMDGPUOperand::ImmTyOffset, false, 0, nullptr},
1477  {"glc", AMDGPUOperand::ImmTyGLC, true, 0, nullptr},
1478  {"slc", AMDGPUOperand::ImmTySLC, true, 0, nullptr},
1479  {"tfe", AMDGPUOperand::ImmTyTFE, true, 0, nullptr}
1480 };
1481 
1482 AMDGPUAsmParser::OperandMatchResultTy
1483 AMDGPUAsmParser::parseMubufOptionalOps(OperandVector &Operands) {
1484  return parseOptionalOps(MubufOptionalOps, Operands);
1485 }
1486 
1487 AMDGPUAsmParser::OperandMatchResultTy
1488 AMDGPUAsmParser::parseOffset(OperandVector &Operands) {
1489  return parseIntWithPrefix("offset", Operands);
1490 }
1491 
1492 AMDGPUAsmParser::OperandMatchResultTy
1493 AMDGPUAsmParser::parseGLC(OperandVector &Operands) {
1494  return parseNamedBit("glc", Operands);
1495 }
1496 
1497 AMDGPUAsmParser::OperandMatchResultTy
1498 AMDGPUAsmParser::parseSLC(OperandVector &Operands) {
1499  return parseNamedBit("slc", Operands);
1500 }
1501 
1502 AMDGPUAsmParser::OperandMatchResultTy
1503 AMDGPUAsmParser::parseTFE(OperandVector &Operands) {
1504  return parseNamedBit("tfe", Operands);
1505 }
1506 
1507 bool AMDGPUOperand::isMubufOffset() const {
1508  return isImm() && isUInt<12>(getImm());
1509 }
1510 
1511 void AMDGPUAsmParser::cvtMubuf(MCInst &Inst,
1512  const OperandVector &Operands) {
1513  std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
1514 
1515  for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
1516  AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
1517 
1518  // Add the register arguments
1519  if (Op.isReg()) {
1520  Op.addRegOperands(Inst, 1);
1521  continue;
1522  }
1523 
1524  // Handle the case where soffset is an immediate
1525  if (Op.isImm() && Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
1526  Op.addImmOperands(Inst, 1);
1527  continue;
1528  }
1529 
1530  // Handle tokens like 'offen' which are sometimes hard-coded into the
1531  // asm string. There are no MCInst operands for these.
1532  if (Op.isToken()) {
1533  continue;
1534  }
1535  assert(Op.isImm());
1536 
1537  // Handle optional arguments
1538  OptionalIdx[Op.getImmTy()] = i;
1539  }
1540 
1541  assert(OptionalIdx.size() == 4);
1542 
1543  unsigned OffsetIdx = OptionalIdx[AMDGPUOperand::ImmTyOffset];
1544  unsigned GLCIdx = OptionalIdx[AMDGPUOperand::ImmTyGLC];
1545  unsigned SLCIdx = OptionalIdx[AMDGPUOperand::ImmTySLC];
1546  unsigned TFEIdx = OptionalIdx[AMDGPUOperand::ImmTyTFE];
1547 
1548  ((AMDGPUOperand &)*Operands[OffsetIdx]).addImmOperands(Inst, 1);
1549  ((AMDGPUOperand &)*Operands[GLCIdx]).addImmOperands(Inst, 1);
1550  ((AMDGPUOperand &)*Operands[SLCIdx]).addImmOperands(Inst, 1);
1551  ((AMDGPUOperand &)*Operands[TFEIdx]).addImmOperands(Inst, 1);
1552 }
1553 
1554 //===----------------------------------------------------------------------===//
1555 // mimg
1556 //===----------------------------------------------------------------------===//
1557 
1558 AMDGPUAsmParser::OperandMatchResultTy
1559 AMDGPUAsmParser::parseDMask(OperandVector &Operands) {
1560  return parseIntWithPrefix("dmask", Operands);
1561 }
1562 
1563 AMDGPUAsmParser::OperandMatchResultTy
1564 AMDGPUAsmParser::parseUNorm(OperandVector &Operands) {
1565  return parseNamedBit("unorm", Operands);
1566 }
1567 
1568 AMDGPUAsmParser::OperandMatchResultTy
1569 AMDGPUAsmParser::parseR128(OperandVector &Operands) {
1570  return parseNamedBit("r128", Operands);
1571 }
1572 
1573 //===----------------------------------------------------------------------===//
1574 // vop3
1575 //===----------------------------------------------------------------------===//
1576 
1577 static bool ConvertOmodMul(int64_t &Mul) {
1578  if (Mul != 1 && Mul != 2 && Mul != 4)
1579  return false;
1580 
1581  Mul >>= 1;
1582  return true;
1583 }
1584 
1585 static bool ConvertOmodDiv(int64_t &Div) {
1586  if (Div == 1) {
1587  Div = 0;
1588  return true;
1589  }
1590 
1591  if (Div == 2) {
1592  Div = 3;
1593  return true;
1594  }
1595 
1596  return false;
1597 }
1598 
1599 static const OptionalOperand VOP3OptionalOps [] = {
1600  {"clamp", AMDGPUOperand::ImmTyClamp, true, 0, nullptr},
1601  {"mul", AMDGPUOperand::ImmTyOMod, false, 1, ConvertOmodMul},
1602  {"div", AMDGPUOperand::ImmTyOMod, false, 1, ConvertOmodDiv},
1603 };
1604 
1605 static bool isVOP3(OperandVector &Operands) {
1606  if (operandsHaveModifiers(Operands))
1607  return true;
1608 
1609  AMDGPUOperand &DstOp = ((AMDGPUOperand&)*Operands[1]);
1610 
1611  if (DstOp.isReg() && DstOp.isRegClass(AMDGPU::SGPR_64RegClassID))
1612  return true;
1613 
1614  if (Operands.size() >= 5)
1615  return true;
1616 
1617  if (Operands.size() > 3) {
1618  AMDGPUOperand &Src1Op = ((AMDGPUOperand&)*Operands[3]);
1619  if (Src1Op.getReg() && (Src1Op.isRegClass(AMDGPU::SReg_32RegClassID) ||
1620  Src1Op.isRegClass(AMDGPU::SReg_64RegClassID)))
1621  return true;
1622  }
1623  return false;
1624 }
1625 
1626 AMDGPUAsmParser::OperandMatchResultTy
1627 AMDGPUAsmParser::parseVOP3OptionalOps(OperandVector &Operands) {
1628 
1629  // The value returned by this function may change after parsing
1630  // an operand so store the original value here.
1631  bool HasModifiers = operandsHaveModifiers(Operands);
1632 
1633  bool IsVOP3 = isVOP3(Operands);
1634  if (HasModifiers || IsVOP3 ||
1635  getLexer().isNot(AsmToken::EndOfStatement) ||
1636  getForcedEncodingSize() == 64) {
1637 
1638  AMDGPUAsmParser::OperandMatchResultTy Res =
1639  parseOptionalOps(VOP3OptionalOps, Operands);
1640 
1641  if (!HasModifiers && Res == MatchOperand_Success) {
1642  // We have added a modifier operation, so we need to make sure all
1643  // previous register operands have modifiers
1644  for (unsigned i = 2, e = Operands.size(); i != e; ++i) {
1645  AMDGPUOperand &Op = ((AMDGPUOperand&)*Operands[i]);
1646  if (Op.isReg())
1647  Op.setModifiers(0);
1648  }
1649  }
1650  return Res;
1651  }
1652  return MatchOperand_NoMatch;
1653 }
1654 
1655 void AMDGPUAsmParser::cvtVOP3(MCInst &Inst, const OperandVector &Operands) {
1656  ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
1657  unsigned i = 2;
1658 
1659  std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
1660 
1661  if (operandsHaveModifiers(Operands)) {
1662  for (unsigned e = Operands.size(); i != e; ++i) {
1663  AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
1664 
1665  if (Op.isRegWithInputMods()) {
1666  ((AMDGPUOperand &)*Operands[i]).addRegWithInputModsOperands(Inst, 2);
1667  continue;
1668  }
1669  OptionalIdx[Op.getImmTy()] = i;
1670  }
1671 
1672  unsigned ClampIdx = OptionalIdx[AMDGPUOperand::ImmTyClamp];
1673  unsigned OModIdx = OptionalIdx[AMDGPUOperand::ImmTyOMod];
1674 
1675  ((AMDGPUOperand &)*Operands[ClampIdx]).addImmOperands(Inst, 1);
1676  ((AMDGPUOperand &)*Operands[OModIdx]).addImmOperands(Inst, 1);
1677  } else {
1678  for (unsigned e = Operands.size(); i != e; ++i)
1679  ((AMDGPUOperand &)*Operands[i]).addRegOrImmOperands(Inst, 1);
1680  }
1681 }
1682 
1683 /// Force static initialization.
1687 }
1688 
1689 #define GET_REGISTER_MATCHER
1690 #define GET_MATCHER_IMPLEMENTATION
1691 #include "AMDGPUGenAsmMatcher.inc"
1692 
static bool isReg(const MCInst &MI, unsigned OpNo)
bool isUInt< 8 >(uint64_t x)
Definition: MathExtras.h:294
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:347
void push_back(const T &Elt)
Definition: SmallVector.h:222
static const OptionalOperand DSOptionalOpsOff01[]
#define S_00B848_VGPRS(x)
Definition: SIDefines.h:142
static bool isVOP3(OperandVector &Operands)
#define S_00B848_PRIV(x)
Definition: SIDefines.h:154
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:315
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:64
Target TheGCNTarget
The target for GCN GPUs.
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:129
MCTargetAsmParser - Generic interface to target specific assembly parsers.
static const OptionalOperand FlatOptionalOps[]
Indicate if the generated ISA is using a dynamically sized call stack.
bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:224
Target specific streamer interface.
Definition: MCStreamer.h:73
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmLexer.h:100
float BitsToFloat(uint32_t Bits)
BitsToFloat - This function takes a 32-bit integer and returns the bit equivalent float...
Definition: MathExtras.h:515
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:405
#define S_00B84C_SCRATCH_EN(x)
Definition: SIDefines.h:105
#define S_00B84C_TG_SIZE_EN(x)
Definition: SIDefines.h:120
#define S_00B848_DX10_CLAMP(x)
Definition: SIDefines.h:157
F(f)
StringSwitch & Case(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:55
static bool ConvertOmodDiv(int64_t &Div)
static const OptionalOperand VOP3OptionalOps[]
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:639
Target TheAMDGPUTarget
The target which suports all AMD GPUs.
uint32_t amd_kernel_code_version_major
uint32_t code_properties
Code properties.
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
AMD Kernel Code Object (amd_kernel_code_t).
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APInt.h:33
uint16_t amd_machine_version_major
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:33
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
Definition: MCAsmLexer.h:22
uint16_t reserved_sgpr_first
If reserved_sgpr_count is 0 then must be 0.
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
#define S_00B84C_TGID_Y_EN(x)
Definition: SIDefines.h:114
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
Context object for machine code objects.
Definition: MCContext.h:48
#define S_00B848_FLOAT_MODE(x)
Definition: SIDefines.h:151
uint8_t kernarg_segment_alignment
The maximum byte alignment of variables used by the kernel in the specified memory segment...
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:107
uint8_t group_segment_alignment
Indicate if code generated has support for debugging.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: ArrayRef.h:31
uint16_t amd_machine_version_minor
uint32_t amd_kernel_code_version_minor
uint64_t runtime_loader_kernel_symbol
uint64_t compute_pgm_resource_registers
Shader program settings for CS.
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
FeatureBitset ToggleFeature(uint64_t FB)
ToggleFeature - Toggle a feature and returns the re-computed feature bits.
A self-contained host- and target-independent arbitrary-precision floating-point software implementat...
Definition: APFloat.h:122
#define S_00B848_IEEE_MODE(x)
Definition: SIDefines.h:163
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
Streaming machine code generation interface.
Definition: MCStreamer.h:157
uint16_t wavefront_sgpr_count
Number of scalar registers used by a wavefront.
IsaVersion getIsaVersion(const FeatureBitset &Features)
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
uint32_t gds_segment_byte_size
Number of byte of GDS required by kernel dispatch.
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:26
#define S_00B84C_TIDIG_COMP_CNT(x)
Definition: SIDefines.h:123
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the class.
uint8_t private_segment_alignment
This file declares a class to represent arbitrary precision floating point values and provide a varie...
#define S_00B84C_EXCP_EN_MSB(x)
Definition: SIDefines.h:127
SI Fold Operands
#define S_00B84C_TGID_Z_EN(x)
Definition: SIDefines.h:117
#define S_00B84C_LDS_SIZE(x)
Definition: SIDefines.h:131
void setLoc(SMLoc loc)
Definition: MCInst.h:161
void initDefaultAMDKernelCodeT(amd_kernel_code_t &Header, const FeatureBitset &Features)
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
static unsigned getRegClass(bool IsVgpr, unsigned RegWidth)
#define S_00B84C_EXCP_EN(x)
Definition: SIDefines.h:134
Are global memory addresses 64 bits.
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:215
uint64_t kernarg_segment_byte_size
The size in bytes of the kernarg segment that holds the values of the arguments to the kernel...
static const OptionalOperand FlatAtomicOptionalOps[]
uint16_t debug_wavefront_private_segment_offset_sgpr
If is_debug_supported is 0 then must be 0.
Promote Memory to Register
Definition: Mem2Reg.cpp:58
static const OptionalOperand MubufOptionalOps[]
uint16_t amd_machine_version_stepping
static bool ConvertOmodMul(int64_t &Mul)
uint16_t workitem_vgpr_count
Number of vector registers used by each work-item.
uint8_t wavefront_size
Wavefront size expressed as a power of two.
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
static bool operandsHaveModifiers(const OperandVector &Operands)
#define S_00B848_DEBUG_MODE(x)
Definition: SIDefines.h:160
double BitsToDouble(uint64_t Bits)
BitsToDouble - This function takes a 64-bit integer and returns the bit equivalent double...
Definition: MathExtras.h:504
R Default(const T &Value) const
Definition: StringSwitch.h:111
#define S_00B84C_TGID_X_EN(x)
Definition: SIDefines.h:111
void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
uint32_t workgroup_group_segment_byte_size
The amount of group segment memory required by a work-group in bytes.
unsigned getOpcode() const
Definition: MCInst.h:159
Class for arbitrary precision integers.
Definition: APInt.h:73
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:136
The interleave (swizzle) element size in bytes required by the code for private memory.
Provides AMDGPU specific target descriptions.
Enable the setup of the SGPR user data registers (AMD_CODE_PROPERTY_ENABLE_SGPR_*), see documentation of amd_kernel_code_t for initial register state.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
static const OptionalOperand DSOptionalOps[]
#define S_00B848_SGPRS(x)
Definition: SIDefines.h:145
uint32_t workitem_private_segment_byte_size
The amount of memory required for the combined private, spill and arg segments for a work-item in byt...
#define S_00B84C_USER_SGPR(x)
Definition: SIDefines.h:108
#define N
MCSubtargetInfo - Generic base class for all target subtargets.
uint64_t kernel_code_prefetch_byte_size
static bool isMem(const MachineInstr *MI, unsigned Op)
Definition: X86InstrInfo.h:147
Control wave ID base counter for GDS ordered-append.
int64_t kernel_code_entry_byte_offset
Byte offset (possibly negative) from start of amd_kernel_code_t object to kernel's entry point instru...
const ARM::ArchExtKind Kind
static unsigned getRegForName(const StringRef &RegName)
#define S_00B848_PRIORITY(x)
Definition: SIDefines.h:148
LLVM Value Representation.
Definition: Value.h:69
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:30
bool isUInt< 16 >(uint64_t x)
Definition: MathExtras.h:298
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
static TraceState * TS
uint16_t amd_machine_kind
uint32_t workgroup_fbarrier_count
Number of fbarrier's used in the kernel and all functions it calls.
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
static bool operandsHasOptionalOp(const OperandVector &Operands, const OptionalOperand &OOp)
Represents a location in source code.
Definition: SMLoc.h:23
uint16_t debug_private_segment_buffer_sgpr
If is_debug_supported is 0 then must be 0.
uint16_t reserved_vgpr_count
The number of consecutive VGPRs reserved by the client.
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117
uint64_t max_scratch_backing_memory_byte_size
Number of bytes of scratch backing memory required for full occupancy of target chip.
uint16_t reserved_vgpr_first
If reserved_vgpr_count is 0 then must be 0.
uint16_t reserved_sgpr_count
The number of consecutive SGPRs reserved by the client.