mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-19 08:00:36 +02:00
nak: Implement 32-bit logic ops
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
parent
8cf12d6a3f
commit
de073a10e6
3 changed files with 100 additions and 1 deletions
|
|
@ -204,6 +204,15 @@ fn encode_iadd3(bs: &mut impl BitSetMut, instr: &Instr) {
|
|||
bs.set_field(84..87, 7_u32); /* pred */
|
||||
}
|
||||
|
||||
fn encode_lop3(bs: &mut impl BitSetMut, instr: &Instr, op: &LogicOp) {
|
||||
encode_alu(bs, instr, 0x012);
|
||||
bs.set_field(72..80, op.lut);
|
||||
bs.set_bit(80, false); /* .PAND */
|
||||
bs.set_field(81..84, 7_u32); /* pred */
|
||||
bs.set_field(84..87, 7_u32); /* pred */
|
||||
bs.set_bit(90, true);
|
||||
}
|
||||
|
||||
fn encode_shl(bs: &mut impl BitSetMut, instr: &Instr) {
|
||||
encode_alu(bs, instr, 0x019);
|
||||
|
||||
|
|
@ -316,6 +325,7 @@ pub fn encode_instr(instr: &Instr) -> [u32; 4] {
|
|||
Opcode::S2R(i) => encode_s2r(&mut bs, instr, *i),
|
||||
Opcode::MOV => encode_mov(&mut bs, instr),
|
||||
Opcode::IADD3 => encode_iadd3(&mut bs, instr),
|
||||
Opcode::LOP3(op) => encode_lop3(&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),
|
||||
|
|
|
|||
|
|
@ -88,6 +88,33 @@ impl<'a> ShaderFromNir<'a> {
|
|||
nir_op_iadd => {
|
||||
self.instrs.push(Instr::new_iadd(dst, srcs[0], srcs[1]));
|
||||
}
|
||||
nir_op_iand => {
|
||||
self.instrs.push(Instr::new_lop3(
|
||||
dst,
|
||||
LogicOp::new_lut(&|x, y, _| x & y),
|
||||
srcs[0],
|
||||
srcs[1],
|
||||
Src::Zero,
|
||||
));
|
||||
}
|
||||
nir_op_inot => {
|
||||
self.instrs.push(Instr::new_lop3(
|
||||
dst,
|
||||
LogicOp::new_lut(&|x, _, _| !x),
|
||||
srcs[0],
|
||||
Src::Zero,
|
||||
Src::Zero,
|
||||
));
|
||||
}
|
||||
nir_op_ior => {
|
||||
self.instrs.push(Instr::new_lop3(
|
||||
dst,
|
||||
LogicOp::new_lut(&|x, y, _| x | y),
|
||||
srcs[0],
|
||||
srcs[1],
|
||||
Src::Zero,
|
||||
));
|
||||
}
|
||||
nir_op_ishl => {
|
||||
self.instrs.push(Instr::new_shl(dst, srcs[0], srcs[1]));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
use std::fmt;
|
||||
use std::ops::Range;
|
||||
use std::ops::{BitAnd, BitOr, Not, Range};
|
||||
use std::slice;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
|
@ -386,6 +386,61 @@ impl InstrRefs {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct LogicOp {
|
||||
pub lut: u8,
|
||||
}
|
||||
|
||||
impl LogicOp {
|
||||
#[inline]
|
||||
pub fn new_lut<F: Fn(u8, u8, u8) -> u8>(f: &F) -> LogicOp {
|
||||
LogicOp {
|
||||
lut: f(0xf0, 0xcc, 0xaa),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eval<
|
||||
T: BitAnd<Output = T> + BitOr<Output = T> + Copy + Not<Output = T>,
|
||||
>(
|
||||
&self,
|
||||
x: T,
|
||||
y: T,
|
||||
z: T,
|
||||
) -> T {
|
||||
let mut res = x & !x; /* zero */
|
||||
if (self.lut & (1 << 0)) != 0 {
|
||||
res = res | (!x & !y & !z);
|
||||
}
|
||||
if (self.lut & (1 << 1)) != 0 {
|
||||
res = res | (!x & !y & z);
|
||||
}
|
||||
if (self.lut & (1 << 2)) != 0 {
|
||||
res = res | (!x & y & !z);
|
||||
}
|
||||
if (self.lut & (1 << 3)) != 0 {
|
||||
res = res | (!x & y & z);
|
||||
}
|
||||
if (self.lut & (1 << 4)) != 0 {
|
||||
res = res | (x & !y & !z);
|
||||
}
|
||||
if (self.lut & (1 << 5)) != 0 {
|
||||
res = res | (x & !y & z);
|
||||
}
|
||||
if (self.lut & (1 << 6)) != 0 {
|
||||
res = res | (x & y & !z);
|
||||
}
|
||||
if (self.lut & (1 << 7)) != 0 {
|
||||
res = res | (x & y & z);
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for LogicOp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "LUT[{:#x}]", self.lut)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AttrAccess {
|
||||
pub addr: u16,
|
||||
pub comps: u8,
|
||||
|
|
@ -632,6 +687,10 @@ impl Instr {
|
|||
Instr::new(Opcode::IADD3, slice::from_ref(&dst), &[Src::Zero, 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])
|
||||
}
|
||||
|
||||
pub fn new_shl(dst: Dst, x: Src, shift: Src) -> Instr {
|
||||
Instr::new(Opcode::SHL, slice::from_ref(&dst), &[x, shift])
|
||||
}
|
||||
|
|
@ -754,6 +813,7 @@ impl Instr {
|
|||
| Opcode::FMNMX
|
||||
| Opcode::FMUL
|
||||
| Opcode::IADD3
|
||||
| Opcode::LOP3(_)
|
||||
| Opcode::SHL => Some(6),
|
||||
Opcode::MOV => Some(15),
|
||||
Opcode::S2R(_) => None,
|
||||
|
|
@ -800,6 +860,7 @@ pub enum Opcode {
|
|||
FMUL,
|
||||
|
||||
IADD3,
|
||||
LOP3(LogicOp),
|
||||
SHL,
|
||||
|
||||
S2R(u8),
|
||||
|
|
@ -827,6 +888,7 @@ impl fmt::Display for Opcode {
|
|||
Opcode::FMNMX => write!(f, "FMNMX"),
|
||||
Opcode::FMUL => write!(f, "FMUL"),
|
||||
Opcode::IADD3 => write!(f, "IADD3"),
|
||||
Opcode::LOP3(op) => write!(f, "LOP3.{}", op),
|
||||
Opcode::SHL => write!(f, "SHL"),
|
||||
Opcode::S2R(i) => write!(f, "S2R({})", i),
|
||||
Opcode::MOV => write!(f, "MOV"),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue