summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glsl/reg_alloc.cpp
diff options
context:
space:
mode:
authorGravatar ameerj2021-05-19 21:58:32 -0400
committerGravatar ameerj2021-07-22 21:51:35 -0400
commiteaff1030de07f3739794207403ea833ee91c0034 (patch)
treec2e6650ba13f55854b5cba9a79d9afc01528eb96 /src/shader_recompiler/backend/glsl/reg_alloc.cpp
parentspirv: Reduce log severity of mismatching denorm rules (diff)
downloadyuzu-eaff1030de07f3739794207403ea833ee91c0034.tar.gz
yuzu-eaff1030de07f3739794207403ea833ee91c0034.tar.xz
yuzu-eaff1030de07f3739794207403ea833ee91c0034.zip
glsl: Initial backend
Diffstat (limited to 'src/shader_recompiler/backend/glsl/reg_alloc.cpp')
-rw-r--r--src/shader_recompiler/backend/glsl/reg_alloc.cpp96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/shader_recompiler/backend/glsl/reg_alloc.cpp b/src/shader_recompiler/backend/glsl/reg_alloc.cpp
new file mode 100644
index 000000000..591a87988
--- /dev/null
+++ b/src/shader_recompiler/backend/glsl/reg_alloc.cpp
@@ -0,0 +1,96 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <string>
6#include <string_view>
7
8#include <fmt/format.h>
9
10#include "shader_recompiler/backend/glsl/reg_alloc.h"
11#include "shader_recompiler/exception.h"
12#include "shader_recompiler/frontend/ir/value.h"
13
14namespace Shader::Backend::GLSL {
15namespace {
16constexpr std::string_view SWIZZLE = "xyzw";
17
18std::string Representation(Id id) {
19 if (id.is_condition_code != 0) {
20 throw NotImplementedException("Condition code");
21 }
22 if (id.is_spill != 0) {
23 throw NotImplementedException("Spilling");
24 }
25 const u32 num_elements{id.num_elements_minus_one + 1};
26 const u32 index{static_cast<u32>(id.index)};
27 if (num_elements == 4) {
28 return fmt::format("R{}", index);
29 } else {
30 return fmt::format("R{}.{}", index, SWIZZLE.substr(id.base_element, num_elements));
31 }
32}
33
34std::string MakeImm(const IR::Value& value) {
35 switch (value.Type()) {
36 case IR::Type::U1:
37 return fmt::format("{}", value.U1() ? "true" : "false");
38 case IR::Type::U32:
39 return fmt::format("{}", value.U32());
40 case IR::Type::F32:
41 return fmt::format("{}", value.F32());
42 case IR::Type::U64:
43 return fmt::format("{}", value.U64());
44 case IR::Type::F64:
45 return fmt::format("{}", value.F64());
46 default:
47 throw NotImplementedException("Immediate type {}", value.Type());
48 }
49}
50} // Anonymous namespace
51
52std::string RegAlloc::Define(IR::Inst& inst, u32 num_elements, u32 alignment) {
53 const Id id{Alloc(num_elements, alignment)};
54 inst.SetDefinition<Id>(id);
55 return Representation(id);
56}
57
58std::string RegAlloc::Consume(const IR::Value& value) {
59 return value.IsImmediate() ? MakeImm(value) : Consume(*value.Inst());
60}
61
62std::string RegAlloc::Consume(IR::Inst& inst) {
63 const Id id{inst.Definition<Id>()};
64 inst.DestructiveRemoveUsage();
65 if (!inst.HasUses()) {
66 Free(id);
67 }
68 return Representation(inst.Definition<Id>());
69}
70
71Id RegAlloc::Alloc(u32 num_elements, [[maybe_unused]] u32 alignment) {
72 for (size_t reg = 0; reg < NUM_REGS; ++reg) {
73 if (register_use[reg]) {
74 continue;
75 }
76 num_used_registers = std::max(num_used_registers, reg + 1);
77 register_use[reg] = true;
78 return Id{
79 .base_element = 0,
80 .num_elements_minus_one = num_elements - 1,
81 .index = static_cast<u32>(reg),
82 .is_spill = 0,
83 .is_condition_code = 0,
84 };
85 }
86 throw NotImplementedException("Register spilling");
87}
88
89void RegAlloc::Free(Id id) {
90 if (id.is_spill != 0) {
91 throw NotImplementedException("Free spill");
92 }
93 register_use[id.index] = false;
94}
95
96} // namespace Shader::Backend::GLSL