nak: Implement fsign

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand 2023-01-30 20:53:18 -06:00 committed by Marge Bot
parent 5ad06de4d3
commit f4c0ea24e5
3 changed files with 78 additions and 0 deletions

View file

@ -321,6 +321,19 @@ impl SM75Instr {
);
}
fn encode_fset(&mut self, op: &OpFSet) {
self.encode_alu(
0x00a,
Some(op.dst),
Some(op.mod_src(0)),
op.mod_src(1),
None,
);
self.set_float_cmp_op(76..80, op.cmp_op);
self.set_bit(80, false); /* TODO: Denorm mode */
self.set_field(87..90, 0x7_u8); /* TODO: src predicate */
}
fn encode_fsetp(&mut self, op: &OpFSetP) {
self.encode_alu(0x00b, None, Some(op.mod_src(0)), op.mod_src(1), None);
@ -597,6 +610,7 @@ impl SM75Instr {
match &instr.op {
Op::FAdd(op) => si.encode_fadd(&op),
Op::FSet(op) => si.encode_fset(&op),
Op::FSetP(op) => si.encode_fsetp(&op),
Op::IAdd3(op) => si.encode_iadd3(&op),
Op::ISetP(op) => si.encode_isetp(&op),

View file

@ -161,6 +161,32 @@ impl<'a> ShaderFromNir<'a> {
saturate: true,
})));
}
nir_op_fsign => {
let lz = self.alloc_ssa(RegFile::GPR, 1);
self.instrs.push(Instr::new_fset(
lz,
FloatCmpOp::OrdLt,
srcs[0].into(),
Src::Zero.into(),
));
let gz = self.alloc_ssa(RegFile::GPR, 1);
self.instrs.push(Instr::new_fset(
gz,
FloatCmpOp::OrdGt,
srcs[0].into(),
Src::Zero.into(),
));
self.instrs.push(Instr::new_fadd(
dst,
gz.into(),
ModSrc {
src: lz,
src_mod: SrcMod::FNeg,
},
));
}
nir_op_i2f32 => {
self.instrs.push(Instr::new_i2f(dst, srcs[0]));
}

View file

@ -835,6 +835,28 @@ impl fmt::Display for OpFAdd {
}
}
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice, SrcModsAsSlice)]
pub struct OpFSet {
pub dst: Dst,
pub cmp_op: FloatCmpOp,
pub srcs: [Src; 2],
pub src_mods: [SrcMod; 2],
}
impl fmt::Display for OpFSet {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"FSET.{} {} {{ {}, {} }}",
self.cmp_op,
self.dst,
self.mod_src(0),
self.mod_src(1),
)
}
}
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice, SrcModsAsSlice)]
pub struct OpFSetP {
@ -1249,6 +1271,7 @@ impl fmt::Display for OpFSOut {
#[derive(Display, DstsAsSlice, SrcsAsSlice)]
pub enum Op {
FAdd(OpFAdd),
FSet(OpFSet),
FSetP(OpFSetP),
IAdd3(OpIAdd3),
ISetP(OpISetP),
@ -1445,6 +1468,20 @@ impl Instr {
}))
}
pub fn new_fset(
dst: Dst,
cmp_op: FloatCmpOp,
x: ModSrc,
y: ModSrc,
) -> Instr {
Instr::new(Op::FSet(OpFSet {
dst: dst,
cmp_op: cmp_op,
srcs: [x.src, y.src],
src_mods: [x.src_mod, y.src_mod],
}))
}
pub fn new_fsetp(
dst: Dst,
cmp_op: FloatCmpOp,
@ -1636,6 +1673,7 @@ impl Instr {
pub fn get_latency(&self) -> Option<u32> {
match self.op {
Op::FAdd(_)
| Op::FSet(_)
| Op::FSetP(_)
| Op::IAdd3(_)
| Op::Lop3(_)