diff options
Diffstat (limited to 'src/shader_recompiler/backend')
| -rw-r--r-- | src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp index 2aee5a56c..2e1c7d55f 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp | |||
| @@ -9,11 +9,10 @@ | |||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLASM { | 11 | namespace Shader::Backend::GLASM { |
| 12 | 12 | namespace { | |
| 13 | template <typename InputType> | 13 | template <typename InputType> |
| 14 | static void Compare(EmitContext& ctx, IR::Inst& inst, InputType lhs, InputType rhs, | 14 | void Compare(EmitContext& ctx, IR::Inst& inst, InputType lhs, InputType rhs, std::string_view op, |
| 15 | std::string_view op, std::string_view type, bool ordered, | 15 | std::string_view type, bool ordered, bool inequality = false) { |
| 16 | bool inequality = false) { | ||
| 17 | const Register ret{ctx.reg_alloc.Define(inst)}; | 16 | const Register ret{ctx.reg_alloc.Define(inst)}; |
| 18 | ctx.Add("{}.{} RC.x,{},{};", op, type, lhs, rhs); | 17 | ctx.Add("{}.{} RC.x,{},{};", op, type, lhs, rhs); |
| 19 | if (ordered && inequality) { | 18 | if (ordered && inequality) { |
| @@ -35,6 +34,16 @@ static void Compare(EmitContext& ctx, IR::Inst& inst, InputType lhs, InputType r | |||
| 35 | } | 34 | } |
| 36 | } | 35 | } |
| 37 | 36 | ||
| 37 | template <typename InputType> | ||
| 38 | void Clamp(EmitContext& ctx, Register ret, InputType value, InputType min_value, | ||
| 39 | InputType max_value) { | ||
| 40 | // Call MAX first to properly clamp nan to min_value instead | ||
| 41 | ctx.Add("MAX.F {}.x,{},{};" | ||
| 42 | "MIN.F {}.x,{},{};", | ||
| 43 | ret, min_value, value, ret, ret, max_value); | ||
| 44 | } | ||
| 45 | } // Anonymous namespace | ||
| 46 | |||
| 38 | void EmitFPAbs16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 47 | void EmitFPAbs16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 39 | [[maybe_unused]] Register value) { | 48 | [[maybe_unused]] Register value) { |
| 40 | throw NotImplementedException("GLASM instruction"); | 49 | throw NotImplementedException("GLASM instruction"); |
| @@ -171,18 +180,12 @@ void EmitFPClamp16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register | |||
| 171 | 180 | ||
| 172 | void EmitFPClamp32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value, ScalarF32 min_value, | 181 | void EmitFPClamp32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value, ScalarF32 min_value, |
| 173 | ScalarF32 max_value) { | 182 | ScalarF32 max_value) { |
| 174 | const Register ret{ctx.reg_alloc.Define(inst)}; | 183 | Clamp(ctx, ctx.reg_alloc.Define(inst), value, min_value, max_value); |
| 175 | ctx.Add("MIN.F {}.x,{},{};" | ||
| 176 | "MAX.F {}.x,{},{};", | ||
| 177 | ret, max_value, value, ret, ret, min_value); | ||
| 178 | } | 184 | } |
| 179 | 185 | ||
| 180 | void EmitFPClamp64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value, ScalarF64 min_value, | 186 | void EmitFPClamp64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value, ScalarF64 min_value, |
| 181 | ScalarF64 max_value) { | 187 | ScalarF64 max_value) { |
| 182 | const Register ret{ctx.reg_alloc.LongDefine(inst)}; | 188 | Clamp(ctx, ctx.reg_alloc.LongDefine(inst), value, min_value, max_value); |
| 183 | ctx.Add("MIN.F64 {}.x,{},{};" | ||
| 184 | "MAX.F64 {}.x,{},{};", | ||
| 185 | ret, max_value, value, ret, ret, min_value); | ||
| 186 | } | 189 | } |
| 187 | 190 | ||
| 188 | void EmitFPRoundEven16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) { | 191 | void EmitFPRoundEven16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) { |