From 08a9e95905fa90d9d2455c9aedf66cebcfc6f6ba Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 27 Feb 2021 16:37:49 -0500 Subject: shader: Implement BFI --- .../maxwell/translate/impl/bitfield_insert.cpp | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp (limited to 'src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp') diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp new file mode 100644 index 000000000..ee312c30d --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp @@ -0,0 +1,56 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/bit_field.h" +#include "common/common_types.h" +#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" + +namespace Shader::Maxwell { +namespace { +void BFI(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::U32& base) { + union { + u64 insn; + BitField<0, 8, IR::Reg> dest_reg; + BitField<8, 8, IR::Reg> insert_reg; + } const bfi{insn}; + + const IR::U32 offset{v.ir.BitFieldExtract(src_a, v.ir.Imm32(0), v.ir.Imm32(8), false)}; + const IR::U32 unsafe_count{v.ir.BitFieldExtract(src_a, v.ir.Imm32(8), v.ir.Imm32(8), false)}; + const IR::U32 max_size{v.ir.Imm32(32)}; + + // Edge case conditions + const IR::U1 zero_offset{v.ir.IEqual(offset, v.ir.Imm32(0))}; + const IR::U1 exceed_offset{v.ir.IGreaterThanEqual(offset, max_size, false)}; + const IR::U1 exceed_count{v.ir.IGreaterThanEqual(unsafe_count, max_size, false)}; + + const IR::U32 remaining_size{v.ir.ISub(max_size, offset)}; + const IR::U32 safe_count{v.ir.Select(exceed_count, remaining_size, unsafe_count)}; + + const IR::U32 insert{v.X(bfi.insert_reg)}; + IR::U32 result{v.ir.BitFieldInsert(base, insert, offset, safe_count)}; + + result = IR::U32{v.ir.Select(exceed_offset, base, result)}; + result = IR::U32{v.ir.Select(zero_offset, base, result)}; + + v.X(bfi.dest_reg, result); +} +} // Anonymous namespace + +void TranslatorVisitor::BFI_reg(u64 insn) { + BFI(*this, insn, GetReg20(insn), GetReg39(insn)); +} + +void TranslatorVisitor::BFI_rc(u64 insn) { + BFI(*this, insn, GetReg39(insn), GetCbuf(insn)); +} + +void TranslatorVisitor::BFI_cr(u64 insn) { + BFI(*this, insn, GetCbuf(insn), GetReg39(insn)); +} + +void TranslatorVisitor::BFI_imm(u64 insn) { + BFI(*this, insn, GetImm20(insn), GetReg39(insn)); +} + +} // namespace Shader::Maxwell -- cgit v1.2.3 From 1be6705408d1a3454146c705fae3dc55031e966e Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Sat, 10 Apr 2021 00:29:12 +0200 Subject: shader: Implement CC for ISET, FSET, PSET, CSET, and DSET Throw when other instructions are missing CC. --- .../frontend/maxwell/translate/impl/bitfield_insert.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp') diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp index ee312c30d..fb7f821e6 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp @@ -13,8 +13,13 @@ void BFI(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::U32& ba u64 insn; BitField<0, 8, IR::Reg> dest_reg; BitField<8, 8, IR::Reg> insert_reg; + BitField<47, 1, u64> cc; } const bfi{insn}; + if (bfi.cc != 0) { + throw NotImplementedException("BFI CC"); + } + const IR::U32 offset{v.ir.BitFieldExtract(src_a, v.ir.Imm32(0), v.ir.Imm32(8), false)}; const IR::U32 unsafe_count{v.ir.BitFieldExtract(src_a, v.ir.Imm32(8), v.ir.Imm32(8), false)}; const IR::U32 max_size{v.ir.Imm32(32)}; -- cgit v1.2.3 From be431f5ed080955cce358e9750347229b2bc9a04 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 17 Apr 2021 00:48:35 -0400 Subject: shader: Implement BFE and BFI CC Fix two bugs in BFI. --- .../frontend/maxwell/translate/impl/bitfield_insert.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp') diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp index fb7f821e6..1e1ec2119 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp @@ -16,18 +16,14 @@ void BFI(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::U32& ba BitField<47, 1, u64> cc; } const bfi{insn}; - if (bfi.cc != 0) { - throw NotImplementedException("BFI CC"); - } - - const IR::U32 offset{v.ir.BitFieldExtract(src_a, v.ir.Imm32(0), v.ir.Imm32(8), false)}; + const IR::U32 zero{v.ir.Imm32(0)}; + const IR::U32 offset{v.ir.BitFieldExtract(src_a, zero, v.ir.Imm32(8), false)}; const IR::U32 unsafe_count{v.ir.BitFieldExtract(src_a, v.ir.Imm32(8), v.ir.Imm32(8), false)}; const IR::U32 max_size{v.ir.Imm32(32)}; // Edge case conditions - const IR::U1 zero_offset{v.ir.IEqual(offset, v.ir.Imm32(0))}; const IR::U1 exceed_offset{v.ir.IGreaterThanEqual(offset, max_size, false)}; - const IR::U1 exceed_count{v.ir.IGreaterThanEqual(unsafe_count, max_size, false)}; + const IR::U1 exceed_count{v.ir.IGreaterThan(unsafe_count, max_size, false)}; const IR::U32 remaining_size{v.ir.ISub(max_size, offset)}; const IR::U32 safe_count{v.ir.Select(exceed_count, remaining_size, unsafe_count)}; @@ -36,9 +32,14 @@ void BFI(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::U32& ba IR::U32 result{v.ir.BitFieldInsert(base, insert, offset, safe_count)}; result = IR::U32{v.ir.Select(exceed_offset, base, result)}; - result = IR::U32{v.ir.Select(zero_offset, base, result)}; v.X(bfi.dest_reg, result); + if (bfi.cc != 0) { + v.SetZFlag(v.ir.IEqual(result, zero)); + v.SetSFlag(v.ir.ILessThan(result, zero, true)); + v.ResetCFlag(); + v.ResetOFlag(); + } } } // Anonymous namespace -- cgit v1.2.3