summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glasm/reg_alloc.h
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-05-25 02:22:21 -0300
committerGravatar ameerj2021-07-22 21:51:33 -0400
commitca05a13c62ad7693f8be924c168e400e8139b0d2 (patch)
tree813638ab0c537089f3493f824707417dd429a48f /src/shader_recompiler/backend/glasm/reg_alloc.h
parentglasm: Fix usage counting on phi nodes (diff)
downloadyuzu-ca05a13c62ad7693f8be924c168e400e8139b0d2.tar.gz
yuzu-ca05a13c62ad7693f8be924c168e400e8139b0d2.tar.xz
yuzu-ca05a13c62ad7693f8be924c168e400e8139b0d2.zip
glasm: Catch more register leaks
Add support for null registers. These are used when an instruction has no usages. This comes handy when an instruction is only used for its CC value, with the caveat of having to invalidate all pseudo-instructions before defining the instruction itself in the register allocator. This commits changes this. Workaround a bug on Nvidia's condition codes conditional execution using branches.
Diffstat (limited to 'src/shader_recompiler/backend/glasm/reg_alloc.h')
-rw-r--r--src/shader_recompiler/backend/glasm/reg_alloc.h16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.h b/src/shader_recompiler/backend/glasm/reg_alloc.h
index 41b7c92be..b97c84146 100644
--- a/src/shader_recompiler/backend/glasm/reg_alloc.h
+++ b/src/shader_recompiler/backend/glasm/reg_alloc.h
@@ -35,10 +35,12 @@ enum class Type : u32 {
35struct Id { 35struct Id {
36 union { 36 union {
37 u32 raw; 37 u32 raw;
38 BitField<0, 29, u32> index; 38 BitField<0, 1, u32> is_valid;
39 BitField<29, 1, u32> is_long; 39 BitField<1, 1, u32> is_long;
40 BitField<30, 1, u32> is_spill; 40 BitField<2, 1, u32> is_spill;
41 BitField<31, 1, u32> is_condition_code; 41 BitField<3, 1, u32> is_condition_code;
42 BitField<4, 1, u32> is_null;
43 BitField<5, 27, u32> index;
42 }; 44 };
43 45
44 bool operator==(Id rhs) const noexcept { 46 bool operator==(Id rhs) const noexcept {
@@ -164,12 +166,18 @@ auto FormatTo(FormatContext& ctx, Id id) {
164 throw NotImplementedException("Spill emission"); 166 throw NotImplementedException("Spill emission");
165 } 167 }
166 if constexpr (scalar) { 168 if constexpr (scalar) {
169 if (id.is_null != 0) {
170 return fmt::format_to(ctx.out(), "{}", id.is_long != 0 ? "DC.x" : "RC.x");
171 }
167 if (id.is_long != 0) { 172 if (id.is_long != 0) {
168 return fmt::format_to(ctx.out(), "D{}.x", id.index.Value()); 173 return fmt::format_to(ctx.out(), "D{}.x", id.index.Value());
169 } else { 174 } else {
170 return fmt::format_to(ctx.out(), "R{}.x", id.index.Value()); 175 return fmt::format_to(ctx.out(), "R{}.x", id.index.Value());
171 } 176 }
172 } else { 177 } else {
178 if (id.is_null != 0) {
179 return fmt::format_to(ctx.out(), "{}", id.is_long != 0 ? "DC" : "RC");
180 }
173 if (id.is_long != 0) { 181 if (id.is_long != 0) {
174 return fmt::format_to(ctx.out(), "D{}", id.index.Value()); 182 return fmt::format_to(ctx.out(), "D{}", id.index.Value());
175 } else { 183 } else {