diff options
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/translate')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp | 116 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | 16 |
2 files changed, 116 insertions, 16 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp new file mode 100644 index 000000000..21cb80d67 --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp | |||
| @@ -0,0 +1,116 @@ | |||
| 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/common_funcs.h" | ||
| 8 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||
| 9 | |||
| 10 | namespace Shader::Maxwell { | ||
| 11 | namespace { | ||
| 12 | enum class FPCompareOp : u64 { | ||
| 13 | F, | ||
| 14 | LT, | ||
| 15 | EQ, | ||
| 16 | LE, | ||
| 17 | GT, | ||
| 18 | NE, | ||
| 19 | GE, | ||
| 20 | NUM, | ||
| 21 | Nan, | ||
| 22 | LTU, | ||
| 23 | EQU, | ||
| 24 | LEU, | ||
| 25 | GTU, | ||
| 26 | NEU, | ||
| 27 | GEU, | ||
| 28 | T, | ||
| 29 | }; | ||
| 30 | |||
| 31 | bool IsCompareOpOrdered(FPCompareOp op) { | ||
| 32 | switch (op) { | ||
| 33 | case FPCompareOp::LTU: | ||
| 34 | case FPCompareOp::EQU: | ||
| 35 | case FPCompareOp::LEU: | ||
| 36 | case FPCompareOp::GTU: | ||
| 37 | case FPCompareOp::NEU: | ||
| 38 | case FPCompareOp::GEU: | ||
| 39 | return false; | ||
| 40 | default: | ||
| 41 | return true; | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | IR::U1 FloatingPointCompare(IR::IREmitter& ir, const IR::F32& operand_1, const IR::F32& operand_2, | ||
| 46 | FPCompareOp compare_op, IR::FpControl control) { | ||
| 47 | const bool ordered{IsCompareOpOrdered(compare_op)}; | ||
| 48 | switch (compare_op) { | ||
| 49 | case FPCompareOp::F: | ||
| 50 | return ir.Imm1(false); | ||
| 51 | case FPCompareOp::LT: | ||
| 52 | case FPCompareOp::LTU: | ||
| 53 | return ir.FPLessThan(operand_1, operand_2, control, ordered); | ||
| 54 | case FPCompareOp::EQ: | ||
| 55 | case FPCompareOp::EQU: | ||
| 56 | return ir.FPEqual(operand_1, operand_2, control, ordered); | ||
| 57 | case FPCompareOp::LE: | ||
| 58 | case FPCompareOp::LEU: | ||
| 59 | return ir.FPLessThanEqual(operand_1, operand_2, control, ordered); | ||
| 60 | case FPCompareOp::GT: | ||
| 61 | case FPCompareOp::GTU: | ||
| 62 | return ir.FPGreaterThan(operand_1, operand_2, control, ordered); | ||
| 63 | case FPCompareOp::NE: | ||
| 64 | case FPCompareOp::NEU: | ||
| 65 | return ir.FPNotEqual(operand_1, operand_2, control, ordered); | ||
| 66 | case FPCompareOp::GE: | ||
| 67 | case FPCompareOp::GEU: | ||
| 68 | return ir.FPGreaterThanEqual(operand_1, operand_2, control, ordered); | ||
| 69 | case FPCompareOp::NUM: | ||
| 70 | return ir.FPOrdered(operand_1, operand_2); | ||
| 71 | case FPCompareOp::Nan: | ||
| 72 | return ir.FPUnordered(operand_1, operand_2); | ||
| 73 | case FPCompareOp::T: | ||
| 74 | return ir.Imm1(true); | ||
| 75 | default: | ||
| 76 | throw NotImplementedException("Invalid compare op {}", compare_op); | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | void FCMP(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::F32& operand) { | ||
| 81 | union { | ||
| 82 | u64 insn; | ||
| 83 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 84 | BitField<8, 8, IR::Reg> src_reg; | ||
| 85 | BitField<47, 1, u64> ftz; | ||
| 86 | BitField<48, 4, FPCompareOp> compare_op; | ||
| 87 | } const fcmp{insn}; | ||
| 88 | |||
| 89 | const IR::F32 zero{v.ir.Imm32(0.0f)}; | ||
| 90 | const IR::F32 neg_zero{v.ir.Imm32(-0.0f)}; | ||
| 91 | IR::FpControl control{.fmz_mode{fcmp.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None}}; | ||
| 92 | const IR::U1 cmp_result{FloatingPointCompare(v.ir, operand, zero, fcmp.compare_op, control)}; | ||
| 93 | const IR::U32 src_reg{v.X(fcmp.src_reg)}; | ||
| 94 | const IR::U32 result{v.ir.Select(cmp_result, src_reg, src_a)}; | ||
| 95 | |||
| 96 | v.X(fcmp.dest_reg, result); | ||
| 97 | } | ||
| 98 | } // Anonymous namespace | ||
| 99 | |||
| 100 | void TranslatorVisitor::FCMP_reg(u64 insn) { | ||
| 101 | FCMP(*this, insn, GetReg20(insn), GetFloatReg39(insn)); | ||
| 102 | } | ||
| 103 | |||
| 104 | void TranslatorVisitor::FCMP_rc(u64 insn) { | ||
| 105 | FCMP(*this, insn, GetReg39(insn), GetFloatCbuf(insn)); | ||
| 106 | } | ||
| 107 | |||
| 108 | void TranslatorVisitor::FCMP_cr(u64 insn) { | ||
| 109 | FCMP(*this, insn, GetCbuf(insn), GetFloatReg39(insn)); | ||
| 110 | } | ||
| 111 | |||
| 112 | void TranslatorVisitor::FCMP_imm(u64 insn) { | ||
| 113 | FCMP(*this, insn, GetReg39(insn), GetFloatImm20(insn)); | ||
| 114 | } | ||
| 115 | |||
| 116 | } // 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 5b153acff..e1904472f 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | |||
| @@ -201,22 +201,6 @@ void TranslatorVisitor::FCHK_imm(u64) { | |||
| 201 | ThrowNotImplemented(Opcode::FCHK_imm); | 201 | ThrowNotImplemented(Opcode::FCHK_imm); |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | void TranslatorVisitor::FCMP_reg(u64) { | ||
| 205 | ThrowNotImplemented(Opcode::FCMP_reg); | ||
| 206 | } | ||
| 207 | |||
| 208 | void TranslatorVisitor::FCMP_rc(u64) { | ||
| 209 | ThrowNotImplemented(Opcode::FCMP_rc); | ||
| 210 | } | ||
| 211 | |||
| 212 | void TranslatorVisitor::FCMP_cr(u64) { | ||
| 213 | ThrowNotImplemented(Opcode::FCMP_cr); | ||
| 214 | } | ||
| 215 | |||
| 216 | void TranslatorVisitor::FCMP_imm(u64) { | ||
| 217 | ThrowNotImplemented(Opcode::FCMP_imm); | ||
| 218 | } | ||
| 219 | |||
| 220 | void TranslatorVisitor::FMNMX_reg(u64) { | 204 | void TranslatorVisitor::FMNMX_reg(u64) { |
| 221 | ThrowNotImplemented(Opcode::FMNMX_reg); | 205 | ThrowNotImplemented(Opcode::FMNMX_reg); |
| 222 | } | 206 | } |