diff options
Diffstat (limited to 'src/shader_recompiler')
4 files changed, 51 insertions, 20 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp index 94dc5019d..22321f386 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp | |||
| @@ -41,10 +41,23 @@ template <typename ObjectType> | |||
| 41 | void CompositeInsert(EmitContext& ctx, IR::Inst& inst, Register composite, ObjectType object, | 41 | void CompositeInsert(EmitContext& ctx, IR::Inst& inst, Register composite, ObjectType object, |
| 42 | u32 index, char type) { | 42 | u32 index, char type) { |
| 43 | const Register ret{ctx.reg_alloc.Define(inst)}; | 43 | const Register ret{ctx.reg_alloc.Define(inst)}; |
| 44 | if (ret != composite) { | 44 | const char swizzle{"xyzw"[index]}; |
| 45 | ctx.Add("MOV.{} {},{};", type, ret, composite); | 45 | if (ret != composite && ret == object) { |
| 46 | // The object is aliased with the return value, so we have to use a temporary to insert | ||
| 47 | ctx.Add("MOV.{} RC,{};" | ||
| 48 | "MOV.{} RC.{},{};" | ||
| 49 | "MOV.{} {},RC;", | ||
| 50 | type, composite, type, swizzle, object, type, ret); | ||
| 51 | } else if (ret != composite) { | ||
| 52 | // The input composite is not aliased with the return value so we have to copy it before | ||
| 53 | // hand. But the insert object is not aliased with the return value, so we don't have to | ||
| 54 | // worry about that | ||
| 55 | ctx.Add("MOV.{} {},{};MOV.{},{}.{},{};", type, ret, composite, type, ret, swizzle, object); | ||
| 56 | } else { | ||
| 57 | // The return value is alised so we can just insert the object, it doesn't matter if it's | ||
| 58 | // aliased | ||
| 59 | ctx.Add("MOV.{} {}.{},{};", type, ret, swizzle, object); | ||
| 46 | } | 60 | } |
| 47 | ctx.Add("MOV.{} {}.{},{};", type, ret, "xyzw"[index], object); | ||
| 48 | } | 61 | } |
| 49 | } // Anonymous namespace | 62 | } // Anonymous namespace |
| 50 | 63 | ||
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 15db6618f..d2c324ad6 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp | |||
| @@ -38,9 +38,9 @@ template <typename InputType> | |||
| 38 | void Clamp(EmitContext& ctx, Register ret, InputType value, InputType min_value, | 38 | void Clamp(EmitContext& ctx, Register ret, InputType value, InputType min_value, |
| 39 | InputType max_value, std::string_view type) { | 39 | InputType max_value, std::string_view type) { |
| 40 | // Call MAX first to properly clamp nan to min_value instead | 40 | // Call MAX first to properly clamp nan to min_value instead |
| 41 | ctx.Add("MAX.{} {}.x,{},{};" | 41 | ctx.Add("MAX.{} RC.x,{},{};" |
| 42 | "MIN.{} {}.x,{}.x,{};", | 42 | "MIN.{} {}.x,RC.x,{};", |
| 43 | type, ret, min_value, value, type, ret, ret, max_value); | 43 | type, min_value, value, type, ret, max_value); |
| 44 | } | 44 | } |
| 45 | } // Anonymous namespace | 45 | } // Anonymous namespace |
| 46 | 46 | ||
| @@ -159,7 +159,7 @@ void EmitFPRecipSqrt64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Regis | |||
| 159 | 159 | ||
| 160 | void EmitFPSqrt(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) { | 160 | void EmitFPSqrt(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) { |
| 161 | const Register ret{ctx.reg_alloc.Define(inst)}; | 161 | const Register ret{ctx.reg_alloc.Define(inst)}; |
| 162 | ctx.Add("RSQ {}.x,{};RCP {}.x,{}.x;", ret, value, ret, ret); | 162 | ctx.Add("RSQ RC.x,{};RCP {}.x,RC.x;", value, ret); |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | void EmitFPSaturate16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) { | 165 | void EmitFPSaturate16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) { |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp index 2be91ccfd..15fd23356 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp | |||
| @@ -87,20 +87,38 @@ void EmitBitwiseXor32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b | |||
| 87 | 87 | ||
| 88 | void EmitBitFieldInsert(EmitContext& ctx, IR::Inst& inst, ScalarS32 base, ScalarS32 insert, | 88 | void EmitBitFieldInsert(EmitContext& ctx, IR::Inst& inst, ScalarS32 base, ScalarS32 insert, |
| 89 | ScalarS32 offset, ScalarS32 count) { | 89 | ScalarS32 offset, ScalarS32 count) { |
| 90 | ctx.Add("MOV.U RC.x,{};MOV.U RC.y,{};", count, offset); | 90 | const Register ret{ctx.reg_alloc.Define(inst)}; |
| 91 | ctx.Add("BFI.S {},RC,{},{};", inst, insert, base); | 91 | if (count.type != Type::Register && offset.type != Type::Register) { |
| 92 | ctx.Add("BFI.S {},{{{},{},0,0}},{},{};", ret, count, offset, insert, base); | ||
| 93 | } else { | ||
| 94 | ctx.Add("MOV.S RC.x,{};MOV.U RC.y,{};" | ||
| 95 | "BFI.S {},RC,{},{};", | ||
| 96 | count, offset, ret, insert, base); | ||
| 97 | } | ||
| 92 | } | 98 | } |
| 93 | 99 | ||
| 94 | void EmitBitFieldSExtract(EmitContext& ctx, IR::Inst& inst, ScalarS32 base, ScalarS32 offset, | 100 | void EmitBitFieldSExtract(EmitContext& ctx, IR::Inst& inst, ScalarS32 base, ScalarS32 offset, |
| 95 | ScalarS32 count) { | 101 | ScalarS32 count) { |
| 96 | ctx.Add("MOV.U RC.x,{};MOV.U RC.y,{};", count, offset); | 102 | const Register ret{ctx.reg_alloc.Define(inst)}; |
| 97 | ctx.Add("BFE.S {},RC,{};", inst, base); | 103 | if (count.type != Type::Register && offset.type != Type::Register) { |
| 104 | ctx.Add("BFE.S {},{{{},{},0,0}},{};", ret, count, offset, base); | ||
| 105 | } else { | ||
| 106 | ctx.Add("MOV.S RC.x,{};MOV.U RC.y,{};" | ||
| 107 | "BFE.S {},RC,{};", | ||
| 108 | count, offset, ret, base); | ||
| 109 | } | ||
| 98 | } | 110 | } |
| 99 | 111 | ||
| 100 | void EmitBitFieldUExtract(EmitContext& ctx, IR::Inst& inst, ScalarU32 base, ScalarU32 offset, | 112 | void EmitBitFieldUExtract(EmitContext& ctx, IR::Inst& inst, ScalarU32 base, ScalarU32 offset, |
| 101 | ScalarU32 count) { | 113 | ScalarU32 count) { |
| 102 | ctx.Add("MOV.U RC.x,{};MOV.U RC.y,{};", count, offset); | 114 | const Register ret{ctx.reg_alloc.Define(inst)}; |
| 103 | ctx.Add("BFE.U {},RC,{};", inst, base); | 115 | if (count.type != Type::Register && offset.type != Type::Register) { |
| 116 | ctx.Add("BFE.U {},{{{},{},0,0}},{};", ret, count, offset, base); | ||
| 117 | } else { | ||
| 118 | ctx.Add("MOV.U RC.x,{};MOV.U RC.y,{};" | ||
| 119 | "BFE.U {},RC,{};", | ||
| 120 | count, offset, ret, base); | ||
| 121 | } | ||
| 104 | } | 122 | } |
| 105 | 123 | ||
| 106 | void EmitBitReverse32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value) { | 124 | void EmitBitReverse32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value) { |
| @@ -141,16 +159,16 @@ void EmitUMax32(EmitContext& ctx, IR::Inst& inst, ScalarU32 a, ScalarU32 b) { | |||
| 141 | 159 | ||
| 142 | void EmitSClamp32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value, ScalarS32 min, ScalarS32 max) { | 160 | void EmitSClamp32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value, ScalarS32 min, ScalarS32 max) { |
| 143 | const Register ret{ctx.reg_alloc.Define(inst)}; | 161 | const Register ret{ctx.reg_alloc.Define(inst)}; |
| 144 | ctx.Add("MIN.S {}.x,{},{};" | 162 | ctx.Add("MIN.S RC.x,{},{};" |
| 145 | "MAX.S {}.x,{},{};", | 163 | "MAX.S {}.x,RC.x,{};", |
| 146 | ret, max, value, ret, ret, min); | 164 | max, value, ret, min); |
| 147 | } | 165 | } |
| 148 | 166 | ||
| 149 | void EmitUClamp32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 min, ScalarU32 max) { | 167 | void EmitUClamp32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 min, ScalarU32 max) { |
| 150 | const Register ret{ctx.reg_alloc.Define(inst)}; | 168 | const Register ret{ctx.reg_alloc.Define(inst)}; |
| 151 | ctx.Add("MIN.U {}.x,{},{};" | 169 | ctx.Add("MIN.U RC.x,{},{};" |
| 152 | "MAX.U {}.x,{},{};", | 170 | "MAX.U {}.x,RC.x,{};", |
| 153 | ret, max, value, ret, ret, min); | 171 | max, value, ret, min); |
| 154 | } | 172 | } |
| 155 | 173 | ||
| 156 | void EmitSLessThan(EmitContext& ctx, IR::Inst& inst, ScalarS32 lhs, ScalarS32 rhs) { | 174 | void EmitSLessThan(EmitContext& ctx, IR::Inst& inst, ScalarS32 lhs, ScalarS32 rhs) { |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_select.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_select.cpp index cfde86047..b9e5cbbbe 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_select.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_select.cpp | |||
| @@ -43,7 +43,7 @@ void EmitSelectU64(EmitContext& ctx, IR::Inst& inst, ScalarS32 cond, Register tr | |||
| 43 | cond, ret, true_value); | 43 | cond, ret, true_value); |
| 44 | } else { | 44 | } else { |
| 45 | ctx.Add("MOV.S.CC RC.x,{};" | 45 | ctx.Add("MOV.S.CC RC.x,{};" |
| 46 | "MOV.U64 {}.x(EQ.x),{};" | 46 | "MOV.U64 {}.x,{};" |
| 47 | "MOV.U64 {}.x(NE.x),{};", | 47 | "MOV.U64 {}.x(NE.x),{};", |
| 48 | cond, ret, false_value, ret, true_value); | 48 | cond, ret, false_value, ret, true_value); |
| 49 | } | 49 | } |