nak: Add the rest of the double-precision ops

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26743>
This commit is contained in:
Faith Ekstrand 2023-12-07 22:26:11 -06:00 committed by Marge Bot
parent 2f899f44eb
commit 1236c5d4f1
3 changed files with 163 additions and 2 deletions

View file

@ -579,6 +579,67 @@ impl SM70Instr {
);
}
fn encode_dadd(&mut self, op: &OpDAdd) {
self.encode_alu(
0x029,
Some(op.dst),
ALUSrc::from_src(&op.srcs[0]),
ALUSrc::None,
ALUSrc::from_src(&op.srcs[1]),
);
self.set_rnd_mode(78..80, op.rnd_mode);
}
fn encode_dfma(&mut self, op: &OpDFma) {
self.encode_alu(
0x02b,
Some(op.dst),
ALUSrc::from_src(&op.srcs[0]),
ALUSrc::from_src(&op.srcs[1]),
ALUSrc::from_src(&op.srcs[2]),
);
self.set_rnd_mode(78..80, op.rnd_mode);
}
fn encode_dmul(&mut self, op: &OpDMul) {
self.encode_alu(
0x028,
Some(op.dst),
ALUSrc::from_src(&op.srcs[0]),
ALUSrc::from_src(&op.srcs[1]),
ALUSrc::None,
);
self.set_rnd_mode(78..80, op.rnd_mode);
}
fn encode_dsetp(&mut self, op: &OpDSetP) {
if op.srcs[1].src_ref.as_reg().is_some() {
self.encode_alu(
0x02a,
None,
ALUSrc::from_src(&op.srcs[0]),
ALUSrc::from_src(&op.srcs[1]),
ALUSrc::None,
);
} else {
self.encode_alu(
0x02a,
None,
ALUSrc::from_src(&op.srcs[0]),
ALUSrc::None,
ALUSrc::from_src(&op.srcs[1]),
);
}
self.set_pred_set_op(74..76, op.set_op);
self.set_float_cmp_op(76..80, op.cmp_op);
self.set_pred_dst(81..84, op.dst);
self.set_pred_dst(84..87, Dst::None); /* dst1 */
self.set_pred_src(87..90, 90, op.accum);
}
fn encode_brev(&mut self, op: &OpBrev) {
self.encode_alu(
0x101,
@ -1925,6 +1986,10 @@ impl SM70Instr {
Op::FSet(op) => si.encode_fset(&op),
Op::FSetP(op) => si.encode_fsetp(&op),
Op::FSwzAdd(op) => si.encode_fswzadd(&op),
Op::DAdd(op) => si.encode_dadd(&op),
Op::DFma(op) => si.encode_dfma(&op),
Op::DMul(op) => si.encode_dmul(&op),
Op::DSetP(op) => si.encode_dsetp(&op),
Op::MuFu(op) => si.encode_mufu(&op),
Op::Brev(op) => si.encode_brev(&op),
Op::Flo(op) => si.encode_flo(&op),

View file

@ -2485,6 +2485,80 @@ impl DisplayOp for OpDAdd {
}
impl_display_for_op!(OpDAdd);
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpDMul {
pub dst: Dst,
#[src_type(F64)]
pub srcs: [Src; 2],
pub rnd_mode: FRndMode,
}
impl DisplayOp for OpDMul {
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "dmul")?;
if self.rnd_mode != FRndMode::NearestEven {
write!(f, "{}", self.rnd_mode)?;
}
write!(f, " {} {}", self.srcs[0], self.srcs[1],)
}
}
impl_display_for_op!(OpDMul);
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpDFma {
pub dst: Dst,
#[src_type(F64)]
pub srcs: [Src; 3],
pub rnd_mode: FRndMode,
}
impl DisplayOp for OpDFma {
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "dfma")?;
if self.rnd_mode != FRndMode::NearestEven {
write!(f, "{}", self.rnd_mode)?;
}
write!(f, " {} {} {}", self.srcs[0], self.srcs[1], self.srcs[2])
}
}
impl_display_for_op!(OpDFma);
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpDSetP {
pub dst: Dst,
pub set_op: PredSetOp,
pub cmp_op: FloatCmpOp,
#[src_type(F64)]
pub srcs: [Src; 2],
#[src_type(Pred)]
pub accum: Src,
}
impl DisplayOp for OpDSetP {
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "dsetp{}", self.cmp_op)?;
if !self.set_op.is_trivial(&self.accum) {
write!(f, "{}", self.set_op)?;
}
write!(f, " {} {}", self.srcs[0], self.srcs[1])?;
if !self.set_op.is_trivial(&self.accum) {
write!(f, " {}", self.accum)?;
}
Ok(())
}
}
impl_display_for_op!(OpDSetP);
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpBrev {
@ -4623,6 +4697,9 @@ pub enum Op {
FSetP(OpFSetP),
FSwzAdd(OpFSwzAdd),
DAdd(OpDAdd),
DFma(OpDFma),
DMul(OpDMul),
DSetP(OpDSetP),
Brev(OpBrev),
Flo(OpFlo),
IAbs(OpIAbs),
@ -5060,7 +5137,7 @@ impl Instr {
Op::MuFu(_) => false,
// Double-precision float ALU
Op::DAdd(_) => false,
Op::DAdd(_) | Op::DFma(_) | Op::DMul(_) | Op::DSetP(_) => false,
// Integer ALU
Op::Brev(_) | Op::Flo(_) | Op::PopC(_) => false,

View file

@ -325,7 +325,26 @@ fn legalize_sm70_instr(
Op::DAdd(op) => {
let [ref mut src0, ref mut src1] = op.srcs;
swap_srcs_if_not_reg(src0, src1);
copy_src_if_not_reg(b, src0, RegFile::GPR);
copy_alu_src_if_not_reg(b, src0, SrcType::F64);
}
Op::DFma(op) => {
let [ref mut src0, ref mut src1, ref mut src2] = op.srcs;
swap_srcs_if_not_reg(src0, src1);
copy_alu_src_if_not_reg(b, src0, SrcType::F64);
copy_alu_src_if_both_not_reg(b, src1, src2, SrcType::F64);
}
Op::DMul(op) => {
let [ref mut src0, ref mut src1] = op.srcs;
swap_srcs_if_not_reg(src0, src1);
copy_alu_src_if_not_reg(b, src0, SrcType::F64);
}
Op::DSetP(op) => {
let [ref mut src0, ref mut src1] = op.srcs;
if !src_is_reg(src0) && src_is_reg(src1) {
std::mem::swap(src0, src1);
op.cmp_op = op.cmp_op.flip();
}
copy_alu_src_if_not_reg(b, src0, SrcType::F64);
}
Op::Brev(_) | Op::Flo(_) | Op::IAbs(_) | Op::INeg(_) => (),
Op::IAdd3(op) => {