summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_context.cpp8
-rw-r--r--src/shader_recompiler/backend/glasm/emit_context.h27
-rw-r--r--src/shader_recompiler/backend/glasm/reg_alloc.cpp37
-rw-r--r--src/shader_recompiler/backend/glasm/reg_alloc.h18
4 files changed, 64 insertions, 26 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_context.cpp b/src/shader_recompiler/backend/glasm/emit_context.cpp
index 02c4d8a5d..b4db4ff8f 100644
--- a/src/shader_recompiler/backend/glasm/emit_context.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_context.cpp
@@ -2,6 +2,10 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#include "shader_recompiler/backend/glasm/emit_context.h"
6 6
7#include "shader_recompiler/backend/glasm/emit_context.h" \ No newline at end of file 7namespace Shader::Backend::GLASM {
8
9EmitContext::EmitContext() = default;
10
11} // namespace Shader::Backend::GLASM
diff --git a/src/shader_recompiler/backend/glasm/emit_context.h b/src/shader_recompiler/backend/glasm/emit_context.h
index ae91069c8..cf66619de 100644
--- a/src/shader_recompiler/backend/glasm/emit_context.h
+++ b/src/shader_recompiler/backend/glasm/emit_context.h
@@ -5,17 +5,38 @@
5#pragma once 5#pragma once
6 6
7#include <string> 7#include <string>
8#include <utility>
9
10#include <fmt/format.h>
8 11
9#include "shader_recompiler/backend/glasm/reg_alloc.h" 12#include "shader_recompiler/backend/glasm/reg_alloc.h"
10 13
14namespace Shader::IR {
15class Inst;
16}
17
11namespace Shader::Backend::GLASM { 18namespace Shader::Backend::GLASM {
12 19
13class EmitContext { 20class EmitContext {
14public: 21public:
15 std::string code; 22 explicit EmitContext();
16 RegAlloc reg_alloc;
17 23
18private: 24 template <typename... Args>
25 void Add(const char* fmt, IR::Inst& inst, Args&&... args) {
26 code += fmt::format(fmt, reg_alloc.Define(inst), std::forward<Args>(args)...);
27 // TODO: Remove this
28 code += '\n';
29 }
30
31 template <typename... Args>
32 void Add(const char* fmt, Args&&... args) {
33 code += fmt::format(fmt, std::forward<Args>(args)...);
34 // TODO: Remove this
35 code += '\n';
36 }
37
38 std::string code;
39 RegAlloc reg_alloc{*this};
19}; 40};
20 41
21} // namespace Shader::Backend::GLASM 42} // namespace Shader::Backend::GLASM
diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.cpp b/src/shader_recompiler/backend/glasm/reg_alloc.cpp
index 0460a394b..55e8107e9 100644
--- a/src/shader_recompiler/backend/glasm/reg_alloc.cpp
+++ b/src/shader_recompiler/backend/glasm/reg_alloc.cpp
@@ -3,18 +3,16 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <string> 5#include <string>
6#include <string_view>
7 6
8#include <fmt/format.h> 7#include <fmt/format.h>
9 8
9#include "shader_recompiler/backend/glasm/emit_context.h"
10#include "shader_recompiler/backend/glasm/reg_alloc.h" 10#include "shader_recompiler/backend/glasm/reg_alloc.h"
11#include "shader_recompiler/exception.h" 11#include "shader_recompiler/exception.h"
12#include "shader_recompiler/frontend/ir/value.h" 12#include "shader_recompiler/frontend/ir/value.h"
13 13
14namespace Shader::Backend::GLASM { 14namespace Shader::Backend::GLASM {
15namespace { 15namespace {
16constexpr std::string_view SWIZZLE = "xyzw";
17
18std::string Representation(Id id) { 16std::string Representation(Id id) {
19 if (id.is_condition_code != 0) { 17 if (id.is_condition_code != 0) {
20 throw NotImplementedException("Condition code"); 18 throw NotImplementedException("Condition code");
@@ -22,27 +20,36 @@ std::string Representation(Id id) {
22 if (id.is_spill != 0) { 20 if (id.is_spill != 0) {
23 throw NotImplementedException("Spilling"); 21 throw NotImplementedException("Spilling");
24 } 22 }
25 const u32 num_elements{id.num_elements_minus_one + 1};
26 const u32 index{static_cast<u32>(id.index)}; 23 const u32 index{static_cast<u32>(id.index)};
27 if (num_elements == 4) { 24 return fmt::format("R{}.x", index);
28 return fmt::format("R{}", index); 25}
29 } else { 26
30 return fmt::format("R{}.{}", index, SWIZZLE.substr(id.base_element, num_elements)); 27std::string ImmValue(const IR::Value& value) {
28 switch (value.Type()) {
29 case IR::Type::U1:
30 return value.U1() ? "-1" : "0";
31 case IR::Type::U32:
32 return fmt::format("{}", value.U32());
33 case IR::Type::F32:
34 return fmt::format("{}", value.F32());
35 default:
36 throw NotImplementedException("Immediate type", value.Type());
31 } 37 }
32} 38}
33} // Anonymous namespace 39} // Anonymous namespace
34 40
35std::string RegAlloc::Define(IR::Inst& inst, u32 num_elements, u32 alignment) { 41std::string RegAlloc::Define(IR::Inst& inst) {
36 const Id id{Alloc(num_elements, alignment)}; 42 const Id id{Alloc()};
37 inst.SetDefinition<Id>(id); 43 inst.SetDefinition<Id>(id);
38 return Representation(id); 44 return Representation(id);
39} 45}
40 46
41std::string RegAlloc::Consume(const IR::Value& value) { 47std::string RegAlloc::Consume(const IR::Value& value) {
42 if (!value.IsImmediate()) { 48 if (value.IsImmediate()) {
43 return Consume(*value.Inst()); 49 return ImmValue(value);
50 } else {
51 return Consume(*value.InstRecursive());
44 } 52 }
45 throw NotImplementedException("Immediate loading");
46} 53}
47 54
48std::string RegAlloc::Consume(IR::Inst& inst) { 55std::string RegAlloc::Consume(IR::Inst& inst) {
@@ -54,7 +61,7 @@ std::string RegAlloc::Consume(IR::Inst& inst) {
54 return Representation(inst.Definition<Id>()); 61 return Representation(inst.Definition<Id>());
55} 62}
56 63
57Id RegAlloc::Alloc(u32 num_elements, [[maybe_unused]] u32 alignment) { 64Id RegAlloc::Alloc() {
58 for (size_t reg = 0; reg < NUM_REGS; ++reg) { 65 for (size_t reg = 0; reg < NUM_REGS; ++reg) {
59 if (register_use[reg]) { 66 if (register_use[reg]) {
60 continue; 67 continue;
@@ -62,8 +69,6 @@ Id RegAlloc::Alloc(u32 num_elements, [[maybe_unused]] u32 alignment) {
62 num_used_registers = std::max(num_used_registers, reg + 1); 69 num_used_registers = std::max(num_used_registers, reg + 1);
63 register_use[reg] = true; 70 register_use[reg] = true;
64 return Id{ 71 return Id{
65 .base_element = 0,
66 .num_elements_minus_one = num_elements - 1,
67 .index = static_cast<u32>(reg), 72 .index = static_cast<u32>(reg),
68 .is_spill = 0, 73 .is_spill = 0,
69 .is_condition_code = 0, 74 .is_condition_code = 0,
diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.h b/src/shader_recompiler/backend/glasm/reg_alloc.h
index 46018b0c2..83d728d20 100644
--- a/src/shader_recompiler/backend/glasm/reg_alloc.h
+++ b/src/shader_recompiler/backend/glasm/reg_alloc.h
@@ -15,27 +15,35 @@ class Value;
15 15
16namespace Shader::Backend::GLASM { 16namespace Shader::Backend::GLASM {
17 17
18class EmitContext;
19
18struct Id { 20struct Id {
19 u32 base_element : 2; 21 u32 index : 30;
20 u32 num_elements_minus_one : 2;
21 u32 index : 26;
22 u32 is_spill : 1; 22 u32 is_spill : 1;
23 u32 is_condition_code : 1; 23 u32 is_condition_code : 1;
24}; 24};
25 25
26class RegAlloc { 26class RegAlloc {
27public: 27public:
28 std::string Define(IR::Inst& inst, u32 num_elements = 1, u32 alignment = 1); 28 RegAlloc(EmitContext& ctx_) : ctx{ctx_} {}
29
30 std::string Define(IR::Inst& inst);
29 31
30 std::string Consume(const IR::Value& value); 32 std::string Consume(const IR::Value& value);
31 33
34 [[nodiscard]] size_t NumUsedRegisters() const noexcept {
35 return num_used_registers;
36 }
37
32private: 38private:
33 static constexpr size_t NUM_REGS = 4096; 39 static constexpr size_t NUM_REGS = 4096;
34 static constexpr size_t NUM_ELEMENTS = 4; 40 static constexpr size_t NUM_ELEMENTS = 4;
35 41
42 EmitContext& ctx;
43
36 std::string Consume(IR::Inst& inst); 44 std::string Consume(IR::Inst& inst);
37 45
38 Id Alloc(u32 num_elements, u32 alignment); 46 Id Alloc();
39 47
40 void Free(Id id); 48 void Free(Id id);
41 49