[llvm] r267410 - [AMDGPU][llvm-mc] s_getreg/setreg* - Add hwreg(...) syntax.

Artem Tamazov via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 25 07:13:53 PDT 2016


Author: artem.tamazov
Date: Mon Apr 25 09:13:51 2016
New Revision: 267410

URL: http://llvm.org/viewvc/llvm-project?rev=267410&view=rev
Log:
[AMDGPU][llvm-mc] s_getreg/setreg* - Add hwreg(...) syntax.

Added hwreg(reg[,offset,width]) syntax.
Default offset = 0, default width = 32.
Possibility to specify 16-bit immediate kept.
Added out-of-range checks.
Disassembling is always to hwreg(...) format.
Tests updated/added.

Differential Revision: http://reviews.llvm.org/D19329

Added:
    llvm/trunk/test/MC/AMDGPU/sopk-err.s
Modified:
    llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
    llvm/trunk/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp
    llvm/trunk/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h
    llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td
    llvm/trunk/lib/Target/AMDGPU/SIInstructions.td
    llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.s.getreg.ll
    llvm/trunk/test/MC/AMDGPU/sopk.s
    llvm/trunk/test/MC/Disassembler/AMDGPU/sopk_vi.txt

Modified: llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp?rev=267410&r1=267409&r2=267410&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp Mon Apr 25 09:13:51 2016
@@ -79,6 +79,7 @@ public:
     ImmTyDA,
     ImmTyR128,
     ImmTyLWE,
+    ImmTyHwreg,
   };
 
   struct TokOp {
@@ -406,6 +407,7 @@ public:
   bool isDSOffset() const;
   bool isDSOffset01() const;
   bool isSWaitCnt() const;
+  bool isHwreg() const;
   bool isMubufOffset() const;
   bool isSMRDOffset() const;
   bool isSMRDLiteralOffset() const;
@@ -530,6 +532,8 @@ public:
 
   bool parseCnt(int64_t &IntVal);
   OperandMatchResultTy parseSWaitCntOps(OperandVector &Operands);
+  bool parseHwreg(int64_t &HwRegCode, int64_t &Offset, int64_t &Width);
+  OperandMatchResultTy parseHwregOp(OperandVector &Operands);
   OperandMatchResultTy parseSOppBrTarget(OperandVector &Operands);
 
   OperandMatchResultTy parseFlatOptionalOps(OperandVector &Operands);
@@ -1570,10 +1574,100 @@ AMDGPUAsmParser::parseSWaitCntOps(Operan
   return MatchOperand_Success;
 }
 
+bool AMDGPUAsmParser::parseHwreg(int64_t &HwRegCode, int64_t &Offset, int64_t &Width) {
+  if (Parser.getTok().getString() != "hwreg")
+    return true;
+  Parser.Lex();
+
+  if (getLexer().isNot(AsmToken::LParen))
+    return true;
+  Parser.Lex();
+
+  if (getLexer().isNot(AsmToken::Integer))
+    return true;
+  if (getParser().parseAbsoluteExpression(HwRegCode))
+    return true;
+
+  if (getLexer().is(AsmToken::RParen)) {
+    Parser.Lex();
+    return false;
+  }
+
+  // optional params
+  if (getLexer().isNot(AsmToken::Comma))
+    return true;
+  Parser.Lex();
+
+  if (getLexer().isNot(AsmToken::Integer))
+    return true;
+  if (getParser().parseAbsoluteExpression(Offset))
+    return true;
+
+  if (getLexer().isNot(AsmToken::Comma))
+    return true;
+  Parser.Lex();
+
+  if (getLexer().isNot(AsmToken::Integer))
+    return true;
+  if (getParser().parseAbsoluteExpression(Width))
+    return true;
+
+  if (getLexer().isNot(AsmToken::RParen))
+    return true;
+  Parser.Lex();
+
+  return false;
+}
+
+AMDGPUAsmParser::OperandMatchResultTy
+AMDGPUAsmParser::parseHwregOp(OperandVector &Operands) {
+  int64_t Imm16Val = 0;
+  SMLoc S = Parser.getTok().getLoc();
+
+  switch(getLexer().getKind()) {
+    default: return MatchOperand_ParseFail;
+    case AsmToken::Integer:
+      // The operand can be an integer value.
+      if (getParser().parseAbsoluteExpression(Imm16Val))
+        return MatchOperand_ParseFail;
+      if (!isInt<16>(Imm16Val) && !isUInt<16>(Imm16Val)) {
+        Error(S, "invalid immediate: only 16-bit values are legal");
+        // Do not return error code, but create an imm operand anyway and proceed
+        // to the next operand, if any. That avoids unneccessary error messages.
+      }
+      break;
+
+    case AsmToken::Identifier: {
+        int64_t HwRegCode = 0;
+        int64_t Offset = 0; // default
+        int64_t Width = 32; // default
+        if (parseHwreg(HwRegCode, Offset, Width))
+          return MatchOperand_ParseFail;
+        // HwRegCode (6) [5:0]
+        // Offset (5) [10:6]
+        // WidthMinusOne (5) [15:11]
+        if (HwRegCode < 0 || HwRegCode > 63)
+          Error(S, "invalid code of hardware register: only 6-bit values are legal");
+        if (Offset < 0 || Offset > 31)
+          Error(S, "invalid bit offset: only 5-bit values are legal");
+        if (Width < 1 || Width > 32)
+          Error(S, "invalid bitfield width: only values from 1 to 32 are legal");
+        Imm16Val = HwRegCode | (Offset << 6) | ((Width-1) << 11);
+      }
+      break;
+  }
+  Operands.push_back(AMDGPUOperand::CreateImm(Imm16Val, S, AMDGPUOperand::ImmTyHwreg));
+  return MatchOperand_Success;
+}
+
 bool AMDGPUOperand::isSWaitCnt() const {
   return isImm();
 }
 
+bool AMDGPUOperand::isHwreg() const {
+  return isImmTy(ImmTyHwreg);
+}
+
 //===----------------------------------------------------------------------===//
 // sopp branch targets
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp?rev=267410&r1=267409&r2=267410&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp Mon Apr 25 09:13:51 2016
@@ -760,4 +760,18 @@ void AMDGPUInstPrinter::printWaitFlag(co
   }
 }
 
+void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
+                                   raw_ostream &O) {
+  unsigned SImm16 = MI->getOperand(OpNo).getImm();
+  const unsigned HwRegCode = SImm16 & 0x3F;
+  const unsigned Offset = (SImm16 >> 6) & 0x1f;
+  const unsigned Width = ((SImm16 >> 11) & 0x1F) + 1;
+
+  if (Width == 32 && Offset == 0) {
+    O << "hwreg(" << HwRegCode << ')';
+  } else {
+    O << "hwreg(" << HwRegCode << ", " << Offset << ", " << Width << ')';
+  }
+}
+
 #include "AMDGPUGenAsmWriter.inc"

Modified: llvm/trunk/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h?rev=267410&r1=267409&r2=267410&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h (original)
+++ llvm/trunk/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h Mon Apr 25 09:13:51 2016
@@ -91,6 +91,7 @@ private:
   static void printKCache(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   static void printSendMsg(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   static void printWaitFlag(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+  static void printHwreg(const MCInst *MI, unsigned OpNo, raw_ostream &O);
 };
 
 } // End namespace llvm

Modified: llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td?rev=267410&r1=267409&r2=267410&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td (original)
+++ llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td Mon Apr 25 09:13:51 2016
@@ -603,6 +603,13 @@ class NamedBitOperand<string BitName> :
   let PrintMethod = "print"#BitName;
 }
 
+def HwregMatchClass : AsmOperandClass {
+  let Name = "Hwreg";
+  let PredicateMethod = "isHwreg";
+  let ParserMethod = "parseHwregOp";
+  let RenderMethod = "addImmOperands";
+}
+
 let OperandType = "OPERAND_IMMEDIATE" in {
 
 def offen : Operand<i1> {
@@ -730,6 +737,11 @@ def bound_ctrl : Operand <i1> {
   let ParserMatchClass = DPPOptionalMatchClass<"BoundCtrl">;
 }
 
+def hwreg : Operand <i16> {
+  let PrintMethod = "printHwreg";
+  let ParserMatchClass = HwregMatchClass;
+}
+
 } // End OperandType = "OPERAND_IMMEDIATE"
 
 

Modified: llvm/trunk/lib/Target/AMDGPU/SIInstructions.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SIInstructions.td?rev=267410&r1=267409&r2=267410&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/SIInstructions.td (original)
+++ llvm/trunk/lib/Target/AMDGPU/SIInstructions.td Mon Apr 25 09:13:51 2016
@@ -418,18 +418,21 @@ defm S_CBRANCH_I_FORK : SOPK_m <
 >;
 
 let mayLoad = 1 in {
-defm S_GETREG_B32 : SOPK_32 <sopk<0x12, 0x11>, "s_getreg_b32", []>;
+defm S_GETREG_B32 : SOPK_m <
+  sopk<0x12, 0x11>, "s_getreg_b32", (outs SReg_32:$sdst),
+  (ins hwreg:$simm16), " $sdst, $simm16"
+>;
 }
 
 defm S_SETREG_B32 : SOPK_m <
   sopk<0x13, 0x12>, "s_setreg_b32", (outs),
-  (ins SReg_32:$sdst, u16imm:$simm16), " $simm16, $sdst"
+  (ins SReg_32:$sdst, hwreg:$simm16), " $simm16, $sdst"
 >;
 // FIXME: Not on SI?
 //defm S_GETREG_REGRD_B32 : SOPK_32 <sopk<0x14, 0x13>, "s_getreg_regrd_b32", []>;
 defm S_SETREG_IMM32_B32 : SOPK_IMM32 <
   sopk<0x15, 0x14>, "s_setreg_imm32_b32", (outs),
-  (ins i32imm:$imm, u16imm:$simm16), " $simm16, $imm"
+  (ins i32imm:$imm, hwreg:$simm16), " $simm16, $imm"
 >;
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.s.getreg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.s.getreg.ll?rev=267410&r1=267409&r2=267410&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.s.getreg.ll (original)
+++ llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.s.getreg.ll Mon Apr 25 09:13:51 2016
@@ -3,7 +3,7 @@
 ; RUN: llc -mtriple=amdgcn--amdhsa -mcpu=fiji -verify-machineinstrs < %s | FileCheck %s
 
 ; FUNC-LABEL: {{^}}s_getreg_test:
-; CHECK: s_getreg_b32 s{{[0-9]+}}, 0xb206
+; CHECK: s_getreg_b32 s{{[0-9]+}}, hwreg(6, 8, 23)
 define void @s_getreg_test(i32 addrspace(1)* %out) { ; simm16=45574 for lds size.
   %lds_size_64dwords = call i32 @llvm.amdgcn.s.getreg(i32 45574) #0
   %lds_size_bytes = shl i32 %lds_size_64dwords, 8

Added: llvm/trunk/test/MC/AMDGPU/sopk-err.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/sopk-err.s?rev=267410&view=auto
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/sopk-err.s (added)
+++ llvm/trunk/test/MC/AMDGPU/sopk-err.s Mon Apr 25 09:13:51 2016
@@ -0,0 +1,24 @@
+// RUN: not llvm-mc -arch=amdgcn %s 2>&1 | FileCheck -check-prefix=GCN %s
+// RUN: not llvm-mc -arch=amdgcn -mcpu=tahiti %s 2>&1 | FileCheck -check-prefix=GCN -check-prefix=SI %s
+// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga %s 2>&1 | FileCheck -check-prefix=GCN -check-prefix=VI %s
+
+s_setreg_b32  0x1f803, s2
+// GCN: error: invalid immediate: only 16-bit values are legal
+
+s_setreg_b32  hwreg(0x40), s2
+// GCN: error: invalid code of hardware register: only 6-bit values are legal
+
+s_setreg_b32  hwreg(3,32,32), s2
+// GCN: error: invalid bit offset: only 5-bit values are legal
+
+s_setreg_b32  hwreg(3,0,33), s2
+// GCN: error: invalid bitfield width: only values from 1 to 32 are legal
+
+s_setreg_imm32_b32  0x1f803, 0xff
+// GCN: error: invalid immediate: only 16-bit values are legal
+
+s_setreg_imm32_b32  hwreg(3,0,33), 0xff
+// GCN: error: invalid bitfield width: only values from 1 to 32 are legal
+
+s_getreg_b32  s2, hwreg(3,32,32)
+// GCN: error: invalid bit offset: only 5-bit values are legal

Modified: llvm/trunk/test/MC/AMDGPU/sopk.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/sopk.s?rev=267410&r1=267409&r2=267410&view=diff
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/sopk.s (original)
+++ llvm/trunk/test/MC/AMDGPU/sopk.s Mon Apr 25 09:13:51 2016
@@ -74,13 +74,33 @@ s_cbranch_i_fork s[2:3], 0x6
 // VI:   s_cbranch_i_fork s[2:3], 0x6 ; encoding: [0x06,0x00,0x02,0xb8]
 
 s_getreg_b32 s2, 0x6
-// SICI: s_getreg_b32 s2, 0x6 ; encoding: [0x06,0x00,0x02,0xb9]
-// VI:   s_getreg_b32 s2, 0x6 ; encoding: [0x06,0x00,0x82,0xb8]
+// SICI: s_getreg_b32 s2, hwreg(6, 0, 1) ; encoding: [0x06,0x00,0x02,0xb9]
+// VI:   s_getreg_b32 s2, hwreg(6, 0, 1) ; encoding: [0x06,0x00,0x82,0xb8]
+
+s_getreg_b32 s2, hwreg(5, 1, 31)
+// SICI: s_getreg_b32 s2, hwreg(5, 1, 31) ; encoding: [0x45,0xf0,0x02,0xb9]
+// VI:   s_getreg_b32 s2, hwreg(5, 1, 31) ; encoding: [0x45,0xf0,0x82,0xb8]
 
 s_setreg_b32 0x6, s2
-// SICI: s_setreg_b32 0x6, s2 ; encoding: [0x06,0x00,0x82,0xb9]
-// VI:   s_setreg_b32 0x6, s2 ; encoding: [0x06,0x00,0x02,0xb9]
+// SICI: s_setreg_b32 hwreg(6, 0, 1), s2 ; encoding: [0x06,0x00,0x82,0xb9]
+// VI:   s_setreg_b32 hwreg(6, 0, 1), s2 ; encoding: [0x06,0x00,0x02,0xb9]
+
+s_setreg_b32 0xf803, s2
+// SICI: s_setreg_b32 hwreg(3), s2       ; encoding: [0x03,0xf8,0x82,0xb9]
+// VI:   s_setreg_b32 hwreg(3), s2       ; encoding: [0x03,0xf8,0x02,0xb9]
+
+s_setreg_b32 hwreg(4), s2
+// SICI: s_setreg_b32 hwreg(4), s2       ; encoding: [0x04,0xf8,0x82,0xb9]
+// VI:   s_setreg_b32 hwreg(4), s2       ; encoding: [0x04,0xf8,0x02,0xb9]
+
+s_setreg_b32 hwreg(5, 1, 31), s2
+// SICI: s_setreg_b32 hwreg(5, 1, 31), s2       ; encoding: [0x45,0xf0,0x82,0xb9]
+// VI:   s_setreg_b32 hwreg(5, 1, 31), s2       ; encoding: [0x45,0xf0,0x02,0xb9]
 
 s_setreg_imm32_b32 0x6, 0xff
-// SICI: s_setreg_imm32_b32 0x6, 0xff ; encoding: [0x06,0x00,0x80,0xba,0xff,0x00,0x00,0x00]
-// VI:   s_setreg_imm32_b32 0x6, 0xff ; encoding: [0x06,0x00,0x00,0xba,0xff,0x00,0x00,0x00]
+// SICI: s_setreg_imm32_b32 hwreg(6, 0, 1), 0xff ; encoding: [0x06,0x00,0x80,0xba,0xff,0x00,0x00,0x00]
+// VI:   s_setreg_imm32_b32 hwreg(6, 0, 1), 0xff ; encoding: [0x06,0x00,0x00,0xba,0xff,0x00,0x00,0x00]
+
+s_setreg_imm32_b32 hwreg(5, 1, 31), 0xff
+// SICI: s_setreg_imm32_b32 hwreg(5, 1, 31), 0xff ; encoding: [0x45,0xf0,0x80,0xba,0xff,0x00,0x00,0x00]
+// VI:   s_setreg_imm32_b32 hwreg(5, 1, 31), 0xff ; encoding: [0x45,0xf0,0x00,0xba,0xff,0x00,0x00,0x00]

Modified: llvm/trunk/test/MC/Disassembler/AMDGPU/sopk_vi.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/AMDGPU/sopk_vi.txt?rev=267410&r1=267409&r2=267410&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/AMDGPU/sopk_vi.txt (original)
+++ llvm/trunk/test/MC/Disassembler/AMDGPU/sopk_vi.txt Mon Apr 25 09:13:51 2016
@@ -48,11 +48,11 @@
 # VI:   s_cbranch_i_fork s[2:3], 0x6 ; encoding: [0x06,0x00,0x02,0xb8]
 0x06 0x00 0x02 0xb8
 
-# VI:   s_getreg_b32 s2, 0x6 ; encoding: [0x06,0x00,0x82,0xb8]
-0x06 0x00 0x82 0xb8
+# VI:   s_getreg_b32 s2, hwreg(6) ; encoding: [0x06,0xf8,0x82,0xb8]
+0x06 0xf8 0x82 0xb8
 
-# VI:   s_setreg_b32 0x6, s2 ; encoding: [0x06,0x00,0x02,0xb9]
+# VI:   s_setreg_b32 hwreg(6, 0, 1), s2 ; encoding: [0x06,0x00,0x02,0xb9]
 0x06 0x00 0x02 0xb9
 
-# VI:   s_setreg_imm32_b32 0x6, 0xff ; encoding: [0x06,0x00,0x00,0xba,0xff,0x00,0x00,0x00]
-0x06 0x00 0x00 0xba 0xff 0x00 0x00 0x00
+# VI:   s_setreg_imm32_b32 hwreg(5, 1, 31), 0xff ; encoding: [0x45,0xf0,0x00,0xba,0xff,0x00,0x00,0x00]
+0x45 0xf0 0x00 0xba 0xff 0x00 0x00 0x00




More information about the llvm-commits mailing list