Index: lib/Target/AMDGPU/AMDGPUInstructions.td =================================================================== --- lib/Target/AMDGPU/AMDGPUInstructions.td +++ lib/Target/AMDGPU/AMDGPUInstructions.td @@ -23,6 +23,14 @@ let Pattern = pattern; let Itinerary = NullALU; + // SoftFail is a field the disassembler can use to provide a way for + // instructions to not match without killing the whole decode process. It is + // mainly used for ARM, but Tablegen expects this field to exist or it fails + // to build the decode table. + field bits<64> SoftFail = 0; + + let DecoderNamespace = Namespace; + let TSFlags{63} = isRegisterLoad; let TSFlags{62} = isRegisterStore; } Index: lib/Target/AMDGPU/CIInstructions.td =================================================================== --- lib/Target/AMDGPU/CIInstructions.td +++ lib/Target/AMDGPU/CIInstructions.td @@ -100,9 +100,11 @@ // MUBUF Instructions //===----------------------------------------------------------------------===// +let DisableSIDecoder = 1 in { defm BUFFER_WBINVL1_VOL : MUBUF_Invalidate , "buffer_wbinvl1_vol", int_amdgcn_buffer_wbinvl1_vol >; +} //===----------------------------------------------------------------------===// // Flat Instructions @@ -233,7 +235,7 @@ // CI Only flat instructions -let SubtargetPredicate = isCI, VIAssemblerPredicate = DisableInst in { +let SubtargetPredicate = isCI, VIAssemblerPredicate = DisableInst, DisableVIDecoder = 1 in { defm FLAT_ATOMIC_FCMPSWAP : FLAT_ATOMIC < flat<0x3e>, "flat_atomic_fcmpswap", VGPR_32, VReg_64 @@ -254,7 +256,7 @@ flat<0x60>, "flat_atomic_fmax_x2", VReg_64 >; -} // End SubtargetPredicate = isCI, VIAssemblerPredicate = DisableInst +} // End SubtargetPredicate = isCI, VIAssemblerPredicate = DisableInst, DisableVIDecoder = 1 let Predicates = [isCI] in { Index: lib/Target/AMDGPU/CMakeLists.txt =================================================================== --- lib/Target/AMDGPU/CMakeLists.txt +++ lib/Target/AMDGPU/CMakeLists.txt @@ -10,6 +10,7 @@ tablegen(LLVM AMDGPUGenDFAPacketizer.inc -gen-dfa-packetizer) tablegen(LLVM AMDGPUGenAsmWriter.inc -gen-asm-writer) tablegen(LLVM AMDGPUGenAsmMatcher.inc -gen-asm-matcher) +tablegen(LLVM AMDGPUGenDisassemblerTables.inc -gen-disassembler) add_public_tablegen_target(AMDGPUCommonTableGen) add_llvm_target(AMDGPUCodeGen @@ -65,6 +66,7 @@ add_subdirectory(AsmParser) add_subdirectory(InstPrinter) +add_subdirectory(Disassembler) add_subdirectory(TargetInfo) add_subdirectory(MCTargetDesc) add_subdirectory(Utils) Index: lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h =================================================================== --- /dev/null +++ lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h @@ -0,0 +1,80 @@ +//===-- AMDGPUDisassembler.hpp - Disassembler for AMDGPU ISA ---*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// \file +/// +/// This file contains declaration for AMDGPU ISA disassembler +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H +#define LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H + +#include "llvm/MC/MCDisassembler/MCDisassembler.h" + +namespace llvm { + + class MCContext; + class MCInst; + class MCSubtargetInfo; + + class AMDGPUDisassembler : public MCDisassembler { + private: + /// true if 32-bit literal constant is placed after instruction + mutable bool HasLiteral; + mutable ArrayRef Bytes; + + public: + AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) : + MCDisassembler(STI, Ctx), HasLiteral(false) {} + + ~AMDGPUDisassembler() {} + + DecodeStatus getInstruction(MCInst &MI, uint64_t &Size, + ArrayRef Bytes, uint64_t Address, + raw_ostream &WS, raw_ostream &CS) const override; + + /// Decode inline float value in SRC field + DecodeStatus DecodeImmedFloat(unsigned Imm, uint32_t &F) const; + /// Decode inline double value in SRC field + DecodeStatus DecodeImmedDouble(unsigned Imm, uint64_t &D) const; + /// Decode inline integer value in SRC field + DecodeStatus DecodeImmedInteger(unsigned Imm, int64_t &I) const; + /// Decode VGPR register + DecodeStatus DecodeVgprRegister(unsigned Val, unsigned &RegID, + unsigned Size = 32) const; + /// Decode SGPR register + DecodeStatus DecodeSgprRegister(unsigned Val, unsigned &RegID, + unsigned Size = 32) const; + /// Decode 32-bit register in SRC field + DecodeStatus DecodeSrc32Register(unsigned Val, unsigned &RegID) const; + /// Decode 64-bit register in SRC field + DecodeStatus DecodeSrc64Register(unsigned Val, unsigned &RegID) const; + + /// Decode literal constant after instruction + DecodeStatus DecodeLiteralConstant(MCInst &Inst, uint64_t &Literal) const; + + DecodeStatus DecodeVGPR_32RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr) const; + + DecodeStatus DecodeVSRegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr, bool Is32) const; + + DecodeStatus DecodeVS_32RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr) const; + + DecodeStatus DecodeVS_64RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr) const; + + DecodeStatus DecodeVReg_64RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr) const; + }; +} // namespace llvm + +#endif LLVM_LIB_TARGET_AMDGPU_DISASSEMBLER_AMDGPUDISASSEMBLER_H \ No newline at end of file Index: lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp =================================================================== --- /dev/null +++ lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -0,0 +1,472 @@ +//===-- AMDGPUDisassembler.cpp - Disassembler for AMDGPU ISA --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// +// +/// \file +/// +/// This file contains definition for AMDGPU ISA disassembler +// +//===----------------------------------------------------------------------===// + +// ToDo: What to do with instruction suffixes (v_mov_b32 vs v_mov_b32_e32)? + +#include "AMDGPUDisassembler.h" +#include "AMDGPU.h" +#include "AMDGPURegisterInfo.h" +#include "Utils/AMDGPUBaseInfo.h" + +#include "llvm/MC/MCFixedLenDisassembler.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/TargetRegistry.h" + + +using namespace llvm; + +#define DEBUG_TYPE "amdgpu-disassembler" + +typedef llvm::MCDisassembler::DecodeStatus DecodeStatus; + + +static DecodeStatus DecodeVGPR_32RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + const AMDGPUDisassembler *Dis = + static_cast(Decoder); + return Dis->DecodeVGPR_32RegisterClass(Inst, Imm, Addr); +} + +static DecodeStatus DecodeVS_32RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + const AMDGPUDisassembler *Dis = + static_cast(Decoder); + return Dis->DecodeVS_32RegisterClass(Inst, Imm, Addr); +} + +static DecodeStatus DecodeVS_64RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + const AMDGPUDisassembler *Dis = + static_cast(Decoder); + return Dis->DecodeVS_64RegisterClass(Inst, Imm, Addr); +} + +static DecodeStatus DecodeVReg_64RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + const AMDGPUDisassembler *Dis = + static_cast(Decoder); + return Dis->DecodeVReg_64RegisterClass(Inst, Imm, Addr); +} + +static DecodeStatus DecodeVReg_96RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + // ToDo + return MCDisassembler::Fail; +} + +static DecodeStatus DecodeVReg_128RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + // ToDo + return MCDisassembler::Fail; +} + +static DecodeStatus DecodeSGPR_32RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + // ToDo + return MCDisassembler::Fail; +} + +static DecodeStatus DecodeSReg_32RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + // ToDo + return MCDisassembler::Fail; +} + +static DecodeStatus DecodeSReg_64RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + // ToDo + return MCDisassembler::Fail; +} + +static DecodeStatus DecodeSReg_128RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + // ToDo + return MCDisassembler::Fail; +} + +static DecodeStatus DecodeSReg_256RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + // ToDo + return MCDisassembler::Fail; +} + +static DecodeStatus DecodeSReg_512RegisterClass(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + // ToDo + return MCDisassembler::Fail; +} + + +#define GET_SUBTARGETINFO_ENUM +#include "AMDGPUGenSubtargetInfo.inc" +#undef GET_SUBTARGETINFO_ENUM + +#include "AMDGPUGenDisassemblerTables.inc" + +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size, + ArrayRef Bytes, + uint64_t Address, + raw_ostream &WS, + raw_ostream &CS) const { + CommentStream = &CS; + + // ToDo: AMDGPUDisassembler supports only VI ISA. + assert(AMDGPU::isVI(STI) && "Can disassemble only VI ISA."); + + HasLiteral = false; + this->Bytes = Bytes; + + // Try decode 32-bit instruction + if (Bytes.size() < 4) { + Size = 0; + return MCDisassembler::Fail; + } + uint32_t Insn = + (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0); + + // Calling the auto-generated decoder function. + DecodeStatus Result = + decodeInstruction(DecoderTableVI32, MI, Insn, Address, this, STI); + if (Result != MCDisassembler::Success) { + Size = 0; + return MCDisassembler::Fail; + } + if (HasLiteral == true) { + Size = 8; + HasLiteral = false; + } else { + Size = 4; + } + + return MCDisassembler::Success; +} + +DecodeStatus AMDGPUDisassembler::DecodeImmedFloat(unsigned Imm, uint32_t &F) const { + // ToDo: case 248: 1/(2*PI) - is allowed only on VI + // ToDo: AMDGPUInstPrinter does not support 1/(2*PI). It consider 1/(2*PI) as + // literal constant. + switch(Imm) { + case 240: F = FloatToBits(0.5f); return MCDisassembler::Success; + case 241: F = FloatToBits(-0.5f); return MCDisassembler::Success; + case 242: F = FloatToBits(1.0f); return MCDisassembler::Success; + case 243: F = FloatToBits(-1.0f); return MCDisassembler::Success; + case 244: F = FloatToBits(2.0f); return MCDisassembler::Success; + case 245: F = FloatToBits(-2.0f); return MCDisassembler::Success; + case 246: F = FloatToBits(4.0f); return MCDisassembler::Success; + case 247: F = FloatToBits(-4.0f); return MCDisassembler::Success; + case 248: F = 0x3e22f983; return MCDisassembler::Success; // 1/(2*PI) + default: return MCDisassembler::Fail; + } +} + +DecodeStatus AMDGPUDisassembler::DecodeImmedDouble(unsigned Imm, uint64_t &D) const { + switch(Imm) { + case 240: D = DoubleToBits(0.5); return MCDisassembler::Success; + case 241: D = DoubleToBits(-0.5); return MCDisassembler::Success; + case 242: D = DoubleToBits(1.0); return MCDisassembler::Success; + case 243: D = DoubleToBits(-1.0); return MCDisassembler::Success; + case 244: D = DoubleToBits(2.0); return MCDisassembler::Success; + case 245: D = DoubleToBits(-2.0); return MCDisassembler::Success; + case 246: D = DoubleToBits(4.0); return MCDisassembler::Success; + case 247: D = DoubleToBits(-4.0); return MCDisassembler::Success; + case 248: D = 0x3fc45f306dc9c882; return MCDisassembler::Success; // 1/(2*PI) + default: return MCDisassembler::Fail; + } +} + +DecodeStatus AMDGPUDisassembler::DecodeImmedInteger(unsigned Imm, + int64_t &I) const { + if ((Imm >= 128) && (Imm <= 192)) { + I = Imm - 128; + return MCDisassembler::Success; + } else if ((Imm >= 193) && (Imm <= 208)) { + I = 192 - Imm; + return MCDisassembler::Success; + } + return MCDisassembler::Fail; +} + +DecodeStatus AMDGPUDisassembler::DecodeVgprRegister(unsigned Val, + unsigned &RegID, + unsigned Size) const { + if (Val > (256 - Size / 32)) { + return MCDisassembler::Fail; + } + unsigned RegClassID; + switch (Size) { + case 32: RegClassID = AMDGPU::VGPR_32RegClassID; break; + case 64: RegClassID = AMDGPU::VReg_64RegClassID; break; + case 96: RegClassID = AMDGPU::VReg_96RegClassID; break; + case 128: RegClassID = AMDGPU::VReg_128RegClassID; break; + case 256: RegClassID = AMDGPU::VReg_256RegClassID; break; + case 512: RegClassID = AMDGPU::VReg_512RegClassID; break; + default: + return MCDisassembler::Fail; + } + + RegID = AMDGPUMCRegisterClasses[RegClassID].getRegister(Val); + return MCDisassembler::Success; +} + +DecodeStatus AMDGPUDisassembler::DecodeSgprRegister(unsigned Val, + unsigned &RegID, + unsigned Size) const { + // ToDo: SI/CI have 104 SGPRs, VI - 102 + unsigned RegClassID; + + switch (Size) { + case 32: + if (Val > 101) { + return MCDisassembler::Fail; + } + RegClassID = AMDGPU::SGPR_32RegClassID; + break; + case 64: + if ((Val % 2 != 0) || (Val > 100)) { + return MCDisassembler::Fail; + } + Val /= 2; + RegClassID = AMDGPU::SGPR_64RegClassID; + break; + case 128: + // ToDo: unclear if s[100:104] is available on VI. Can we use VCC as SGPR in + // this bundle? + if ((Val % 4 != 0) || (Val > 96)) { + return MCDisassembler::Fail; + } + Val /= 4; + RegClassID = AMDGPU::SReg_128RegClassID; + break; + case 256: + // ToDo: unclear if s[96:104] is available on VI. Can we use VCC as SGPR in + // this bundle? + if ((Val % 4 != 0) || (Val > 92)) { + return MCDisassembler::Fail; + } + Val /= 4; + RegClassID = AMDGPU::SReg_256RegClassID; + break; + case 512: + // ToDo: unclear if s[88:104] is available on VI. Can we use VCC as SGPR in + // this bundle? + if ((Val % 4 != 0) || (Val > 84)) { + return MCDisassembler::Fail; + } + Val /= 4; + RegClassID = AMDGPU::SReg_512RegClassID; + break; + default: + return MCDisassembler::Fail; + } + + RegID = AMDGPUMCRegisterClasses[RegClassID].getRegister(Val); + return MCDisassembler::Success; +} + +DecodeStatus AMDGPUDisassembler::DecodeSrc32Register(unsigned Val, + unsigned &RegID) const { + // ToDo: deal with out-of range registers + using namespace AMDGPU; + if (Val <= 101) { + return DecodeSgprRegister(Val, RegID, 32); + } else if ((Val >= 256) && (Val <= 511)) { + return DecodeVgprRegister(Val - 256, RegID, 32); + } else { + switch(Val) { + case 102: RegID = getMCReg(FLAT_SCR_LO, STI); return MCDisassembler::Success; + case 103: RegID = getMCReg(FLAT_SCR_HI, STI); return MCDisassembler::Success; + // ToDo: no support for xnack_mask_lo/_hi register + case 104: + case 105: return MCDisassembler::Fail; + case 106: RegID = getMCReg(VCC_LO, STI); return MCDisassembler::Success; + case 107: RegID = getMCReg(VCC_HI, STI); return MCDisassembler::Success; + // ToDo: no support for tba_lo/_hi register + case 108: + case 109: return MCDisassembler::Fail; + // ToDo: no support for tma_lo/_hi register + case 110: + case 111: return MCDisassembler::Fail; + // ToDo: no support for ttmp[0:11] register + case 112: + case 113: + case 114: + case 115: + case 116: + case 117: + case 118: + case 119: + case 120: + case 121: + case 122: + case 123: return MCDisassembler::Fail; + case 124: RegID = getMCReg(M0, STI); return MCDisassembler::Success; + case 126: RegID = getMCReg(EXEC_LO, STI); return MCDisassembler::Success; + case 127: RegID = getMCReg(EXEC_HI, STI); return MCDisassembler::Success; + // ToDo: no support for vccz register + case 251: return MCDisassembler::Fail; + // ToDo: no support for execz register + case 252: return MCDisassembler::Fail; + case 253: RegID = getMCReg(SCC, STI); return MCDisassembler::Success; + default: return MCDisassembler::Fail; + } + } + return MCDisassembler::Fail; +} + +DecodeStatus AMDGPUDisassembler::DecodeSrc64Register(unsigned Val, + unsigned &RegID) const { + // ToDo: deal with out-of range registers + using namespace AMDGPU; + if (Val <= 101) { + return DecodeSgprRegister(Val, RegID, 64); + } else if ((Val >= 256) && (Val <= 511)) { + return DecodeVgprRegister(Val - 256, RegID, 64); + } else { + switch(Val) { + case 102: RegID = getMCReg(FLAT_SCR, STI); return MCDisassembler::Success; + case 106: RegID = getMCReg(VCC, STI); return MCDisassembler::Success; + case 126: RegID = getMCReg(EXEC, STI); return MCDisassembler::Success; + default: return MCDisassembler::Fail; + } + } + return MCDisassembler::Fail; +} + +DecodeStatus AMDGPUDisassembler::DecodeLiteralConstant(MCInst &Inst, + uint64_t &Literal) const { + // For now all literal constants are supposed to be unsigned integer + // ToDo: deal with signed/unsigned 64-bit integer constants + // ToDo: deal with float/double constants + if (Bytes.size() < 8) { + return MCDisassembler::Fail; + } + Literal = + 0 | (Bytes[7] << 24) | (Bytes[6] << 16) | (Bytes[5] << 8) | (Bytes[4] << 0); + return MCDisassembler::Success; +} + +DecodeStatus AMDGPUDisassembler::DecodeVGPR_32RegisterClass(llvm::MCInst &Inst, + unsigned Imm, + uint64_t Addr) const { + unsigned RegID; + if (DecodeVgprRegister(Imm, RegID) == MCDisassembler::Success) { + Inst.addOperand(MCOperand::createReg(RegID)); + return MCDisassembler::Success; + } + return MCDisassembler::Fail; +} + +DecodeStatus AMDGPUDisassembler::DecodeVSRegisterClass(MCInst &Inst, + unsigned Imm, + uint64_t Addr, + bool Is32) const { + // ToDo: different opcodes allow different formats of this operands + if ((Imm >= 128) && (Imm <= 208)) { + // immediate integer + int64_t Val; + if (DecodeImmedInteger(Imm, Val) == MCDisassembler::Success) { + Inst.addOperand(MCOperand::createImm(Val)); + return MCDisassembler::Success; + } + } else if ((Imm >= 240) && (Imm <= 248)) { + // immediate float/double + uint64_t Val; + DecodeStatus status; + if (Is32) { + uint32_t Val32; + status = DecodeImmedFloat(Imm, Val32); + Val = static_cast(Val32); + } else { + status = DecodeImmedDouble(Imm, Val); + } + if (status == MCDisassembler::Success) { + Inst.addOperand(MCOperand::createImm(Val)); + return MCDisassembler::Success; + } + } else if (Imm == 254) { + // LDS direct + // ToDo: implement LDS direct read + } else if (Imm == 255) { + // literal constant + HasLiteral = true; + uint64_t Literal; + if (DecodeLiteralConstant(Inst, Literal) == MCDisassembler::Success) { + Inst.addOperand(MCOperand::createImm(Literal)); + return MCDisassembler::Success; + } + return MCDisassembler::Fail; + } else if ((Imm == 125) || + ((Imm >= 209) && (Imm <= 239)) || + (Imm == 249) || + (Imm == 250) || + (Imm >= 512)) { + // reserved + return MCDisassembler::Fail; + } else { + // register + unsigned RegID; + DecodeStatus status = Is32 ? DecodeSrc32Register(Imm, RegID) + : DecodeSrc64Register(Imm, RegID); + if (status == MCDisassembler::Success) { + Inst.addOperand(MCOperand::createReg(RegID)); + return MCDisassembler::Success; + } + } + return MCDisassembler::Fail; +} + +DecodeStatus AMDGPUDisassembler::DecodeVS_32RegisterClass(MCInst &Inst, + unsigned Imm, + uint64_t Addr) const { + return DecodeVSRegisterClass(Inst, Imm, Addr, true); +} + +DecodeStatus AMDGPUDisassembler::DecodeVS_64RegisterClass(MCInst &Inst, + unsigned Imm, + uint64_t Addr) const { + return DecodeVSRegisterClass(Inst, Imm, Addr, false); +} + +DecodeStatus AMDGPUDisassembler::DecodeVReg_64RegisterClass(llvm::MCInst &Inst, + unsigned Imm, + uint64_t Addr) const { + unsigned RegID; + if (DecodeVgprRegister(Imm, RegID, 64) == MCDisassembler::Success) { + Inst.addOperand(MCOperand::createReg(RegID)); + return MCDisassembler::Success; + } + return MCDisassembler::Fail; +} + + + +static MCDisassembler *createAMDGPUDisassembler(const Target &T, + const MCSubtargetInfo &STI, + MCContext &Ctx) { + return new AMDGPUDisassembler(STI, Ctx); +} + +extern "C" void LLVMInitializeAMDGPUDisassembler() { + TargetRegistry::RegisterMCDisassembler(TheGCNTarget, createAMDGPUDisassembler); +} Index: lib/Target/AMDGPU/Disassembler/CMakeLists.txt =================================================================== --- /dev/null +++ lib/Target/AMDGPU/Disassembler/CMakeLists.txt @@ -0,0 +1,7 @@ +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +add_llvm_library(LLVMAMDGPUDisassembler + AMDGPUDisassembler.cpp + ) + +add_dependencies(LLVMAMDGPUDisassembler AMDGPUCommonTableGen) Index: lib/Target/AMDGPU/Disassembler/LLVMBuild.txt =================================================================== --- /dev/null +++ lib/Target/AMDGPU/Disassembler/LLVMBuild.txt @@ -0,0 +1,23 @@ +;===- ./lib/Target/AMDGPU/Disassembler/LLVMBuild.txt ------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = AMDGPUDisassembler +parent = AMDGPU +required_libraries = AMDGPUDesc AMDGPUInfo AMDGPUUtils MC MCDisassembler Support +add_to_library_groups = AMDGPU Index: lib/Target/AMDGPU/LLVMBuild.txt =================================================================== --- lib/Target/AMDGPU/LLVMBuild.txt +++ lib/Target/AMDGPU/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = AsmParser InstPrinter MCTargetDesc TargetInfo Utils +subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo Utils [component_0] type = TargetGroup @@ -24,6 +24,7 @@ parent = Target has_asmparser = 1 has_asmprinter = 1 +has_disassembler = 1 [component_1] type = Library Index: lib/Target/AMDGPU/SIInstrFormats.td =================================================================== --- lib/Target/AMDGPU/SIInstrFormats.td +++ lib/Target/AMDGPU/SIInstrFormats.td @@ -75,6 +75,12 @@ let TSFlags{22} = VOPAsmPrefer32Bit; let SchedRW = [Write32Bit]; + + field bits<1> DisableSIDecoder = 0; + field bits<1> DisableVIDecoder = 0; + field bits<1> DisableDecoder = 0; + + let isAsmParserOnly = !if(!eq(DisableDecoder{0}, {0}), 0, 1); } class Enc32 { @@ -362,8 +368,7 @@ let Inst{63-32} = src2; } -class VOP3e op> : Enc64 { - bits<8> vdst; +class VOP3a op> : Enc64 { bits<2> src0_modifiers; bits<9> src0; bits<2> src1_modifiers; @@ -373,7 +378,6 @@ bits<1> clamp; bits<2> omod; - let Inst{7-0} = vdst; let Inst{8} = src0_modifiers{1}; let Inst{9} = src1_modifiers{1}; let Inst{10} = src2_modifiers{1}; @@ -389,6 +393,20 @@ let Inst{63} = src2_modifiers{0}; } +class VOP3e op> : VOP3a { + bits<8> vdst; + + let Inst{7-0} = vdst; +} + +// Encoding used for VOPC instructions encoded as VOP3 +// Differs from VOP3e by destination name (sdst) as VOPC doesn't have vector dst +class VOP3ce op> : VOP3a { + bits<8> sdst; + + let Inst{7-0} = sdst; +} + class VOP3be op> : Enc64 { bits<8> vdst; bits<2> src0_modifiers; Index: lib/Target/AMDGPU/SIInstrInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.cpp +++ lib/Target/AMDGPU/SIInstrInfo.cpp @@ -1244,7 +1244,7 @@ } } - const MachineOperand *Dst = getNamedOperand(*MI, AMDGPU::OpName::dst); + const MachineOperand *Dst = getNamedOperand(*MI, AMDGPU::OpName::vdst); const MachineOperand *Src0 = getNamedOperand(*MI, AMDGPU::OpName::src0); const MachineOperand *Src1 = getNamedOperand(*MI, AMDGPU::OpName::src1); const MachineOperand *Src2 = getNamedOperand(*MI, AMDGPU::OpName::src2); Index: lib/Target/AMDGPU/SIInstrInfo.td =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.td +++ lib/Target/AMDGPU/SIInstrInfo.td @@ -680,9 +680,15 @@ def "" : EXPCommon, SIMCInstr <"exp", SISubtarget.NONE> ; } - def _si : EXPCommon, SIMCInstr <"exp", SISubtarget.SI>, EXPe; + def _si : EXPCommon, SIMCInstr <"exp", SISubtarget.SI>, EXPe { + let DecoderNamespace="SICI"; + let DisableDecoder = DisableSIDecoder; + } - def _vi : EXPCommon, SIMCInstr <"exp", SISubtarget.VI>, EXPe_vi; + def _vi : EXPCommon, SIMCInstr <"exp", SISubtarget.VI>, EXPe_vi { + let DecoderNamespace="VI"; + let DisableDecoder = DisableVIDecoder; + } } //===----------------------------------------------------------------------===// @@ -702,6 +708,8 @@ SIMCInstr { let isCodeGenOnly = 0; let AssemblerPredicates = [isSICI]; + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; } class SOP1_Real_vi : @@ -710,6 +718,8 @@ SIMCInstr { let isCodeGenOnly = 0; let AssemblerPredicates = [isVI]; + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; } multiclass SOP1_m , SIMCInstr { let AssemblerPredicates = [isSICI]; + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; } class SOP2_Real_vi : @@ -795,6 +807,8 @@ SOP2e, SIMCInstr { let AssemblerPredicates = [isVI]; + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; } multiclass SOP2_m , SIMCInstr { let AssemblerPredicates = [isSICI]; + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; let isCodeGenOnly = 0; } @@ -856,6 +872,8 @@ SOPKe , SIMCInstr { let AssemblerPredicates = [isVI]; + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; let isCodeGenOnly = 0; } @@ -912,6 +930,8 @@ SOPK64e , SIMCInstr { let AssemblerPredicates = [isSICI]; + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; let isCodeGenOnly = 0; } @@ -919,6 +939,8 @@ SOPK64e , SIMCInstr { let AssemblerPredicates = [isVI]; + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; let isCodeGenOnly = 0; } } @@ -939,6 +961,8 @@ SMRDe , SIMCInstr { let AssemblerPredicates = [isSICI]; + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; } class SMRD_Real_vi op, string opName, bit imm, dag outs, dag ins, @@ -947,6 +971,8 @@ SMEMe_vi , SIMCInstr { let AssemblerPredicates = [isVI]; + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; } multiclass SMRD_m , SMRD_IMMe_ci { let AssemblerPredicates = [isCIOnly]; + let DecoderNamespace = "CI"; } defm _SGPR : SMRD_m < @@ -1093,6 +1120,10 @@ bit HasModifiers> { dag ret = + !if (!eq(NumSrcArgs, 0), + // VOP1 without input operands (V_NOP, V_CLREXCP) + (ins), + /* else */ !if (!eq(NumSrcArgs, 1), !if (!eq(HasModifiers, 1), // VOP1 with modifiers @@ -1122,14 +1153,14 @@ /* else */, // VOP3 without modifiers (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2) - /* endif */ ))); + /* endif */ )))); } // Returns the assembly string for the inputs and outputs of a VOP[12C] // instruction. This does not add the _e32 suffix, so it can be reused // by getAsm64. -class getAsm32 { - string dst = "$dst"; +class getAsm32 { + string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC string src0 = ", $src0"; string src1 = ", $src1"; string src2 = ", $src2"; @@ -1141,7 +1172,8 @@ // Returns the assembly string for the inputs and outputs of a VOP3 // instruction. -class getAsm64 { +class getAsm64 { + string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); string src1 = !if(!eq(NumSrcArgs, 1), "", !if(!eq(NumSrcArgs, 2), " $src1_modifiers", @@ -1149,8 +1181,8 @@ string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", ""); string ret = !if(!eq(HasModifiers, 0), - getAsm32.ret, - "$dst, "#src0#src1#src2#"$clamp"#"$omod"); + getAsm32.ret, + dst#", "#src0#src1#src2#"$clamp"#"$omod"); } class VOPProfile _ArgVT> { @@ -1173,7 +1205,7 @@ field int NumSrcArgs = getNumSrcArgs.ret; field bit HasModifiers = hasModifiers.ret; - field dag Outs = !if(HasDst,(outs DstRC:$dst),(outs)); + field dag Outs = !if(HasDst,(outs DstRC:$vdst),(outs)); // VOP3b instructions are a special case with a second explicit // output. This is manually overridden for them. @@ -1184,8 +1216,8 @@ field dag Ins64 = getIns64.ret; - field string Asm32 = getAsm32.ret; - field string Asm64 = getAsm64.ret; + field string Asm32 = getAsm32.ret; + field string Asm64 = getAsm64.ret; } // FIXME: I think these F16/I16 profiles will need to use f16/i16 types in order @@ -1220,10 +1252,10 @@ // Write out to vcc or arbitrary SGPR. def VOP2b_I32_I1_I32_I32 : VOPProfile<[i32, i32, i32, untyped]> { - let Asm32 = "$dst, vcc, $src0, $src1"; - let Asm64 = "$dst, $sdst, $src0, $src1"; - let Outs32 = (outs DstRC:$dst); - let Outs64 = (outs DstRC:$dst, SReg_64:$sdst); + let Asm32 = "$vdst, vcc, $src0, $src1"; + let Asm64 = "$vdst, $sdst, $src0, $src1"; + let Outs32 = (outs DstRC:$vdst); + let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst); } // Write out to vcc or arbitrary SGPR and read in from vcc or @@ -1235,10 +1267,10 @@ // restriction. SGPRs are still allowed because it should // technically be possible to use VCC again as src0. let Src0RC32 = VCSrc_32; - let Asm32 = "$dst, vcc, $src0, $src1, vcc"; - let Asm64 = "$dst, $sdst, $src0, $src1, $src2"; - let Outs32 = (outs DstRC:$dst); - let Outs64 = (outs DstRC:$dst, SReg_64:$sdst); + let Asm32 = "$vdst, vcc, $src0, $src1, vcc"; + let Asm64 = "$vdst, $sdst, $src0, $src1, $src2"; + let Outs32 = (outs DstRC:$vdst); + let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst); // Suppress src2 implied by type since the 32-bit encoding uses an // implicit VCC use. @@ -1267,11 +1299,12 @@ let Asm32 = "vcc, $src0, $src1"; // The destination for 32-bit encoding is implicit. let HasDst32 = 0; + let Outs64 = (outs DstRC:$sdst); } class VOPC_Class_Profile : VOPC_Profile { let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1); - let Asm64 = "$dst, $src0_modifiers, $src1"; + let Asm64 = "$sdst, $src0_modifiers, $src1"; } def VOPC_I1_F32_F32 : VOPC_Profile; @@ -1288,25 +1321,26 @@ def VOP_CNDMASK : VOPProfile <[i32, i32, i32, untyped]> { let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1); let Ins64 = (ins Src0RC64:$src0, Src1RC64:$src1, SSrc_64:$src2); - let Asm64 = "$dst, $src0, $src1, $src2"; + let Asm64 = "$vdst, $src0, $src1, $src2"; } def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>; def VOP_MADK : VOPProfile <[f32, f32, f32, f32]> { field dag Ins = (ins VCSrc_32:$src0, VGPR_32:$vsrc1, u32imm:$src2); - field string Asm = "$dst, $src0, $vsrc1, $src2"; + field string Asm = "$vdst, $src0, $vsrc1, $src2"; } def VOP_MAC : VOPProfile <[f32, f32, f32, f32]> { let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VGPR_32:$src2); let Ins64 = getIns64, 3, HasModifiers>.ret; - let Asm32 = getAsm32<1, 2>.ret; - let Asm64 = getAsm64<1, 2, HasModifiers>.ret; + let Asm32 = getAsm32<1, f32, 2>.ret; + let Asm64 = getAsm64<1, f32, 2, HasModifiers>.ret; } def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>; def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>; def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>; +// This class is used only with VOPC instructions. Use $sdst for out operand class SIInstAlias : InstAlias , PredicateControl { @@ -1317,13 +1351,13 @@ !if (p.HasDst32, !if (!eq(p.NumSrcArgs, 0), // 1 dst, 0 src - (inst p.DstRC:$dst), + (inst p.DstRC:$sdst), !if (!eq(p.NumSrcArgs, 1), // 1 dst, 1 src - (inst p.DstRC:$dst, p.Src0RC32:$src0), + (inst p.DstRC:$sdst, p.Src0RC32:$src0), !if (!eq(p.NumSrcArgs, 2), // 1 dst, 2 src - (inst p.DstRC:$dst, p.Src0RC32:$src0, p.Src1RC32:$src1), + (inst p.DstRC:$sdst, p.Src0RC32:$src0, p.Src1RC32:$src1), // else - unreachable (inst)))), // else @@ -1385,12 +1419,16 @@ VOP1, SIMCInstr { let AssemblerPredicate = SIAssemblerPredicate; + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; } class VOP1_Real_vi : VOP1, SIMCInstr { let AssemblerPredicates = [isVI]; + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; } multiclass VOP1_m pattern, @@ -1424,12 +1462,16 @@ VOP2 , SIMCInstr { let AssemblerPredicates = [isSICI]; + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; } class VOP2_Real_vi : VOP2 , SIMCInstr { let AssemblerPredicates = [isVI]; + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; } multiclass VOP2SI_m pattern, @@ -1494,6 +1536,8 @@ VOP3e , SIMCInstr { let AssemblerPredicates = [isSICI]; + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; } class VOP3_Real_vi op, dag outs, dag ins, string asm, string opName, @@ -1502,6 +1546,28 @@ VOP3e_vi , SIMCInstr { let AssemblerPredicates = [isVI]; + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; +} + +class VOP3_C_Real_si op, dag outs, dag ins, string asm, string opName, + bit HasMods = 0, bit VOP3Only = 0> : + VOP3Common , + VOP3ce , + SIMCInstr { + let AssemblerPredicates = [isSICI]; + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; +} + +class VOP3_C_Real_vi op, dag outs, dag ins, string asm, string opName, + bit HasMods = 0, bit VOP3Only = 0> : + VOP3Common , + VOP3ce_vi , + SIMCInstr { + let AssemblerPredicates = [isVI]; + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; } class VOP3b_Real_si op, dag outs, dag ins, string asm, string opName, @@ -1510,6 +1576,8 @@ VOP3be , SIMCInstr { let AssemblerPredicates = [isSICI]; + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; } class VOP3b_Real_vi op, dag outs, dag ins, string asm, string opName, @@ -1518,6 +1586,8 @@ VOP3be_vi , SIMCInstr { let AssemblerPredicates = [isVI]; + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; } multiclass VOP3_m pattern, @@ -1609,13 +1679,13 @@ let SchedRW = sched; } - def _si : VOP3_Real_si , + def _si : VOP3_C_Real_si , VOP3DisableFields<1, 0, HasMods> { let Defs = !if(defExec, [EXEC], []); let SchedRW = sched; } - def _vi : VOP3_Real_vi , + def _vi : VOP3_C_Real_vi , VOP3DisableFields<1, 0, HasMods> { let Defs = !if(defExec, [EXEC], []); let SchedRW = sched; @@ -1633,6 +1703,8 @@ def _si : VOP2 , SIMCInstr { let AssemblerPredicates = [isSICI]; + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; } def _vi : VOP3Common , @@ -1640,6 +1712,8 @@ VOP3DisableFields <1, 0, 0>, SIMCInstr { let AssemblerPredicates = [isVI]; + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; } } @@ -1656,9 +1730,9 @@ SDPatternOperator node = null_frag> : VOP1_Helper < op, opName, P, [], !if(P.HasModifiers, - [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, + [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod))))], - [(set P.DstVT:$dst, (node P.Src0VT:$src0))]) + [(set P.DstVT:$vdst, (node P.Src0VT:$src0))]) >; multiclass VOP1InstSI ; } @@ -1688,11 +1762,11 @@ string revOp = opName> : VOP2_Helper < op, opName, P, [], !if(P.HasModifiers, - [(set P.DstVT:$dst, + [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], - [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), + [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), revOp >; @@ -1704,11 +1778,11 @@ defm _e64 : VOP3SI_2_m ; } @@ -1731,11 +1805,11 @@ string revOp = opName> : VOP2b_Helper < op, opName, P, [], !if(P.HasModifiers, - [(set P.DstVT:$dst, + [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], - [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), + [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), revOp, !eq(P.NumSrcArgs, 3) >; @@ -1755,11 +1829,11 @@ : VOP2_VI3_Helper < op, opName, P, [], !if(P.HasModifiers, - [(set P.DstVT:$dst, + [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], - [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), + [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), revOp >; @@ -1773,6 +1847,8 @@ SIMCInstr , VOP2_MADKe { let AssemblerPredicates = [isSICI]; + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; } def _vi : VOP2Common , VOP2_MADKe { let AssemblerPredicates = [isVI]; + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; } } // End isCodeGenOnly = 0 } @@ -1809,6 +1887,8 @@ let Defs = !if(DefExec, [VCC, EXEC], [VCC]); let hasSideEffects = DefExec; let SchedRW = sched; + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; } } // End AssemblerPredicates = [isSICI] @@ -1819,6 +1899,8 @@ let Defs = !if(DefExec, [VCC, EXEC], [VCC]); let hasSideEffects = DefExec; let SchedRW = sched; + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; } } // End AssemblerPredicates = [isVI] @@ -1832,7 +1914,7 @@ defm _e32 : VOPC_m ; - defm _e64 : VOP3_C_m ; } @@ -1843,7 +1925,7 @@ VOPProfile p, list sched> { defm _e32 : VOPC_m ; - defm _e64 : VOP3_C_m , VOP3DisableModFields<1, 0, 0>; } @@ -1856,12 +1938,12 @@ VOPC_Helper < op, opName, [], !if(P.HasModifiers, - [(set i1:$dst, + [(set i1:$sdst, (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), cond))], - [(set i1:$dst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]), + [(set i1:$sdst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]), DefExec, revOp, P, sched >; @@ -1870,9 +1952,9 @@ list sched> : VOPC_Class_Helper < op, opName, [], !if(P.HasModifiers, - [(set i1:$dst, + [(set i1:$sdst, (AMDGPUfp_class (P.Src0VT (VOP3Mods0Clamp0OMod P.Src0VT:$src0, i32:$src0_modifiers)), P.Src1VT:$src1))], - [(set i1:$dst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]), + [(set i1:$sdst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]), DefExec, opName, P, sched >; @@ -1929,29 +2011,29 @@ multiclass VOP3Inst : VOP3_Helper < - op, opName, (outs P.DstRC.RegClass:$dst), P.Ins64, P.Asm64, + op, opName, (outs P.DstRC.RegClass:$vdst), P.Ins64, P.Asm64, !if(!eq(P.NumSrcArgs, 3), !if(P.HasModifiers, - [(set P.DstVT:$dst, + [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))], - [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1, + [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2))]), !if(!eq(P.NumSrcArgs, 2), !if(P.HasModifiers, - [(set P.DstVT:$dst, + [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], - [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]) + [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]) /* P.NumSrcArgs == 1 */, !if(P.HasModifiers, - [(set P.DstVT:$dst, + [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod))))], - [(set P.DstVT:$dst, (node P.Src0VT:$src0))]))), + [(set P.DstVT:$vdst, (node P.Src0VT:$src0))]))), P.NumSrcArgs, P.HasModifiers, VOP3Only >; @@ -1961,14 +2043,14 @@ VOPProfile P, SDPatternOperator node = null_frag> : VOP3_Helper < op, opName, - (outs P.DstRC.RegClass:$dst), + (outs P.DstRC.RegClass:$vdst), (ins InputModsNoDefault:$src0_modifiers, P.Src0RC64:$src0, InputModsNoDefault:$src1_modifiers, P.Src1RC64:$src1, InputModsNoDefault:$src2_modifiers, P.Src2RC64:$src2, ClampMod:$clamp, omod:$omod), - "$dst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod", - [(set P.DstVT:$dst, + "$vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod", + [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), @@ -2009,13 +2091,19 @@ string asm> : VINTRPCommon , VINTRPe , - SIMCInstr; + SIMCInstr { + let DecoderNamespace = "SICI"; + let DisableDecoder = DisableSIDecoder; +} class VINTRP_Real_vi op, string opName, dag outs, dag ins, string asm> : VINTRPCommon , VINTRPe_vi , - SIMCInstr; + SIMCInstr { + let DecoderNamespace = "VI"; + let DisableDecoder = DisableVIDecoder; +} multiclass VINTRP_m op, dag outs, dag ins, string asm, list pattern = []> { @@ -2042,12 +2130,17 @@ DSe , SIMCInstr { let isCodeGenOnly = 0; + let DecoderNamespace="SICI"; + let DisableDecoder = DisableSIDecoder; } class DS_Real_vi op, string opName, dag outs, dag ins, string asm> : DS , DSe_vi , - SIMCInstr ; + SIMCInstr { + let DecoderNamespace="VI"; + let DisableDecoder = DisableVIDecoder; +} class DS_Off16_Real_si op, string opName, dag outs, dag ins, string asm> : DS_Real_si { @@ -2248,12 +2341,18 @@ string asm> : MTBUF , MTBUFe , - SIMCInstr; + SIMCInstr { + let DecoderNamespace="SICI"; + let DisableDecoder = DisableSIDecoder; +} class MTBUF_Real_vi op, string opName, dag outs, dag ins, string asm> : MTBUF , MTBUFe_vi , - SIMCInstr ; + SIMCInstr { + let DecoderNamespace="VI"; + let DisableDecoder = DisableVIDecoder; +} multiclass MTBUF_m op, string opName, dag outs, dag ins, string asm, list pattern> { @@ -2344,6 +2443,8 @@ MUBUFe , SIMCInstr { let lds = 0; + let DecoderNamespace="SICI"; + let DisableDecoder = DisableSIDecoder; } class MUBUF_Real_vi , SIMCInstr { let lds = 0; + let DecoderNamespace="VI"; + let DisableDecoder = DisableVIDecoder; } multiclass MUBUF_m , SIMCInstr { let AssemblerPredicate = isCIOnly; + let DecoderNamespace="CI"; } class FLAT_Real_vi op, string opName, dag outs, dag ins, string asm> : FLAT , SIMCInstr { let AssemblerPredicate = VIAssemblerPredicate; + let DecoderNamespace="VI"; + let DisableDecoder = DisableVIDecoder; } multiclass FLAT_AtomicRet_m { + bits<4> res = !if(!eq(channels,1), 0x1, + !if(!eq(channels,2), 0x3, + !if(!eq(channels,3), 0x7, + !if(!eq(channels,4), 0xF, 0)))); +} + +class MIMG_Helper op, dag outs, dag ins, string asm, + int channels, + string dns=""> : MIMG { + let mayLoad = 1; + let mayStore = 0; + let hasPostISelHook = 1; + let dmask = getDMask.res; + let DecoderNamespace = dns; + let isAsmParserOnly = !if(!eq(dns,""), 1, 0); +} + class MIMG_NoSampler_Helper op, string asm, RegisterClass dst_rc, - RegisterClass src_rc> : MIMG < + RegisterClass src_rc, + int channels, + string dns=""> : MIMG_Helper < op, (outs dst_rc:$vdata), (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128, @@ -2711,21 +2837,18 @@ SReg_256:$srsrc), asm#" $vdata, $dmask, $unorm, $glc, $da, $r128," #" $tfe, $lwe, $slc, $vaddr, $srsrc", - []> { + channels, dns> { let ssamp = 0; - let mayLoad = 1; - let mayStore = 0; - let hasPostISelHook = 1; } multiclass MIMG_NoSampler_Src_Helper op, string asm, RegisterClass dst_rc, int channels> { - def _V1 : MIMG_NoSampler_Helper , + def _V1 : MIMG_NoSampler_Helper , MIMG_Mask; - def _V2 : MIMG_NoSampler_Helper , + def _V2 : MIMG_NoSampler_Helper , MIMG_Mask; - def _V4 : MIMG_NoSampler_Helper , + def _V4 : MIMG_NoSampler_Helper , MIMG_Mask; } @@ -2738,7 +2861,10 @@ class MIMG_Sampler_Helper op, string asm, RegisterClass dst_rc, - RegisterClass src_rc, int wqm> : MIMG < + RegisterClass src_rc, + int wqm, + int channels, + string dns=""> : MIMG_Helper < op, (outs dst_rc:$vdata), (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128, @@ -2746,41 +2872,33 @@ SReg_256:$srsrc, SReg_128:$ssamp), asm#" $vdata, $dmask, $unorm, $glc, $da, $r128," #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp", - []> { - let mayLoad = 1; - let mayStore = 0; - let hasPostISelHook = 1; + channels, dns> { let WQM = wqm; } multiclass MIMG_Sampler_Src_Helper op, string asm, RegisterClass dst_rc, int channels, int wqm> { - def _V1 : MIMG_Sampler_Helper , + def _V1 : MIMG_Sampler_Helper , MIMG_Mask; - def _V2 : MIMG_Sampler_Helper , + def _V2 : MIMG_Sampler_Helper , MIMG_Mask; - def _V4 : MIMG_Sampler_Helper , + def _V4 : MIMG_Sampler_Helper , MIMG_Mask; - def _V8 : MIMG_Sampler_Helper , + def _V8 : MIMG_Sampler_Helper , MIMG_Mask; - def _V16 : MIMG_Sampler_Helper , + def _V16 : MIMG_Sampler_Helper , MIMG_Mask; } -multiclass MIMG_Sampler op, string asm> { - defm _V1 : MIMG_Sampler_Src_Helper; - defm _V2 : MIMG_Sampler_Src_Helper; - defm _V3 : MIMG_Sampler_Src_Helper; - defm _V4 : MIMG_Sampler_Src_Helper; +multiclass MIMG_Sampler op, string asm, int wqm=0> { + defm _V1 : MIMG_Sampler_Src_Helper; + defm _V2 : MIMG_Sampler_Src_Helper; + defm _V3 : MIMG_Sampler_Src_Helper; + defm _V4 : MIMG_Sampler_Src_Helper; } -multiclass MIMG_Sampler_WQM op, string asm> { - defm _V1 : MIMG_Sampler_Src_Helper; - defm _V2 : MIMG_Sampler_Src_Helper; - defm _V3 : MIMG_Sampler_Src_Helper; - defm _V4 : MIMG_Sampler_Src_Helper; -} +multiclass MIMG_Sampler_WQM op, string asm> : MIMG_Sampler; class MIMG_Gather_Helper op, string asm, RegisterClass dst_rc, @@ -2806,6 +2924,8 @@ let MIMG = 0; let hasPostISelHook = 0; let WQM = wqm; + + let isAsmParserOnly = 1; // TBD: fix it later } multiclass MIMG_Gather_Src_Helper op, string asm, @@ -2823,19 +2943,14 @@ MIMG_Mask; } -multiclass MIMG_Gather op, string asm> { - defm _V1 : MIMG_Gather_Src_Helper; - defm _V2 : MIMG_Gather_Src_Helper; - defm _V3 : MIMG_Gather_Src_Helper; - defm _V4 : MIMG_Gather_Src_Helper; +multiclass MIMG_Gather op, string asm, int wqm=0> { + defm _V1 : MIMG_Gather_Src_Helper; + defm _V2 : MIMG_Gather_Src_Helper; + defm _V3 : MIMG_Gather_Src_Helper; + defm _V4 : MIMG_Gather_Src_Helper; } -multiclass MIMG_Gather_WQM op, string asm> { - defm _V1 : MIMG_Gather_Src_Helper; - defm _V2 : MIMG_Gather_Src_Helper; - defm _V3 : MIMG_Gather_Src_Helper; - defm _V4 : MIMG_Gather_Src_Helper; -} +multiclass MIMG_Gather_WQM op, string asm> : MIMG_Gather; //===----------------------------------------------------------------------===// // Vector instruction mappings Index: lib/Target/AMDGPU/SIInstructions.td =================================================================== --- lib/Target/AMDGPU/SIInstructions.td +++ lib/Target/AMDGPU/SIInstructions.td @@ -1033,7 +1033,7 @@ //def BUFFER_ATOMIC_FMIN_X2 : MUBUF_X2 , "buffer_atomic_fmin_x2", []>; // isn't on VI //def BUFFER_ATOMIC_FMAX_X2 : MUBUF_X2 , "buffer_atomic_fmax_x2", []>; // isn't on VI -let SubtargetPredicate = isSI in { +let SubtargetPredicate = isSI, DisableVIDecoder = 1 in { defm BUFFER_WBINVL1_SC : MUBUF_Invalidate , "buffer_wbinvl1_sc", int_amdgcn_buffer_wbinvl1_sc>; // isn't on CI & VI } @@ -1394,11 +1394,11 @@ } // End OtherPredicates = [has32BankLDS] -let OtherPredicates = [has16BankLDS], Constraints = "@earlyclobber $dst" in { +let OtherPredicates = [has16BankLDS], Constraints = "@earlyclobber $dst", isAsmParserOnly=1 in { defm V_INTERP_P1_F32_16bank : V_INTERP_P1_F32_m; -} // End OtherPredicates = [has32BankLDS], Constraints = "@earlyclobber $dst" +} // End OtherPredicates = [has32BankLDS], Constraints = "@earlyclobber $dst", isAsmParserOnly=1 let DisableEncoding = "$src0", Constraints = "$src0 = $dst" in { @@ -1501,7 +1501,7 @@ defm V_OR_B32 : VOP2Inst , "v_or_b32", VOP_I32_I32_I32>; defm V_XOR_B32 : VOP2Inst , "v_xor_b32", VOP_I32_I32_I32>; -let Constraints = "$dst = $src2", DisableEncoding="$src2", +let Constraints = "$vdst = $src2", DisableEncoding="$src2", isConvertibleToThreeAddress = 1 in { defm V_MAC_F32 : VOP2Inst , "v_mac_f32", VOP_MAC>; } @@ -1757,9 +1757,12 @@ VOP_I32_I32_I32, mulhu >; +let DisableVIDecoder=1 in { // removed from VI as identical to V_MUL_LO_U32 defm V_MUL_LO_I32 : VOP3Inst , "v_mul_lo_i32", VOP_I32_I32_I32 >; +} + defm V_MUL_HI_I32 : VOP3Inst , "v_mul_hi_i32", VOP_I32_I32_I32, mulhs >; @@ -1828,7 +1831,7 @@ } // End SubtargetPredicate = isSICI -let SubtargetPredicate = isVI in { +let SubtargetPredicate = isVI, DisableSIDecoder = 1 in { defm V_LSHLREV_B64 : VOP3Inst , "v_lshlrev_b64", VOP_I64_I32_I64 @@ -1848,14 +1851,14 @@ let isCodeGenOnly = 1, isPseudo = 1 in { // For use in patterns -def V_CNDMASK_B64_PSEUDO : VOP3Common <(outs VReg_64:$dst), +def V_CNDMASK_B64_PSEUDO : VOP3Common <(outs VReg_64:$vdst), (ins VSrc_64:$src0, VSrc_64:$src1, SSrc_64:$src2), "", [] >; let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [EXEC] in { // 64-bit vector move instruction. This is mainly used by the SIFoldOperands // pass to enable folding of inline immediates. -def V_MOV_B64_PSEUDO : InstSI <(outs VReg_64:$dst), (ins VSrc_64:$src0), "", []>; +def V_MOV_B64_PSEUDO : InstSI <(outs VReg_64:$vdst), (ins VSrc_64:$src0), "", []>; } // End let hasSideEffects = 0, mayLoad = 0, mayStore = 0 let hasSideEffects = 1, SALU = 1 in { Index: lib/Target/AMDGPU/SIShrinkInstructions.cpp =================================================================== --- lib/Target/AMDGPU/SIShrinkInstructions.cpp +++ lib/Target/AMDGPU/SIShrinkInstructions.cpp @@ -287,9 +287,9 @@ MachineInstrBuilder Inst32 = BuildMI(MBB, I, MI.getDebugLoc(), TII->get(Op32)); - // Add the dst operand if the 32-bit encoding also has an explicit $dst. + // Add the dst operand if the 32-bit encoding also has an explicit $vdst. // For VOPC instructions, this is replaced by an implicit def of vcc. - int Op32DstIdx = AMDGPU::getNamedOperandIdx(Op32, AMDGPU::OpName::dst); + int Op32DstIdx = AMDGPU::getNamedOperandIdx(Op32, AMDGPU::OpName::vdst); if (Op32DstIdx != -1) { // dst Inst32.addOperand(MI.getOperand(0)); Index: lib/Target/AMDGPU/VIInstrFormats.td =================================================================== --- lib/Target/AMDGPU/VIInstrFormats.td +++ lib/Target/AMDGPU/VIInstrFormats.td @@ -104,8 +104,7 @@ let Inst{51-32} = offset; } -class VOP3e_vi op> : Enc64 { - bits<8> vdst; +class VOP3a_vi op> : Enc64 { bits<2> src0_modifiers; bits<9> src0; bits<2> src1_modifiers; @@ -115,7 +114,6 @@ bits<1> clamp; bits<2> omod; - let Inst{7-0} = vdst; let Inst{8} = src0_modifiers{1}; let Inst{9} = src1_modifiers{1}; let Inst{10} = src2_modifiers{1}; @@ -131,6 +129,20 @@ let Inst{63} = src2_modifiers{0}; } +class VOP3e_vi op> : VOP3a_vi { + bits<8> vdst; + + let Inst{7-0} = vdst; +} + +// Encoding used for VOPC instructions encoded as VOP3 +// Differs from VOP3e by destination name (sdst) as VOPC doesn't have vector dst +class VOP3ce_vi op> : VOP3a_vi { + bits<8> sdst; + + let Inst{7-0} = sdst; +} + class VOP3be_vi op> : Enc64 { bits<8> vdst; bits<2> src0_modifiers; Index: lib/Target/AMDGPU/VIInstructions.td =================================================================== --- lib/Target/AMDGPU/VIInstructions.td +++ lib/Target/AMDGPU/VIInstructions.td @@ -11,6 +11,8 @@ let SIAssemblerPredicate = DisableInst, SubtargetPredicate = isVI in { +let DisableSIDecoder = 1 in { + //===----------------------------------------------------------------------===// // VOP1 Instructions //===----------------------------------------------------------------------===// @@ -73,6 +75,8 @@ } // End isCommutable = 1 defm V_LDEXP_F16 : VOP2Inst , "v_ldexp_f16", VOP_F16_F16_I16>; +} // let DisableSIDecoder = 1 + // Aliases to simplify matching of floating-point instructions that // are VOP2 on SI and VOP3 on VI. Index: test/MC/Disassembler/AMDGPU/lit.local.cfg =================================================================== --- /dev/null +++ test/MC/Disassembler/AMDGPU/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'AMDGPU' in config.root.targets: + config.unsupported = True Index: test/MC/Disassembler/AMDGPU/vop1.txt =================================================================== --- /dev/null +++ test/MC/Disassembler/AMDGPU/vop1.txt @@ -0,0 +1,250 @@ +# RUN: llvm-mc -arch=amdgcn -mcpu=tonga -disassemble -show-encoding < %s | FileCheck %s + +# CHECK: v_nop ; encoding: [0x00,0x00,0x00,0x7e] +0x00 0x00 0x00 0x7e + +# CHECK: v_clrexcp ; encoding: [0x00,0x6a,0x00,0x7e] +0x00 0x6a 0x00 0x7e + +# CHECK: v_mov_b32_e32 v2, v1 ; encoding: [0x01,0x03,0x04,0x7e] +0x01 0x03 0x04 0x7e + +# CHECK: v_mov_b32_e32 v1, 0.5 ; encoding: [0xf0,0x02,0x02,0x7e] +0xf0 0x02 0x02 0x7e + +# CHECK: v_mov_b32_e32 v15, s100 ; encoding: [0x64,0x02,0x1e,0x7e] +0x64 0x02 0x1e 0x7e + +# CHECK: v_mov_b32_e32 v90, flat_scratch_lo ; encoding: [0x66,0x02,0xb4,0x7e] +0x66 0x02 0xb4 0x7e + +# CHECK: v_mov_b32_e32 v150, vcc_lo ; encoding: [0x6a,0x02,0x2c,0x7f] +0x6a 0x02 0x2c 0x7f + +# CHECK: v_mov_b32_e32 v199, exec_lo ; encoding: [0x7e,0x02,0x8e,0x7f] +0x7e 0x02 0x8e 0x7f + +# CHECK: v_mov_b32_e32 v222, m0 ; encoding: [0x7c,0x02,0xbc,0x7f] +0x7c 0x02 0xbc 0x7f + +# CHECK: v_mov_b32_e32 v255, -13 ; encoding: [0xcd,0x02,0xfe,0x7f] +0xcd 0x02 0xfe 0x7f + +# CHECK: v_cvt_f32_i32_e32 v153, s98 ; encoding: [0x62,0x0a,0x32,0x7f] +0x62 0x0a 0x32 0x7f + +# CHECK: v_cvt_f32_u32_e32 v33, -4.0 ; encoding: [0xf7,0x0c,0x42,0x7e] +0xf7 0x0c 0x42 0x7e + +# CHECK: v_cvt_i32_f64_e32 v2, s[0:1] ; encoding: [0x00,0x06,0x04,0x7e] +0x00 0x06 0x04 0x7e + +# CHECK: v_cvt_u32_f32_e32 v123, vcc_hi ; encoding: [0x6b,0x0e,0xf6,0x7e] +0x6b 0x0e 0xf6 0x7e + +# CHECK: v_cvt_i32_f32_e32 v123, flat_scratch_lo ; encoding: [0x66,0x10,0xf6,0x7e] +0x66 0x10 0xf6 0x7e + +# CHECK: v_cvt_rpi_i32_f32_e32 v123, s101 ; encoding: [0x65,0x18,0xf6,0x7e] +0x65 0x18 0xf6 0x7e + +# CHECK: v_cvt_flr_i32_f32_e32 v123, -4.0 ; encoding: [0xf7,0x1a,0xf6,0x7e] +0xf7 0x1a 0xf6 0x7e + +# CHECK: v_cvt_f32_f64_e32 v123, vcc ; encoding: [0x6a,0x1e,0xf6,0x7e] +0x6a 0x1e 0xf6 0x7e + +# CHECK: v_cvt_u32_f64_e32 v123, exec ; encoding: [0x7e,0x2a,0xf6,0x7e] +0x7e 0x2a 0xf6 0x7e + +# CHECK: v_fract_f32_e32 v123, m0 ; encoding: [0x7c,0x36,0xf6,0x7e] +0x7c 0x36 0xf6 0x7e + +# CHECK: v_trunc_f32_e32 v123, exec_lo ; encoding: [0x7e,0x38,0xf6,0x7e] +0x7e 0x38 0xf6 0x7e + +# CHECK: v_ceil_f32_e32 v123, exec_hi ; encoding: [0x7f,0x3a,0xf6,0x7e] +0x7f 0x3a 0xf6 0x7e + +# CHECK: v_rndne_f32_e32 v123, 0 ; encoding: [0x80,0x3c,0xf6,0x7e] +0x80 0x3c 0xf6 0x7e + +# CHECK: v_floor_f32_e32 v123, -0.5 ; encoding: [0xf1,0x3e,0xf6,0x7e] +0xf1 0x3e 0xf6 0x7e + +# CHECK: v_exp_f32_e32 v123, 1.0 ; encoding: [0xf2,0x40,0xf6,0x7e] +0xf2 0x40 0xf6 0x7e + +# CHECK: v_log_f32_e32 v123, -1.0 ; encoding: [0xf3,0x42,0xf6,0x7e] +0xf3 0x42 0xf6 0x7e + +# CHECK: v_rcp_f32_e32 v123, 2.0 ; encoding: [0xf4,0x44,0xf6,0x7e] +0xf4 0x44 0xf6 0x7e + +# CHECK: v_rcp_iflag_f32_e32 v123, -2.0 ; encoding: [0xf5,0x46,0xf6,0x7e] +0xf5 0x46 0xf6 0x7e + +# CHECK: v_rsq_f32_e32 v123, 4.0 ; encoding: [0xf6,0x48,0xf6,0x7e] +0xf6 0x48 0xf6 0x7e + +# CHECK: v_sqrt_f32_e32 v123, v12 ; encoding: [0x0c,0x4f,0xf6,0x7e] +0x0c 0x4f 0xf6 0x7e + +# CHECK: v_sin_f32_e32 v123, v12 ; encoding: [0x0c,0x53,0xf6,0x7e] +0x0c 0x53 0xf6 0x7e + +# CHECK: v_cos_f32_e32 v123, v12 ; encoding: [0x0c,0x55,0xf6,0x7e] +0x0c 0x55 0xf6 0x7e + +# CHECK: v_not_b32_e32 v123, v12 ; encoding: [0x0c,0x57,0xf6,0x7e] +0x0c 0x57 0xf6 0x7e + +# CHECK: v_bfrev_b32_e32 v123, v12 ; encoding: [0x0c,0x59,0xf6,0x7e] +0x0c 0x59 0xf6 0x7e + +# CHECK: v_ffbh_u32_e32 v123, v12 ; encoding: [0x0c,0x5b,0xf6,0x7e] +0x0c 0x5b 0xf6 0x7e + +# CHECK: v_ffbl_b32_e32 v123, v12 ; encoding: [0x0c,0x5d,0xf6,0x7e] +0x0c 0x5d 0xf6 0x7e + +# CHECK: v_ffbh_i32_e32 v123, v12 ; encoding: [0x0c,0x5f,0xf6,0x7e] +0x0c 0x5f 0xf6 0x7e + +# CHECK: v_frexp_exp_i32_f64_e32 v123, 2.0 ; encoding: [0xf4,0x60,0xf6,0x7e] +0xf4 0x60 0xf6 0x7e + +# CHECK: v_frexp_exp_i32_f32_e32 v123, s33 ; encoding: [0x21,0x66,0xf6,0x7e] +0x21 0x66 0xf6 0x7e + +# CHECK: v_frexp_mant_f32_e32 v123, s33 ; encoding: [0x21,0x68,0xf6,0x7e] +0x21 0x68 0xf6 0x7e + +# CHECK: v_movreld_b32_e32 v123, s33 ; encoding: [0x21,0x6c,0xf6,0x7e] +0x21 0x6c 0xf6 0x7e + +# CHECK: v_movrels_b32_e32 v123, s33 ; encoding: [0x21,0x6e,0xf6,0x7e] +0x21 0x6e 0xf6 0x7e + +# CHECK: v_movrelsd_b32_e32 v123, s33 ; encoding: [0x21,0x70,0xf6,0x7e] +0x21 0x70 0xf6 0x7e + +# CHECK: v_cvt_f16_f32_e32 v123, flat_scratch_hi ; encoding: [0x67,0x14,0xf6,0x7e] +0x67 0x14 0xf6 0x7e + +# CHECK: v_cvt_f32_f16_e32 v123, s55 ; encoding: [0x37,0x16,0xf6,0x7e] +0x37 0x16 0xf6 0x7e + +# CHECK: v_cvt_off_f32_i4_e32 v123, v12 ; encoding: [0x0c,0x1d,0xf6,0x7e] +0x0c 0x1d 0xf6 0x7e + +# CHECK: v_cvt_f32_ubyte0_e32 v123, v12 ; encoding: [0x0c,0x23,0xf6,0x7e] +0x0c 0x23 0xf6 0x7e + +# CHECK: v_cvt_f32_ubyte1_e32 v123, v12 ; encoding: [0x0c,0x25,0xf6,0x7e] +0x0c 0x25 0xf6 0x7e + +# CHECK: v_cvt_f32_ubyte2_e32 v123, v12 ; encoding: [0x0c,0x27,0xf6,0x7e] +0x0c 0x27 0xf6 0x7e + +# CHECK: v_cvt_f32_ubyte3_e32 v123, v12 ; encoding: [0x0c,0x29,0xf6,0x7e] +0x0c 0x29 0xf6 0x7e + +# CHECK: v_cvt_f64_i32_e32 v[222:223], 1.0 ; encoding: [0xf2,0x08,0xbc,0x7f] +0xf2 0x08 0xbc 0x7f + +# CHECK: v_cvt_f64_i32_e32 v[222:223], exec_hi ; encoding: [0x7f,0x08,0xbc,0x7f] +0x7f 0x08 0xbc 0x7f + +# CHECK: v_cvt_f64_f32_e32 v[222:223], s33 ; encoding: [0x21,0x20,0xbc,0x7f] +0x21 0x20 0xbc 0x7f + +# CHECK: v_cvt_f64_u32_e32 v[222:223], s33 ; encoding: [0x21,0x2c,0xbc,0x7f] +0x21 0x2c 0xbc 0x7f + +# CHECK: v_rcp_f64_e32 v[222:223], s[22:23] ; encoding: [0x16,0x4a,0xbc,0x7f] +0x16 0x4a 0xbc 0x7f + +# CHECK: v_rsq_f64_e32 v[222:223], s[22:23] ; encoding: [0x16,0x4c,0xbc,0x7f] +0x16 0x4c 0xbc 0x7f + +# CHECK: v_sqrt_f64_e32 v[222:223], s[22:23] ; encoding: [0x16,0x50,0xbc,0x7f] +0x16 0x50 0xbc 0x7f + +# CHECK: v_frexp_mant_f64_e32 v[222:223], s[22:23] ; encoding: [0x16,0x62,0xbc,0x7f] +0x16 0x62 0xbc 0x7f + +# CHECK: v_fract_f64_e32 v[222:223], s[22:23] ; encoding: [0x16,0x64,0xbc,0x7f] +0x16 0x64 0xbc 0x7f + +# CHECK: v_cvt_f16_u16_e32 v123, 23 ; encoding: [0x97,0x72,0xf6,0x7e] +0x97 0x72 0xf6 0x7e + +# CHECK: v_cvt_f16_i16_e32 v123, vcc_hi ; encoding: [0x6b,0x74,0xf6,0x7e] +0x6b 0x74 0xf6 0x7e + +# CHECK: v_cvt_u16_f16_e32 v123, m0 ; encoding: [0x7c,0x76,0xf6,0x7e] +0x7c 0x76 0xf6 0x7e + +# CHECK: v_cvt_i16_f16_e32 v123, exec_lo ; encoding: [0x7e,0x78,0xf6,0x7e] +0x7e 0x78 0xf6 0x7e + +# CHECK: v_rcp_f16_e32 v123, 1.0 ; encoding: [0xf2,0x7a,0xf6,0x7e] +0xf2 0x7a 0xf6 0x7e + +# CHECK: v_sqrt_f16_e32 v123, 4.0 ; encoding: [0xf6,0x7c,0xf6,0x7e] +0xf6 0x7c 0xf6 0x7e + +# CHECK: v_rsq_f16_e32 v123, -1.0 ; encoding: [0xf3,0x7e,0xf6,0x7e] +0xf3 0x7e 0xf6 0x7e + +# CHECK: v_log_f16_e32 v123, s33 ; encoding: [0x21,0x80,0xf6,0x7e] +0x21 0x80 0xf6 0x7e + +# CHECK: v_exp_f16_e32 v123, v12 ; encoding: [0x0c,0x83,0xf6,0x7e] +0x0c 0x83 0xf6 0x7e + +# CHECK: v_frexp_mant_f16_e32 v123, v12 ; encoding: [0x0c,0x85,0xf6,0x7e] +0x0c 0x85 0xf6 0x7e + +# CHECK: v_frexp_exp_i16_f16_e32 v123, v12 ; encoding: [0x0c,0x87,0xf6,0x7e] +0x0c 0x87 0xf6 0x7e + +# CHECK: v_floor_f16_e32 v123, v12 ; encoding: [0x0c,0x89,0xf6,0x7e] +0x0c 0x89 0xf6 0x7e + +# CHECK: v_ceil_f16_e32 v123, v12 ; encoding: [0x0c,0x8b,0xf6,0x7e] +0x0c 0x8b 0xf6 0x7e + +# CHECK: v_trunc_f16_e32 v123, s33 ; encoding: [0x21,0x8c,0xf6,0x7e] +0x21 0x8c 0xf6 0x7e + +# CHECK: v_rndne_f16_e32 v123, s33 ; encoding: [0x21,0x8e,0xf6,0x7e] +0x21 0x8e 0xf6 0x7e + +# CHECK: v_fract_f16_e32 v123, s33 ; encoding: [0x21,0x90,0xf6,0x7e] +0x21 0x90 0xf6 0x7e + +# CHECK: v_sin_f16_e32 v123, s33 ; encoding: [0x21,0x92,0xf6,0x7e] +0x21 0x92 0xf6 0x7e + +# CHECK: v_cos_f16_e32 v123, s33 ; encoding: [0x21,0x94,0xf6,0x7e] +0x21 0x94 0xf6 0x7e + +# CHECK: v_mov_b32_e32 v2, 0x75bcd15 ; encoding: [0xff,0x02,0x04,0x7e,0x15,0xcd,0x5b,0x07] +0xff 0x02 0x04 0x7e 0x15 0xcd 0x5b 0x07 + +# CHECK: v_cvt_f32_u32_e32 v33, 0x4236b732 ; encoding: [0xff,0x0c,0x42,0x7e,0x32,0xb7,0x36,0x42] +0xff 0x0c 0x42 0x7e 0x32 0xb7 0x36 0x42 + +# CHECK: v_cvt_i32_f64_e32 v2, 0x4236b732 ; encoding: [0xff,0x06,0x04,0x7e,0x32,0xb7,0x36,0x42] +0xff 0x06 0x04 0x7e 0x32 0xb7 0x36 0x42 + +# CHECK: v_cvt_f16_u16_e32 v123, 0x3ade68b1 ; encoding: [0xff,0x72,0xf6,0x7e,0xb1,0x68,0xde,0x3a] +0xff 0x72 0xf6 0x7e 0xb1 0x68 0xde 0x3a + +# CHECK: v_cvt_f16_i16_e32 v123, 0x21c2 ; encoding: [0xff,0x74,0xf6,0x7e,0xc2,0x21,0x00,0x00] +0xff 0x74 0xf6 0x7e 0xc2 0x21 0x00 0x00 + +# CHECK: v_cvt_u16_f16_e32 v123, 0x3f200000 ; encoding: [0xff,0x76,0xf6,0x7e,0x00,0x00,0x20,0x3f] +0xff 0x76 0xf6 0x7e 0x00 0x00 0x20 0x3f \ No newline at end of file