summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-05-11 00:20:15 +0200
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:31 +0200
commit70fbede213bfadfc4015b3227e57fca34bea46eb (patch)
tree72a860110d4228ba5a9bc6ca977b0fed55385d77
parentglasm: Implement shuffle and vote instructions on GLASM (diff)
downloadyuzu-70fbede213bfadfc4015b3227e57fca34bea46eb.tar
yuzu-70fbede213bfadfc4015b3227e57fca34bea46eb.tar.gz
yuzu-70fbede213bfadfc4015b3227e57fca34bea46eb.tar.bz2
yuzu-70fbede213bfadfc4015b3227e57fca34bea46eb.tar.lz
yuzu-70fbede213bfadfc4015b3227e57fca34bea46eb.tar.xz
yuzu-70fbede213bfadfc4015b3227e57fca34bea46eb.tar.zst
yuzu-70fbede213bfadfc4015b3227e57fca34bea46eb.zip
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp19
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp8
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp42
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_select.cpp2
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>
void CompositeInsert(EmitContext& ctx, IR::Inst& inst, Register composite, ObjectType object,
u32 index, char type) {
const Register ret{ctx.reg_alloc.Define(inst)};
- if (ret != composite) {
- ctx.Add("MOV.{} {},{};", type, ret, composite);
+ const char swizzle{"xyzw"[index]};
+ if (ret != composite && ret == object) {
+ // The object is aliased with the return value, so we have to use a temporary to insert
+ ctx.Add("MOV.{} RC,{};"
+ "MOV.{} RC.{},{};"
+ "MOV.{} {},RC;",
+ type, composite, type, swizzle, object, type, ret);
+ } else if (ret != composite) {
+ // The input composite is not aliased with the return value so we have to copy it before
+ // hand. But the insert object is not aliased with the return value, so we don't have to
+ // worry about that
+ ctx.Add("MOV.{} {},{};MOV.{},{}.{},{};", type, ret, composite, type, ret, swizzle, object);
+ } else {
+ // The return value is alised so we can just insert the object, it doesn't matter if it's
+ // aliased
+ ctx.Add("MOV.{} {}.{},{};", type, ret, swizzle, object);
}
- ctx.Add("MOV.{} {}.{},{};", type, ret, "xyzw"[index], object);
}
} // Anonymous namespace
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>
void Clamp(EmitContext& ctx, Register ret, InputType value, InputType min_value,
InputType max_value, std::string_view type) {
// Call MAX first to properly clamp nan to min_value instead
- ctx.Add("MAX.{} {}.x,{},{};"
- "MIN.{} {}.x,{}.x,{};",
- type, ret, min_value, value, type, ret, ret, max_value);
+ ctx.Add("MAX.{} RC.x,{},{};"
+ "MIN.{} {}.x,RC.x,{};",
+ type, min_value, value, type, ret, max_value);
}
} // Anonymous namespace
@@ -159,7 +159,7 @@ void EmitFPRecipSqrt64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Regis
void EmitFPSqrt(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
const Register ret{ctx.reg_alloc.Define(inst)};
- ctx.Add("RSQ {}.x,{};RCP {}.x,{}.x;", ret, value, ret, ret);
+ ctx.Add("RSQ RC.x,{};RCP {}.x,RC.x;", value, ret);
}
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
void EmitBitFieldInsert(EmitContext& ctx, IR::Inst& inst, ScalarS32 base, ScalarS32 insert,
ScalarS32 offset, ScalarS32 count) {
- ctx.Add("MOV.U RC.x,{};MOV.U RC.y,{};", count, offset);
- ctx.Add("BFI.S {},RC,{},{};", inst, insert, base);
+ const Register ret{ctx.reg_alloc.Define(inst)};
+ if (count.type != Type::Register && offset.type != Type::Register) {
+ ctx.Add("BFI.S {},{{{},{},0,0}},{},{};", ret, count, offset, insert, base);
+ } else {
+ ctx.Add("MOV.S RC.x,{};MOV.U RC.y,{};"
+ "BFI.S {},RC,{},{};",
+ count, offset, ret, insert, base);
+ }
}
void EmitBitFieldSExtract(EmitContext& ctx, IR::Inst& inst, ScalarS32 base, ScalarS32 offset,
ScalarS32 count) {
- ctx.Add("MOV.U RC.x,{};MOV.U RC.y,{};", count, offset);
- ctx.Add("BFE.S {},RC,{};", inst, base);
+ const Register ret{ctx.reg_alloc.Define(inst)};
+ if (count.type != Type::Register && offset.type != Type::Register) {
+ ctx.Add("BFE.S {},{{{},{},0,0}},{};", ret, count, offset, base);
+ } else {
+ ctx.Add("MOV.S RC.x,{};MOV.U RC.y,{};"
+ "BFE.S {},RC,{};",
+ count, offset, ret, base);
+ }
}
void EmitBitFieldUExtract(EmitContext& ctx, IR::Inst& inst, ScalarU32 base, ScalarU32 offset,
ScalarU32 count) {
- ctx.Add("MOV.U RC.x,{};MOV.U RC.y,{};", count, offset);
- ctx.Add("BFE.U {},RC,{};", inst, base);
+ const Register ret{ctx.reg_alloc.Define(inst)};
+ if (count.type != Type::Register && offset.type != Type::Register) {
+ ctx.Add("BFE.U {},{{{},{},0,0}},{};", ret, count, offset, base);
+ } else {
+ ctx.Add("MOV.U RC.x,{};MOV.U RC.y,{};"
+ "BFE.U {},RC,{};",
+ count, offset, ret, base);
+ }
}
void EmitBitReverse32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value) {
@@ -141,16 +159,16 @@ void EmitUMax32(EmitContext& ctx, IR::Inst& inst, ScalarU32 a, ScalarU32 b) {
void EmitSClamp32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value, ScalarS32 min, ScalarS32 max) {
const Register ret{ctx.reg_alloc.Define(inst)};
- ctx.Add("MIN.S {}.x,{},{};"
- "MAX.S {}.x,{},{};",
- ret, max, value, ret, ret, min);
+ ctx.Add("MIN.S RC.x,{},{};"
+ "MAX.S {}.x,RC.x,{};",
+ max, value, ret, min);
}
void EmitUClamp32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 min, ScalarU32 max) {
const Register ret{ctx.reg_alloc.Define(inst)};
- ctx.Add("MIN.U {}.x,{},{};"
- "MAX.U {}.x,{},{};",
- ret, max, value, ret, ret, min);
+ ctx.Add("MIN.U RC.x,{},{};"
+ "MAX.U {}.x,RC.x,{};",
+ max, value, ret, min);
}
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
cond, ret, true_value);
} else {
ctx.Add("MOV.S.CC RC.x,{};"
- "MOV.U64 {}.x(EQ.x),{};"
+ "MOV.U64 {}.x,{};"
"MOV.U64 {}.x(NE.x),{};",
cond, ret, false_value, ret, true_value);
}