Re: [Mesa-dev] R600/SI: New intrinsics for radeonsi geometry shaders
On Fri, Jan 24, 2014 at 03:17:04PM +0900, Michel Dänzer wrote: > > The attached patches add two intrinsics to the R600 backend which are > necessary for geometry shader support in the radeonsi driver. > Patch 1 and v2 of Patch 2 are: Reviewed-by: Tom Stellard -Tom > > -- > Earthling Michel Dänzer| http://www.amd.com > Libre software enthusiast |Mesa and X developer > From 8feb7201ac894e5a6731a157020ac807936f584d Mon Sep 17 00:00:00 2001 > From: =?UTF-8?q?Michel=20D=C3=A4nzer?= > Date: Fri, 29 Nov 2013 18:21:41 +0900 > Subject: [PATCH 1/2] R600/SI: Add intrinsic for S_SENDMSG instruction > MIME-Version: 1.0 > Content-Type: text/plain; charset=UTF-8 > Content-Transfer-Encoding: 8bit > > Signed-off-by: Michel Dänzer > --- > lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp | 31 > +++ > lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h | 1 + > lib/Target/R600/SIInsertWaits.cpp | 6 + > lib/Target/R600/SIInstructions.td | 16 ++-- > lib/Target/R600/SIIntrinsics.td | 2 ++ > test/CodeGen/R600/llvm.SI.sendmsg.ll | 21 +++ > 6 files changed, 75 insertions(+), 2 deletions(-) > create mode 100644 test/CodeGen/R600/llvm.SI.sendmsg.ll > > diff --git a/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp > b/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp > index 99e1377..7105879 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 77af942..2876dd2 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 7ef662e..695ec40 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 3baa4cd..c0ad398 100644 > --- a/lib/Target/R600/SIInstructions.td > +++ b/lib/Target/R600/SIInstructions.td > @@ -22,6 +22,10 @@ def InterpSlot : Operand { >let PrintMethod = "printInterpSlot"; > } > > +def SendMsgImm : Operand { > + let PrintMethod = "printSendMsg"; > +} > + > def isSI : Predicate<"Subtarget.getGeneration() " >">= AMDGPUSubtarget::SOUTHERN_ISLANDS">; > > @@ -826,17 +830,25 @@ def S_BARRIER : SOPP <0x000a, (ins), "S_BARRIER", > def S_WAITCNT : SOPP <0x000c, (ins WAIT_FLAG:$simm16), "S_WAITCNT > $simm16", >[] > >; > -} // End hasSideEffects > //def S_SETHALT : SOPP_ <0x000d, "S_SETHALT", []>; > //def S_SLEEP : SOPP_ <0x000e, "S_SL
[Mesa-dev] R600/SI: New intrinsics for radeonsi geometry shaders
The attached patches add two intrinsics to the R600 backend which are necessary for geometry shader support in the radeonsi driver. -- Earthling Michel Dänzer| http://www.amd.com Libre software enthusiast |Mesa and X developer >From 8feb7201ac894e5a6731a157020ac807936f584d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 29 Nov 2013 18:21:41 +0900 Subject: [PATCH 1/2] R600/SI: Add intrinsic for S_SENDMSG instruction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michel Dänzer --- lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp | 31 +++ lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h | 1 + lib/Target/R600/SIInsertWaits.cpp | 6 + lib/Target/R600/SIInstructions.td | 16 ++-- lib/Target/R600/SIIntrinsics.td | 2 ++ test/CodeGen/R600/llvm.SI.sendmsg.ll | 21 +++ 6 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/R600/llvm.SI.sendmsg.ll diff --git a/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp b/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp index 99e1377..7105879 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 77af942..2876dd2 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 7ef662e..695ec40 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 3baa4cd..c0ad398 100644 --- a/lib/Target/R600/SIInstructions.td +++ b/lib/Target/R600/SIInstructions.td @@ -22,6 +22,10 @@ def InterpSlot : Operand { let PrintMethod = "printInterpSlot"; } +def SendMsgImm : Operand { + let PrintMethod = "printSendMsg"; +} + def isSI : Predicate<"Subtarget.getGeneration() " ">= AMDGPUSubtarget::SOUTHERN_ISLANDS">; @@ -826,17 +830,25 @@ def S_BARRIER : SOPP <0x000a, (ins), "S_BARRIER", def S_WAITCNT : SOPP <0x000c, (ins WAIT_FLAG:$simm16), "S_WAITCNT $simm16", [] >; -} // End hasSideEffects //def S_SETHALT : SOPP_ <0x000d, "S_SETHALT", []>; //def S_SLEEP : SOPP_ <0x000e, "S_SLEEP", []>; //def S_SETPRIO : SOPP_ <0x000f, "S_SETPRIO", []>; -//def S_SENDMSG : SOPP_ <0x0010, "S_SENDMSG", []>; + +let Uses = [EXEC] in { + def S_SENDMSG : SOPP <0x0010, (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_ <0x0011,