nak: use carry register file for IADD2

This allows detecting dependencies between IADD.X and IADD.CC, which is
necessary for SM50 sched and DCE.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26114>
This commit is contained in:
Benjamin Lee 2023-11-11 15:58:02 -08:00 committed by Marge Bot
parent 9d6c487a75
commit 4b8a8b2a28
3 changed files with 30 additions and 23 deletions

View file

@ -196,8 +196,8 @@ pub trait SSABuilder: Builder {
self.push_op(OpIAdd2 {
dst: dst.into(),
srcs: [x, y],
carry_in: false,
carry_out: false,
carry_in: 0.into(),
carry_out: Dst::None,
});
}
dst
@ -221,17 +221,18 @@ pub trait SSABuilder: Builder {
carry: [carry.into(), false.into()],
});
} else {
let carry = self.alloc_ssa(RegFile::Carry, 1);
self.push_op(OpIAdd2 {
dst: dst[0].into(),
srcs: [x[0].into(), y[0].into()],
carry_out: true,
carry_in: false,
carry_out: carry.into(),
carry_in: 0.into(),
});
self.push_op(OpIAdd2 {
dst: dst[1].into(),
srcs: [x[1].into(), y[1].into()],
carry_out: false,
carry_in: true,
carry_out: Dst::None,
carry_in: carry.into(),
});
}
dst

View file

@ -1885,6 +1885,17 @@ impl SM50Instr {
}
fn encode_iadd2(&mut self, op: &OpIAdd2) {
let carry_in = match op.carry_in.src_ref {
SrcRef::Reg(reg) if reg.file() == RegFile::Carry => true,
SrcRef::Zero => false,
other => panic!("invalid carry_in src for IADD2 {other}"),
};
let carry_out = match op.carry_out {
Dst::Reg(reg) if reg.file() == RegFile::Carry => true,
Dst::None => false,
other => panic!("invalid carry_out dst for IADD2 {other}"),
};
if let Some(imm32) = op.srcs[1].as_imm_not_i20() {
self.set_opcode(0x1c00);
@ -1892,8 +1903,8 @@ impl SM50Instr {
self.set_reg_ineg_src(8..16, 56, op.srcs[0]);
self.set_src_imm32(20..56, imm32);
self.set_bit(53, op.carry_in);
self.set_bit(52, op.carry_out);
self.set_bit(53, carry_in);
self.set_bit(52, carry_out);
} else {
match &op.srcs[1].src_ref {
SrcRef::Zero | SrcRef::Reg(_) => {
@ -1914,8 +1925,8 @@ impl SM50Instr {
self.set_dst(op.dst);
self.set_reg_ineg_src(8..16, 49, op.srcs[0]);
self.set_bit(43, op.carry_in);
self.set_bit(47, op.carry_out);
self.set_bit(43, carry_in);
self.set_bit(47, carry_out);
}
}

View file

@ -2491,25 +2491,20 @@ impl_display_for_op!(OpINeg);
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpIAdd2 {
pub dst: Dst,
pub carry_out: Dst,
#[src_type(ALU)]
pub srcs: [Src; 2],
// TODO: We should probably track this as an SSA value somehow
pub carry_out: bool,
pub carry_in: bool,
pub carry_in: Src,
}
impl DisplayOp for OpIAdd2 {
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "iadd")?;
if self.carry_in {
write!(f, ".x")?;
write!(f, "iadd2 {} {}", self.srcs[0], self.srcs[1])?;
if !self.carry_in.is_zero() {
write!(f, " {}", self.carry_in)?;
}
if self.carry_out {
write!(f, ".cc")?;
}
write!(f, " {} {}", self.srcs[0], self.srcs[1])
Ok(())
}
}
@ -5498,8 +5493,8 @@ impl Shader {
instr.op = Op::IAdd2(OpIAdd2 {
dst: neg.dst,
srcs: [0.into(), neg.src.ineg()],
carry_in: false,
carry_out: false,
carry_in: 0.into(),
carry_out: Dst::None,
});
}
MappedInstrs::One(instr)