nak: Rework source modifiers a bit

They now carry some type informaiton so FNeg and INeg are different
modifiers.  Since only INeg exists in hardware, we don't need IAbs or
INegAbs.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand 2023-04-26 09:33:40 -05:00 committed by Marge Bot
parent a2390fdbc1
commit 42d31b4bfd
5 changed files with 114 additions and 74 deletions

View file

@ -29,6 +29,30 @@ enum ALUSrc {
CBuf(ALUCBufRef),
}
fn src_mod_has_abs(src_mod: SrcMod) -> bool {
match src_mod {
SrcMod::None | SrcMod::FNeg | SrcMod::INeg => false,
SrcMod::FAbs | SrcMod::FNegAbs => true,
_ => panic!("Not an ALU source modifier"),
}
}
fn src_mod_has_neg(src_mod: SrcMod) -> bool {
match src_mod {
SrcMod::None | SrcMod::FAbs => false,
SrcMod::FNeg | SrcMod::FNegAbs | SrcMod::INeg => true,
_ => panic!("Not an ALU source modifier"),
}
}
fn src_mod_is_bnot(src_mod: SrcMod) -> bool {
match src_mod {
SrcMod::None => false,
SrcMod::BNot => true,
_ => panic!("Not an predicate source modifier"),
}
}
impl ALUSrc {
fn from_nonzero_src(src: &Src) -> ALUSrc {
match src.src_ref {
@ -36,8 +60,8 @@ impl ALUSrc {
assert!(reg.comps() == 1);
let alu_ref = ALURegRef {
reg: reg,
abs: src.src_mod.has_abs(),
neg: src.src_mod.has_neg(),
abs: src_mod_has_abs(src.src_mod),
neg: src_mod_has_neg(src.src_mod),
};
match reg.file() {
RegFile::GPR => ALUSrc::Reg(alu_ref),
@ -52,8 +76,8 @@ impl ALUSrc {
SrcRef::CBuf(cb) => {
let alu_ref = ALUCBufRef {
cb: cb,
abs: src.src_mod.has_abs(),
neg: src.src_mod.has_neg(),
abs: src_mod_has_abs(src.src_mod),
neg: src_mod_has_neg(src.src_mod),
};
ALUSrc::CBuf(alu_ref)
}
@ -174,7 +198,7 @@ impl SM75Instr {
_ => panic!("Not a register"),
};
self.set_pred_reg(range, reg);
self.set_bit(not_bit, not ^ src.src_mod.has_not());
self.set_bit(not_bit, not ^ src_mod_is_bnot(src.src_mod));
}
fn set_src_cb(&mut self, range: Range<usize>, cb: &CBufRef) {

View file

@ -167,14 +167,14 @@ impl<'a> ShaderFromNir<'a> {
nir_op_b2f32 => {
self.instrs.push(Instr::new(Op::Sel(OpSel {
dst: dst,
cond: srcs[0].not(),
cond: srcs[0].bnot(),
srcs: [Src::new_zero(), Src::new_imm_u32(0x3f800000)],
})));
}
nir_op_b2i32 => {
self.instrs.push(Instr::new(Op::Sel(OpSel {
dst: dst,
cond: srcs[0].not(),
cond: srcs[0].bnot(),
srcs: [Src::new_zero(), Src::new_imm_u32(1)],
})));
}
@ -197,7 +197,7 @@ impl<'a> ShaderFromNir<'a> {
nir_op_fabs => {
self.instrs.push(Instr::new(Op::FMov(OpFMov {
dst: dst,
src: srcs[0].abs(),
src: srcs[0].fabs(),
saturate: false,
})));
}
@ -283,7 +283,7 @@ impl<'a> ShaderFromNir<'a> {
nir_op_fneg => {
self.instrs.push(Instr::new(Op::FMov(OpFMov {
dst: dst,
src: srcs[0].neg(),
src: srcs[0].fneg(),
saturate: false,
})));
}
@ -345,7 +345,7 @@ impl<'a> ShaderFromNir<'a> {
self.instrs.push(Instr::new_fadd(
dst,
gz.into(),
Src::from(lz).neg(),
Src::from(lz).fneg(),
));
}
nir_op_fsin => {
@ -503,7 +503,7 @@ impl<'a> ShaderFromNir<'a> {
nir_op_ineg => {
self.instrs.push(Instr::new(Op::IMov(OpIMov {
dst: dst,
src: srcs[0].neg(),
src: srcs[0].ineg(),
})));
}
nir_op_inot => {

View file

@ -517,10 +517,11 @@ impl fmt::Display for SrcRef {
#[derive(Clone, Copy)]
pub enum SrcMod {
None,
Abs,
Neg,
NegAbs,
Not,
FAbs,
FNeg,
FNegAbs,
INeg,
BNot,
}
impl SrcMod {
@ -533,65 +534,63 @@ impl SrcMod {
pub fn is_alu(&self) -> bool {
match self {
SrcMod::None | SrcMod::Abs | SrcMod::Neg | SrcMod::NegAbs => true,
SrcMod::Not => false,
SrcMod::None
| SrcMod::FAbs
| SrcMod::FNeg
| SrcMod::FNegAbs
| SrcMod::INeg => true,
SrcMod::BNot => false,
}
}
pub fn is_bitwise(&self) -> bool {
match self {
SrcMod::None | SrcMod::Not => true,
SrcMod::Abs | SrcMod::Neg | SrcMod::NegAbs => false,
SrcMod::None | SrcMod::BNot => true,
SrcMod::FAbs | SrcMod::FNeg | SrcMod::FNegAbs | SrcMod::INeg => {
false
}
}
}
pub fn has_neg(&self) -> bool {
match self {
SrcMod::None | SrcMod::Abs => false,
SrcMod::Neg | SrcMod::NegAbs => true,
SrcMod::Not => panic!("Not an ALU source modifier"),
}
}
pub fn has_abs(&self) -> bool {
match self {
SrcMod::None | SrcMod::Neg => false,
SrcMod::Abs | SrcMod::NegAbs => true,
SrcMod::Not => panic!("Not an ALU source modifier"),
}
}
pub fn has_not(&self) -> bool {
pub fn is_bnot(&self) -> bool {
match self {
SrcMod::None => false,
SrcMod::Not => true,
_ => panic!("Not a boolean source modifier"),
SrcMod::BNot => true,
_ => panic!("Not a bitwise modifier"),
}
}
pub fn abs(self) -> SrcMod {
pub fn fabs(self) -> SrcMod {
match self {
SrcMod::None | SrcMod::Abs | SrcMod::Neg | SrcMod::NegAbs => {
SrcMod::Abs
SrcMod::None | SrcMod::FAbs | SrcMod::FNeg | SrcMod::FNegAbs => {
SrcMod::FAbs
}
SrcMod::Not => panic!("Not an ALU source modifier"),
_ => panic!("Not a float source modifier"),
}
}
pub fn neg(self) -> SrcMod {
pub fn fneg(self) -> SrcMod {
match self {
SrcMod::None => SrcMod::Neg,
SrcMod::Abs => SrcMod::NegAbs,
SrcMod::Neg => SrcMod::None,
SrcMod::NegAbs => SrcMod::Abs,
SrcMod::Not => panic!("Not an ALU source modifier"),
SrcMod::None => SrcMod::FNeg,
SrcMod::FAbs => SrcMod::FNegAbs,
SrcMod::FNeg => SrcMod::None,
SrcMod::FNegAbs => SrcMod::FAbs,
_ => panic!("Not a float source modifier"),
}
}
pub fn not(self) -> SrcMod {
pub fn ineg(self) -> SrcMod {
match self {
SrcMod::None => SrcMod::Not,
SrcMod::Not => SrcMod::None,
SrcMod::None => SrcMod::INeg,
SrcMod::INeg => SrcMod::None,
_ => panic!("Not an integer source modifier"),
}
}
pub fn bnot(self) -> SrcMod {
match self {
SrcMod::None => SrcMod::BNot,
SrcMod::BNot => SrcMod::None,
_ => panic!("Not a boolean source modifier"),
}
}
@ -599,10 +598,11 @@ impl SrcMod {
pub fn modify(self, other: SrcMod) -> SrcMod {
match other {
SrcMod::None => self,
SrcMod::Abs => self.abs(),
SrcMod::Neg => self.neg(),
SrcMod::NegAbs => self.abs().neg(),
SrcMod::Not => self.not(),
SrcMod::FAbs => self.fabs(),
SrcMod::FNeg => self.fneg(),
SrcMod::FNegAbs => self.fabs().fneg(),
SrcMod::INeg => self.ineg(),
SrcMod::BNot => self.bnot(),
}
}
}
@ -646,24 +646,31 @@ impl Src {
.into()
}
pub fn abs(&self) -> Src {
pub fn fabs(&self) -> Src {
Src {
src_ref: self.src_ref,
src_mod: self.src_mod.abs(),
src_mod: self.src_mod.fabs(),
}
}
pub fn neg(&self) -> Src {
pub fn fneg(&self) -> Src {
Src {
src_ref: self.src_ref,
src_mod: self.src_mod.neg(),
src_mod: self.src_mod.fneg(),
}
}
pub fn not(&self) -> Src {
pub fn ineg(&self) -> Src {
Src {
src_ref: self.src_ref,
src_mod: self.src_mod.not(),
src_mod: self.src_mod.ineg(),
}
}
pub fn bnot(&self) -> Src {
Src {
src_ref: self.src_ref,
src_mod: self.src_mod.bnot(),
}
}
@ -735,10 +742,11 @@ impl fmt::Display for Src {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.src_mod {
SrcMod::None => write!(f, "{}", self.src_ref),
SrcMod::Abs => write!(f, "|{}|", self.src_ref),
SrcMod::Neg => write!(f, "-{}", self.src_ref),
SrcMod::NegAbs => write!(f, "-|{}|", self.src_ref),
SrcMod::Not => write!(f, "!{}", self.src_ref),
SrcMod::FAbs => write!(f, "|{}|", self.src_ref),
SrcMod::FNeg => write!(f, "-{}", self.src_ref),
SrcMod::FNegAbs => write!(f, "-|{}|", self.src_ref),
SrcMod::INeg => write!(f, "-{}", self.src_ref),
SrcMod::BNot => write!(f, "!{}", self.src_ref),
}
}
}

View file

@ -36,7 +36,7 @@ fn src_as_lop_imm(src: &Src) -> Option<bool> {
}
_ => return None,
};
Some(x ^ src.src_mod.has_not())
Some(x ^ src.src_mod.is_bnot())
}
fn fold_lop_src(src: &Src, x: &mut u8) {

View file

@ -53,11 +53,15 @@ impl CopyPropPass {
}
let typ = match src.src_mod {
SrcMod::None => CopyType::Raw,
SrcMod::Abs | SrcMod::Neg | SrcMod::NegAbs => {
assert!(typ != CopyType::Raw && typ != CopyType::Bits);
SrcMod::FAbs | SrcMod::FNeg | SrcMod::FNegAbs => {
assert!(typ == CopyType::F32 || typ == CopyType::F64H);
typ
}
SrcMod::Not => {
SrcMod::INeg => {
assert!(typ == CopyType::I32);
typ
}
SrcMod::BNot => {
assert!(typ == CopyType::Bits);
typ
}
@ -83,8 +87,12 @@ impl CopyPropPass {
let copy_ssa = entry.src.src_ref.as_ssa().unwrap();
assert!(copy_ssa.comps() == 1 && copy_ssa.is_predicate());
*pred = Pred::SSA(copy_ssa[0]);
if entry.src.src_mod.has_not() {
*pred_inv = !*pred_inv;
match entry.src.src_mod {
SrcMod::None => (),
SrcMod::BNot => {
*pred_inv = !*pred_inv;
}
_ => panic!("Invalid predicate modifier"),
}
}
}
@ -239,13 +247,13 @@ impl CopyPropPass {
Op::Lop3(op) => {
if self.prop_to_srcs(&mut op.srcs, CopyType::Bits) {
op.op = LogicOp::new_lut(&|mut x, mut y, mut z| {
if op.srcs[0].src_mod.has_not() {
if op.srcs[0].src_mod.is_bnot() {
x = !x;
}
if op.srcs[1].src_mod.has_not() {
if op.srcs[1].src_mod.is_bnot() {
y = !y;
}
if op.srcs[2].src_mod.has_not() {
if op.srcs[2].src_mod.is_bnot() {
z = !z;
}
op.op.eval(x, y, z)