nak: Implement integer comparisons

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand
2023-01-30 20:53:17 -06:00
committed by Marge Bot
parent ac2a56f56f
commit b3d6dafc7d
3 changed files with 163 additions and 0 deletions
+35
View File
@@ -232,6 +232,40 @@ fn encode_lop3(bs: &mut impl BitSetMut, instr: &Instr, op: &LogicOp) {
bs.set_bit(90, true);
}
fn encode_cmp_op(bs: &mut impl BitSetMut, range: Range<usize>, op: &CmpOp) {
assert!(range.len() == 3);
bs.set_field(
range,
match op {
CmpOp::Eq => 2_u8,
CmpOp::Ne => 5_u8,
CmpOp::Lt => 1_u8,
CmpOp::Le => 3_u8,
CmpOp::Gt => 4_u8,
CmpOp::Ge => 6_u8,
},
);
}
fn encode_isetp(bs: &mut impl BitSetMut, instr: &Instr, op: &IntCmpOp) {
encode_alu(bs, instr, 0x00c);
bs.set_field(
73..74,
match op.cmp_type {
IntCmpType::U32 => 0_u32,
IntCmpType::I32 => 1_u32,
},
);
bs.set_field(74..76, 0_u32); /* pred combine op */
encode_cmp_op(bs, 76..79, &op.cmp_op);
bs.set_field(84..87, 7_u32); /* dst1 */
bs.set_field(87..90, 7_u32); /* src pred */
bs.set_bit(90, false); /* src pred neg */
}
fn encode_shl(bs: &mut impl BitSetMut, instr: &Instr) {
encode_alu(bs, instr, 0x019);
@@ -345,6 +379,7 @@ pub fn encode_instr(instr: &Instr) -> [u32; 4] {
Opcode::MOV => encode_mov(&mut bs, instr),
Opcode::IADD3 => encode_iadd3(&mut bs, instr),
Opcode::LOP3(op) => encode_lop3(&mut bs, instr, &op),
Opcode::ISETP(op) => encode_isetp(&mut bs, instr, &op),
Opcode::SHL => encode_shl(&mut bs, instr),
Opcode::ALD(a) => encode_ald(&mut bs, instr, &a),
Opcode::AST(a) => encode_ast(&mut bs, instr, &a),
+54
View File
@@ -101,6 +101,42 @@ impl<'a> ShaderFromNir<'a> {
Src::Zero,
));
}
nir_op_ieq => {
self.instrs.push(Instr::new_isetp(
dst,
IntCmpType::I32,
CmpOp::Eq,
srcs[0],
srcs[1],
));
}
nir_op_ige => {
self.instrs.push(Instr::new_isetp(
dst,
IntCmpType::I32,
CmpOp::Ge,
srcs[0],
srcs[1],
));
}
nir_op_ilt => {
self.instrs.push(Instr::new_isetp(
dst,
IntCmpType::I32,
CmpOp::Lt,
srcs[0],
srcs[1],
));
}
nir_op_ine => {
self.instrs.push(Instr::new_isetp(
dst,
IntCmpType::I32,
CmpOp::Ne,
srcs[0],
srcs[1],
));
}
nir_op_inot => {
self.instrs.push(Instr::new_lop3(
dst,
@@ -128,6 +164,24 @@ impl<'a> ShaderFromNir<'a> {
nir_op_pack_64_2x32_split => {
self.instrs.push(Instr::new_vec(dst, &[srcs[0], srcs[1]]));
}
nir_op_uge => {
self.instrs.push(Instr::new_isetp(
dst,
IntCmpType::U32,
CmpOp::Ge,
srcs[0],
srcs[1],
));
}
nir_op_ult => {
self.instrs.push(Instr::new_isetp(
dst,
IntCmpType::U32,
CmpOp::Lt,
srcs[0],
srcs[1],
));
}
_ => panic!("Unsupported ALU instruction"),
}
}
+74
View File
@@ -440,6 +440,63 @@ impl InstrRefs {
}
}
pub enum PredSetOp {
Set,
And,
Or,
Xor,
AndNot,
OrNot,
XorNot,
}
pub enum CmpOp {
Eq,
Ne,
Lt,
Le,
Gt,
Ge,
}
impl fmt::Display for CmpOp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
CmpOp::Eq => write!(f, "EQ"),
CmpOp::Ne => write!(f, "NE"),
CmpOp::Lt => write!(f, "LT"),
CmpOp::Le => write!(f, "LE"),
CmpOp::Gt => write!(f, "GT"),
CmpOp::Ge => write!(f, "GE"),
}
}
}
pub enum IntCmpType {
U32,
I32,
}
impl fmt::Display for IntCmpType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
IntCmpType::U32 => write!(f, "U32"),
IntCmpType::I32 => write!(f, "I32"),
}
}
}
pub struct IntCmpOp {
pub cmp_op: CmpOp,
pub cmp_type: IntCmpType,
}
impl fmt::Display for IntCmpOp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}.{}", self.cmp_op, self.cmp_type)
}
}
pub struct LogicOp {
pub lut: u8,
}
@@ -745,6 +802,20 @@ impl Instr {
Instr::new(Opcode::IADD3, slice::from_ref(&dst), &[Src::Zero, x, y])
}
pub fn new_isetp(
dst: Dst,
cmp_type: IntCmpType,
cmp_op: CmpOp,
x: Src,
y: Src,
) -> Instr {
let op = IntCmpOp {
cmp_type: cmp_type,
cmp_op: cmp_op,
};
Instr::new(Opcode::ISETP(op), slice::from_ref(&dst), &[x, y])
}
pub fn new_lop3(dst: Dst, op: LogicOp, x: Src, y: Src, z: Src) -> Instr {
Instr::new(Opcode::LOP3(op), slice::from_ref(&dst), &[x, y, z])
}
@@ -872,6 +943,7 @@ impl Instr {
| Opcode::FMUL
| Opcode::IADD3
| Opcode::LOP3(_)
| Opcode::ISETP(_)
| Opcode::SHL => Some(6),
Opcode::MOV => Some(15),
Opcode::S2R(_) => None,
@@ -919,6 +991,7 @@ pub enum Opcode {
IADD3,
LOP3(LogicOp),
ISETP(IntCmpOp),
SHL,
S2R(u8),
@@ -947,6 +1020,7 @@ impl fmt::Display for Opcode {
Opcode::FMUL => write!(f, "FMUL"),
Opcode::IADD3 => write!(f, "IADD3"),
Opcode::LOP3(op) => write!(f, "LOP3.{}", op),
Opcode::ISETP(op) => write!(f, "ISETP.{}", op),
Opcode::SHL => write!(f, "SHL"),
Opcode::S2R(i) => write!(f, "S2R({})", i),
Opcode::MOV => write!(f, "MOV"),