summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glasm/reg_alloc.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-05-09 18:03:01 -0300
committerGravatar ameerj2021-07-22 21:51:30 -0400
commit4502595bc2518eecf934110e9393b11bf0c2f75a (patch)
tree3e75e200936bce393152792b9ba90413ea83482c /src/shader_recompiler/backend/glasm/reg_alloc.cpp
parentglasm: Implement GLASM fp16 packing and move bitwise insns (diff)
downloadyuzu-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.cpp66
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 @@
14namespace Shader::Backend::GLASM { 14namespace Shader::Backend::GLASM {
15 15
16Register RegAlloc::Define(IR::Inst& inst) { 16Register 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; 20Register RegAlloc::LongDefine(IR::Inst& inst) {
21 ret.id = id; 21 return Define(inst, true);
22 return ret;
23} 22}
24 23
25Value RegAlloc::Consume(const IR::Value& value) { 24Value 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) {
49Register RegAlloc::AllocReg() { 52Register 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
59Register 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
70Register 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
60Value RegAlloc::Consume(IR::Inst& inst) { 79Value 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
72Id RegAlloc::Alloc() { 91Id 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