nak: Add OpSgxt

Reviewed-by: Karol Herbst <kherbst@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37592>
This commit is contained in:
Mel Henning
2025-09-25 18:36:13 -04:00
committed by Marge Bot
parent 1c08e7766e
commit c8116679c3
9 changed files with 140 additions and 8 deletions
+27
View File
@@ -1924,3 +1924,30 @@ fn test_render_enable() -> io::Result<()> {
Ok(())
}
#[test]
fn test_op_sgxt() {
let sm = &RunSingleton::get().sm;
if sm.sm() < 70 {
return;
}
for signed in [false, true] {
let op = OpSgxt {
dst: Dst::None,
a: 0.into(),
bits: 0.into(),
signed,
};
let bits_idx = op.src_idx(&op.bits);
let mut a = Acorn::new();
test_foldable_op_with(op, &mut |i| {
if i == bits_idx && a.get_bool() {
a.get_uint(5) as u32
} else {
a.get_u32()
}
});
}
}
+48 -1
View File
@@ -5112,6 +5112,52 @@ impl DisplayOp for OpSel {
}
impl_display_for_op!(OpSel);
#[repr(C)]
#[derive(Clone, SrcsAsSlice, DstsAsSlice)]
pub struct OpSgxt {
#[dst_type(GPR)]
pub dst: Dst,
#[src_type(ALU)]
pub a: Src,
#[src_type(ALU)]
pub bits: Src,
pub signed: bool,
}
impl DisplayOp for OpSgxt {
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let modifier = if self.signed { "" } else { ".u32" };
write!(f, "sgxt{} {} {}", modifier, self.a, self.bits)
}
}
impl_display_for_op!(OpSgxt);
impl Foldable for OpSgxt {
fn fold(&self, _sm: &dyn ShaderModel, f: &mut OpFoldData<'_>) {
let a = f.get_u32_src(self, &self.a);
let bits = f.get_u32_src(self, &self.bits);
let dst = if bits >= 32 {
a
} else if bits == 0 {
0
} else {
let shift = 32 - bits;
let a = a << shift;
if self.signed {
let a = a as i32;
(a >> shift) as u32
} else {
a >> shift
}
};
f.set_u32_dst(self, &self.dst, dst);
}
}
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpShfl {
@@ -7895,6 +7941,7 @@ pub enum Op {
Mov(Box<OpMov>),
Prmt(Box<OpPrmt>),
Sel(Box<OpSel>),
Sgxt(Box<OpSgxt>),
Shfl(Box<OpShfl>),
PLop3(Box<OpPLop3>),
PSetP(Box<OpPSetP>),
@@ -8068,7 +8115,7 @@ impl Op {
}
// Move ops
Op::Mov(_) | Op::Prmt(_) | Op::Sel(_) => true,
Op::Mov(_) | Op::Prmt(_) | Op::Sel(_) | Op::Sgxt(_) => true,
Op::Shfl(_) => false,
// Predicate ops
@@ -750,3 +750,30 @@ pub fn test_match() {
c.check(sm);
}
}
#[test]
pub fn test_sgxt() {
let r0 = RegRef::new(RegFile::GPR, 0, 1);
let r1 = RegRef::new(RegFile::GPR, 1, 1);
let r2 = RegRef::new(RegFile::GPR, 2, 1);
for sm in SM_LIST {
let mut c = DisasmCheck::new();
for signed in [false, true] {
let instr = OpSgxt {
dst: Dst::Reg(r0),
a: SrcRef::Reg(r1).into(),
bits: SrcRef::Reg(r2).into(),
signed,
};
let disasm = if signed {
"sgxt r0, r1, r2;"
} else {
"sgxt.u32 r0, r1, r2;"
};
c.push(instr, disasm);
}
c.check(sm);
}
}
@@ -145,7 +145,7 @@ pub fn side_effect_type(op: &Op) -> SideEffect {
}
// Move ops
Op::Mov(_) | Op::Prmt(_) | Op::Sel(_) => SideEffect::None,
Op::Mov(_) | Op::Prmt(_) | Op::Sel(_) | Op::Sgxt(_) => SideEffect::None,
Op::Shfl(_) => SideEffect::None,
// Predicate ops
@@ -42,7 +42,7 @@ fn op_reg_latency(op: &Op, reader: bool, op_reg_idx: usize) -> RegLatencySM100 {
Op::IAdd3(_) | Op::IAdd3X(_) => Alu,
Op::BMsk(_) => Alu,
// Sgxt => Alu,
Op::Sgxt(_) => Alu,
Op::Lop3(_) => Alu,
Op::Flo(_) => Decoupled,
Op::ISetP(_) => Dualalu,
@@ -282,7 +282,7 @@ fn op_ureg_latency(
Op::PSetP(_) => coupled,
// UR2UP
Op::Sel(_) => coupled,
// SGXT
Op::Sgxt(_) => coupled,
Op::Shf(_) => coupled,
Op::Shfl(_) => decoupled,
+1
View File
@@ -136,6 +136,7 @@ impl ShaderModel for ShaderModel70 {
| Op::Prmt(_)
| Op::PSetP(_)
| Op::Sel(_)
| Op::Sgxt(_)
| Op::Shf(_)
| Op::Shl(_)
| Op::Shr(_)
+30
View File
@@ -2138,6 +2138,35 @@ impl SM70Op for OpSel {
}
}
impl SM70Op for OpSgxt {
fn legalize(&mut self, b: &mut LegalizeBuilder) {
let gpr = op_gpr(self);
b.copy_alu_src_if_not_reg(&mut self.a, gpr, SrcType::ALU);
}
fn encode(&self, e: &mut SM70Encoder<'_>) {
if self.is_uniform() {
e.encode_ualu(
0x09a,
Some(&self.dst),
Some(&self.a),
Some(&self.bits),
None,
);
} else {
e.encode_alu(
0x01a,
Some(&self.dst),
Some(&self.a),
Some(&self.bits),
None,
);
}
e.set_bit(73, self.signed);
e.set_bit(75, false); // .W (wrap vs clamp)
}
}
impl SM70Op for OpShfl {
fn legalize(&mut self, b: &mut LegalizeBuilder) {
let gpr = op_gpr(self);
@@ -4047,6 +4076,7 @@ macro_rules! sm70_op_match {
Op::Mov($x) => $y,
Op::Prmt($x) => $y,
Op::Sel($x) => $y,
Op::Sgxt($x) => $y,
Op::Shfl($x) => $y,
Op::PLop3($x) => $y,
Op::R2UR($x) => $y,
@@ -69,7 +69,7 @@ impl RegLatencySM75 {
Op::IAdd3(_) | Op::IAdd3X(_) => CoupledAlu,
Op::BMsk(_) => CoupledAlu,
// Sgxt => CoupledAlu,
Op::Sgxt(_) => CoupledAlu,
Op::Lop3(_) => CoupledAlu,
Op::Flo(_) => Decoupled,
Op::ISetP(_) => CoupledAlu,
@@ -954,7 +954,7 @@ impl URegLatencySM75 {
Op::PSetP(_) => vcoupled,
// UR2UP
Op::Sel(_) => vcoupled,
// SGXT
Op::Sgxt(_) => vcoupled,
Op::Shf(_) => vcoupled,
Op::Shfl(_) => vdecoupled,
@@ -105,7 +105,7 @@ impl RegLatencySM80 {
Op::IAdd3(_) | Op::IAdd3X(_) => CoupledAlu,
Op::BMsk(_) => CoupledAlu,
// Sgxt => CoupledAlu,
Op::Sgxt(_) => CoupledAlu,
Op::Lop3(_) => CoupledAlu,
Op::Flo(_) => Decoupled,
Op::ISetP(_) => CoupledAlu,
@@ -1072,7 +1072,7 @@ impl URegLatencySM80 {
Op::PSetP(_) => vcoupled,
// UR2UP
Op::Sel(_) => vcoupled,
// SGXT
Op::Sgxt(_) => vcoupled,
Op::Shf(_) => vcoupled,
Op::Shfl(_) => vdecoupled,