Index: lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h =================================================================== --- lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h +++ lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h @@ -69,13 +69,13 @@ MCOperand decodeOperand_SReg_256(unsigned Val) const; MCOperand decodeOperand_SReg_512(unsigned Val) const; - enum { OP32 = true, OP64 = false }; + enum OpWidthTy { OPW32, OPW64, OPW128, OPW_LAST_, OPW_FIRST_ = OPW32 }; static MCOperand decodeIntImmed(unsigned Imm); static MCOperand decodeFPImmed(bool Is32, unsigned Imm); MCOperand decodeLiteralConstant() const; - MCOperand decodeSrcOp(bool Is32, unsigned Val) const; + MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val) const; MCOperand decodeSpecialReg32(unsigned Val) const; MCOperand decodeSpecialReg64(unsigned Val) const; }; Index: lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp =================================================================== --- lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -193,10 +193,11 @@ int shift = 0; switch (SRegClassID) { case AMDGPU::SGPR_32RegClassID: - case AMDGPU::SReg_32RegClassID: break; + case AMDGPU::TTMP_32RegClassID: break; case AMDGPU::SGPR_64RegClassID: - case AMDGPU::SReg_64RegClassID: shift = 1; break; - case AMDGPU::SReg_128RegClassID: + case AMDGPU::TTMP_64RegClassID: shift = 1; break; + case AMDGPU::SGPR_128RegClassID: + case AMDGPU::TTMP_128RegClassID: // ToDo: unclear if s[100:104] is available on VI. Can we use VCC as SGPR in // this bundle? case AMDGPU::SReg_256RegClassID: @@ -214,11 +215,11 @@ } MCOperand AMDGPUDisassembler::decodeOperand_VS_32(unsigned Val) const { - return decodeSrcOp(OP32, Val); + return decodeSrcOp(OPW32, Val); } MCOperand AMDGPUDisassembler::decodeOperand_VS_64(unsigned Val) const { - return decodeSrcOp(OP64, Val); + return decodeSrcOp(OPW64, Val); } MCOperand AMDGPUDisassembler::decodeOperand_VGPR_32(unsigned Val) const { @@ -241,7 +242,7 @@ // table-gen generated disassembler doesn't care about operand types // leaving only registry class so SSrc_32 operand turns into SReg_32 // and therefore we accept immediates and literals here as well - return decodeSrcOp(OP32, Val); + return decodeSrcOp(OPW32, Val); } MCOperand AMDGPUDisassembler::decodeOperand_SReg_32_XM0(unsigned Val) const { @@ -251,11 +252,11 @@ MCOperand AMDGPUDisassembler::decodeOperand_SReg_64(unsigned Val) const { // see decodeOperand_SReg_32 comment - return decodeSrcOp(OP64, Val); + return decodeSrcOp(OPW64, Val); } MCOperand AMDGPUDisassembler::decodeOperand_SReg_128(unsigned Val) const { - return createSRegOperand(AMDGPU::SReg_128RegClassID, Val); + return decodeSrcOp(OPW128, Val); } MCOperand AMDGPUDisassembler::decodeOperand_SReg_256(unsigned Val) const { @@ -305,16 +306,44 @@ return MCOperand::createImm(Is32? FloatToBits(V) : DoubleToBits(V)); } -MCOperand AMDGPUDisassembler::decodeSrcOp(bool Is32, unsigned Val) const { +MCOperand AMDGPUDisassembler::decodeSrcOp(const OpWidthTy Width, unsigned Val) const { using namespace AMDGPU; assert(Val < 512); // enum9 + assert(OPW_FIRST_ <= Width && Width < OPW_LAST_); + + if (Val >= 256) { + unsigned RegClassId = 0; + switch(Width) { + default: // fall + case OPW32: RegClassId = VGPR_32RegClassID; break; + case OPW64: RegClassId = VReg_64RegClassID; break; + case OPW128: RegClassId = VReg_128RegClassID; break; + } + return createRegOperand(RegClassId,Val - 256); + } + if (0 <= Val && Val < 102) { + unsigned RegClassId = 0; + switch(Width) { + default: // fall + case OPW32: RegClassId = SGPR_32RegClassID; break; + case OPW64: RegClassId = SGPR_64RegClassID; break; + case OPW128: RegClassId = SGPR_128RegClassID; break; + } + return createSRegOperand(RegClassId, Val); + } + if (112 <= Val && Val < 124) { + unsigned RegClassId = 0; + switch(Width) { + default: // fall + case OPW32: RegClassId = TTMP_32RegClassID; break; + case OPW64: RegClassId = TTMP_64RegClassID; break; + case OPW128: RegClassId = TTMP_128RegClassID; break; + } + return createSRegOperand(RegClassId, Val - 112); + } - if (Val >= 256) - return createRegOperand(Is32 ? VGPR_32RegClassID : VReg_64RegClassID, - Val - 256); - if (Val <= 101) - return createSRegOperand(Is32 ? SGPR_32RegClassID : SGPR_64RegClassID, - Val); + assert(Width == OPW32 || Width == OPW64); + const bool Is32 = (Width == OPW32); if (Val >= 128 && Val <= 208) return decodeIntImmed(Val); @@ -338,25 +367,10 @@ case 105: break; case 106: return createRegOperand(VCC_LO); case 107: return createRegOperand(VCC_HI); - // ToDo: no support for tba_lo/_hi register - case 108: - case 109: break; - // ToDo: no support for tma_lo/_hi register - case 110: - case 111: break; - // 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: break; + case 108: return createRegOperand(TBA_LO); + case 109: return createRegOperand(TBA_HI); + case 110: return createRegOperand(TMA_LO); + case 111: return createRegOperand(TMA_HI); case 124: return createRegOperand(M0); case 126: return createRegOperand(EXEC_LO); case 127: return createRegOperand(EXEC_HI); @@ -375,6 +389,8 @@ switch (Val) { case 102: return createRegOperand(getMCReg(FLAT_SCR, STI)); case 106: return createRegOperand(VCC); + case 108: return createRegOperand(TBA); + case 110: return createRegOperand(TMA); case 126: return createRegOperand(EXEC); default: break; } Index: test/MC/Disassembler/AMDGPU/trap_vi.txt =================================================================== --- /dev/null +++ test/MC/Disassembler/AMDGPU/trap_vi.txt @@ -0,0 +1,109 @@ +# RUN: llvm-mc -arch=amdgcn -mcpu=tonga -disassemble -show-encoding < %s | FileCheck %s -check-prefix=VI + +#===----------------------------------------------------------------------===# +# Trap Handler related - 32 bit registers +#===----------------------------------------------------------------------===# + +# VI: s_add_u32 ttmp0, ttmp0, 4 ; encoding: [0x70,0x84,0x70,0x80] +0x70,0x84,0x70,0x80 + +# VI: s_add_u32 ttmp4, 8, ttmp4 ; encoding: [0x88,0x74,0x74,0x80] +0x88,0x74,0x74,0x80 + +# VI: s_add_u32 ttmp4, ttmp4, 0x100 ; encoding: [0x74,0xff,0x74,0x80,0x00,0x01,0x00,0x00] +0x74,0xff,0x74,0x80,0x00,0x01,0x00,0x00 + +# VI: s_add_u32 ttmp4, ttmp4, 4 ; encoding: [0x74,0x84,0x74,0x80] +0x74,0x84,0x74,0x80 + +# VI: s_add_u32 ttmp4, ttmp8, ttmp4 ; encoding: [0x78,0x74,0x74,0x80] +0x78,0x74,0x74,0x80 + +# VI: s_and_b32 ttmp10, ttmp8, 0x80 ; encoding: [0x78,0xff,0x7a,0x86,0x80,0x00,0x00,0x00] +0x78,0xff,0x7a,0x86,0x80,0x00,0x00,0x00 + +# VI: s_and_b32 ttmp9, tma_hi, 0xffff ; encoding: [0x6f,0xff,0x79,0x86,0xff,0xff,0x00,0x00] +0x6f,0xff,0x79,0x86,0xff,0xff,0x00,0x00 + +# VI: s_and_b32 ttmp9, ttmp9, 0x1ff ; encoding: [0x79,0xff,0x79,0x86,0xff,0x01,0x00,0x00] +0x79,0xff,0x79,0x86,0xff,0x01,0x00,0x00 + +# VI: s_and_b32 ttmp9, tma_lo, 0xffff0000 ; encoding: [0x6e,0xff,0x79,0x86,0x00,0x00,0xff,0xff] +0x6e,0xff,0x79,0x86,0x00,0x00,0xff,0xff + +# VI: s_and_b32 ttmp9, ttmp9, ttmp8 ; encoding: [0x79,0x78,0x79,0x86] +0x79,0x78,0x79,0x86 + +# VI: s_and_b32 ttmp8, ttmp1, 0x1000000 ; encoding: [0x71,0xff,0x78,0x86,0x00,0x00,0x00,0x01] +0x71,0xff,0x78,0x86,0x00,0x00,0x00,0x01 + +# VI: s_cmp_eq_i32 ttmp8, 0 ; encoding: [0x78,0x80,0x00,0xbf] +0x78,0x80,0x00,0xbf + +# VI: s_cmp_eq_i32 ttmp8, 0xfe ; encoding: [0x78,0xff,0x00,0xbf,0xfe,0x00,0x00,0x00] +0x78,0xff,0x00,0xbf,0xfe,0x00,0x00,0x00 + +# VI: s_lshr_b32 ttmp8, ttmp8, 12 ; encoding: [0x78,0x8c,0x78,0x8f] +0x78,0x8c,0x78,0x8f + +# VI: v_mov_b32_e32 v1, ttmp8 ; encoding: [0x78,0x02,0x02,0x7e] +0x78,0x02,0x02,0x7e + +# VI: s_mov_b32 m0, ttmp8 ; encoding: [0x78,0x00,0xfc,0xbe] +0x78,0x00,0xfc,0xbe + +# VI: s_mov_b32 ttmp10, 0 ; encoding: [0x80,0x00,0xfa,0xbe] +0x80,0x00,0xfa,0xbe + +# VI: s_mov_b32 ttmp11, 0x1024fac ; encoding: [0xff,0x00,0xfb,0xbe,0xac,0x4f,0x02,0x01] +0xff,0x00,0xfb,0xbe,0xac,0x4f,0x02,0x01 + +# VI: s_mov_b32 ttmp8, m0 ; encoding: [0x7c,0x00,0xf8,0xbe] +0x7c,0x00,0xf8,0xbe + +# VI: s_mov_b32 ttmp8, tma_lo ; encoding: [0x6e,0x00,0xf8,0xbe] +0x6e,0x00,0xf8,0xbe + +# VI: s_mul_i32 ttmp8, 0x324, ttmp8 ; encoding: [0xff,0x78,0x78,0x92,0x24,0x03,0x00,0x00] +0xff,0x78,0x78,0x92,0x24,0x03,0x00,0x00 + +# VI: s_or_b32 ttmp9, ttmp9, 0x280000 ; encoding: [0x79,0xff,0x79,0x87,0x00,0x00,0x28,0x00] +0x79,0xff,0x79,0x87,0x00,0x00,0x28,0x00 + +#===----------------------------------------------------------------------===# +# Trap Handler related - Pairs and quadruples of registers +#===----------------------------------------------------------------------===# + +# VI: s_mov_b64 ttmp[4:5], exec ; encoding: [0x7e,0x01,0xf4,0xbe] +0x7e,0x01,0xf4,0xbe + +# VI: s_mov_b64 ttmp[4:5], exec ; encoding: [0x7e,0x01,0xf4,0xbe] +0x7e,0x01,0xf4,0xbe + +# VI: s_mov_b64 exec, ttmp[4:5] ; encoding: [0x74,0x01,0xfe,0xbe] +0x74,0x01,0xfe,0xbe + +# VI: s_mov_b64 tba, ttmp[4:5] ; encoding: [0x74,0x01,0xec,0xbe] +0x74,0x01,0xec,0xbe + +# VI: s_mov_b64 ttmp[4:5], tba ; encoding: [0x6c,0x01,0xf4,0xbe] +0x6c,0x01,0xf4,0xbe + +# VI: s_mov_b64 tma, ttmp[4:5] ; encoding: [0x74,0x01,0xee,0xbe] +0x74,0x01,0xee,0xbe + +# VI: s_mov_b64 ttmp[4:5], tma ; encoding: [0x6e,0x01,0xf4,0xbe] +0x6e,0x01,0xf4,0xbe + +#===----------------------------------------------------------------------===# +# Trap Handler related - Some specific instructions +#===----------------------------------------------------------------------===# + +# VI: s_setpc_b64 ttmp[2:3] ; encoding: [0x72,0x1d,0x80,0xbe] +0x72,0x1d,0x80,0xbe + +# VI: v_readfirstlane_b32 ttmp8, v1 ; encoding: [0x01,0x05,0xf0,0x7e] +0x01,0x05,0xf0,0x7e + +# VI: buffer_atomic_inc v1, off, ttmp[8:11], 56 glc ; encoding: [0x00,0x40,0x2c,0xe1,0x00,0x01,0x1e,0xb8] +0x00,0x40,0x2c,0xe1,0x00,0x01,0x1e,0xb8