mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-17 21:42:12 +00:00
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
This commit is contained in:
parent
650e286dcf
commit
b3bfe7f18c
@ -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,
|
void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
|
||||||
raw_ostream &O) {
|
raw_ostream &O) {
|
||||||
// Note: Mask values are taken from SIInsertWaits.cpp and not from ISA docs
|
// Note: Mask values are taken from SIInsertWaits.cpp and not from ISA docs
|
||||||
|
@ -53,6 +53,7 @@ private:
|
|||||||
void printRSel(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
void printRSel(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||||
void printCT(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 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);
|
void printWaitFlag(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -314,6 +314,12 @@ Counters SIInsertWaits::handleOperands(MachineInstr &MI) {
|
|||||||
|
|
||||||
Counters Result = ZeroCounts;
|
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
|
// For each register affected by this
|
||||||
// instruction increase the result sequence
|
// instruction increase the result sequence
|
||||||
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
|
||||||
|
@ -22,6 +22,10 @@ def InterpSlot : Operand<i32> {
|
|||||||
let PrintMethod = "printInterpSlot";
|
let PrintMethod = "printInterpSlot";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def SendMsgImm : Operand<i32> {
|
||||||
|
let PrintMethod = "printSendMsg";
|
||||||
|
}
|
||||||
|
|
||||||
def isSI : Predicate<"Subtarget.getGeneration() "
|
def isSI : Predicate<"Subtarget.getGeneration() "
|
||||||
">= AMDGPUSubtarget::SOUTHERN_ISLANDS">;
|
">= 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",
|
def S_WAITCNT : SOPP <0x0000000c, (ins WAIT_FLAG:$simm16), "S_WAITCNT $simm16",
|
||||||
[]
|
[]
|
||||||
>;
|
>;
|
||||||
} // End hasSideEffects
|
|
||||||
//def S_SETHALT : SOPP_ <0x0000000d, "S_SETHALT", []>;
|
//def S_SETHALT : SOPP_ <0x0000000d, "S_SETHALT", []>;
|
||||||
//def S_SLEEP : SOPP_ <0x0000000e, "S_SLEEP", []>;
|
//def S_SLEEP : SOPP_ <0x0000000e, "S_SLEEP", []>;
|
||||||
//def S_SETPRIO : SOPP_ <0x0000000f, "S_SETPRIO", []>;
|
//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_SENDMSGHALT : SOPP_ <0x00000011, "S_SENDMSGHALT", []>;
|
||||||
//def S_TRAP : SOPP_ <0x00000012, "S_TRAP", []>;
|
//def S_TRAP : SOPP_ <0x00000012, "S_TRAP", []>;
|
||||||
//def S_ICACHE_INV : SOPP_ <0x00000013, "S_ICACHE_INV", []>;
|
//def S_ICACHE_INV : SOPP_ <0x00000013, "S_ICACHE_INV", []>;
|
||||||
//def S_INCPERFLEVEL : SOPP_ <0x00000014, "S_INCPERFLEVEL", []>;
|
//def S_INCPERFLEVEL : SOPP_ <0x00000014, "S_INCPERFLEVEL", []>;
|
||||||
//def S_DECPERFLEVEL : SOPP_ <0x00000015, "S_DECPERFLEVEL", []>;
|
//def S_DECPERFLEVEL : SOPP_ <0x00000015, "S_DECPERFLEVEL", []>;
|
||||||
//def S_TTRACEDATA : SOPP_ <0x00000016, "S_TTRACEDATA", []>;
|
//def S_TTRACEDATA : SOPP_ <0x00000016, "S_TTRACEDATA", []>;
|
||||||
|
} // End hasSideEffects
|
||||||
|
|
||||||
def V_CNDMASK_B32_e32 : VOP2 <0x00000000, (outs VReg_32:$dst),
|
def V_CNDMASK_B32_e32 : VOP2 <0x00000000, (outs VReg_32:$dst),
|
||||||
(ins VSrc_32:$src0, VReg_32:$src1, VCCReg:$vcc),
|
(ins VSrc_32:$src0, VReg_32:$src1, VCCReg:$vcc),
|
||||||
|
@ -38,6 +38,8 @@ let TargetPrefix = "SI", isTarget = 1 in {
|
|||||||
llvm_i32_ty], // tfe(imm)
|
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]>;
|
class Sample : Intrinsic <[llvm_v4f32_ty], [llvm_anyvector_ty, llvm_v32i8_ty, llvm_anyint_ty, llvm_i32_ty], [IntrNoMem]>;
|
||||||
|
|
||||||
def int_SI_sample : Sample;
|
def int_SI_sample : Sample;
|
||||||
|
21
test/CodeGen/R600/llvm.SI.sendmsg.ll
Normal file
21
test/CodeGen/R600/llvm.SI.sendmsg.ll
Normal file
@ -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 }
|
Loading…
x
Reference in New Issue
Block a user