diff options
3 files changed, 67 insertions, 12 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index b4d2dcc42..8be2d353f 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt | |||
| @@ -59,6 +59,7 @@ add_library(shader_recompiler STATIC | |||
| 59 | frontend/maxwell/opcodes.h | 59 | frontend/maxwell/opcodes.h |
| 60 | frontend/maxwell/program.cpp | 60 | frontend/maxwell/program.cpp |
| 61 | frontend/maxwell/program.h | 61 | frontend/maxwell/program.h |
| 62 | frontend/maxwell/translate/impl/bitfield_extract.cpp | ||
| 62 | frontend/maxwell/translate/impl/common_encoding.h | 63 | frontend/maxwell/translate/impl/common_encoding.h |
| 63 | frontend/maxwell/translate/impl/floating_point_add.cpp | 64 | frontend/maxwell/translate/impl/floating_point_add.cpp |
| 64 | frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp | 65 | frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_extract.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_extract.cpp new file mode 100644 index 000000000..4a03e6939 --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_extract.cpp | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/bit_field.h" | ||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||
| 8 | |||
| 9 | namespace Shader::Maxwell { | ||
| 10 | namespace { | ||
| 11 | void BFE(TranslatorVisitor& v, u64 insn, const IR::U32& src) { | ||
| 12 | union { | ||
| 13 | u64 insn; | ||
| 14 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 15 | BitField<8, 8, IR::Reg> offset_reg; | ||
| 16 | BitField<40, 1, u64> brev; | ||
| 17 | BitField<48, 1, u64> is_signed; | ||
| 18 | } const bfe{insn}; | ||
| 19 | |||
| 20 | const IR::U32 offset{v.ir.BitFieldExtract(src, v.ir.Imm32(0), v.ir.Imm32(8), false)}; | ||
| 21 | const IR::U32 count{v.ir.BitFieldExtract(src, v.ir.Imm32(8), v.ir.Imm32(8), false)}; | ||
| 22 | |||
| 23 | // Common constants | ||
| 24 | const IR::U32 zero{v.ir.Imm32(0)}; | ||
| 25 | const IR::U32 one{v.ir.Imm32(1)}; | ||
| 26 | const IR::U32 max_size{v.ir.Imm32(32)}; | ||
| 27 | // Edge case conditions | ||
| 28 | const IR::U1 zero_count{v.ir.IEqual(count, zero)}; | ||
| 29 | const IR::U1 exceed_count{v.ir.IGreaterThanEqual(v.ir.IAdd(offset, count), max_size, false)}; | ||
| 30 | const IR::U1 replicate{v.ir.IGreaterThanEqual(offset, max_size, false)}; | ||
| 31 | |||
| 32 | IR::U32 base{v.X(bfe.offset_reg)}; | ||
| 33 | if (bfe.brev != 0) { | ||
| 34 | base = v.ir.BitReverse(base); | ||
| 35 | } | ||
| 36 | IR::U32 result{v.ir.BitFieldExtract(base, offset, count, bfe.is_signed != 0)}; | ||
| 37 | if (bfe.is_signed != 0) { | ||
| 38 | const IR::U1 is_negative{v.ir.ILessThan(base, zero, true)}; | ||
| 39 | const IR::U32 replicated_bit{v.ir.Select(is_negative, v.ir.Imm32(-1), zero)}; | ||
| 40 | const IR::U32 exceed_bit{v.ir.BitFieldExtract(base, v.ir.Imm32(31), one, false)}; | ||
| 41 | // Replicate condition | ||
| 42 | result = IR::U32{v.ir.Select(replicate, replicated_bit, result)}; | ||
| 43 | // Exceeding condition | ||
| 44 | const IR::U32 exceed_result{v.ir.BitFieldInsert(result, exceed_bit, v.ir.Imm32(31), one)}; | ||
| 45 | result = IR::U32{v.ir.Select(exceed_count, exceed_result, result)}; | ||
| 46 | } | ||
| 47 | // Zero count condition | ||
| 48 | result = IR::U32{v.ir.Select(zero_count, zero, result)}; | ||
| 49 | |||
| 50 | v.X(bfe.dest_reg, result); | ||
| 51 | } | ||
| 52 | } // Anonymous namespace | ||
| 53 | |||
| 54 | void TranslatorVisitor::BFE_reg(u64 insn) { | ||
| 55 | BFE(*this, insn, GetReg20(insn)); | ||
| 56 | } | ||
| 57 | |||
| 58 | void TranslatorVisitor::BFE_cbuf(u64 insn) { | ||
| 59 | BFE(*this, insn, GetCbuf(insn)); | ||
| 60 | } | ||
| 61 | |||
| 62 | void TranslatorVisitor::BFE_imm(u64 insn) { | ||
| 63 | BFE(*this, insn, GetImm20(insn)); | ||
| 64 | } | ||
| 65 | |||
| 66 | } // namespace Shader::Maxwell | ||
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp index 127686b43..3714f5f4f 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | |||
| @@ -49,18 +49,6 @@ void TranslatorVisitor::BAR(u64) { | |||
| 49 | ThrowNotImplemented(Opcode::BAR); | 49 | ThrowNotImplemented(Opcode::BAR); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | void TranslatorVisitor::BFE_reg(u64) { | ||
| 53 | ThrowNotImplemented(Opcode::BFE_reg); | ||
| 54 | } | ||
| 55 | |||
| 56 | void TranslatorVisitor::BFE_cbuf(u64) { | ||
| 57 | ThrowNotImplemented(Opcode::BFE_cbuf); | ||
| 58 | } | ||
| 59 | |||
| 60 | void TranslatorVisitor::BFE_imm(u64) { | ||
| 61 | ThrowNotImplemented(Opcode::BFE_imm); | ||
| 62 | } | ||
| 63 | |||
| 64 | void TranslatorVisitor::BFI_reg(u64) { | 52 | void TranslatorVisitor::BFI_reg(u64) { |
| 65 | ThrowNotImplemented(Opcode::BFI_reg); | 53 | ThrowNotImplemented(Opcode::BFI_reg); |
| 66 | } | 54 | } |