diff options
3 files changed, 42 insertions, 35 deletions
| diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 354d72c9b..ce6c9af07 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp @@ -1622,84 +1622,86 @@ U32U64 IREmitter::ConvertFToI(size_t bitsize, bool is_signed, const F16F32F64& v      return is_signed ? ConvertFToS(bitsize, value) : ConvertFToU(bitsize, value);  } -F16F32F64 IREmitter::ConvertSToF(size_t dest_bitsize, size_t src_bitsize, const Value& value) { +F16F32F64 IREmitter::ConvertSToF(size_t dest_bitsize, size_t src_bitsize, const Value& value, +                                 FpControl control) {      switch (dest_bitsize) {      case 16:          switch (src_bitsize) {          case 8: -            return Inst<F16>(Opcode::ConvertF16S8, value); +            return Inst<F16>(Opcode::ConvertF16S8, Flags{control}, value);          case 16: -            return Inst<F16>(Opcode::ConvertF16S16, value); +            return Inst<F16>(Opcode::ConvertF16S16, Flags{control}, value);          case 32: -            return Inst<F16>(Opcode::ConvertF16S32, value); +            return Inst<F16>(Opcode::ConvertF16S32, Flags{control}, value);          case 64: -            return Inst<F16>(Opcode::ConvertF16S64, value); +            return Inst<F16>(Opcode::ConvertF16S64, Flags{control}, value);          }          break;      case 32:          switch (src_bitsize) {          case 8: -            return Inst<F32>(Opcode::ConvertF32S8, value); +            return Inst<F32>(Opcode::ConvertF32S8, Flags{control}, value);          case 16: -            return Inst<F32>(Opcode::ConvertF32S16, value); +            return Inst<F32>(Opcode::ConvertF32S16, Flags{control}, value);          case 32: -            return Inst<F32>(Opcode::ConvertF32S32, value); +            return Inst<F32>(Opcode::ConvertF32S32, Flags{control}, value);          case 64: -            return Inst<F32>(Opcode::ConvertF32S64, value); +            return Inst<F32>(Opcode::ConvertF32S64, Flags{control}, value);          }          break;      case 64:          switch (src_bitsize) {          case 8: -            return Inst<F64>(Opcode::ConvertF64S8, value); +            return Inst<F64>(Opcode::ConvertF64S8, Flags{control}, value);          case 16: -            return Inst<F64>(Opcode::ConvertF64S16, value); +            return Inst<F64>(Opcode::ConvertF64S16, Flags{control}, value);          case 32: -            return Inst<F64>(Opcode::ConvertF64S32, value); +            return Inst<F64>(Opcode::ConvertF64S32, Flags{control}, value);          case 64: -            return Inst<F64>(Opcode::ConvertF64S64, value); +            return Inst<F64>(Opcode::ConvertF64S64, Flags{control}, value);          }          break;      }      throw InvalidArgument("Invalid bit size combination dst={} src={}", dest_bitsize, src_bitsize);  } -F16F32F64 IREmitter::ConvertUToF(size_t dest_bitsize, size_t src_bitsize, const Value& value) { +F16F32F64 IREmitter::ConvertUToF(size_t dest_bitsize, size_t src_bitsize, const Value& value, +                                 FpControl control) {      switch (dest_bitsize) {      case 16:          switch (src_bitsize) {          case 8: -            return Inst<F16>(Opcode::ConvertF16U8, value); +            return Inst<F16>(Opcode::ConvertF16U8, Flags{control}, value);          case 16: -            return Inst<F16>(Opcode::ConvertF16U16, value); +            return Inst<F16>(Opcode::ConvertF16U16, Flags{control}, value);          case 32: -            return Inst<F16>(Opcode::ConvertF16U32, value); +            return Inst<F16>(Opcode::ConvertF16U32, Flags{control}, value);          case 64: -            return Inst<F16>(Opcode::ConvertF16U64, value); +            return Inst<F16>(Opcode::ConvertF16U64, Flags{control}, value);          }          break;      case 32:          switch (src_bitsize) {          case 8: -            return Inst<F32>(Opcode::ConvertF32U8, value); +            return Inst<F32>(Opcode::ConvertF32U8, Flags{control}, value);          case 16: -            return Inst<F32>(Opcode::ConvertF32U16, value); +            return Inst<F32>(Opcode::ConvertF32U16, Flags{control}, value);          case 32: -            return Inst<F32>(Opcode::ConvertF32U32, value); +            return Inst<F32>(Opcode::ConvertF32U32, Flags{control}, value);          case 64: -            return Inst<F32>(Opcode::ConvertF32U64, value); +            return Inst<F32>(Opcode::ConvertF32U64, Flags{control}, value);          }          break;      case 64:          switch (src_bitsize) {          case 8: -            return Inst<F64>(Opcode::ConvertF64U8, value); +            return Inst<F64>(Opcode::ConvertF64U8, Flags{control}, value);          case 16: -            return Inst<F64>(Opcode::ConvertF64U16, value); +            return Inst<F64>(Opcode::ConvertF64U16, Flags{control}, value);          case 32: -            return Inst<F64>(Opcode::ConvertF64U32, value); +            return Inst<F64>(Opcode::ConvertF64U32, Flags{control}, value);          case 64: -            return Inst<F64>(Opcode::ConvertF64U64, value); +            return Inst<F64>(Opcode::ConvertF64U64, Flags{control}, value);          }          break;      } @@ -1707,9 +1709,9 @@ F16F32F64 IREmitter::ConvertUToF(size_t dest_bitsize, size_t src_bitsize, const  }  F16F32F64 IREmitter::ConvertIToF(size_t dest_bitsize, size_t src_bitsize, bool is_signed, -                                 const Value& value) { -    return is_signed ? ConvertSToF(dest_bitsize, src_bitsize, value) -                     : ConvertUToF(dest_bitsize, src_bitsize, value); +                                 const Value& value, FpControl control) { +    return is_signed ? ConvertSToF(dest_bitsize, src_bitsize, value, control) +                     : ConvertUToF(dest_bitsize, src_bitsize, value, control);  }  U32U64 IREmitter::UConvert(size_t result_bitsize, const U32U64& value) { diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index 4e614d424..fd41b7e89 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h @@ -291,12 +291,12 @@ public:      [[nodiscard]] U32U64 ConvertFToS(size_t bitsize, const F16F32F64& value);      [[nodiscard]] U32U64 ConvertFToU(size_t bitsize, const F16F32F64& value);      [[nodiscard]] U32U64 ConvertFToI(size_t bitsize, bool is_signed, const F16F32F64& value); -    [[nodiscard]] F16F32F64 ConvertSToF(size_t dest_bitsize, size_t src_bitsize, -                                        const Value& value); -    [[nodiscard]] F16F32F64 ConvertUToF(size_t dest_bitsize, size_t src_bitsize, -                                        const Value& value); +    [[nodiscard]] F16F32F64 ConvertSToF(size_t dest_bitsize, size_t src_bitsize, const Value& value, +                                        FpControl control = {}); +    [[nodiscard]] F16F32F64 ConvertUToF(size_t dest_bitsize, size_t src_bitsize, const Value& value, +                                        FpControl control = {});      [[nodiscard]] F16F32F64 ConvertIToF(size_t dest_bitsize, size_t src_bitsize, bool is_signed, -                                        const Value& value); +                                        const Value& value, FpControl control = {});      [[nodiscard]] U32U64 UConvert(size_t result_bitsize, const U32U64& value);      [[nodiscard]] F16F32F64 FPConvert(size_t result_bitsize, const F16F32F64& value, diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp index 3c233597f..d6224d5cc 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp @@ -99,7 +99,12 @@ void I2F(TranslatorVisitor& v, u64 insn, IR::U32U64 src) {      }      const int conversion_src_bitsize{i2f.int_format == IntFormat::U64 ? 64 : 32};      const int dst_bitsize{BitSize(i2f.float_format)}; -    IR::F16F32F64 value{v.ir.ConvertIToF(dst_bitsize, conversion_src_bitsize, is_signed, src)}; +    const IR::FpControl fp_control{ +        .no_contraction = false, +        .rounding = CastFpRounding(i2f.fp_rounding), +        .fmz_mode = IR::FmzMode::DontCare, +    }; +    auto value{v.ir.ConvertIToF(dst_bitsize, conversion_src_bitsize, is_signed, src, fp_control)};      if (i2f.neg != 0) {          if (i2f.abs != 0 || !is_signed) {              // We know the value is positive | 
