diff options
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/translate/impl')
10 files changed, 93 insertions, 38 deletions
| diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h b/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h index 3da37a2bb..fd73f656c 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h @@ -46,7 +46,8 @@ inline IR::FmzMode CastFmzMode(FmzMode fmz_mode) {      case FmzMode::FTZ:          return IR::FmzMode::FTZ;      case FmzMode::FMZ: -        return IR::FmzMode::FMZ; +        // FMZ is manually handled in the instruction +        return IR::FmzMode::FTZ;      case FmzMode::INVALIDFMZ3:          break;      } diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp index 219ffcc6a..76a807d4e 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp @@ -53,7 +53,7 @@ void FADD(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {  } // Anonymous namespace  void TranslatorVisitor::FADD_reg(u64 insn) { -    FADD(*this, insn, GetRegFloat20(insn)); +    FADD(*this, insn, GetFloatReg20(insn));  }  void TranslatorVisitor::FADD_cbuf(u64 insn) { diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp index 758700d3c..c2ca0873b 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp @@ -51,7 +51,7 @@ void FFMA(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, const IR::F32& s  } // Anonymous namespace  void TranslatorVisitor::FFMA_reg(u64 insn) { -    FFMA(*this, insn, GetRegFloat20(insn), GetRegFloat39(insn)); +    FFMA(*this, insn, GetFloatReg20(insn), GetFloatReg39(insn));  }  void TranslatorVisitor::FFMA_rc(u64) { @@ -59,7 +59,7 @@ void TranslatorVisitor::FFMA_rc(u64) {  }  void TranslatorVisitor::FFMA_cr(u64 insn) { -    FFMA(*this, insn, GetFloatCbuf(insn), GetRegFloat39(insn)); +    FFMA(*this, insn, GetFloatCbuf(insn), GetFloatReg39(insn));  }  void TranslatorVisitor::FFMA_imm(u64) { diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp index ba005fbf4..2f8605619 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp @@ -10,7 +10,7 @@  namespace Shader::Maxwell {  namespace { -enum class Operation { +enum class Operation : u64 {      Cos = 0,      Sin = 1,      Ex2 = 2,    // Base 2 exponent @@ -39,11 +39,11 @@ void TranslatorVisitor::MUFU(u64 insn) {      IR::F32 value{[&]() -> IR::F32 {          switch (mufu.operation) {          case Operation::Cos: -            return ir.FPCosNotReduced(op_a); +            return ir.FPCos(op_a);          case Operation::Sin: -            return ir.FPSinNotReduced(op_a); +            return ir.FPSin(op_a);          case Operation::Ex2: -            return ir.FPExp2NotReduced(op_a); +            return ir.FPExp2(op_a);          case Operation::Lg2:              return ir.FPLog2(op_a);          case Operation::Rcp: diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp index 5c38d3fc1..edf2cadae 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp @@ -55,9 +55,6 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, FmzMode fmz_mode      if (cc) {          throw NotImplementedException("FMUL CC");      } -    if (sat) { -        throw NotImplementedException("FMUL SAT"); -    }      IR::F32 op_a{v.F(fmul.src_a)};      if (scale != Scale::None) {          if (fmz_mode != FmzMode::FTZ || fp_rounding != FpRounding::RN) { @@ -71,7 +68,20 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, FmzMode fmz_mode          .rounding{CastFpRounding(fp_rounding)},          .fmz_mode{CastFmzMode(fmz_mode)},      }; -    v.F(fmul.dest_reg, v.ir.FPMul(op_a, op_b, fp_control)); +    IR::F32 value{v.ir.FPMul(op_a, op_b, fp_control)}; +    if (fmz_mode == FmzMode::FMZ && !sat) { +        // Do not implement FMZ if SAT is enabled, as it does the logic for us. +        // On D3D9 mode, anything * 0 is zero, even NAN and infinity +        const IR::F32 zero{v.ir.Imm32(0.0f)}; +        const IR::U1 zero_a{v.ir.FPEqual(op_a, zero)}; +        const IR::U1 zero_b{v.ir.FPEqual(op_b, zero)}; +        const IR::U1 any_zero{v.ir.LogicalOr(zero_a, zero_b)}; +        value = IR::F32{v.ir.Select(any_zero, zero, value)}; +    } +    if (sat) { +        value = v.ir.FPSaturate(value); +    } +    v.F(fmul.dest_reg, value);  }  void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) { @@ -83,27 +93,33 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {          BitField<47, 1, u64> cc;          BitField<48, 1, u64> neg_b;          BitField<50, 1, u64> sat; -    } fmul{insn}; - +    } const fmul{insn};      FMUL(v, insn, src_b, fmul.fmz, fmul.fp_rounding, fmul.scale, fmul.sat != 0, fmul.cc != 0,           fmul.neg_b != 0);  }  } // Anonymous namespace  void TranslatorVisitor::FMUL_reg(u64 insn) { -    return FMUL(*this, insn, GetRegFloat20(insn)); +    return FMUL(*this, insn, GetFloatReg20(insn));  } -void TranslatorVisitor::FMUL_cbuf(u64) { -    throw NotImplementedException("FMUL (cbuf)"); +void TranslatorVisitor::FMUL_cbuf(u64 insn) { +    return FMUL(*this, insn, GetFloatCbuf(insn));  } -void TranslatorVisitor::FMUL_imm(u64) { -    throw NotImplementedException("FMUL (imm)"); +void TranslatorVisitor::FMUL_imm(u64 insn) { +    return FMUL(*this, insn, GetFloatImm20(insn));  } -void TranslatorVisitor::FMUL32I(u64) { -    throw NotImplementedException("FMUL32I"); +void TranslatorVisitor::FMUL32I(u64 insn) { +    union { +        u64 raw; +        BitField<52, 1, u64> cc; +        BitField<53, 2, FmzMode> fmz; +        BitField<55, 1, u64> sat; +    } const fmul32i{insn}; +    FMUL(*this, insn, GetFloatImm32(insn), fmul32i.fmz, FpRounding::RN, Scale::None, +         fmul32i.sat != 0, fmul32i.cc != 0, false);  }  } // namespace Shader::Maxwell
\ No newline at end of file diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp new file mode 100644 index 000000000..f91b93fad --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp @@ -0,0 +1,41 @@ +// 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 { +enum class Mode : u64 { +    SINCOS, +    EX2, +}; + +void RRO(TranslatorVisitor& v, u64 insn, const IR::F32& src) { +    union { +        u64 raw; +        BitField<0, 8, IR::Reg> dest_reg; +        BitField<39, 1, Mode> mode; +        BitField<45, 1, u64> neg; +        BitField<49, 1, u64> abs; +    } const rro{insn}; + +    v.F(rro.dest_reg, v.ir.FPAbsNeg(src, rro.abs != 0, rro.neg != 0)); +} +} // Anonymous namespace + +void TranslatorVisitor::RRO_reg(u64 insn) { +    RRO(*this, insn, GetFloatReg20(insn)); +} + +void TranslatorVisitor::RRO_cbuf(u64 insn) { +    RRO(*this, insn, GetFloatCbuf(insn)); +} + +void TranslatorVisitor::RRO_imm(u64) { +    throw NotImplementedException("RRO (imm)"); +} + +} // namespace Shader::Maxwell diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp index 165d475b9..a5a0e1a9b 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp @@ -48,11 +48,11 @@ IR::U32 TranslatorVisitor::GetReg39(u64 insn) {      return X(reg.index);  } -IR::F32 TranslatorVisitor::GetRegFloat20(u64 insn) { +IR::F32 TranslatorVisitor::GetFloatReg20(u64 insn) {      return ir.BitCast<IR::F32>(GetReg20(insn));  } -IR::F32 TranslatorVisitor::GetRegFloat39(u64 insn) { +IR::F32 TranslatorVisitor::GetFloatReg39(u64 insn) {      return ir.BitCast<IR::F32>(GetReg39(insn));  } @@ -110,6 +110,14 @@ IR::U32 TranslatorVisitor::GetImm32(u64 insn) {      return ir.Imm32(static_cast<u32>(imm.value));  } +IR::F32 TranslatorVisitor::GetFloatImm32(u64 insn) { +    union { +        u64 raw; +        BitField<20, 32, u64> value; +    } const imm{insn}; +    return ir.Imm32(Common::BitCast<f32>(static_cast<u32>(imm.value))); +} +  void TranslatorVisitor::SetZFlag(const IR::U1& value) {      ir.SetZFlag(value);  } diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h index 4d4cf2ebf..4e722e205 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h @@ -304,8 +304,8 @@ public:      [[nodiscard]] IR::U32 GetReg8(u64 insn);      [[nodiscard]] IR::U32 GetReg20(u64 insn);      [[nodiscard]] IR::U32 GetReg39(u64 insn); -    [[nodiscard]] IR::F32 GetRegFloat20(u64 insn); -    [[nodiscard]] IR::F32 GetRegFloat39(u64 insn); +    [[nodiscard]] IR::F32 GetFloatReg20(u64 insn); +    [[nodiscard]] IR::F32 GetFloatReg39(u64 insn);      [[nodiscard]] IR::U32 GetCbuf(u64 insn);      [[nodiscard]] IR::F32 GetFloatCbuf(u64 insn); @@ -314,6 +314,7 @@ public:      [[nodiscard]] IR::F32 GetFloatImm20(u64 insn);      [[nodiscard]] IR::U32 GetImm32(u64 insn); +    [[nodiscard]] IR::F32 GetFloatImm32(u64 insn);      void SetZFlag(const IR::U1& value);      void SetSFlag(const IR::U1& value); diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp index d8a5158b5..20af68852 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp @@ -50,7 +50,7 @@ void SHL(TranslatorVisitor& v, u64 insn, const IR::U32& unsafe_shift) {          //          const IR::U1 is_safe{v.ir.ILessThan(unsafe_shift, v.ir.Imm32(32), false)};          const IR::U32 unsafe_result{v.ir.ShiftLeftLogical(base, unsafe_shift)}; -        result = v.ir.Select(is_safe, unsafe_result, v.ir.Imm32(0)); +        result = IR::U32{v.ir.Select(is_safe, unsafe_result, v.ir.Imm32(0))};      }      v.X(shl.dest_reg, result);  } 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 628cf1c14..4114e10be 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp @@ -721,18 +721,6 @@ void TranslatorVisitor::RET(u64) {      ThrowNotImplemented(Opcode::RET);  } -void TranslatorVisitor::RRO_reg(u64) { -    ThrowNotImplemented(Opcode::RRO_reg); -} - -void TranslatorVisitor::RRO_cbuf(u64) { -    ThrowNotImplemented(Opcode::RRO_cbuf); -} - -void TranslatorVisitor::RRO_imm(u64) { -    ThrowNotImplemented(Opcode::RRO_imm); -} -  void TranslatorVisitor::RTT(u64) {      ThrowNotImplemented(Opcode::RTT);  } | 
