arch-gcn3: add support of 64-bit SOPK instruction
authorXianwei Zhang <xianwei.zhang@amd.com>
Thu, 24 May 2018 17:21:27 +0000 (13:21 -0400)
committerAnthony Gutierrez <anthony.gutierrez@amd.com>
Thu, 16 Jul 2020 20:37:22 +0000 (20:37 +0000)
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 <anthony.gutierrez@amd.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Xianwei Zhang <xianwei.zhang@amd.com>
src/arch/gcn3/insts/op_encodings.cc
src/arch/gcn3/insts/op_encodings.hh

index fe501f215d1e6620ca64eddce47d87d6ce0165cd..22d0f4898ad1adc4d0ba11874808c6829c41d1af 100644 (file)
@@ -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<uint32_t*>(&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();
     }
index 22c146a7831b7cd71f57d56cead95d00ae0c7ef9..4f151b9197c92be6b93eb827a2c72ad7655b64a2 100644 (file)
@@ -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