LLVM  4.0.0
AMDGPUDisassembler.cpp
Go to the documentation of this file.
1 //===-- AMDGPUDisassembler.cpp - Disassembler for AMDGPU ISA --------------===//
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 //===----------------------------------------------------------------------===//
11 //
12 /// \file
13 ///
14 /// This file contains definition for AMDGPU ISA disassembler
15 //
16 //===----------------------------------------------------------------------===//
17 
18 // ToDo: What to do with instruction suffixes (v_mov_b32 vs v_mov_b32_e32)?
19 
20 #include "AMDGPUDisassembler.h"
21 #include "AMDGPU.h"
22 #include "AMDGPURegisterInfo.h"
23 #include "SIDefines.h"
24 #include "Utils/AMDGPUBaseInfo.h"
25 
26 #include "llvm/MC/MCContext.h"
28 #include "llvm/MC/MCInst.h"
29 #include "llvm/MC/MCInstrDesc.h"
31 #include "llvm/Support/ELF.h"
32 #include "llvm/Support/Endian.h"
33 #include "llvm/Support/Debug.h"
35 
36 
37 using namespace llvm;
38 
39 #define DEBUG_TYPE "amdgpu-disassembler"
40 
42 
43 
44 inline static MCDisassembler::DecodeStatus
45 addOperand(MCInst &Inst, const MCOperand& Opnd) {
46  Inst.addOperand(Opnd);
47  return Opnd.isValid() ?
50 }
51 
52 static DecodeStatus decodeSoppBrTarget(MCInst &Inst, unsigned Imm,
53  uint64_t Addr, const void *Decoder) {
54  auto DAsm = static_cast<const AMDGPUDisassembler*>(Decoder);
55 
56  APInt SignedOffset(18, Imm * 4, true);
57  int64_t Offset = (SignedOffset.sext(64) + 4 + Addr).getSExtValue();
58 
59  if (DAsm->tryAddingSymbolicOperand(Inst, Offset, Addr, true, 2, 2))
61  return addOperand(Inst, MCOperand::createImm(Imm));
62 }
63 
64 #define DECODE_OPERAND2(RegClass, DecName) \
65 static DecodeStatus Decode##RegClass##RegisterClass(MCInst &Inst, \
66  unsigned Imm, \
67  uint64_t /*Addr*/, \
68  const void *Decoder) { \
69  auto DAsm = static_cast<const AMDGPUDisassembler*>(Decoder); \
70  return addOperand(Inst, DAsm->decodeOperand_##DecName(Imm)); \
71 }
72 
73 #define DECODE_OPERAND(RegClass) DECODE_OPERAND2(RegClass, RegClass)
74 
75 DECODE_OPERAND(VGPR_32)
76 DECODE_OPERAND(VS_32)
77 DECODE_OPERAND(VS_64)
78 
79 DECODE_OPERAND(VReg_64)
80 DECODE_OPERAND(VReg_96)
81 DECODE_OPERAND(VReg_128)
82 
83 DECODE_OPERAND(SReg_32)
84 DECODE_OPERAND(SReg_32_XM0_XEXEC)
85 DECODE_OPERAND(SReg_64)
86 DECODE_OPERAND(SReg_64_XEXEC)
87 DECODE_OPERAND(SReg_128)
88 DECODE_OPERAND(SReg_256)
89 DECODE_OPERAND(SReg_512)
90 
91 
93  unsigned Imm,
94  uint64_t Addr,
95  const void *Decoder) {
96  auto DAsm = static_cast<const AMDGPUDisassembler*>(Decoder);
97  return addOperand(Inst, DAsm->decodeOperand_VSrc16(Imm));
98 }
99 
100 #define GET_SUBTARGETINFO_ENUM
101 #include "AMDGPUGenSubtargetInfo.inc"
102 #undef GET_SUBTARGETINFO_ENUM
103 
104 #include "AMDGPUGenDisassemblerTables.inc"
105 
106 //===----------------------------------------------------------------------===//
107 //
108 //===----------------------------------------------------------------------===//
109 
110 template <typename T> static inline T eatBytes(ArrayRef<uint8_t>& Bytes) {
111  assert(Bytes.size() >= sizeof(T));
112  const auto Res = support::endian::read<T, support::endianness::little>(Bytes.data());
113  Bytes = Bytes.slice(sizeof(T));
114  return Res;
115 }
116 
118  MCInst &MI,
119  uint64_t Inst,
120  uint64_t Address) const {
121  assert(MI.getOpcode() == 0);
122  assert(MI.getNumOperands() == 0);
123  MCInst TmpInst;
124  const auto SavedBytes = Bytes;
125  if (decodeInstruction(Table, TmpInst, Inst, Address, this, STI)) {
126  MI = TmpInst;
128  }
129  Bytes = SavedBytes;
130  return MCDisassembler::Fail;
131 }
132 
134  ArrayRef<uint8_t> Bytes_,
135  uint64_t Address,
136  raw_ostream &WS,
137  raw_ostream &CS) const {
138  CommentStream = &CS;
139 
140  // ToDo: AMDGPUDisassembler supports only VI ISA.
141  assert(AMDGPU::isVI(STI) && "Can disassemble only VI ISA.");
142 
143  const unsigned MaxInstBytesNum = (std::min)((size_t)8, Bytes_.size());
144  Bytes = Bytes_.slice(0, MaxInstBytesNum);
145 
147  do {
148  // ToDo: better to switch encoding length using some bit predicate
149  // but it is unknown yet, so try all we can
150 
151  // Try to decode DPP and SDWA first to solve conflict with VOP1 and VOP2
152  // encodings
153  if (Bytes.size() >= 8) {
154  const uint64_t QW = eatBytes<uint64_t>(Bytes);
155  Res = tryDecodeInst(DecoderTableDPP64, MI, QW, Address);
156  if (Res) break;
157 
158  Res = tryDecodeInst(DecoderTableSDWA64, MI, QW, Address);
159  if (Res) break;
160  }
161 
162  // Reinitialize Bytes as DPP64 could have eaten too much
163  Bytes = Bytes_.slice(0, MaxInstBytesNum);
164 
165  // Try decode 32-bit instruction
166  if (Bytes.size() < 4) break;
167  const uint32_t DW = eatBytes<uint32_t>(Bytes);
168  Res = tryDecodeInst(DecoderTableVI32, MI, DW, Address);
169  if (Res) break;
170 
171  Res = tryDecodeInst(DecoderTableAMDGPU32, MI, DW, Address);
172  if (Res) break;
173 
174  if (Bytes.size() < 4) break;
175  const uint64_t QW = ((uint64_t)eatBytes<uint32_t>(Bytes) << 32) | DW;
176  Res = tryDecodeInst(DecoderTableVI64, MI, QW, Address);
177  if (Res) break;
178 
179  Res = tryDecodeInst(DecoderTableAMDGPU64, MI, QW, Address);
180  } while (false);
181 
182  Size = Res ? (MaxInstBytesNum - Bytes.size()) : 0;
183  return Res;
184 }
185 
186 const char* AMDGPUDisassembler::getRegClassName(unsigned RegClassID) const {
187  return getContext().getRegisterInfo()->
188  getRegClassName(&AMDGPUMCRegisterClasses[RegClassID]);
189 }
190 
191 inline
193  const Twine& ErrMsg) const {
194  *CommentStream << "Error: " + ErrMsg;
195 
196  // ToDo: add support for error operands to MCInst.h
197  // return MCOperand::createError(V);
198  return MCOperand();
199 }
200 
201 inline
203  return MCOperand::createReg(RegId);
204 }
205 
206 inline
208  unsigned Val) const {
209  const auto& RegCl = AMDGPUMCRegisterClasses[RegClassID];
210  if (Val >= RegCl.getNumRegs())
211  return errOperand(Val, Twine(getRegClassName(RegClassID)) +
212  ": unknown register " + Twine(Val));
213  return createRegOperand(RegCl.getRegister(Val));
214 }
215 
216 inline
218  unsigned Val) const {
219  // ToDo: SI/CI have 104 SGPRs, VI - 102
220  // Valery: here we accepting as much as we can, let assembler sort it out
221  int shift = 0;
222  switch (SRegClassID) {
223  case AMDGPU::SGPR_32RegClassID:
224  case AMDGPU::TTMP_32RegClassID:
225  break;
226  case AMDGPU::SGPR_64RegClassID:
227  case AMDGPU::TTMP_64RegClassID:
228  shift = 1;
229  break;
230  case AMDGPU::SGPR_128RegClassID:
231  case AMDGPU::TTMP_128RegClassID:
232  // ToDo: unclear if s[100:104] is available on VI. Can we use VCC as SGPR in
233  // this bundle?
234  case AMDGPU::SReg_256RegClassID:
235  // ToDo: unclear if s[96:104] is available on VI. Can we use VCC as SGPR in
236  // this bundle?
237  case AMDGPU::SReg_512RegClassID:
238  shift = 2;
239  break;
240  // ToDo: unclear if s[88:104] is available on VI. Can we use VCC as SGPR in
241  // this bundle?
242  default:
243  llvm_unreachable("unhandled register class");
244  }
245 
246  if (Val % (1 << shift)) {
247  *CommentStream << "Warning: " << getRegClassName(SRegClassID)
248  << ": scalar reg isn't aligned " << Val;
249  }
250 
251  return createRegOperand(SRegClassID, Val >> shift);
252 }
253 
255  return decodeSrcOp(OPW32, Val);
256 }
257 
259  return decodeSrcOp(OPW64, Val);
260 }
261 
263  return decodeSrcOp(OPW16, Val);
264 }
265 
267  // Some instructions have operand restrictions beyond what the encoding
268  // allows. Some ordinarily VSrc_32 operands are VGPR_32, so clear the extra
269  // high bit.
270  Val &= 255;
271 
272  return createRegOperand(AMDGPU::VGPR_32RegClassID, Val);
273 }
274 
276  return createRegOperand(AMDGPU::VReg_64RegClassID, Val);
277 }
278 
280  return createRegOperand(AMDGPU::VReg_96RegClassID, Val);
281 }
282 
284  return createRegOperand(AMDGPU::VReg_128RegClassID, Val);
285 }
286 
288  // table-gen generated disassembler doesn't care about operand types
289  // leaving only registry class so SSrc_32 operand turns into SReg_32
290  // and therefore we accept immediates and literals here as well
291  return decodeSrcOp(OPW32, Val);
292 }
293 
295  unsigned Val) const {
296  // SReg_32_XM0 is SReg_32 without M0 or EXEC_LO/EXEC_HI
297  return decodeOperand_SReg_32(Val);
298 }
299 
301  return decodeSrcOp(OPW64, Val);
302 }
303 
305  return decodeSrcOp(OPW64, Val);
306 }
307 
309  return decodeSrcOp(OPW128, Val);
310 }
311 
313  return createSRegOperand(AMDGPU::SReg_256RegClassID, Val);
314 }
315 
317  return createSRegOperand(AMDGPU::SReg_512RegClassID, Val);
318 }
319 
320 
322  // For now all literal constants are supposed to be unsigned integer
323  // ToDo: deal with signed/unsigned 64-bit integer constants
324  // ToDo: deal with float/double constants
325  if (Bytes.size() < 4)
326  return errOperand(0, "cannot read literal, inst bytes left " +
327  Twine(Bytes.size()));
328  return MCOperand::createImm(eatBytes<uint32_t>(Bytes));
329 }
330 
332  using namespace AMDGPU::EncValues;
335  (static_cast<int64_t>(Imm) - INLINE_INTEGER_C_MIN) :
336  (INLINE_INTEGER_C_POSITIVE_MAX - static_cast<int64_t>(Imm)));
337  // Cast prevents negative overflow.
338 }
339 
340 static int64_t getInlineImmVal32(unsigned Imm) {
341  switch (Imm) {
342  case 240:
343  return FloatToBits(0.5f);
344  case 241:
345  return FloatToBits(-0.5f);
346  case 242:
347  return FloatToBits(1.0f);
348  case 243:
349  return FloatToBits(-1.0f);
350  case 244:
351  return FloatToBits(2.0f);
352  case 245:
353  return FloatToBits(-2.0f);
354  case 246:
355  return FloatToBits(4.0f);
356  case 247:
357  return FloatToBits(-4.0f);
358  case 248: // 1 / (2 * PI)
359  return 0x3e22f983;
360  default:
361  llvm_unreachable("invalid fp inline imm");
362  }
363 }
364 
365 static int64_t getInlineImmVal64(unsigned Imm) {
366  switch (Imm) {
367  case 240:
368  return DoubleToBits(0.5);
369  case 241:
370  return DoubleToBits(-0.5);
371  case 242:
372  return DoubleToBits(1.0);
373  case 243:
374  return DoubleToBits(-1.0);
375  case 244:
376  return DoubleToBits(2.0);
377  case 245:
378  return DoubleToBits(-2.0);
379  case 246:
380  return DoubleToBits(4.0);
381  case 247:
382  return DoubleToBits(-4.0);
383  case 248: // 1 / (2 * PI)
384  return 0x3fc45f306dc9c882;
385  default:
386  llvm_unreachable("invalid fp inline imm");
387  }
388 }
389 
390 static int64_t getInlineImmVal16(unsigned Imm) {
391  switch (Imm) {
392  case 240:
393  return 0x3800;
394  case 241:
395  return 0xB800;
396  case 242:
397  return 0x3C00;
398  case 243:
399  return 0xBC00;
400  case 244:
401  return 0x4000;
402  case 245:
403  return 0xC000;
404  case 246:
405  return 0x4400;
406  case 247:
407  return 0xC400;
408  case 248: // 1 / (2 * PI)
409  return 0x3118;
410  default:
411  llvm_unreachable("invalid fp inline imm");
412  }
413 }
414 
418 
419  // ToDo: case 248: 1/(2*PI) - is allowed only on VI
420  switch (Width) {
421  case OPW32:
423  case OPW64:
425  case OPW16:
427  default:
428  llvm_unreachable("implement me");
429  }
430 }
431 
432 unsigned AMDGPUDisassembler::getVgprClassId(const OpWidthTy Width) const {
433  using namespace AMDGPU;
434  assert(OPW_FIRST_ <= Width && Width < OPW_LAST_);
435  switch (Width) {
436  default: // fall
437  case OPW32:
438  case OPW16:
439  return VGPR_32RegClassID;
440  case OPW64: return VReg_64RegClassID;
441  case OPW128: return VReg_128RegClassID;
442  }
443 }
444 
445 unsigned AMDGPUDisassembler::getSgprClassId(const OpWidthTy Width) const {
446  using namespace AMDGPU;
447  assert(OPW_FIRST_ <= Width && Width < OPW_LAST_);
448  switch (Width) {
449  default: // fall
450  case OPW32:
451  case OPW16:
452  return SGPR_32RegClassID;
453  case OPW64: return SGPR_64RegClassID;
454  case OPW128: return SGPR_128RegClassID;
455  }
456 }
457 
458 unsigned AMDGPUDisassembler::getTtmpClassId(const OpWidthTy Width) const {
459  using namespace AMDGPU;
460  assert(OPW_FIRST_ <= Width && Width < OPW_LAST_);
461  switch (Width) {
462  default: // fall
463  case OPW32:
464  case OPW16:
465  return TTMP_32RegClassID;
466  case OPW64: return TTMP_64RegClassID;
467  case OPW128: return TTMP_128RegClassID;
468  }
469 }
470 
471 MCOperand AMDGPUDisassembler::decodeSrcOp(const OpWidthTy Width, unsigned Val) const {
472  using namespace AMDGPU::EncValues;
473  assert(Val < 512); // enum9
474 
475  if (VGPR_MIN <= Val && Val <= VGPR_MAX) {
476  return createRegOperand(getVgprClassId(Width), Val - VGPR_MIN);
477  }
478  if (Val <= SGPR_MAX) {
479  assert(SGPR_MIN == 0); // "SGPR_MIN <= Val" is always true and causes compilation warning.
480  return createSRegOperand(getSgprClassId(Width), Val - SGPR_MIN);
481  }
482  if (TTMP_MIN <= Val && Val <= TTMP_MAX) {
483  return createSRegOperand(getTtmpClassId(Width), Val - TTMP_MIN);
484  }
485 
486  assert(Width == OPW16 || Width == OPW32 || Width == OPW64);
487 
488  if (INLINE_INTEGER_C_MIN <= Val && Val <= INLINE_INTEGER_C_MAX)
489  return decodeIntImmed(Val);
490 
491  if (INLINE_FLOATING_C_MIN <= Val && Val <= INLINE_FLOATING_C_MAX)
492  return decodeFPImmed(Width, Val);
493 
494  if (Val == LITERAL_CONST)
495  return decodeLiteralConstant();
496 
497  switch (Width) {
498  case OPW32:
499  case OPW16:
500  return decodeSpecialReg32(Val);
501  case OPW64:
502  return decodeSpecialReg64(Val);
503  default:
504  llvm_unreachable("unexpected immediate type");
505  }
506 }
507 
509  using namespace AMDGPU;
510  switch (Val) {
511  case 102: return createRegOperand(getMCReg(FLAT_SCR_LO, STI));
512  case 103: return createRegOperand(getMCReg(FLAT_SCR_HI, STI));
513  // ToDo: no support for xnack_mask_lo/_hi register
514  case 104:
515  case 105: break;
516  case 106: return createRegOperand(VCC_LO);
517  case 107: return createRegOperand(VCC_HI);
518  case 108: return createRegOperand(TBA_LO);
519  case 109: return createRegOperand(TBA_HI);
520  case 110: return createRegOperand(TMA_LO);
521  case 111: return createRegOperand(TMA_HI);
522  case 124: return createRegOperand(M0);
523  case 126: return createRegOperand(EXEC_LO);
524  case 127: return createRegOperand(EXEC_HI);
525  // ToDo: no support for vccz register
526  case 251: break;
527  // ToDo: no support for execz register
528  case 252: break;
529  case 253: return createRegOperand(SCC);
530  default: break;
531  }
532  return errOperand(Val, "unknown operand encoding " + Twine(Val));
533 }
534 
536  using namespace AMDGPU;
537  switch (Val) {
538  case 102: return createRegOperand(getMCReg(FLAT_SCR, STI));
539  case 106: return createRegOperand(VCC);
540  case 108: return createRegOperand(TBA);
541  case 110: return createRegOperand(TMA);
542  case 126: return createRegOperand(EXEC);
543  default: break;
544  }
545  return errOperand(Val, "unknown operand encoding " + Twine(Val));
546 }
547 
548 //===----------------------------------------------------------------------===//
549 // AMDGPUSymbolizer
550 //===----------------------------------------------------------------------===//
551 
552 // Try to find symbol name for specified label
554  raw_ostream &/*cStream*/, int64_t Value,
555  uint64_t /*Address*/, bool IsBranch,
556  uint64_t /*Offset*/, uint64_t /*InstSize*/) {
557  typedef std::tuple<uint64_t, StringRef, uint8_t> SymbolInfoTy;
558  typedef std::vector<SymbolInfoTy> SectionSymbolsTy;
559 
560  if (!IsBranch) {
561  return false;
562  }
563 
564  auto *Symbols = static_cast<SectionSymbolsTy *>(DisInfo);
565  auto Result = std::find_if(Symbols->begin(), Symbols->end(),
566  [Value](const SymbolInfoTy& Val) {
567  return std::get<0>(Val) == static_cast<uint64_t>(Value)
568  && std::get<2>(Val) == ELF::STT_NOTYPE;
569  });
570  if (Result != Symbols->end()) {
571  auto *Sym = Ctx.getOrCreateSymbol(std::get<1>(*Result));
572  const auto *Add = MCSymbolRefExpr::create(Sym, Ctx);
574  return true;
575  }
576  return false;
577 }
578 
580  int64_t Value,
581  uint64_t Address) {
582  llvm_unreachable("unimplemented");
583 }
584 
585 //===----------------------------------------------------------------------===//
586 // Initialization
587 //===----------------------------------------------------------------------===//
588 
590  LLVMOpInfoCallback /*GetOpInfo*/,
591  LLVMSymbolLookupCallback /*SymbolLookUp*/,
592  void *DisInfo,
593  MCContext *Ctx,
594  std::unique_ptr<MCRelocationInfo> &&RelInfo) {
595  return new AMDGPUSymbolizer(*Ctx, std::move(RelInfo), DisInfo);
596 }
597 
599  const MCSubtargetInfo &STI,
600  MCContext &Ctx) {
601  return new AMDGPUDisassembler(STI, Ctx);
602 }
603 
609 }
static int64_t getInlineImmVal16(unsigned Imm)
Target & getTheGCNTarget()
The target for GCN GPUs.
bool isValid() const
Definition: MCInst.h:55
#define DECODE_OPERAND(RegClass)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:298
MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const
DecodeStatus
Ternary decode status.
static MCOperand decodeFPImmed(OpWidthTy Width, unsigned Imm)
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:129
Superclass for all disassemblers.
const char *(* LLVMSymbolLookupCallback)(void *DisInfo, uint64_t ReferenceValue, uint64_t *ReferenceType, uint64_t ReferencePC, const char **ReferenceName)
The type for the symbol lookup function.
raw_ostream * CommentStream
MCOperand errOperand(unsigned V, const Twine &ErrMsg) const
static T eatBytes(ArrayRef< uint8_t > &Bytes)
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
MCOperand decodeOperand_VReg_64(unsigned Val) const
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array...
Definition: ArrayRef.h:171
MCOperand createRegOperand(unsigned int RegId) const
MCOperand decodeOperand_VS_64(unsigned Val) const
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
MCOperand decodeOperand_VReg_96(unsigned Val) const
void tryAddingPcLoadReferenceComment(raw_ostream &cStream, int64_t Value, uint64_t Address) override
Try to add a comment on the PC-relative load.
TargetRegisterInfo interface that is implemented by all hw codegen targets.
static int64_t getInlineImmVal32(unsigned Imm)
Context object for machine code objects.
Definition: MCContext.h:51
const MCSubtargetInfo & STI
int decodeInstruction(InternalInstruction *insn, byteReader_t reader, const void *readerArg, dlog_t logger, void *loggerArg, const void *miiArg, uint64_t startLoc, DisassemblerMode mode)
Decode one instruction and store the decoding results in a buffer provided by the consumer...
#define T
MCOperand decodeOperand_VS_32(unsigned Val) const
MCOperand decodeSpecialReg32(unsigned Val) const
MCContext & getContext() const
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:141
static MCSymbolizer * createAMDGPUSymbolizer(const Triple &, LLVMOpInfoCallback, LLVMSymbolLookupCallback, void *DisInfo, MCContext *Ctx, std::unique_ptr< MCRelocationInfo > &&RelInfo)
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
MCOperand decodeOperand_SReg_64_XEXEC(unsigned Val) const
uint32_t FloatToBits(float Float)
FloatToBits - This function takes a float and returns the bit equivalent 32-bit integer.
Definition: MathExtras.h:580
MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val) const
MCOperand decodeOperand_SReg_512(unsigned Val) const
Symbolize and annotate disassembled instructions.
Definition: MCSymbolizer.h:40
AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
MCOperand decodeOperand_SReg_128(unsigned Val) const
APInt sext(unsigned width) const
Sign extend to a new width.
Definition: APInt.cpp:939
DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, uint64_t Inst, uint64_t Address) const
uint32_t Offset
static DecodeStatus decodeSoppBrTarget(MCInst &Inst, unsigned Imm, uint64_t Addr, const void *Decoder)
static int64_t getInlineImmVal64(unsigned Imm)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::MCDisassembler::DecodeStatus DecodeStatus
const char * getRegClassName(unsigned RegClassID) const
MCOperand decodeOperand_VSrc16(unsigned Val) const
MCOperand decodeOperand_SReg_32(unsigned Val) const
MCOperand decodeOperand_VGPR_32(unsigned Val) const
static DecodeStatus decodeOperand_VSrc16(MCInst &Inst, unsigned Imm, uint64_t Addr, const void *Decoder)
uint64_t DoubleToBits(double Double)
DoubleToBits - This function takes a double and returns the bit equivalent 64-bit integer...
Definition: MathExtras.h:569
MCOperand decodeOperand_VReg_128(unsigned Val) const
static MCOperand decodeIntImmed(unsigned Imm)
unsigned getOpcode() const
Definition: MCInst.h:159
Target - Wrapper for Target specific information.
Class for arbitrary precision integers.
Definition: APInt.h:77
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:245
bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream, int64_t Value, uint64_t Address, bool IsBranch, uint64_t Offset, uint64_t InstSize) override
Try to add a symbolic operand instead of Value to the MCInst.
void LLVMInitializeAMDGPUDisassembler()
bool isVI(const MCSubtargetInfo &STI)
unsigned getNumOperands() const
Definition: MCInst.h:166
This file contains declaration for AMDGPU ISA disassembler.
MCOperand decodeSpecialReg64(unsigned Val) const
MCSubtargetInfo - Generic base class for all target subtargets.
unsigned getSgprClassId(const OpWidthTy Width) const
MCOperand decodeOperand_SReg_32_XM0_XEXEC(unsigned Val) const
static void RegisterMCSymbolizer(Target &T, Target::MCSymbolizerCtorTy Fn)
RegisterMCSymbolizer - Register an MCSymbolizer implementation for the given target.
unsigned getTtmpClassId(const OpWidthTy Width) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getVgprClassId(const OpWidthTy Width) const
aarch64 promote const
LLVM Value Representation.
Definition: Value.h:71
MCOperand decodeOperand_SReg_64(unsigned Val) const
unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg...
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
MCOperand decodeLiteralConstant() const
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
MCOperand decodeOperand_SReg_256(unsigned Val) const
DecodeStatus getInstruction(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address, raw_ostream &WS, raw_ostream &CS) const override
Returns the disassembly of a single instruction.
auto find_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:764
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
static MCDisassembler * createAMDGPUDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
int(* LLVMOpInfoCallback)(void *DisInfo, uint64_t PC, uint64_t Offset, uint64_t Size, int TagType, void *TagBuf)
The type for the operand information call back function.
const T * data() const
Definition: ArrayRef.h:138
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117