summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glasm/emit_glasm.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-05-10 03:47:31 -0300
committerGravatar ameerj2021-07-22 21:51:31 -0400
commitdeda89372f78dc78b37e941bf86e3026708e3ea2 (patch)
tree070a356b32b84b57b9ef409869e2476b57c00bfb /src/shader_recompiler/backend/glasm/emit_glasm.cpp
parentglasm: Implement SelectU64 on GLASM (diff)
downloadyuzu-deda89372f78dc78b37e941bf86e3026708e3ea2.tar.gz
yuzu-deda89372f78dc78b37e941bf86e3026708e3ea2.tar.xz
yuzu-deda89372f78dc78b37e941bf86e3026708e3ea2.zip
glasm: Fix register allocation when moving immediate on GLASM
Diffstat (limited to 'src/shader_recompiler/backend/glasm/emit_glasm.cpp')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm.cpp50
1 files changed, 39 insertions, 11 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
index 8e5d575a9..ad27b8b06 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
@@ -39,14 +39,16 @@ struct Identity {
39}; 39};
40 40
41template <bool scalar> 41template <bool scalar>
42struct RegWrapper { 42class RegWrapper {
43 RegWrapper(EmitContext& ctx, Value value) 43public:
44 : reg_alloc{ctx.reg_alloc}, allocated{value.type != Type::Register} { 44 RegWrapper(EmitContext& ctx, const IR::Value& ir_value) : reg_alloc{ctx.reg_alloc} {
45 if (allocated) { 45 const Value value{reg_alloc.Peek(ir_value)};
46 if (value.type == Type::Register) {
47 inst = ir_value.InstRecursive();
48 reg = Register{value};
49 } else {
46 const bool is_long{value.type == Type::F64 || value.type == Type::U64}; 50 const bool is_long{value.type == Type::F64 || value.type == Type::U64};
47 reg = is_long ? reg_alloc.AllocLongReg() : reg_alloc.AllocReg(); 51 reg = is_long ? reg_alloc.AllocLongReg() : reg_alloc.AllocReg();
48 } else {
49 reg = Register{value};
50 } 52 }
51 switch (value.type) { 53 switch (value.type) {
52 case Type::Register: 54 case Type::Register:
@@ -68,8 +70,11 @@ struct RegWrapper {
68 break; 70 break;
69 } 71 }
70 } 72 }
73
71 ~RegWrapper() { 74 ~RegWrapper() {
72 if (allocated) { 75 if (inst) {
76 reg_alloc.Unref(*inst);
77 } else {
73 reg_alloc.FreeReg(reg); 78 reg_alloc.FreeReg(reg);
74 } 79 }
75 } 80 }
@@ -78,19 +83,42 @@ struct RegWrapper {
78 return std::conditional_t<scalar, ScalarRegister, Register>{Value{reg}}; 83 return std::conditional_t<scalar, ScalarRegister, Register>{Value{reg}};
79 } 84 }
80 85
86private:
81 RegAlloc& reg_alloc; 87 RegAlloc& reg_alloc;
88 IR::Inst* inst{};
82 Register reg{}; 89 Register reg{};
83 bool allocated{}; 90};
91
92template <typename ArgType>
93class ValueWrapper {
94public:
95 ValueWrapper(EmitContext& ctx, const IR::Value& ir_value_)
96 : reg_alloc{ctx.reg_alloc}, ir_value{ir_value_}, value{reg_alloc.Peek(ir_value)} {}
97
98 ~ValueWrapper() {
99 if (!ir_value.IsImmediate()) {
100 reg_alloc.Unref(*ir_value.InstRecursive());
101 }
102 }
103
104 ArgType Extract() {
105 return value;
106 }
107
108private:
109 RegAlloc& reg_alloc;
110 const IR::Value& ir_value;
111 ArgType value;
84}; 112};
85 113
86template <typename ArgType> 114template <typename ArgType>
87auto Arg(EmitContext& ctx, const IR::Value& arg) { 115auto Arg(EmitContext& ctx, const IR::Value& arg) {
88 if constexpr (std::is_same_v<ArgType, Register>) { 116 if constexpr (std::is_same_v<ArgType, Register>) {
89 return RegWrapper<false>{ctx, ctx.reg_alloc.Consume(arg)}; 117 return RegWrapper<false>{ctx, arg};
90 } else if constexpr (std::is_same_v<ArgType, ScalarRegister>) { 118 } else if constexpr (std::is_same_v<ArgType, ScalarRegister>) {
91 return RegWrapper<true>{ctx, ctx.reg_alloc.Consume(arg)}; 119 return RegWrapper<true>{ctx, arg};
92 } else if constexpr (std::is_base_of_v<Value, ArgType>) { 120 } else if constexpr (std::is_base_of_v<Value, ArgType>) {
93 return Identity{ArgType{ctx.reg_alloc.Consume(arg)}}; 121 return ValueWrapper<ArgType>{ctx, arg};
94 } else if constexpr (std::is_same_v<ArgType, const IR::Value&>) { 122 } else if constexpr (std::is_same_v<ArgType, const IR::Value&>) {
95 return Identity{arg}; 123 return Identity{arg};
96 } else if constexpr (std::is_same_v<ArgType, u32>) { 124 } else if constexpr (std::is_same_v<ArgType, u32>) {