diff options
author | Michel Danzer <michel.daenzer@amd.com> | 2014-01-27 07:20:44 +0000 |
---|---|---|
committer | Michel Danzer <michel.daenzer@amd.com> | 2014-01-27 07:20:44 +0000 |
commit | b3bfe7f18cb15368f94c105e88682c297576160c (patch) | |
tree | a2db7c559c5616ffd91baa6d6f0987c95efed7f2 /lib | |
parent | 650e286dcf39e58a1e9de767354ff0bda4a9a82e (diff) | |
download | llvm-b3bfe7f18cb15368f94c105e88682c297576160c.tar.gz llvm-b3bfe7f18cb15368f94c105e88682c297576160c.tar.bz2 llvm-b3bfe7f18cb15368f94c105e88682c297576160c.tar.xz |
R600/SI: Add intrinsic for S_SENDMSG instruction
Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200195 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp | 31 | ||||
-rw-r--r-- | lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h | 1 | ||||
-rw-r--r-- | lib/Target/R600/SIInsertWaits.cpp | 6 | ||||
-rw-r--r-- | lib/Target/R600/SIInstructions.td | 16 | ||||
-rw-r--r-- | lib/Target/R600/SIIntrinsics.td | 2 |
5 files changed, 54 insertions, 2 deletions
diff --git a/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp b/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp index 99e1377a65..7105879906 100644 --- a/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp +++ b/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp @@ -316,6 +316,37 @@ void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo, } } +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 diff --git a/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h b/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h index 77af9425c5..2876dd26b2 100644 --- a/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h +++ b/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h @@ -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); }; diff --git a/lib/Target/R600/SIInsertWaits.cpp b/lib/Target/R600/SIInsertWaits.cpp index 7ef662eb65..695ec407fd 100644 --- a/lib/Target/R600/SIInsertWaits.cpp +++ b/lib/Target/R600/SIInsertWaits.cpp @@ -314,6 +314,12 @@ Counters SIInsertWaits::handleOperands(MachineInstr &MI) { 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) { diff --git a/lib/Target/R600/SIInstructions.td b/lib/Target/R600/SIInstructions.td index 3baa4cd33a..c0ad398dbe 100644 --- a/lib/Target/R600/SIInstructions.td +++ b/lib/Target/R600/SIInstructions.td @@ -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), "S_BARRIER", 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), diff --git a/lib/Target/R600/SIIntrinsics.td b/lib/Target/R600/SIIntrinsics.td index 7fcc964521..efcdc84610 100644 --- a/lib/Target/R600/SIIntrinsics.td +++ b/lib/Target/R600/SIIntrinsics.td @@ -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; |