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]
|
||||
fn test_op_prmt() {
|
||||
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 {
|
||||
U8,
|
||||
I8,
|
||||
@@ -3616,7 +3616,7 @@ impl fmt::Display for ShflOp {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(SrcsAsSlice, DstsAsSlice)]
|
||||
#[derive(Clone, SrcsAsSlice, DstsAsSlice)]
|
||||
pub struct OpShf {
|
||||
#[dst_type(GPR)]
|
||||
pub dst: Dst,
|
||||
@@ -3636,6 +3636,55 @@ pub struct OpShf {
|
||||
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 {
|
||||
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "shf")?;
|
||||
|
Reference in New Issue
Block a user