nak: Implement integer comparisons
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
committed by
Marge Bot
parent
ac2a56f56f
commit
b3d6dafc7d
@@ -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),
|
||||
|
||||
@@ -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"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"),
|
||||
|
||||
Reference in New Issue
Block a user