nak: Implement i2f

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand 2023-01-30 20:53:18 -06:00 committed by Marge Bot
parent 8adeae1dc2
commit 5935c62d4e
3 changed files with 142 additions and 1 deletions

View file

@ -357,6 +357,24 @@ impl SM75Instr {
self.set_bit(80, false /* HI */);
}
fn encode_i2f(&mut self, op: &OpI2F) {
self.encode_alu(0x106, Some(op.dst), None, op.src.into(), None);
self.set_field(60..62, 0_u8); /* TODO: subop */
self.set_bit(74, op.src_type.is_signed());
self.set_field(75..77, op.dst_type.bytes().trailing_zeros());
self.set_field(
78..80,
match op.rnd_mode {
FRndMode::NearestEven => 0_u8,
FRndMode::NegInf => 1_u8,
FRndMode::PosInf => 2_u8,
FRndMode::Zero => 3_u8,
},
);
self.set_field(84..86, op.src_type.bytes().trailing_zeros());
}
fn encode_mov(&mut self, op: &OpMov) {
self.encode_alu(0x002, Some(op.dst), None, op.src.into(), None);
self.set_field(72..76, op.quad_lanes);
@ -515,6 +533,7 @@ impl SM75Instr {
Op::ISetP(op) => si.encode_isetp(&op),
Op::Lop3(op) => si.encode_lop3(&op),
Op::Shl(op) => si.encode_shl(&op),
Op::I2F(op) => si.encode_i2f(&op),
Op::Mov(op) => si.encode_mov(&op),
Op::Sel(op) => si.encode_sel(&op),
Op::PLop3(op) => si.encode_plop3(&op),

View file

@ -90,6 +90,9 @@ impl<'a> ShaderFromNir<'a> {
self.instrs
.push(Instr::new_sel(dst, srcs[0], srcs[1], srcs[2]));
}
nir_op_i2f32 => {
self.instrs.push(Instr::new_i2f(dst, srcs[0]));
}
nir_op_iadd => {
self.instrs.push(Instr::new_iadd(dst, srcs[0], srcs[1]));
}

View file

@ -545,6 +545,94 @@ impl fmt::Display for LogicOp {
}
}
pub enum FloatType {
F16,
F32,
F64,
}
impl FloatType {
pub fn bytes(&self) -> usize {
match self {
FloatType::F16 => 2,
FloatType::F32 => 4,
FloatType::F64 => 8,
}
}
}
impl fmt::Display for FloatType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
FloatType::F16 => write!(f, "F16"),
FloatType::F32 => write!(f, "F32"),
FloatType::F64 => write!(f, "F64"),
}
}
}
pub enum FRndMode {
NearestEven,
NegInf,
PosInf,
Zero,
}
impl fmt::Display for FRndMode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
FRndMode::NearestEven => write!(f, "RE"),
FRndMode::NegInf => write!(f, "RM"),
FRndMode::PosInf => write!(f, "RP"),
FRndMode::Zero => write!(f, "RZ"),
}
}
}
pub enum IntType {
U8,
I8,
U16,
I16,
U32,
I32,
U64,
I64,
}
impl IntType {
pub fn is_signed(&self) -> bool {
match self {
IntType::U8 | IntType::U16 | IntType::U32 | IntType::U64 => false,
IntType::I8 | IntType::I16 | IntType::I32 | IntType::I64 => true,
}
}
pub fn bytes(&self) -> usize {
match self {
IntType::U8 | IntType::I8 => 1,
IntType::U16 | IntType::I16 => 2,
IntType::U32 | IntType::I32 => 4,
IntType::U64 | IntType::I64 => 8,
}
}
}
impl fmt::Display for IntType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
IntType::U8 => write!(f, "U8"),
IntType::I8 => write!(f, "I8"),
IntType::U16 => write!(f, "U16"),
IntType::I16 => write!(f, "I16"),
IntType::U32 => write!(f, "U32"),
IntType::I32 => write!(f, "I32"),
IntType::U64 => write!(f, "U64"),
IntType::I64 => write!(f, "I64"),
}
}
}
pub enum MemAddrType {
A32,
A64,
@ -751,6 +839,26 @@ impl fmt::Display for OpShl {
}
}
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice, SrcModsAsSlice)]
pub struct OpI2F {
pub dst: Dst,
pub src: Src,
pub dst_type: FloatType,
pub src_type: IntType,
pub rnd_mode: FRndMode,
}
impl fmt::Display for OpI2F {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"I2F.{}.{}.{} {} {}",
self.dst_type, self.src_type, self.rnd_mode, self.dst, self.src,
)
}
}
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice, SrcModsAsSlice)]
pub struct OpMov {
@ -1011,6 +1119,7 @@ pub enum Op {
ISetP(OpISetP),
Lop3(OpLop3),
Shl(OpShl),
I2F(OpI2F),
Mov(OpMov),
Sel(OpSel),
PLop3(OpPLop3),
@ -1198,6 +1307,16 @@ impl Instr {
}))
}
pub fn new_i2f(dst: Dst, src: Src) -> Instr {
Instr::new(Op::I2F(OpI2F {
dst: dst,
src: src,
dst_type: FloatType::F32,
src_type: IntType::I32,
rnd_mode: FRndMode::NearestEven,
}))
}
pub fn new_isetp(
dst: Dst,
cmp_type: IntCmpType,
@ -1360,7 +1479,7 @@ impl Instr {
| Op::PLop3(_)
| Op::ISetP(_)
| Op::Shl(_) => Some(6),
Op::Mov(_) => Some(15),
Op::I2F(_) | Op::Mov(_) => Some(15),
Op::Sel(_) => Some(15),
Op::S2R(_) => None,
Op::ALd(_) => None,