|
21 | 21 | #include "SIDefines.h"
|
22 | 22 | #include "SIRegisterInfo.h"
|
23 | 23 | #include "TargetInfo/AMDGPUTargetInfo.h"
|
| 24 | +#include "Utils/AMDGPUAsmUtils.h" |
24 | 25 | #include "Utils/AMDGPUBaseInfo.h"
|
25 | 26 | #include "llvm-c/DisassemblerTypes.h"
|
26 | 27 | #include "llvm/BinaryFormat/ELF.h"
|
@@ -52,6 +53,13 @@ AMDGPUDisassembler::AMDGPUDisassembler(const MCSubtargetInfo &STI,
|
52 | 53 | // ToDo: AMDGPUDisassembler supports only VI ISA.
|
53 | 54 | if (!STI.hasFeature(AMDGPU::FeatureGCN3Encoding) && !isGFX10Plus())
|
54 | 55 | report_fatal_error("Disassembly not yet supported for subtarget");
|
| 56 | + |
| 57 | + for (auto [Symbol, Code] : AMDGPU::UCVersion::getGFXVersions()) |
| 58 | + createConstantSymbolExpr(Symbol, Code); |
| 59 | + |
| 60 | + UCVersionW64Expr = createConstantSymbolExpr("UC_VERSION_W64_BIT", 0x2000); |
| 61 | + UCVersionW32Expr = createConstantSymbolExpr("UC_VERSION_W32_BIT", 0x4000); |
| 62 | + UCVersionMDPExpr = createConstantSymbolExpr("UC_VERSION_MDP_BIT", 0x8000); |
55 | 63 | }
|
56 | 64 |
|
57 | 65 | void AMDGPUDisassembler::setABIVersion(unsigned Version) {
|
@@ -421,6 +429,13 @@ DECODE_SDWA(Src32)
|
421 | 429 | DECODE_SDWA(Src16)
|
422 | 430 | DECODE_SDWA(VopcDst)
|
423 | 431 |
|
| 432 | +static DecodeStatus decodeVersionImm(MCInst &Inst, unsigned Imm, |
| 433 | + uint64_t /* Addr */, |
| 434 | + const MCDisassembler *Decoder) { |
| 435 | + auto DAsm = static_cast<const AMDGPUDisassembler *>(Decoder); |
| 436 | + return addOperand(Inst, DAsm->decodeVersionImm(Imm)); |
| 437 | +} |
| 438 | + |
424 | 439 | #include "AMDGPUGenDisassemblerTables.inc"
|
425 | 440 |
|
426 | 441 | //===----------------------------------------------------------------------===//
|
@@ -1727,6 +1742,41 @@ MCOperand AMDGPUDisassembler::decodeDpp8FI(unsigned Val) const {
|
1727 | 1742 | return MCOperand::createImm(Val);
|
1728 | 1743 | }
|
1729 | 1744 |
|
| 1745 | +MCOperand AMDGPUDisassembler::decodeVersionImm(unsigned Imm) const { |
| 1746 | + using VersionField = AMDGPU::EncodingField<7, 0>; |
| 1747 | + using W64Bit = AMDGPU::EncodingBit<13>; |
| 1748 | + using W32Bit = AMDGPU::EncodingBit<14>; |
| 1749 | + using MDPBit = AMDGPU::EncodingBit<15>; |
| 1750 | + using Encoding = AMDGPU::EncodingFields<VersionField, W64Bit, W32Bit, MDPBit>; |
| 1751 | + |
| 1752 | + auto [Version, W64, W32, MDP] = Encoding::decode(Imm); |
| 1753 | + |
| 1754 | + // Decode into a plain immediate if any unused bits are raised. |
| 1755 | + if (Encoding::encode(Version, W64, W32, MDP) != Imm) |
| 1756 | + return MCOperand::createImm(Imm); |
| 1757 | + |
| 1758 | + const auto &Versions = AMDGPU::UCVersion::getGFXVersions(); |
| 1759 | + auto I = find_if(Versions, |
| 1760 | + [Version = Version](const AMDGPU::UCVersion::GFXVersion &V) { |
| 1761 | + return V.Code == Version; |
| 1762 | + }); |
| 1763 | + MCContext &Ctx = getContext(); |
| 1764 | + const MCExpr *E; |
| 1765 | + if (I == Versions.end()) |
| 1766 | + E = MCConstantExpr::create(Version, Ctx); |
| 1767 | + else |
| 1768 | + E = MCSymbolRefExpr::create(Ctx.getOrCreateSymbol(I->Symbol), Ctx); |
| 1769 | + |
| 1770 | + if (W64) |
| 1771 | + E = MCBinaryExpr::createOr(E, UCVersionW64Expr, Ctx); |
| 1772 | + if (W32) |
| 1773 | + E = MCBinaryExpr::createOr(E, UCVersionW32Expr, Ctx); |
| 1774 | + if (MDP) |
| 1775 | + E = MCBinaryExpr::createOr(E, UCVersionMDPExpr, Ctx); |
| 1776 | + |
| 1777 | + return MCOperand::createExpr(E); |
| 1778 | +} |
| 1779 | + |
1730 | 1780 | bool AMDGPUDisassembler::isVI() const {
|
1731 | 1781 | return STI.hasFeature(AMDGPU::FeatureVolcanicIslands);
|
1732 | 1782 | }
|
@@ -2312,6 +2362,15 @@ Expected<bool> AMDGPUDisassembler::onSymbolStart(SymbolInfoTy &Symbol,
|
2312 | 2362 | return false;
|
2313 | 2363 | }
|
2314 | 2364 |
|
| 2365 | +const MCExpr *AMDGPUDisassembler::createConstantSymbolExpr(StringRef Id, |
| 2366 | + int64_t Val) { |
| 2367 | + MCContext &Ctx = getContext(); |
| 2368 | + MCSymbol *Sym = Ctx.getOrCreateSymbol(Id); |
| 2369 | + assert(!Sym->isVariable()); |
| 2370 | + Sym->setVariableValue(MCConstantExpr::create(Val, Ctx)); |
| 2371 | + return MCSymbolRefExpr::create(Sym, Ctx); |
| 2372 | +} |
| 2373 | + |
2315 | 2374 | //===----------------------------------------------------------------------===//
|
2316 | 2375 | // AMDGPUSymbolizer
|
2317 | 2376 | //===----------------------------------------------------------------------===//
|
|
0 commit comments