diff options
Diffstat (limited to 'src/shader_recompiler/backend/glasm/reg_alloc.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/glasm/reg_alloc.cpp | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.cpp b/src/shader_recompiler/backend/glasm/reg_alloc.cpp index e198dd522..030b48d83 100644 --- a/src/shader_recompiler/backend/glasm/reg_alloc.cpp +++ b/src/shader_recompiler/backend/glasm/reg_alloc.cpp | |||
| @@ -12,53 +12,61 @@ | |||
| 12 | #include "shader_recompiler/frontend/ir/value.h" | 12 | #include "shader_recompiler/frontend/ir/value.h" |
| 13 | 13 | ||
| 14 | namespace Shader::Backend::GLASM { | 14 | namespace Shader::Backend::GLASM { |
| 15 | namespace { | 15 | |
| 16 | std::string Representation(Id id) { | 16 | Register RegAlloc::Define(IR::Inst& inst) { |
| 17 | if (id.is_condition_code != 0) { | 17 | const Id id{Alloc()}; |
| 18 | throw NotImplementedException("Condition code"); | 18 | inst.SetDefinition<Id>(id); |
| 19 | } | 19 | Register ret; |
| 20 | if (id.is_spill != 0) { | 20 | ret.type = Type::Register; |
| 21 | throw NotImplementedException("Spilling"); | 21 | ret.id = id; |
| 22 | } | 22 | return ret; |
| 23 | const u32 index{static_cast<u32>(id.index)}; | ||
| 24 | return fmt::format("R{}.x", index); | ||
| 25 | } | 23 | } |
| 26 | 24 | ||
| 27 | std::string ImmValue(const IR::Value& value) { | 25 | Value RegAlloc::Consume(const IR::Value& value) { |
| 26 | if (!value.IsImmediate()) { | ||
| 27 | return Consume(*value.InstRecursive()); | ||
| 28 | } | ||
| 29 | Value ret; | ||
| 28 | switch (value.Type()) { | 30 | switch (value.Type()) { |
| 29 | case IR::Type::U1: | 31 | case IR::Type::U1: |
| 30 | return value.U1() ? "-1" : "0"; | 32 | ret.type = Type::U32; |
| 33 | ret.imm_u32 = value.U1() ? 0xffffffff : 0; | ||
| 34 | break; | ||
| 31 | case IR::Type::U32: | 35 | case IR::Type::U32: |
| 32 | return fmt::format("{}", value.U32()); | 36 | ret.type = Type::U32; |
| 37 | ret.imm_u32 = value.U32(); | ||
| 38 | break; | ||
| 33 | case IR::Type::F32: | 39 | case IR::Type::F32: |
| 34 | return fmt::format("{}", value.F32()); | 40 | ret.type = Type::F32; |
| 41 | ret.imm_f32 = value.F32(); | ||
| 42 | break; | ||
| 35 | default: | 43 | default: |
| 36 | throw NotImplementedException("Immediate type {}", value.Type()); | 44 | throw NotImplementedException("Immediate type {}", value.Type()); |
| 37 | } | 45 | } |
| 46 | return ret; | ||
| 38 | } | 47 | } |
| 39 | } // Anonymous namespace | ||
| 40 | 48 | ||
| 41 | std::string RegAlloc::Define(IR::Inst& inst) { | 49 | Register RegAlloc::AllocReg() { |
| 42 | const Id id{Alloc()}; | 50 | Register ret; |
| 43 | inst.SetDefinition<Id>(id); | 51 | ret.type = Type::Register; |
| 44 | return Representation(id); | 52 | ret.id = Alloc(); |
| 53 | return ret; | ||
| 45 | } | 54 | } |
| 46 | 55 | ||
| 47 | std::string RegAlloc::Consume(const IR::Value& value) { | 56 | void RegAlloc::FreeReg(Register reg) { |
| 48 | if (value.IsImmediate()) { | 57 | Free(reg.id); |
| 49 | return ImmValue(value); | ||
| 50 | } else { | ||
| 51 | return Consume(*value.InstRecursive()); | ||
| 52 | } | ||
| 53 | } | 58 | } |
| 54 | 59 | ||
| 55 | std::string RegAlloc::Consume(IR::Inst& inst) { | 60 | Value RegAlloc::Consume(IR::Inst& inst) { |
| 56 | const Id id{inst.Definition<Id>()}; | 61 | const Id id{inst.Definition<Id>()}; |
| 57 | inst.DestructiveRemoveUsage(); | 62 | inst.DestructiveRemoveUsage(); |
| 58 | if (!inst.HasUses()) { | 63 | if (!inst.HasUses()) { |
| 59 | Free(id); | 64 | Free(id); |
| 60 | } | 65 | } |
| 61 | return Representation(inst.Definition<Id>()); | 66 | Value ret; |
| 67 | ret.type = Type::Register; | ||
| 68 | ret.id = id; | ||
| 69 | return ret; | ||
| 62 | } | 70 | } |
| 63 | 71 | ||
| 64 | Id RegAlloc::Alloc() { | 72 | Id RegAlloc::Alloc() { |