From 97d2187f483444e16f5a27c0e106c18488fc8605 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Fri, 8 Mar 2024 11:13:38 -0600 Subject: [PATCH] nak/sm50: Add control-flow sync ops Part-of: --- src/nouveau/compiler/nak/ir.rs | 99 +++++++++++++++++++++++++++++++- src/nouveau/compiler/nak/sm50.rs | 75 ++++++++++++++++++++++++ 2 files changed, 173 insertions(+), 1 deletion(-) diff --git a/src/nouveau/compiler/nak/ir.rs b/src/nouveau/compiler/nak/ir.rs index 4eb754c9be9..085b5a60ff4 100644 --- a/src/nouveau/compiler/nak/ir.rs +++ b/src/nouveau/compiler/nak/ir.rs @@ -5105,6 +5105,78 @@ impl DisplayOp for OpBra { } impl_display_for_op!(OpBra); +#[repr(C)] +#[derive(SrcsAsSlice, DstsAsSlice)] +pub struct OpSSy { + pub target: Label, +} + +impl DisplayOp for OpSSy { + fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ssy {}", self.target) + } +} +impl_display_for_op!(OpSSy); + +#[repr(C)] +#[derive(SrcsAsSlice, DstsAsSlice)] +pub struct OpSync {} + +impl DisplayOp for OpSync { + fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "sync") + } +} +impl_display_for_op!(OpSync); + +#[repr(C)] +#[derive(SrcsAsSlice, DstsAsSlice)] +pub struct OpBrk {} + +impl DisplayOp for OpBrk { + fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "brk") + } +} +impl_display_for_op!(OpBrk); + +#[repr(C)] +#[derive(SrcsAsSlice, DstsAsSlice)] +pub struct OpPBk { + pub target: Label, +} + +impl DisplayOp for OpPBk { + fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "pbk {}", self.target) + } +} +impl_display_for_op!(OpPBk); + +#[repr(C)] +#[derive(SrcsAsSlice, DstsAsSlice)] +pub struct OpCont {} + +impl DisplayOp for OpCont { + fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "cont") + } +} +impl_display_for_op!(OpCont); + +#[repr(C)] +#[derive(SrcsAsSlice, DstsAsSlice)] +pub struct OpPCnt { + pub target: Label, +} + +impl DisplayOp for OpPCnt { + fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "pcnt {}", self.target) + } +} +impl_display_for_op!(OpPCnt); + #[repr(C)] #[derive(Clone, SrcsAsSlice, DstsAsSlice)] pub struct OpExit {} @@ -5841,6 +5913,12 @@ pub enum Op { BSSy(OpBSSy), BSync(OpBSync), Bra(OpBra), + SSy(OpSSy), + Sync(OpSync), + Brk(OpBrk), + PBk(OpPBk), + Cont(OpCont), + PCnt(OpPCnt), Exit(OpExit), WarpSync(OpWarpSync), Bar(OpBar), @@ -6160,7 +6238,14 @@ impl Instr { } pub fn is_branch(&self) -> bool { - matches!(self.op, Op::Bra(_) | Op::Exit(_)) + match &self.op { + Op::Bra(_) + | Op::Sync(_) + | Op::Brk(_) + | Op::Cont(_) + | Op::Exit(_) => true, + _ => false, + } } pub fn uses_global_mem(&self) -> bool { @@ -6195,6 +6280,12 @@ impl Instr { | Op::Nop(_) | Op::BSync(_) | Op::Bra(_) + | Op::SSy(_) + | Op::Sync(_) + | Op::Brk(_) + | Op::PBk(_) + | Op::Cont(_) + | Op::PCnt(_) | Op::Exit(_) | Op::WarpSync(_) | Op::Bar(_) @@ -6300,6 +6391,12 @@ impl Instr { // Control-flow ops Op::BClear(_) | Op::Break(_) | Op::BSSy(_) | Op::BSync(_) => true, + Op::SSy(_) + | Op::Sync(_) + | Op::Brk(_) + | Op::PBk(_) + | Op::Cont(_) + | Op::PCnt(_) => true, Op::Bra(_) | Op::Exit(_) => true, Op::WarpSync(_) => false, diff --git a/src/nouveau/compiler/nak/sm50.rs b/src/nouveau/compiler/nak/sm50.rs index 3aefdebf27a..02d3af824b6 100644 --- a/src/nouveau/compiler/nak/sm50.rs +++ b/src/nouveau/compiler/nak/sm50.rs @@ -2714,6 +2714,75 @@ impl SM50Op for OpBra { } } +impl SM50Op for OpSSy { + fn legalize(&mut self, _b: &mut LegalizeBuilder) { + // Nothing to do + } + + fn encode(&self, e: &mut SM50Encoder<'_>) { + e.set_opcode(0xe290); + e.set_rel_offset(20..44, &self.target); + e.set_field(0..5, 0xF_u8); // TODO: Pred? + } +} + +impl SM50Op for OpSync { + fn legalize(&mut self, _b: &mut LegalizeBuilder) { + // Nothing to do + } + + fn encode(&self, e: &mut SM50Encoder<'_>) { + e.set_opcode(0xf0f8); + e.set_field(0..5, 0xF_u8); // TODO: Pred? + } +} + +impl SM50Op for OpBrk { + fn legalize(&mut self, _b: &mut LegalizeBuilder) { + // Nothing to do + } + + fn encode(&self, e: &mut SM50Encoder<'_>) { + e.set_opcode(0xe340); + e.set_field(0..5, 0xF_u8); // TODO: Pred? + } +} + +impl SM50Op for OpPBk { + fn legalize(&mut self, _b: &mut LegalizeBuilder) { + // Nothing to do + } + + fn encode(&self, e: &mut SM50Encoder<'_>) { + e.set_opcode(0xe2a0); + e.set_rel_offset(20..44, &self.target); + e.set_field(0..5, 0xF_u8); // TODO: Pred? + } +} + +impl SM50Op for OpCont { + fn legalize(&mut self, _b: &mut LegalizeBuilder) { + // Nothing to do + } + + fn encode(&self, e: &mut SM50Encoder<'_>) { + e.set_opcode(0xe350); + e.set_field(0..5, 0xF_u8); // TODO: Pred? + } +} + +impl SM50Op for OpPCnt { + fn legalize(&mut self, _b: &mut LegalizeBuilder) { + // Nothing to do + } + + fn encode(&self, e: &mut SM50Encoder<'_>) { + e.set_opcode(0xe2b0); + e.set_rel_offset(20..44, &self.target); + e.set_field(0..5, 0xF_u8); // TODO: Pred? + } +} + impl SM50Op for OpExit { fn legalize(&mut self, _b: &mut LegalizeBuilder) { // Nothing to do @@ -2954,6 +3023,12 @@ macro_rules! as_sm50_op_match { Op::MemBar(op) => op, Op::Atom(op) => op, Op::Bra(op) => op, + Op::SSy(op) => op, + Op::Sync(op) => op, + Op::Brk(op) => op, + Op::PBk(op) => op, + Op::Cont(op) => op, + Op::PCnt(op) => op, Op::Exit(op) => op, Op::Bar(op) => op, Op::SuLd(op) => op,