nak: Add back OpBMov with better semantics
It now takes a regular Src and Dst and we handle both GPR -> Bar vs. Bar -> GPR forms in the emit code. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26463>
This commit is contained in:

committed by
Marge Bot

parent
40c96ff6ea
commit
7cd9680554
@@ -354,6 +354,28 @@ pub trait SSABuilder: Builder {
|
|||||||
self.copy_to(dst.into(), src);
|
self.copy_to(dst.into(), src);
|
||||||
dst
|
dst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bmov_to_bar(&mut self, src: Src) -> SSARef {
|
||||||
|
assert!(src.src_ref.as_ssa().unwrap().file() == RegFile::GPR);
|
||||||
|
let dst = self.alloc_ssa(RegFile::Bar, 1);
|
||||||
|
self.push_op(OpBMov {
|
||||||
|
dst: dst.into(),
|
||||||
|
src: src,
|
||||||
|
clear: false,
|
||||||
|
});
|
||||||
|
dst
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bmov_to_gpr(&mut self, src: Src) -> SSARef {
|
||||||
|
assert!(src.src_ref.as_ssa().unwrap().file() == RegFile::Bar);
|
||||||
|
let dst = self.alloc_ssa(RegFile::GPR, 1);
|
||||||
|
self.push_op(OpBMov {
|
||||||
|
dst: dst.into(),
|
||||||
|
src: src,
|
||||||
|
clear: false,
|
||||||
|
});
|
||||||
|
dst
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InstrBuilder {
|
pub struct InstrBuilder {
|
||||||
|
@@ -51,6 +51,14 @@ fn src_mod_is_bnot(src_mod: SrcMod) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dst_is_bar(dst: Dst) -> bool {
|
||||||
|
match dst {
|
||||||
|
Dst::None => false,
|
||||||
|
Dst::SSA(ssa) => ssa.file() == RegFile::Bar,
|
||||||
|
Dst::Reg(reg) => reg.file() == RegFile::Bar,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ALUSrc {
|
impl ALUSrc {
|
||||||
fn from_src_file(src: &Src, file: RegFile) -> ALUSrc {
|
fn from_src_file(src: &Src, file: RegFile) -> ALUSrc {
|
||||||
match src.src_ref {
|
match src.src_ref {
|
||||||
@@ -243,6 +251,22 @@ impl SM70Instr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_bar_reg(&mut self, range: Range<usize>, reg: RegRef) {
|
||||||
|
assert!(range.len() == 4);
|
||||||
|
assert!(reg.file() == RegFile::Bar);
|
||||||
|
assert!(reg.comps() == 1);
|
||||||
|
self.set_field(range, reg.base_idx());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_bar_dst(&mut self, range: Range<usize>, dst: Dst) {
|
||||||
|
self.set_bar_reg(range, *dst.as_reg().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_bar_src(&mut self, range: Range<usize>, src: Src) {
|
||||||
|
assert!(src.src_mod.is_none());
|
||||||
|
self.set_bar_reg(range, *src.src_ref.as_reg().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
fn set_alu_reg(
|
fn set_alu_reg(
|
||||||
&mut self,
|
&mut self,
|
||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
@@ -1673,6 +1697,24 @@ impl SM70Instr {
|
|||||||
self.set_bit(84, true); // .CLEAR
|
self.set_bit(84, true); // .CLEAR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn encode_bmov(&mut self, op: &OpBMov) {
|
||||||
|
if dst_is_bar(op.dst) {
|
||||||
|
self.set_opcode(0x356);
|
||||||
|
|
||||||
|
self.set_bar_dst(24..28, op.dst);
|
||||||
|
self.set_reg_src(32..40, op.src);
|
||||||
|
|
||||||
|
self.set_bit(84, op.clear);
|
||||||
|
} else {
|
||||||
|
self.set_opcode(0x355);
|
||||||
|
|
||||||
|
self.set_dst(op.dst);
|
||||||
|
self.set_bar_src(24..28, op.src);
|
||||||
|
|
||||||
|
self.set_bit(84, op.clear);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn encode_break(&mut self, op: &OpBreak) {
|
fn encode_break(&mut self, op: &OpBreak) {
|
||||||
self.set_opcode(0x942);
|
self.set_opcode(0x942);
|
||||||
self.set_field(16..20, op.bar.idx());
|
self.set_field(16..20, op.bar.idx());
|
||||||
@@ -1909,6 +1951,7 @@ impl SM70Instr {
|
|||||||
Op::CCtl(op) => si.encode_cctl(&op),
|
Op::CCtl(op) => si.encode_cctl(&op),
|
||||||
Op::MemBar(op) => si.encode_membar(&op),
|
Op::MemBar(op) => si.encode_membar(&op),
|
||||||
Op::BClear(op) => si.encode_bclear(&op),
|
Op::BClear(op) => si.encode_bclear(&op),
|
||||||
|
Op::BMov(op) => si.encode_bmov(&op),
|
||||||
Op::Break(op) => si.encode_break(&op),
|
Op::Break(op) => si.encode_break(&op),
|
||||||
Op::BSSy(op) => si.encode_bssy(&op, ip, labels),
|
Op::BSSy(op) => si.encode_bssy(&op, ip, labels),
|
||||||
Op::BSync(op) => si.encode_bsync(&op),
|
Op::BSync(op) => si.encode_bsync(&op),
|
||||||
|
@@ -3643,6 +3643,25 @@ impl DisplayOp for OpBClear {
|
|||||||
}
|
}
|
||||||
impl_display_for_op!(OpBClear);
|
impl_display_for_op!(OpBClear);
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(SrcsAsSlice, DstsAsSlice)]
|
||||||
|
pub struct OpBMov {
|
||||||
|
pub dst: Dst,
|
||||||
|
pub src: Src,
|
||||||
|
pub clear: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DisplayOp for OpBMov {
|
||||||
|
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "bmov.32")?;
|
||||||
|
if self.clear {
|
||||||
|
write!(f, ".clear")?;
|
||||||
|
}
|
||||||
|
write!(f, " {}", self.src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl_display_for_op!(OpBMov);
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(SrcsAsSlice, DstsAsSlice)]
|
#[derive(SrcsAsSlice, DstsAsSlice)]
|
||||||
pub struct OpBreak {
|
pub struct OpBreak {
|
||||||
@@ -4326,6 +4345,7 @@ pub enum Op {
|
|||||||
CCtl(OpCCtl),
|
CCtl(OpCCtl),
|
||||||
MemBar(OpMemBar),
|
MemBar(OpMemBar),
|
||||||
BClear(OpBClear),
|
BClear(OpBClear),
|
||||||
|
BMov(OpBMov),
|
||||||
Break(OpBreak),
|
Break(OpBreak),
|
||||||
BSSy(OpBSSy),
|
BSSy(OpBSSy),
|
||||||
BSync(OpBSync),
|
BSync(OpBSync),
|
||||||
@@ -4695,12 +4715,13 @@ impl Instr {
|
|||||||
| Op::FSOut(_)
|
| Op::FSOut(_)
|
||||||
| Op::Out(_)
|
| Op::Out(_)
|
||||||
| Op::OutFinal(_) => false,
|
| Op::OutFinal(_) => false,
|
||||||
|
Op::BMov(op) => !op.clear,
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_fixed_latency(&self) -> bool {
|
pub fn has_fixed_latency(&self) -> bool {
|
||||||
match self.op {
|
match &self.op {
|
||||||
// Float ALU
|
// Float ALU
|
||||||
Op::FAdd(_)
|
Op::FAdd(_)
|
||||||
| Op::FFma(_)
|
| Op::FFma(_)
|
||||||
@@ -4768,6 +4789,14 @@ impl Instr {
|
|||||||
Op::Bra(_) | Op::Exit(_) => true,
|
Op::Bra(_) | Op::Exit(_) => true,
|
||||||
Op::WarpSync(_) => false,
|
Op::WarpSync(_) => false,
|
||||||
|
|
||||||
|
// BMOV: barriers only when using gprs (and only valid for the gpr),
|
||||||
|
// no barriers for the others.
|
||||||
|
Op::BMov(op) => match &op.dst {
|
||||||
|
Dst::None => true,
|
||||||
|
Dst::SSA(vec) => vec.file() == RegFile::Bar,
|
||||||
|
Dst::Reg(reg) => reg.file() == RegFile::Bar,
|
||||||
|
},
|
||||||
|
|
||||||
// Geometry ops
|
// Geometry ops
|
||||||
Op::Out(_) | Op::OutFinal(_) => false,
|
Op::Out(_) | Op::OutFinal(_) => false,
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user