Skip to content

Commit

Permalink
R600/SI: Add intrinsic for S_SENDMSG instruction
Browse files Browse the repository at this point in the history
Reviewed-by: Tom Stellard <[email protected]>
llvm-svn: 200195
  • Loading branch information
Michel Danzer committed Jan 27, 2014
1 parent 17d4e98 commit 6064f57
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 2 deletions.
31 changes: 31 additions & 0 deletions llvm/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class AMDGPUInstPrinter : public MCInstPrinter {
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);
};

Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/R600/SIInsertWaits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
16 changes: 14 additions & 2 deletions llvm/lib/Target/R600/SIInstructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -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">;

Expand Down Expand Up @@ -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),
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/R600/SIIntrinsics.td
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
21 changes: 21 additions & 0 deletions llvm/test/CodeGen/R600/llvm.SI.sendmsg.ll
Original file line number Diff line number Diff line change
@@ -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 }

0 comments on commit 6064f57

Please sign in to comment.