diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2021-05-25 02:22:21 -0300 |
---|---|---|
committer | ameerj <52414509+ameerj@users.noreply.github.com> | 2021-07-22 21:51:33 -0400 |
commit | ca05a13c62ad7693f8be924c168e400e8139b0d2 (patch) | |
tree | 813638ab0c537089f3493f824707417dd429a48f /src/shader_recompiler/backend/glasm/reg_alloc.h | |
parent | 9fbfe7d676790dea160368eda6492e8feb6e2f4a (diff) |
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.h | 16 |
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 41b7c92be3..b97c84146d 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 { struct Id { union { u32 raw; - BitField<0, 29, u32> index; - BitField<29, 1, u32> is_long; - BitField<30, 1, u32> is_spill; - BitField<31, 1, u32> is_condition_code; + BitField<0, 1, u32> is_valid; + BitField<1, 1, u32> is_long; + BitField<2, 1, u32> is_spill; + BitField<3, 1, u32> is_condition_code; + BitField<4, 1, u32> is_null; + BitField<5, 27, u32> index; }; bool operator==(Id rhs) const noexcept { @@ -164,12 +166,18 @@ auto FormatTo(FormatContext& ctx, Id id) { throw NotImplementedException("Spill emission"); } if constexpr (scalar) { + if (id.is_null != 0) { + return fmt::format_to(ctx.out(), "{}", id.is_long != 0 ? "DC.x" : "RC.x"); + } if (id.is_long != 0) { return fmt::format_to(ctx.out(), "D{}.x", id.index.Value()); } else { return fmt::format_to(ctx.out(), "R{}.x", id.index.Value()); } } else { + if (id.is_null != 0) { + return fmt::format_to(ctx.out(), "{}", id.is_long != 0 ? "DC" : "RC"); + } if (id.is_long != 0) { return fmt::format_to(ctx.out(), "D{}", id.index.Value()); } else { |