diff options
| author | 2021-05-09 18:03:01 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:30 -0400 | |
| commit | 4502595bc2518eecf934110e9393b11bf0c2f75a (patch) | |
| tree | 3e75e200936bce393152792b9ba90413ea83482c /src/shader_recompiler/backend/glasm/reg_alloc.cpp | |
| parent | glasm: Implement GLASM fp16 packing and move bitwise insns (diff) | |
| download | yuzu-4502595bc2518eecf934110e9393b11bf0c2f75a.tar.gz yuzu-4502595bc2518eecf934110e9393b11bf0c2f75a.tar.xz yuzu-4502595bc2518eecf934110e9393b11bf0c2f75a.zip | |
glasm: Initial GLASM fp64 support
Diffstat (limited to 'src/shader_recompiler/backend/glasm/reg_alloc.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/glasm/reg_alloc.cpp | 66 |
1 files changed, 47 insertions, 19 deletions
diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.cpp b/src/shader_recompiler/backend/glasm/reg_alloc.cpp index 030b48d83..82b627500 100644 --- a/src/shader_recompiler/backend/glasm/reg_alloc.cpp +++ b/src/shader_recompiler/backend/glasm/reg_alloc.cpp | |||
| @@ -14,12 +14,11 @@ | |||
| 14 | namespace Shader::Backend::GLASM { | 14 | namespace Shader::Backend::GLASM { |
| 15 | 15 | ||
| 16 | Register RegAlloc::Define(IR::Inst& inst) { | 16 | Register RegAlloc::Define(IR::Inst& inst) { |
| 17 | const Id id{Alloc()}; | 17 | return Define(inst, false); |
| 18 | inst.SetDefinition<Id>(id); | 18 | } |
| 19 | Register ret; | 19 | |
| 20 | ret.type = Type::Register; | 20 | Register RegAlloc::LongDefine(IR::Inst& inst) { |
| 21 | ret.id = id; | 21 | return Define(inst, true); |
| 22 | return ret; | ||
| 23 | } | 22 | } |
| 24 | 23 | ||
| 25 | Value RegAlloc::Consume(const IR::Value& value) { | 24 | Value RegAlloc::Consume(const IR::Value& value) { |
| @@ -40,6 +39,10 @@ Value RegAlloc::Consume(const IR::Value& value) { | |||
| 40 | ret.type = Type::F32; | 39 | ret.type = Type::F32; |
| 41 | ret.imm_f32 = value.F32(); | 40 | ret.imm_f32 = value.F32(); |
| 42 | break; | 41 | break; |
| 42 | case IR::Type::F64: | ||
| 43 | ret.type = Type::F64; | ||
| 44 | ret.imm_f64 = value.F64(); | ||
| 45 | break; | ||
| 43 | default: | 46 | default: |
| 44 | throw NotImplementedException("Immediate type {}", value.Type()); | 47 | throw NotImplementedException("Immediate type {}", value.Type()); |
| 45 | } | 48 | } |
| @@ -49,7 +52,14 @@ Value RegAlloc::Consume(const IR::Value& value) { | |||
| 49 | Register RegAlloc::AllocReg() { | 52 | Register RegAlloc::AllocReg() { |
| 50 | Register ret; | 53 | Register ret; |
| 51 | ret.type = Type::Register; | 54 | ret.type = Type::Register; |
| 52 | ret.id = Alloc(); | 55 | ret.id = Alloc(false); |
| 56 | return ret; | ||
| 57 | } | ||
| 58 | |||
| 59 | Register RegAlloc::AllocLongReg() { | ||
| 60 | Register ret; | ||
| 61 | ret.type = Type::Register; | ||
| 62 | ret.id = Alloc(true); | ||
| 53 | return ret; | 63 | return ret; |
| 54 | } | 64 | } |
| 55 | 65 | ||
| @@ -57,6 +67,15 @@ void RegAlloc::FreeReg(Register reg) { | |||
| 57 | Free(reg.id); | 67 | Free(reg.id); |
| 58 | } | 68 | } |
| 59 | 69 | ||
| 70 | Register RegAlloc::Define(IR::Inst& inst, bool is_long) { | ||
| 71 | const Id id{Alloc(is_long)}; | ||
| 72 | inst.SetDefinition<Id>(id); | ||
| 73 | Register ret; | ||
| 74 | ret.type = Type::Register; | ||
| 75 | ret.id = id; | ||
| 76 | return ret; | ||
| 77 | } | ||
| 78 | |||
| 60 | Value RegAlloc::Consume(IR::Inst& inst) { | 79 | Value RegAlloc::Consume(IR::Inst& inst) { |
| 61 | const Id id{inst.Definition<Id>()}; | 80 | const Id id{inst.Definition<Id>()}; |
| 62 | inst.DestructiveRemoveUsage(); | 81 | inst.DestructiveRemoveUsage(); |
| @@ -69,18 +88,23 @@ Value RegAlloc::Consume(IR::Inst& inst) { | |||
| 69 | return ret; | 88 | return ret; |
| 70 | } | 89 | } |
| 71 | 90 | ||
| 72 | Id RegAlloc::Alloc() { | 91 | Id RegAlloc::Alloc(bool is_long) { |
| 73 | for (size_t reg = 0; reg < NUM_REGS; ++reg) { | 92 | size_t& num_regs{is_long ? num_used_long_registers : num_used_registers}; |
| 74 | if (register_use[reg]) { | 93 | std::bitset<NUM_REGS>& use{is_long ? long_register_use : register_use}; |
| 75 | continue; | 94 | if (num_used_registers + num_used_long_registers < NUM_REGS) { |
| 95 | for (size_t reg = 0; reg < NUM_REGS; ++reg) { | ||
| 96 | if (use[reg]) { | ||
| 97 | continue; | ||
| 98 | } | ||
| 99 | num_regs = std::max(num_regs, reg + 1); | ||
| 100 | use[reg] = true; | ||
| 101 | Id ret{}; | ||
| 102 | ret.index.Assign(static_cast<u32>(reg)); | ||
| 103 | ret.is_long.Assign(is_long ? 1 : 0); | ||
| 104 | ret.is_spill.Assign(0); | ||
| 105 | ret.is_condition_code.Assign(0); | ||
| 106 | return ret; | ||
| 76 | } | 107 | } |
| 77 | num_used_registers = std::max(num_used_registers, reg + 1); | ||
| 78 | register_use[reg] = true; | ||
| 79 | Id ret{}; | ||
| 80 | ret.index.Assign(static_cast<u32>(reg)); | ||
| 81 | ret.is_spill.Assign(0); | ||
| 82 | ret.is_condition_code.Assign(0); | ||
| 83 | return ret; | ||
| 84 | } | 108 | } |
| 85 | throw NotImplementedException("Register spilling"); | 109 | throw NotImplementedException("Register spilling"); |
| 86 | } | 110 | } |
| @@ -89,7 +113,11 @@ void RegAlloc::Free(Id id) { | |||
| 89 | if (id.is_spill != 0) { | 113 | if (id.is_spill != 0) { |
| 90 | throw NotImplementedException("Free spill"); | 114 | throw NotImplementedException("Free spill"); |
| 91 | } | 115 | } |
| 92 | register_use[id.index] = false; | 116 | if (id.is_long != 0) { |
| 117 | long_register_use[id.index] = false; | ||
| 118 | } else { | ||
| 119 | register_use[id.index] = false; | ||
| 120 | } | ||
| 93 | } | 121 | } |
| 94 | 122 | ||
| 95 | } // namespace Shader::Backend::GLASM | 123 | } // namespace Shader::Backend::GLASM |