diff options
Diffstat (limited to 'src/shader_recompiler/backend/glsl/reg_alloc.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/glsl/reg_alloc.cpp | 191 |
1 files changed, 0 insertions, 191 deletions
diff --git a/src/shader_recompiler/backend/glsl/reg_alloc.cpp b/src/shader_recompiler/backend/glsl/reg_alloc.cpp deleted file mode 100644 index b1de022d4..000000000 --- a/src/shader_recompiler/backend/glsl/reg_alloc.cpp +++ /dev/null | |||
| @@ -1,191 +0,0 @@ | |||
| 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 | |||
| 14 | namespace Shader::Backend::GLSL { | ||
| 15 | namespace { | ||
| 16 | std::string Representation(Id id) { | ||
| 17 | if (id.is_condition_code != 0) { | ||
| 18 | throw NotImplementedException("Condition code"); | ||
| 19 | } | ||
| 20 | if (id.is_spill != 0) { | ||
| 21 | throw NotImplementedException("Spilling"); | ||
| 22 | } | ||
| 23 | const u32 index{static_cast<u32>(id.index)}; | ||
| 24 | return fmt::format("R{}", index); | ||
| 25 | } | ||
| 26 | |||
| 27 | std::string FormatFloat(std::string_view value, IR::Type type) { | ||
| 28 | // TODO: Confirm FP64 nan/inf | ||
| 29 | if (type == IR::Type::F32) { | ||
| 30 | if (value == "nan") { | ||
| 31 | return "uintBitsToFloat(0x7fc00000)"; | ||
| 32 | } | ||
| 33 | if (value == "inf") { | ||
| 34 | return "uintBitsToFloat(0x7f800000)"; | ||
| 35 | } | ||
| 36 | if (value == "-inf") { | ||
| 37 | return "uintBitsToFloat(0xff800000)"; | ||
| 38 | } | ||
| 39 | } | ||
| 40 | if (value.find_first_of('e') != std::string_view::npos) { | ||
| 41 | // scientific notation | ||
| 42 | const auto cast{type == IR::Type::F32 ? "float" : "double"}; | ||
| 43 | return fmt::format("{}({})", cast, value); | ||
| 44 | } | ||
| 45 | const bool needs_dot{value.find_first_of('.') == std::string_view::npos}; | ||
| 46 | const bool needs_suffix{!value.ends_with('f')}; | ||
| 47 | const auto suffix{type == IR::Type::F32 ? "f" : "lf"}; | ||
| 48 | return fmt::format("{}{}{}", value, needs_dot ? "." : "", needs_suffix ? suffix : ""); | ||
| 49 | } | ||
| 50 | |||
| 51 | std::string MakeImm(const IR::Value& value) { | ||
| 52 | switch (value.Type()) { | ||
| 53 | case IR::Type::U1: | ||
| 54 | return fmt::format("{}", value.U1() ? "true" : "false"); | ||
| 55 | case IR::Type::U32: | ||
| 56 | return fmt::format("{}u", value.U32()); | ||
| 57 | case IR::Type::F32: | ||
| 58 | return FormatFloat(fmt::format("{}", value.F32()), IR::Type::F32); | ||
| 59 | case IR::Type::U64: | ||
| 60 | return fmt::format("{}ul", value.U64()); | ||
| 61 | case IR::Type::F64: | ||
| 62 | return FormatFloat(fmt::format("{}", value.F64()), IR::Type::F64); | ||
| 63 | case IR::Type::Void: | ||
| 64 | return ""; | ||
| 65 | default: | ||
| 66 | throw NotImplementedException("Immediate type {}", value.Type()); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | } // Anonymous namespace | ||
| 70 | |||
| 71 | std::string RegAlloc::Define(IR::Inst& inst) { | ||
| 72 | const Id id{Alloc()}; | ||
| 73 | inst.SetDefinition<Id>(id); | ||
| 74 | return Representation(id); | ||
| 75 | } | ||
| 76 | |||
| 77 | std::string RegAlloc::Define(IR::Inst& inst, Type type) { | ||
| 78 | const Id id{Alloc()}; | ||
| 79 | std::string type_str = ""; | ||
| 80 | if (!register_defined[id.index]) { | ||
| 81 | register_defined[id.index] = true; | ||
| 82 | // type_str = GetGlslType(type); | ||
| 83 | reg_types.push_back(GetGlslType(type)); | ||
| 84 | ++num_used_registers; | ||
| 85 | } | ||
| 86 | inst.SetDefinition<Id>(id); | ||
| 87 | return type_str + Representation(id); | ||
| 88 | } | ||
| 89 | |||
| 90 | std::string RegAlloc::Define(IR::Inst& inst, IR::Type type) { | ||
| 91 | return Define(inst, RegType(type)); | ||
| 92 | } | ||
| 93 | |||
| 94 | std::string RegAlloc::Consume(const IR::Value& value) { | ||
| 95 | return value.IsImmediate() ? MakeImm(value) : Consume(*value.InstRecursive()); | ||
| 96 | } | ||
| 97 | |||
| 98 | std::string RegAlloc::Consume(IR::Inst& inst) { | ||
| 99 | inst.DestructiveRemoveUsage(); | ||
| 100 | // TODO: reuse variables of same type if possible | ||
| 101 | // if (!inst.HasUses()) { | ||
| 102 | // Free(id); | ||
| 103 | // } | ||
| 104 | return Representation(inst.Definition<Id>()); | ||
| 105 | } | ||
| 106 | |||
| 107 | Type RegAlloc::RegType(IR::Type type) { | ||
| 108 | switch (type) { | ||
| 109 | case IR::Type::U1: | ||
| 110 | return Type::U1; | ||
| 111 | case IR::Type::U32: | ||
| 112 | return Type::U32; | ||
| 113 | case IR::Type::F32: | ||
| 114 | return Type::F32; | ||
| 115 | case IR::Type::U64: | ||
| 116 | return Type::U64; | ||
| 117 | case IR::Type::F64: | ||
| 118 | return Type::F64; | ||
| 119 | default: | ||
| 120 | throw NotImplementedException("IR type {}", type); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | std::string RegAlloc::GetGlslType(Type type) { | ||
| 125 | switch (type) { | ||
| 126 | case Type::U1: | ||
| 127 | return "bool "; | ||
| 128 | case Type::F16x2: | ||
| 129 | return "f16vec2 "; | ||
| 130 | case Type::U32: | ||
| 131 | return "uint "; | ||
| 132 | case Type::S32: | ||
| 133 | return "int "; | ||
| 134 | case Type::F32: | ||
| 135 | return "float "; | ||
| 136 | case Type::S64: | ||
| 137 | return "int64_t "; | ||
| 138 | case Type::U64: | ||
| 139 | return "uint64_t "; | ||
| 140 | case Type::F64: | ||
| 141 | return "double "; | ||
| 142 | case Type::U32x2: | ||
| 143 | return "uvec2 "; | ||
| 144 | case Type::F32x2: | ||
| 145 | return "vec2 "; | ||
| 146 | case Type::U32x3: | ||
| 147 | return "uvec3 "; | ||
| 148 | case Type::F32x3: | ||
| 149 | return "vec3 "; | ||
| 150 | case Type::U32x4: | ||
| 151 | return "uvec4 "; | ||
| 152 | case Type::F32x4: | ||
| 153 | return "vec4 "; | ||
| 154 | case Type::Void: | ||
| 155 | return ""; | ||
| 156 | default: | ||
| 157 | throw NotImplementedException("Type {}", type); | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | std::string RegAlloc::GetGlslType(IR::Type type) { | ||
| 162 | return GetGlslType(RegType(type)); | ||
| 163 | } | ||
| 164 | |||
| 165 | Id RegAlloc::Alloc() { | ||
| 166 | if (num_used_registers < NUM_REGS) { | ||
| 167 | for (size_t reg = 0; reg < NUM_REGS; ++reg) { | ||
| 168 | if (register_use[reg]) { | ||
| 169 | continue; | ||
| 170 | } | ||
| 171 | register_use[reg] = true; | ||
| 172 | Id ret{}; | ||
| 173 | ret.is_valid.Assign(1); | ||
| 174 | ret.is_long.Assign(0); | ||
| 175 | ret.is_spill.Assign(0); | ||
| 176 | ret.is_condition_code.Assign(0); | ||
| 177 | ret.index.Assign(static_cast<u32>(reg)); | ||
| 178 | return ret; | ||
| 179 | } | ||
| 180 | } | ||
| 181 | throw NotImplementedException("Register spilling"); | ||
| 182 | } | ||
| 183 | |||
| 184 | void RegAlloc::Free(Id id) { | ||
| 185 | if (id.is_spill != 0) { | ||
| 186 | throw NotImplementedException("Free spill"); | ||
| 187 | } | ||
| 188 | register_use[id.index] = false; | ||
| 189 | } | ||
| 190 | |||
| 191 | } // namespace Shader::Backend::GLSL | ||