diff --git a/rsx_decompiler/rsx_fp_decompiler.cpp b/rsx_decompiler/rsx_fp_decompiler.cpp index c92493a..3324c78 100644 --- a/rsx_decompiler/rsx_fp_decompiler.cpp +++ b/rsx_decompiler/rsx_fp_decompiler.cpp @@ -2,6 +2,7 @@ #include "rsx_fp_ucode.h" #include #include +#include #include "../rsx_program_decompiler/endianness.h" namespace rsx @@ -33,6 +34,14 @@ namespace rsx template using integer_t = typename base::template integer_t; + using type_class_t = typename base::type_class_t; + + template + using expression_t = typename base::template expression_t; + + template + using type_t = typename base::template type_t; + struct context_t { decompiled_shader program; @@ -436,7 +445,8 @@ namespace rsx return arg; } - builder::writer_t set_dst(const float_point_expr<4>& arg, u32 flags = none) + template 1)>> + builder::writer_t set_dst(expression_t arg, u32 flags = none) { builder::writer_t result; @@ -576,9 +586,10 @@ namespace rsx } } - builder::writer_t set_dst(const integer_expr<1>& arg, u32 flags = none) + template + builder::writer_t set_dst(const expression_t& arg, u32 flags = none) { - return set_dst(float_point_t<1>::ctor(arg), flags); + return set_dst(float_point_t::ctor(arg), flags); } builder::writer_t set_dst(const boolean_expr<4>& arg, u32 flags = none) @@ -601,10 +612,23 @@ namespace rsx return set_dst(float_point_expr<4>{ arg_string, std::string("xyzw"), is_single, 4 }, flags); } - template - Type make_not_zero(Type arg) + template + expression_t make_not_zero(const expression_t &arg) { - return base::max(base::abs(arg), float_point_t::ctor(1e-15f)) * base::sign(arg); + std::string expr = "1e-15"; + + switch (std::min(Count, instruction.destination_swizzle().size())) + { + case 1: break; + case 2: expr = float_point_t<2>::ctor(boolean_expr<2>{ expr }).to_string(); break; + case 3: expr = float_point_t<3>::ctor(boolean_expr<3>{ expr }).to_string(); break; + case 4: expr = float_point_t<4>::ctor(boolean_expr<4>{ expr }).to_string(); break; + + default: + throw std::logic_error("bad destination swizzle."); + } + + return base::max(base::abs(arg), expression_t{ expr }) * base::sign(arg); } builder::expression_base_t decode_instruction() diff --git a/rsx_decompiler/rsx_vp_decompiler.cpp b/rsx_decompiler/rsx_vp_decompiler.cpp index c2e6a8c..34982ba 100644 --- a/rsx_decompiler/rsx_vp_decompiler.cpp +++ b/rsx_decompiler/rsx_vp_decompiler.cpp @@ -2,6 +2,7 @@ #include #include "rsx_decompiler_base.h" #include +#include namespace rsx { @@ -32,6 +33,14 @@ namespace rsx template using integer_t = typename base::template integer_t; + using type_class_t = typename base::type_class_t; + + template + using expression_t = typename base::template expression_t; + + template + using type_t = typename base::template type_t; + struct context_t { decompiled_shader program; @@ -348,7 +357,8 @@ namespace rsx never = 0 }; - typename base::writer_t set_dst(float_point_expr<4> arg) + template 1)>> + typename base::writer_t set_dst(expression_t arg) { auto dst_pair = destination_register(); bool has_dst = dst_pair.first; @@ -562,10 +572,23 @@ namespace rsx return expr; } - template - Type make_not_zero(Type arg) + template + expression_t make_not_zero(const expression_t &arg) { - return base::max(base::abs(arg), float_point_t::ctor(1e-15f)) * base::sign(arg); + std::string expr = "1e-15"; + + switch (std::min(Count, destination_swizzle().size())) + { + case 1: break; + case 2: expr = float_point_t<2>::ctor(boolean_expr<2>{ expr }).to_string(); break; + case 3: expr = float_point_t<3>::ctor(boolean_expr<3>{ expr }).to_string(); break; + case 4: expr = float_point_t<4>::ctor(boolean_expr<4>{ expr }).to_string(); break; + + default: + throw std::logic_error("bad destination swizzle."); + } + + return base::max(base::abs(arg), expression_t{ expr }) * base::sign(arg); } typename base::expression_base_t decode_sca_instruction()