summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp60
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h10
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp7
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
1622 return is_signed ? ConvertFToS(bitsize, value) : ConvertFToU(bitsize, value); 1622 return is_signed ? ConvertFToS(bitsize, value) : ConvertFToU(bitsize, value);
1623} 1623}
1624 1624
1625F16F32F64 IREmitter::ConvertSToF(size_t dest_bitsize, size_t src_bitsize, const Value& value) { 1625F16F32F64 IREmitter::ConvertSToF(size_t dest_bitsize, size_t src_bitsize, const Value& value,
1626 FpControl control) {
1626 switch (dest_bitsize) { 1627 switch (dest_bitsize) {
1627 case 16: 1628 case 16:
1628 switch (src_bitsize) { 1629 switch (src_bitsize) {
1629 case 8: 1630 case 8:
1630 return Inst<F16>(Opcode::ConvertF16S8, value); 1631 return Inst<F16>(Opcode::ConvertF16S8, Flags{control}, value);
1631 case 16: 1632 case 16:
1632 return Inst<F16>(Opcode::ConvertF16S16, value); 1633 return Inst<F16>(Opcode::ConvertF16S16, Flags{control}, value);
1633 case 32: 1634 case 32:
1634 return Inst<F16>(Opcode::ConvertF16S32, value); 1635 return Inst<F16>(Opcode::ConvertF16S32, Flags{control}, value);
1635 case 64: 1636 case 64:
1636 return Inst<F16>(Opcode::ConvertF16S64, value); 1637 return Inst<F16>(Opcode::ConvertF16S64, Flags{control}, value);
1637 } 1638 }
1638 break; 1639 break;
1639 case 32: 1640 case 32:
1640 switch (src_bitsize) { 1641 switch (src_bitsize) {
1641 case 8: 1642 case 8:
1642 return Inst<F32>(Opcode::ConvertF32S8, value); 1643 return Inst<F32>(Opcode::ConvertF32S8, Flags{control}, value);
1643 case 16: 1644 case 16:
1644 return Inst<F32>(Opcode::ConvertF32S16, value); 1645 return Inst<F32>(Opcode::ConvertF32S16, Flags{control}, value);
1645 case 32: 1646 case 32:
1646 return Inst<F32>(Opcode::ConvertF32S32, value); 1647 return Inst<F32>(Opcode::ConvertF32S32, Flags{control}, value);
1647 case 64: 1648 case 64:
1648 return Inst<F32>(Opcode::ConvertF32S64, value); 1649 return Inst<F32>(Opcode::ConvertF32S64, Flags{control}, value);
1649 } 1650 }
1650 break; 1651 break;
1651 case 64: 1652 case 64:
1652 switch (src_bitsize) { 1653 switch (src_bitsize) {
1653 case 8: 1654 case 8:
1654 return Inst<F64>(Opcode::ConvertF64S8, value); 1655 return Inst<F64>(Opcode::ConvertF64S8, Flags{control}, value);
1655 case 16: 1656 case 16:
1656 return Inst<F64>(Opcode::ConvertF64S16, value); 1657 return Inst<F64>(Opcode::ConvertF64S16, Flags{control}, value);
1657 case 32: 1658 case 32:
1658 return Inst<F64>(Opcode::ConvertF64S32, value); 1659 return Inst<F64>(Opcode::ConvertF64S32, Flags{control}, value);
1659 case 64: 1660 case 64:
1660 return Inst<F64>(Opcode::ConvertF64S64, value); 1661 return Inst<F64>(Opcode::ConvertF64S64, Flags{control}, value);
1661 } 1662 }
1662 break; 1663 break;
1663 } 1664 }
1664 throw InvalidArgument("Invalid bit size combination dst={} src={}", dest_bitsize, src_bitsize); 1665 throw InvalidArgument("Invalid bit size combination dst={} src={}", dest_bitsize, src_bitsize);
1665} 1666}
1666 1667
1667F16F32F64 IREmitter::ConvertUToF(size_t dest_bitsize, size_t src_bitsize, const Value& value) { 1668F16F32F64 IREmitter::ConvertUToF(size_t dest_bitsize, size_t src_bitsize, const Value& value,
1669 FpControl control) {
1668 switch (dest_bitsize) { 1670 switch (dest_bitsize) {
1669 case 16: 1671 case 16:
1670 switch (src_bitsize) { 1672 switch (src_bitsize) {
1671 case 8: 1673 case 8:
1672 return Inst<F16>(Opcode::ConvertF16U8, value); 1674 return Inst<F16>(Opcode::ConvertF16U8, Flags{control}, value);
1673 case 16: 1675 case 16:
1674 return Inst<F16>(Opcode::ConvertF16U16, value); 1676 return Inst<F16>(Opcode::ConvertF16U16, Flags{control}, value);
1675 case 32: 1677 case 32:
1676 return Inst<F16>(Opcode::ConvertF16U32, value); 1678 return Inst<F16>(Opcode::ConvertF16U32, Flags{control}, value);
1677 case 64: 1679 case 64:
1678 return Inst<F16>(Opcode::ConvertF16U64, value); 1680 return Inst<F16>(Opcode::ConvertF16U64, Flags{control}, value);
1679 } 1681 }
1680 break; 1682 break;
1681 case 32: 1683 case 32:
1682 switch (src_bitsize) { 1684 switch (src_bitsize) {
1683 case 8: 1685 case 8:
1684 return Inst<F32>(Opcode::ConvertF32U8, value); 1686 return Inst<F32>(Opcode::ConvertF32U8, Flags{control}, value);
1685 case 16: 1687 case 16:
1686 return Inst<F32>(Opcode::ConvertF32U16, value); 1688 return Inst<F32>(Opcode::ConvertF32U16, Flags{control}, value);
1687 case 32: 1689 case 32:
1688 return Inst<F32>(Opcode::ConvertF32U32, value); 1690 return Inst<F32>(Opcode::ConvertF32U32, Flags{control}, value);
1689 case 64: 1691 case 64:
1690 return Inst<F32>(Opcode::ConvertF32U64, value); 1692 return Inst<F32>(Opcode::ConvertF32U64, Flags{control}, value);
1691 } 1693 }
1692 break; 1694 break;
1693 case 64: 1695 case 64:
1694 switch (src_bitsize) { 1696 switch (src_bitsize) {
1695 case 8: 1697 case 8:
1696 return Inst<F64>(Opcode::ConvertF64U8, value); 1698 return Inst<F64>(Opcode::ConvertF64U8, Flags{control}, value);
1697 case 16: 1699 case 16:
1698 return Inst<F64>(Opcode::ConvertF64U16, value); 1700 return Inst<F64>(Opcode::ConvertF64U16, Flags{control}, value);
1699 case 32: 1701 case 32:
1700 return Inst<F64>(Opcode::ConvertF64U32, value); 1702 return Inst<F64>(Opcode::ConvertF64U32, Flags{control}, value);
1701 case 64: 1703 case 64:
1702 return Inst<F64>(Opcode::ConvertF64U64, value); 1704 return Inst<F64>(Opcode::ConvertF64U64, Flags{control}, value);
1703 } 1705 }
1704 break; 1706 break;
1705 } 1707 }
@@ -1707,9 +1709,9 @@ F16F32F64 IREmitter::ConvertUToF(size_t dest_bitsize, size_t src_bitsize, const
1707} 1709}
1708 1710
1709F16F32F64 IREmitter::ConvertIToF(size_t dest_bitsize, size_t src_bitsize, bool is_signed, 1711F16F32F64 IREmitter::ConvertIToF(size_t dest_bitsize, size_t src_bitsize, bool is_signed,
1710 const Value& value) { 1712 const Value& value, FpControl control) {
1711 return is_signed ? ConvertSToF(dest_bitsize, src_bitsize, value) 1713 return is_signed ? ConvertSToF(dest_bitsize, src_bitsize, value, control)
1712 : ConvertUToF(dest_bitsize, src_bitsize, value); 1714 : ConvertUToF(dest_bitsize, src_bitsize, value, control);
1713} 1715}
1714 1716
1715U32U64 IREmitter::UConvert(size_t result_bitsize, const U32U64& value) { 1717U32U64 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:
291 [[nodiscard]] U32U64 ConvertFToS(size_t bitsize, const F16F32F64& value); 291 [[nodiscard]] U32U64 ConvertFToS(size_t bitsize, const F16F32F64& value);
292 [[nodiscard]] U32U64 ConvertFToU(size_t bitsize, const F16F32F64& value); 292 [[nodiscard]] U32U64 ConvertFToU(size_t bitsize, const F16F32F64& value);
293 [[nodiscard]] U32U64 ConvertFToI(size_t bitsize, bool is_signed, const F16F32F64& value); 293 [[nodiscard]] U32U64 ConvertFToI(size_t bitsize, bool is_signed, const F16F32F64& value);
294 [[nodiscard]] F16F32F64 ConvertSToF(size_t dest_bitsize, size_t src_bitsize, 294 [[nodiscard]] F16F32F64 ConvertSToF(size_t dest_bitsize, size_t src_bitsize, const Value& value,
295 const Value& value); 295 FpControl control = {});
296 [[nodiscard]] F16F32F64 ConvertUToF(size_t dest_bitsize, size_t src_bitsize, 296 [[nodiscard]] F16F32F64 ConvertUToF(size_t dest_bitsize, size_t src_bitsize, const Value& value,
297 const Value& value); 297 FpControl control = {});
298 [[nodiscard]] F16F32F64 ConvertIToF(size_t dest_bitsize, size_t src_bitsize, bool is_signed, 298 [[nodiscard]] F16F32F64 ConvertIToF(size_t dest_bitsize, size_t src_bitsize, bool is_signed,
299 const Value& value); 299 const Value& value, FpControl control = {});
300 300
301 [[nodiscard]] U32U64 UConvert(size_t result_bitsize, const U32U64& value); 301 [[nodiscard]] U32U64 UConvert(size_t result_bitsize, const U32U64& value);
302 [[nodiscard]] F16F32F64 FPConvert(size_t result_bitsize, const F16F32F64& value, 302 [[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) {
99 } 99 }
100 const int conversion_src_bitsize{i2f.int_format == IntFormat::U64 ? 64 : 32}; 100 const int conversion_src_bitsize{i2f.int_format == IntFormat::U64 ? 64 : 32};
101 const int dst_bitsize{BitSize(i2f.float_format)}; 101 const int dst_bitsize{BitSize(i2f.float_format)};
102 IR::F16F32F64 value{v.ir.ConvertIToF(dst_bitsize, conversion_src_bitsize, is_signed, src)}; 102 const IR::FpControl fp_control{
103 .no_contraction = false,
104 .rounding = CastFpRounding(i2f.fp_rounding),
105 .fmz_mode = IR::FmzMode::DontCare,
106 };
107 auto value{v.ir.ConvertIToF(dst_bitsize, conversion_src_bitsize, is_signed, src, fp_control)};
103 if (i2f.neg != 0) { 108 if (i2f.neg != 0) {
104 if (i2f.abs != 0 || !is_signed) { 109 if (i2f.abs != 0 || !is_signed) {
105 // We know the value is positive 110 // We know the value is positive