nak: Implement Foldable for OpShf
Also add an assert for an invalid combination on Maxwell. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30275>
This commit is contained in:

committed by
Marge Bot

parent
ebc1c052ab
commit
9321a785cf
@@ -566,6 +566,40 @@ fn test_op_iadd3x() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_op_shf() {
|
||||||
|
let sm = &RunSingleton::get().sm;
|
||||||
|
|
||||||
|
let types = [IntType::U32, IntType::I32, IntType::U64, IntType::I64];
|
||||||
|
|
||||||
|
for i in 0..32 {
|
||||||
|
let op = OpShf {
|
||||||
|
dst: Dst::None,
|
||||||
|
low: 0.into(),
|
||||||
|
high: 0.into(),
|
||||||
|
shift: 0.into(),
|
||||||
|
data_type: types[i & 0x3],
|
||||||
|
right: i & 0x4 != 0,
|
||||||
|
wrap: i & 0x8 != 0,
|
||||||
|
dst_high: i & 0x10 != 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
if sm.sm() < 70 && !(op.dst_high || op.right) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let shift_idx = op.src_idx(&op.shift);
|
||||||
|
let mut a = Acorn::new();
|
||||||
|
test_foldable_op_with(op, &mut |i| {
|
||||||
|
if i == shift_idx {
|
||||||
|
a.get_uint(6) as u32
|
||||||
|
} else {
|
||||||
|
a.get_u32()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_op_prmt() {
|
fn test_op_prmt() {
|
||||||
let op = OpPrmt {
|
let op = OpPrmt {
|
||||||
|
@@ -2071,7 +2071,7 @@ impl fmt::Display for ImageDim {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||||
pub enum IntType {
|
pub enum IntType {
|
||||||
U8,
|
U8,
|
||||||
I8,
|
I8,
|
||||||
@@ -3616,7 +3616,7 @@ impl fmt::Display for ShflOp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(SrcsAsSlice, DstsAsSlice)]
|
#[derive(Clone, SrcsAsSlice, DstsAsSlice)]
|
||||||
pub struct OpShf {
|
pub struct OpShf {
|
||||||
#[dst_type(GPR)]
|
#[dst_type(GPR)]
|
||||||
pub dst: Dst,
|
pub dst: Dst,
|
||||||
@@ -3636,6 +3636,55 @@ pub struct OpShf {
|
|||||||
pub dst_high: bool,
|
pub dst_high: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Foldable for OpShf {
|
||||||
|
fn fold(&self, sm: &dyn ShaderModel, f: &mut OpFoldData<'_>) {
|
||||||
|
let low = f.get_u32_src(self, &self.low);
|
||||||
|
let high = f.get_u32_src(self, &self.high);
|
||||||
|
let shift = f.get_u32_src(self, &self.shift);
|
||||||
|
|
||||||
|
let bits: u32 = self.data_type.bits().try_into().unwrap();
|
||||||
|
let shift = if self.wrap {
|
||||||
|
shift & (bits - 1)
|
||||||
|
} else {
|
||||||
|
min(shift, bits)
|
||||||
|
};
|
||||||
|
|
||||||
|
let x = u64::from(low) | (u64::from(high) << 32);
|
||||||
|
let shifted = if sm.sm() < 70
|
||||||
|
&& self.dst_high
|
||||||
|
&& self.data_type != IntType::I64
|
||||||
|
{
|
||||||
|
if self.right {
|
||||||
|
x.checked_shr(shift).unwrap_or(0) as u64
|
||||||
|
} else {
|
||||||
|
x.checked_shl(shift).unwrap_or(0) as u64
|
||||||
|
}
|
||||||
|
} else if self.data_type.is_signed() {
|
||||||
|
if self.right {
|
||||||
|
(x as i64).checked_shr(shift).unwrap_or(0) as u64
|
||||||
|
} else {
|
||||||
|
(x as i64).checked_shl(shift).unwrap_or(0) as u64
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if self.right {
|
||||||
|
x.checked_shr(shift).unwrap_or(0) as u64
|
||||||
|
} else {
|
||||||
|
x.checked_shl(shift).unwrap_or(0) as u64
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let dst = if sm.sm() < 70 && !self.right {
|
||||||
|
(shifted >> 32) as u32
|
||||||
|
} else if self.dst_high {
|
||||||
|
(shifted >> 32) as u32
|
||||||
|
} else {
|
||||||
|
shifted as u32
|
||||||
|
};
|
||||||
|
|
||||||
|
f.set_u32_dst(self, &self.dst, dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl DisplayOp for OpShf {
|
impl DisplayOp for OpShf {
|
||||||
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "shf")?;
|
write!(f, "shf")?;
|
||||||
|
Reference in New Issue
Block a user