[llvm] r200195 - R600/SI: Add intrinsic for S_SENDMSG instruction

Michel Danzer michel.daenzer at amd.com
Sun Jan 26 23:20:45 PST 2014


Author: daenzer
Date: Mon Jan 27 01:20:44 2014
New Revision: 200195

URL: http://llvm.org/viewvc/llvm-project?rev=200195&view=rev
Log:
R600/SI: Add intrinsic for S_SENDMSG instruction

Reviewed-by: Tom Stellard <thomas.stellard at amd.com>

Added:
    llvm/trunk/test/CodeGen/R600/llvm.SI.sendmsg.ll
Modified:
    llvm/trunk/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp
    llvm/trunk/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h
    llvm/trunk/lib/Target/R600/SIInsertWaits.cpp
    llvm/trunk/lib/Target/R600/SIInstructions.td
    llvm/trunk/lib/Target/R600/SIIntrinsics.td

Modified: llvm/trunk/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp?rev=200195&r1=200194&r2=200195&view=diff
==============================================================================
--- llvm/trunk/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp Mon Jan 27 01:20:44 2014
@@ -316,6 +316,37 @@ void AMDGPUInstPrinter::printKCache(cons
   }
 }
 
+void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
+                                     raw_ostream &O) {
+  unsigned SImm16 = MI->getOperand(OpNo).getImm();
+  unsigned Msg = SImm16 & 0xF;
+  if (Msg == 2 || Msg == 3) {
+    unsigned Op = (SImm16 >> 4) & 0xF;
+    if (Msg == 3)
+      O << "Gs_done(";
+    else
+      O << "Gs(";
+    if (Op == 0) {
+      O << "nop";
+    } else {
+      unsigned Stream = (SImm16 >> 8) & 0x3;
+      if (Op == 1)
+	O << "cut";
+      else if (Op == 2)
+	O << "emit";
+      else if (Op == 3)
+	O << "emit-cut";
+      O << " stream " << Stream;
+    }
+    O << "), [m0] ";
+  } else if (Msg == 1)
+    O << "interrupt ";
+  else if (Msg == 15)
+    O << "system ";
+  else
+    O << "unknown(" << Msg << ") ";
+}
+
 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
                                       raw_ostream &O) {
   // Note: Mask values are taken from SIInsertWaits.cpp and not from ISA docs

Modified: llvm/trunk/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h?rev=200195&r1=200194&r2=200195&view=diff
==============================================================================
--- llvm/trunk/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h (original)
+++ llvm/trunk/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h Mon Jan 27 01:20:44 2014
@@ -53,6 +53,7 @@ private:
   void printRSel(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printCT(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printKCache(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+  void printSendMsg(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printWaitFlag(const MCInst *MI, unsigned OpNo, raw_ostream &O);
 };
 

Modified: llvm/trunk/lib/Target/R600/SIInsertWaits.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/SIInsertWaits.cpp?rev=200195&r1=200194&r2=200195&view=diff
==============================================================================
--- llvm/trunk/lib/Target/R600/SIInsertWaits.cpp (original)
+++ llvm/trunk/lib/Target/R600/SIInsertWaits.cpp Mon Jan 27 01:20:44 2014
@@ -314,6 +314,12 @@ Counters SIInsertWaits::handleOperands(M
 
   Counters Result = ZeroCounts;
 
+  // S_SENDMSG implicitly waits for all outstanding LGKM transfers to finish,
+  // but we also want to wait for any other outstanding transfers before
+  // signalling other hardware blocks
+  if (MI.getOpcode() == AMDGPU::S_SENDMSG)
+    return LastIssued;
+
   // For each register affected by this
   // instruction increase the result sequence
   for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {

Modified: llvm/trunk/lib/Target/R600/SIInstructions.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/SIInstructions.td?rev=200195&r1=200194&r2=200195&view=diff
==============================================================================
--- llvm/trunk/lib/Target/R600/SIInstructions.td (original)
+++ llvm/trunk/lib/Target/R600/SIInstructions.td Mon Jan 27 01:20:44 2014
@@ -22,6 +22,10 @@ def InterpSlot : Operand<i32> {
   let PrintMethod = "printInterpSlot";
 }
 
+def SendMsgImm : Operand<i32> {
+  let PrintMethod = "printSendMsg";
+}
+
 def isSI : Predicate<"Subtarget.getGeneration() "
                       ">= AMDGPUSubtarget::SOUTHERN_ISLANDS">;
 
@@ -826,17 +830,25 @@ def S_BARRIER : SOPP <0x0000000a, (ins),
 def S_WAITCNT : SOPP <0x0000000c, (ins WAIT_FLAG:$simm16), "S_WAITCNT $simm16",
   []
 >;
-} // End hasSideEffects
 //def S_SETHALT : SOPP_ <0x0000000d, "S_SETHALT", []>;
 //def S_SLEEP : SOPP_ <0x0000000e, "S_SLEEP", []>;
 //def S_SETPRIO : SOPP_ <0x0000000f, "S_SETPRIO", []>;
-//def S_SENDMSG : SOPP_ <0x00000010, "S_SENDMSG", []>;
+
+let Uses = [EXEC] in {
+  def S_SENDMSG : SOPP <0x00000010, (ins SendMsgImm:$simm16, M0Reg:$m0), "S_SENDMSG $simm16",
+      [(int_SI_sendmsg imm:$simm16, M0Reg:$m0)]
+  > {
+    let DisableEncoding = "$m0";
+  }
+} // End Uses = [EXEC]
+
 //def S_SENDMSGHALT : SOPP_ <0x00000011, "S_SENDMSGHALT", []>;
 //def S_TRAP : SOPP_ <0x00000012, "S_TRAP", []>;
 //def S_ICACHE_INV : SOPP_ <0x00000013, "S_ICACHE_INV", []>;
 //def S_INCPERFLEVEL : SOPP_ <0x00000014, "S_INCPERFLEVEL", []>;
 //def S_DECPERFLEVEL : SOPP_ <0x00000015, "S_DECPERFLEVEL", []>;
 //def S_TTRACEDATA : SOPP_ <0x00000016, "S_TTRACEDATA", []>;
+} // End hasSideEffects
 
 def V_CNDMASK_B32_e32 : VOP2 <0x00000000, (outs VReg_32:$dst),
   (ins VSrc_32:$src0, VReg_32:$src1, VCCReg:$vcc),

Modified: llvm/trunk/lib/Target/R600/SIIntrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/SIIntrinsics.td?rev=200195&r1=200194&r2=200195&view=diff
==============================================================================
--- llvm/trunk/lib/Target/R600/SIIntrinsics.td (original)
+++ llvm/trunk/lib/Target/R600/SIIntrinsics.td Mon Jan 27 01:20:44 2014
@@ -38,6 +38,8 @@ let TargetPrefix = "SI", isTarget = 1 in
      llvm_i32_ty],   // tfe(imm)
     []>;
 
+  def int_SI_sendmsg : Intrinsic <[], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
   class Sample : Intrinsic <[llvm_v4f32_ty], [llvm_anyvector_ty, llvm_v32i8_ty, llvm_anyint_ty, llvm_i32_ty], [IntrNoMem]>;
 
   def int_SI_sample : Sample;

Added: llvm/trunk/test/CodeGen/R600/llvm.SI.sendmsg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/R600/llvm.SI.sendmsg.ll?rev=200195&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/R600/llvm.SI.sendmsg.ll (added)
+++ llvm/trunk/test/CodeGen/R600/llvm.SI.sendmsg.ll Mon Jan 27 01:20:44 2014
@@ -0,0 +1,21 @@
+;RUN: llc < %s -march=r600 -mcpu=verde -verify-machineinstrs | FileCheck %s
+
+; CHECK-LABEL: @main
+; CHECK: S_SENDMSG Gs(emit stream 0)
+; CHECK: S_SENDMSG Gs(cut stream 1)
+; CHECK: S_SENDMSG Gs(emit-cut stream 2)
+; CHECK: S_SENDMSG Gs_done(nop)
+
+define void @main() {
+main_body:
+  call void @llvm.SI.sendmsg(i32 34, i32 0);
+  call void @llvm.SI.sendmsg(i32 274, i32 0);
+  call void @llvm.SI.sendmsg(i32 562, i32 0);
+  call void @llvm.SI.sendmsg(i32 3, i32 0);
+  ret void
+}
+
+; Function Attrs: nounwind
+declare void @llvm.SI.sendmsg(i32, i32) #0
+
+attributes #0 = { nounwind }





More information about the llvm-commits mailing list