From: Xianwei Zhang Date: Thu, 24 May 2018 17:21:27 +0000 (-0400) Subject: arch-gcn3: add support of 64-bit SOPK instruction X-Git-Tag: v20.1.0.0~454 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c2641eec894da38ff6bc35be8c9241b322f2bb2f;p=gem5.git arch-gcn3: add support of 64-bit SOPK instruction s_setreg_imm32_b32 is a 64-bit instruction, using a 32-bit literal constant. Related functions are added to support decoding the second dword. Change-Id: I290f8578f726885c137dbfac3773035f814e0a3a Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/29942 Maintainer: Anthony Gutierrez Tested-by: kokoro Reviewed-by: Xianwei Zhang --- diff --git a/src/arch/gcn3/insts/op_encodings.cc b/src/arch/gcn3/insts/op_encodings.cc index fe501f215..22d0f4898 100644 --- a/src/arch/gcn3/insts/op_encodings.cc +++ b/src/arch/gcn3/insts/op_encodings.cc @@ -160,6 +160,14 @@ namespace Gcn3ISA // copy first instruction DWORD instData = iFmt[0]; + if (hasSecondDword(iFmt)) { + // copy second instruction DWORD into union + extData = ((MachInst)iFmt)[1]; + _srcLiteral = *reinterpret_cast(&iFmt[1]); + varSize = 4 + 4; + } else { + varSize = 4; + } // if } // Inst_SOPK Inst_SOPK::~Inst_SOPK() @@ -169,18 +177,43 @@ namespace Gcn3ISA int Inst_SOPK::instSize() const { - return 4; + return varSize; } // instSize + bool + Inst_SOPK::hasSecondDword(InFmt_SOPK *iFmt) + { + /* + SOPK can be a 64-bit instruction, i.e., have a second dword: + S_SETREG_IMM32_B32 writes some or all of the LSBs of a 32-bit + literal constant into a hardware register; + the way to detect such special case is to explicitly check the + opcode (20/0x14) + */ + if (iFmt->OP == 0x14) + return true; + + return false; + } + + void Inst_SOPK::generateDisassembly() { std::stringstream dis_stream; dis_stream << _opcode << " "; - dis_stream << opSelectorToRegSym(instData.SDST) << ", "; - dis_stream << "0x" << std::hex << std::setfill('0') << std::setw(4) - << instData.SIMM16; + // S_SETREG_IMM32_B32 is a 64-bit instruction, using a + // 32-bit literal constant + if (instData.OP == 0x14) { + dis_stream << "0x" << std::hex << std::setfill('0') + << std::setw(8) << extData.imm_u32 << ", "; + } else { + dis_stream << opSelectorToRegSym(instData.SDST) << ", "; + } + + dis_stream << "0x" << std::hex << std::setfill('0') << std::setw(4) + << instData.SIMM16; disassembly = dis_stream.str(); } diff --git a/src/arch/gcn3/insts/op_encodings.hh b/src/arch/gcn3/insts/op_encodings.hh index 22c146a78..4f151b919 100644 --- a/src/arch/gcn3/insts/op_encodings.hh +++ b/src/arch/gcn3/insts/op_encodings.hh @@ -87,6 +87,12 @@ namespace Gcn3ISA protected: // first instruction DWORD InFmt_SOPK instData; + // possible second DWORD + InstFormat extData; + uint32_t varSize; + + private: + bool hasSecondDword(InFmt_SOPK *); }; // Inst_SOPK class Inst_SOP1 : public GCN3GPUStaticInst