diff options
author | ameerj <52414509+ameerj@users.noreply.github.com> | 2021-02-27 22:37:49 +0100 |
---|---|---|
committer | ameerj <52414509+ameerj@users.noreply.github.com> | 2021-07-23 03:51:22 +0200 |
commit | 08a9e95905fa90d9d2455c9aedf66cebcfc6f6ba (patch) | |
tree | 8b707c93ce3fe6a240faa8807b7eef14c5735415 /src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp | |
parent | shader: Implement BFE (diff) | |
download | yuzu-08a9e95905fa90d9d2455c9aedf66cebcfc6f6ba.tar yuzu-08a9e95905fa90d9d2455c9aedf66cebcfc6f6ba.tar.gz yuzu-08a9e95905fa90d9d2455c9aedf66cebcfc6f6ba.tar.bz2 yuzu-08a9e95905fa90d9d2455c9aedf66cebcfc6f6ba.tar.lz yuzu-08a9e95905fa90d9d2455c9aedf66cebcfc6f6ba.tar.xz yuzu-08a9e95905fa90d9d2455c9aedf66cebcfc6f6ba.tar.zst yuzu-08a9e95905fa90d9d2455c9aedf66cebcfc6f6ba.zip |
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp')
-rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp | 56 |
1 files changed, 56 insertions, 0 deletions
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 |