[AMDGPU][MC][gfx8] Support 20-bit immediate offset in SMEM instructions.
authorArtem Tamazov <artem.tamazov@amd.com>
Mon, 31 Oct 2016 16:07:39 +0000 (16:07 +0000)
committerArtem Tamazov <artem.tamazov@amd.com>
Mon, 31 Oct 2016 16:07:39 +0000 (16:07 +0000)
Fixes Bug 30808.
Note that passing subtarget information to predicates seems too complicated, so gfx8-specific def smrd_offset_20 introduced.
Old gfx6/7-specific def renamed to smrd_offset_8 for clarity.
Lit tests updated.

Differential Revision: https://reviews.llvm.org/D26085

llvm-svn: 285590

llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp
llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h
llvm/lib/Target/AMDGPU/SMInstructions.td
llvm/test/MC/AMDGPU/smrd.s
llvm/test/MC/Disassembler/AMDGPU/smrd_vi.txt

index 957233caa9f8433ef50be6664812492c8bd53df2..b7e61ad35fc3c5055097bb1c877865545c8a5123 100644 (file)
@@ -341,7 +341,8 @@ public:
   bool isSWaitCnt() const;
   bool isHwreg() const;
   bool isSendMsg() const;
-  bool isSMRDOffset() const;
+  bool isSMRDOffset8() const;
+  bool isSMRDOffset20() const;
   bool isSMRDLiteralOffset() const;
   bool isDPPCtrl() const;
   bool isGPRIdxMode() const;
@@ -741,7 +742,8 @@ public:
   AMDGPUOperand::Ptr defaultDA() const;
   AMDGPUOperand::Ptr defaultR128() const;
   AMDGPUOperand::Ptr defaultLWE() const;
-  AMDGPUOperand::Ptr defaultSMRDOffset() const;
+  AMDGPUOperand::Ptr defaultSMRDOffset8() const;
+  AMDGPUOperand::Ptr defaultSMRDOffset20() const;
   AMDGPUOperand::Ptr defaultSMRDLiteralOffset() const;
 
   OperandMatchResultTy parseOModOperand(OperandVector &Operands);
@@ -2533,20 +2535,25 @@ AMDGPUOperand::Ptr AMDGPUAsmParser::defaultLWE() const {
 // smrd
 //===----------------------------------------------------------------------===//
 
-bool AMDGPUOperand::isSMRDOffset() const {
-
-  // FIXME: Support 20-bit offsets on VI.  We need to to pass subtarget
-  // information here.
+bool AMDGPUOperand::isSMRDOffset8() const {
   return isImm() && isUInt<8>(getImm());
 }
 
+bool AMDGPUOperand::isSMRDOffset20() const {
+  return isImm() && isUInt<20>(getImm());
+}
+
 bool AMDGPUOperand::isSMRDLiteralOffset() const {
   // 32-bit literals are only supported on CI and we only want to use them
   // when the offset is > 8-bits.
   return isImm() && !isUInt<8>(getImm()) && isUInt<32>(getImm());
 }
 
-AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDOffset() const {
+AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDOffset8() const {
+  return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyOffset);
+}
+
+AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDOffset20() const {
   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyOffset);
 }
 
index aec10087a884d90210c226f631e5e85ff931c9d8..3ab030082ec786ddaa389607a970331d588de562 100644 (file)
@@ -129,7 +129,13 @@ void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo,
   }
 }
 
-void AMDGPUInstPrinter::printSMRDOffset(const MCInst *MI, unsigned OpNo,
+void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
+                                        const MCSubtargetInfo &STI,
+                                        raw_ostream &O) {
+  printU32ImmOperand(MI, OpNo, STI, O);
+}
+
+void AMDGPUInstPrinter::printSMRDOffset20(const MCInst *MI, unsigned OpNo,
                                         const MCSubtargetInfo &STI,
                                         raw_ostream &O) {
   printU32ImmOperand(MI, OpNo, STI, O);
index 8a5ce60742882be79c6e9aea73888353308c54a8..960e65814c117e585ff998ae882bf1c0b8dd887f 100644 (file)
@@ -56,7 +56,9 @@ private:
                     raw_ostream &O);
   void printOffset1(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
                     raw_ostream &O);
-  void printSMRDOffset(const MCInst *MI, unsigned OpNo,
+  void printSMRDOffset8(const MCInst *MI, unsigned OpNo,
+                       const MCSubtargetInfo &STI, raw_ostream &O);
+  void printSMRDOffset20(const MCInst *MI, unsigned OpNo,
                        const MCSubtargetInfo &STI, raw_ostream &O);
   void printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
                               const MCSubtargetInfo &STI, raw_ostream &O);
index 9b9d5588ed5c3c4b404740db5005de03ff3b8412..ddb695aa3e41e29b42cf1f644f8c72a8bd5cb7b4 100644 (file)
@@ -7,11 +7,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-def smrd_offset : NamedOperandU32<"SMRDOffset",
-                                  NamedMatchClass<"SMRDOffset">> {
+def smrd_offset_8 : NamedOperandU32<"SMRDOffset8",
+                                  NamedMatchClass<"SMRDOffset8">> {
   let OperandType = "OPERAND_IMMEDIATE";
 }
 
+def smrd_offset_20 : NamedOperandU32<"SMRDOffset20",
+                                  NamedMatchClass<"SMRDOffset20">> {
+  let OperandType = "OPERAND_IMMEDIATE";
+}
 
 //===----------------------------------------------------------------------===//
 // Scalar Memory classes
@@ -325,7 +329,7 @@ multiclass SM_Real_Loads_si<bits<5> op, string ps,
                             SM_Load_Pseudo sgprPs = !cast<SM_Load_Pseudo>(ps#_SGPR)> {
 
   def _IMM_si : SMRD_Real_si <op, immPs> {
-    let InOperandList = (ins immPs.BaseClass:$sbase, smrd_offset:$offset, GLC:$glc);
+    let InOperandList = (ins immPs.BaseClass:$sbase, smrd_offset_8:$offset, GLC:$glc);
   }
 
   // FIXME: The operand name $offset is inconsistent with $soff used
@@ -378,7 +382,7 @@ multiclass SM_Real_Loads_vi<bits<8> op, string ps,
                             SM_Load_Pseudo immPs = !cast<SM_Load_Pseudo>(ps#_IMM),
                             SM_Load_Pseudo sgprPs = !cast<SM_Load_Pseudo>(ps#_SGPR)> {
   def _IMM_vi : SMEM_Real_vi <op, immPs> {
-    let InOperandList = (ins immPs.BaseClass:$sbase, smrd_offset:$offset, GLC:$glc);
+    let InOperandList = (ins immPs.BaseClass:$sbase, smrd_offset_20:$offset, GLC:$glc);
   }
   def _SGPR_vi : SMEM_Real_vi <op, sgprPs> {
     let InOperandList = (ins sgprPs.BaseClass:$sbase, SReg_32:$offset, GLC:$glc);
@@ -391,7 +395,7 @@ multiclass SM_Real_Stores_vi<bits<8> op, string ps,
   // FIXME: The operand name $offset is inconsistent with $soff used
   // in the pseudo
   def _IMM_vi : SMEM_Real_vi <op, immPs> {
-    let InOperandList = (ins immPs.SrcClass:$sdata, immPs.BaseClass:$sbase, smrd_offset:$offset, GLC:$glc);
+    let InOperandList = (ins immPs.SrcClass:$sdata, immPs.BaseClass:$sbase, smrd_offset_20:$offset, GLC:$glc);
   }
 
   def _SGPR_vi : SMEM_Real_vi <op, sgprPs> {
index ac3ce26db98cb52bedf8d9392eda6e27b3019b29..211ec7e618b11074ba944a3bc598bde20cc69ca0 100644 (file)
@@ -21,8 +21,23 @@ s_load_dword s1, s[2:3], 0xff
 
 s_load_dword s1, s[2:3], 0x100
 // NOSI: error: instruction not supported on this GPU
-// NOVI: error: instruction not supported on this GPU
 // CI: s_load_dword s1, s[2:3], 0x100 ; encoding: [0xff,0x82,0x00,0xc0,0x00,0x01,0x00,0x00]
+// VI: s_load_dword s1, s[2:3], 0x100 ; encoding: [0x41,0x00,0x02,0xc0,0x00,0x01,0x00,0x00]
+
+s_load_dword s1, s[2:3], 0xfffff
+// NOSI: error: instruction not supported on this GPU
+// CI: s_load_dword s1, s[2:3], 0xfffff ; encoding: [0xff,0x82,0x00,0xc0,0xff,0xff,0x0f,0x00]
+// VI: s_load_dword s1, s[2:3], 0xfffff ; encoding: [0x41,0x00,0x02,0xc0,0xff,0xff,0x0f,0x00]
+
+s_load_dword s1, s[2:3], 0x100000
+// NOSI: error: instruction not supported on this GPU
+// CI: s_load_dword s1, s[2:3], 0x100000 ; encoding: [0xff,0x82,0x00,0xc0,0x00,0x00,0x10,0x00]
+// NOVI: error: instruction not supported on this GPU
+
+s_load_dword s1, s[2:3], 0xffffffff
+// NOSI: error: instruction not supported on this GPU
+// CI: s_load_dword s1, s[2:3], 0xffffffff ; encoding: [0xff,0x82,0x00,0xc0,0xff,0xff,0xff,0xff]
+// NOVI: error: instruction not supported on this GPU
 
 //===----------------------------------------------------------------------===//
 // Instructions
index 8191bd1845ec7b07f1cb41a474a3a38507533262..630c55f6b55504ec09b110a97513105e37510f61 100644 (file)
@@ -9,6 +9,9 @@
 # VI:  s_load_dword s1, s[2:3], 0x1    ; encoding: [0x41,0x00,0x02,0xc0,0x01,0x00,0x00,0x00]
 0x41 0x00 0x02 0xc0 0x01 0x00 0x00 0x00
 
+# VI:  s_load_dword s1, s[2:3], 0xfffff ; encoding: [0x41,0x00,0x02,0xc0,0xff,0xff,0x0f,0x00]
+0x41,0x00,0x02,0xc0,0xff,0xff,0x0f,0x00
+
 # VI:  s_load_dword s1, s[2:3], s4     ; encoding: [0x41,0x00,0x00,0xc0,0x04,0x00,0x00,0x00]
 0x41 0x00 0x00 0xc0 0x04 0x00 0x00 0x00