summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glasm/reg_alloc.h
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.h
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.h')
-rw-r--r--src/shader_recompiler/backend/glasm/reg_alloc.h63
1 files changed, 58 insertions, 5 deletions
diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.h b/src/shader_recompiler/backend/glasm/reg_alloc.h
index 6a238afa9..f1899eae1 100644
--- a/src/shader_recompiler/backend/glasm/reg_alloc.h
+++ b/src/shader_recompiler/backend/glasm/reg_alloc.h
@@ -27,12 +27,14 @@ enum class Type : u32 {
27 U32, 27 U32,
28 S32, 28 S32,
29 F32, 29 F32,
30 F64,
30}; 31};
31 32
32struct Id { 33struct Id {
33 union { 34 union {
34 u32 raw; 35 u32 raw;
35 BitField<0, 30, u32> index; 36 BitField<0, 29, u32> index;
37 BitField<29, 1, u32> is_long;
36 BitField<30, 1, u32> is_spill; 38 BitField<30, 1, u32> is_spill;
37 BitField<31, 1, u32> is_condition_code; 39 BitField<31, 1, u32> is_condition_code;
38 }; 40 };
@@ -53,6 +55,7 @@ struct Value {
53 u32 imm_u32; 55 u32 imm_u32;
54 s32 imm_s32; 56 s32 imm_s32;
55 f32 imm_f32; 57 f32 imm_f32;
58 f64 imm_f64;
56 }; 59 };
57 60
58 bool operator==(const Value& rhs) const noexcept { 61 bool operator==(const Value& rhs) const noexcept {
@@ -68,6 +71,8 @@ struct Value {
68 return imm_s32 == rhs.imm_s32; 71 return imm_s32 == rhs.imm_s32;
69 case Type::F32: 72 case Type::F32:
70 return Common::BitCast<u32>(imm_f32) == Common::BitCast<u32>(rhs.imm_f32); 73 return Common::BitCast<u32>(imm_f32) == Common::BitCast<u32>(rhs.imm_f32);
74 case Type::F64:
75 return Common::BitCast<u64>(imm_f64) == Common::BitCast<u64>(rhs.imm_f64);
71 } 76 }
72 return false; 77 return false;
73 } 78 }
@@ -80,6 +85,7 @@ struct ScalarRegister : Value {};
80struct ScalarU32 : Value {}; 85struct ScalarU32 : Value {};
81struct ScalarS32 : Value {}; 86struct ScalarS32 : Value {};
82struct ScalarF32 : Value {}; 87struct ScalarF32 : Value {};
88struct ScalarF64 : Value {};
83 89
84class RegAlloc { 90class RegAlloc {
85public: 91public:
@@ -87,9 +93,13 @@ public:
87 93
88 Register Define(IR::Inst& inst); 94 Register Define(IR::Inst& inst);
89 95
96 Register LongDefine(IR::Inst& inst);
97
90 Value Consume(const IR::Value& value); 98 Value Consume(const IR::Value& value);
91 99
92 Register AllocReg(); 100 [[nodiscard]] Register AllocReg();
101
102 [[nodiscard]] Register AllocLongReg();
93 103
94 void FreeReg(Register reg); 104 void FreeReg(Register reg);
95 105
@@ -97,19 +107,27 @@ public:
97 return num_used_registers; 107 return num_used_registers;
98 } 108 }
99 109
110 [[nodiscard]] size_t NumUsedLongRegisters() const noexcept {
111 return num_used_long_registers;
112 }
113
100private: 114private:
101 static constexpr size_t NUM_REGS = 4096; 115 static constexpr size_t NUM_REGS = 4096;
102 static constexpr size_t NUM_ELEMENTS = 4; 116 static constexpr size_t NUM_ELEMENTS = 4;
103 117
118 Register Define(IR::Inst& inst, bool is_long);
119
104 Value Consume(IR::Inst& inst); 120 Value Consume(IR::Inst& inst);
105 121
106 Id Alloc(); 122 Id Alloc(bool is_long);
107 123
108 void Free(Id id); 124 void Free(Id id);
109 125
110 EmitContext& ctx; 126 EmitContext& ctx;
111 size_t num_used_registers{}; 127 size_t num_used_registers{};
128 size_t num_used_long_registers{};
112 std::bitset<NUM_REGS> register_use{}; 129 std::bitset<NUM_REGS> register_use{};
130 std::bitset<NUM_REGS> long_register_use{};
113}; 131};
114 132
115template <bool scalar, typename FormatContext> 133template <bool scalar, typename FormatContext>
@@ -121,9 +139,17 @@ auto FormatTo(FormatContext& ctx, Id id) {
121 throw NotImplementedException("Spill emission"); 139 throw NotImplementedException("Spill emission");
122 } 140 }
123 if constexpr (scalar) { 141 if constexpr (scalar) {
124 return fmt::format_to(ctx.out(), "R{}.x", id.index.Value()); 142 if (id.is_long != 0) {
143 return fmt::format_to(ctx.out(), "D{}.x", id.index.Value());
144 } else {
145 return fmt::format_to(ctx.out(), "R{}.x", id.index.Value());
146 }
125 } else { 147 } else {
126 return fmt::format_to(ctx.out(), "R{}", id.index.Value()); 148 if (id.is_long != 0) {
149 return fmt::format_to(ctx.out(), "D{}", id.index.Value());
150 } else {
151 return fmt::format_to(ctx.out(), "R{}", id.index.Value());
152 }
127 } 153 }
128} 154}
129 155
@@ -184,6 +210,8 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarU32> {
184 return fmt::format_to(ctx.out(), "{}", static_cast<u32>(value.imm_s32)); 210 return fmt::format_to(ctx.out(), "{}", static_cast<u32>(value.imm_s32));
185 case Shader::Backend::GLASM::Type::F32: 211 case Shader::Backend::GLASM::Type::F32:
186 return fmt::format_to(ctx.out(), "{}", Common::BitCast<u32>(value.imm_f32)); 212 return fmt::format_to(ctx.out(), "{}", Common::BitCast<u32>(value.imm_f32));
213 case Shader::Backend::GLASM::Type::F64:
214 break;
187 } 215 }
188 throw Shader::InvalidArgument("Invalid value type {}", value.type); 216 throw Shader::InvalidArgument("Invalid value type {}", value.type);
189 } 217 }
@@ -205,6 +233,8 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarS32> {
205 return fmt::format_to(ctx.out(), "{}", value.imm_s32); 233 return fmt::format_to(ctx.out(), "{}", value.imm_s32);
206 case Shader::Backend::GLASM::Type::F32: 234 case Shader::Backend::GLASM::Type::F32:
207 return fmt::format_to(ctx.out(), "{}", Common::BitCast<s32>(value.imm_f32)); 235 return fmt::format_to(ctx.out(), "{}", Common::BitCast<s32>(value.imm_f32));
236 case Shader::Backend::GLASM::Type::F64:
237 break;
208 } 238 }
209 throw Shader::InvalidArgument("Invalid value type {}", value.type); 239 throw Shader::InvalidArgument("Invalid value type {}", value.type);
210 } 240 }
@@ -226,6 +256,29 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarF32> {
226 return fmt::format_to(ctx.out(), "{}", Common::BitCast<s32>(value.imm_s32)); 256 return fmt::format_to(ctx.out(), "{}", Common::BitCast<s32>(value.imm_s32));
227 case Shader::Backend::GLASM::Type::F32: 257 case Shader::Backend::GLASM::Type::F32:
228 return fmt::format_to(ctx.out(), "{}", value.imm_f32); 258 return fmt::format_to(ctx.out(), "{}", value.imm_f32);
259 case Shader::Backend::GLASM::Type::F64:
260 break;
261 }
262 throw Shader::InvalidArgument("Invalid value type {}", value.type);
263 }
264};
265
266template <>
267struct fmt::formatter<Shader::Backend::GLASM::ScalarF64> {
268 constexpr auto parse(format_parse_context& ctx) {
269 return ctx.begin();
270 }
271 template <typename FormatContext>
272 auto format(const Shader::Backend::GLASM::ScalarF64& value, FormatContext& ctx) {
273 switch (value.type) {
274 case Shader::Backend::GLASM::Type::Register:
275 return Shader::Backend::GLASM::FormatTo<true>(ctx, value.id);
276 case Shader::Backend::GLASM::Type::U32:
277 case Shader::Backend::GLASM::Type::S32:
278 case Shader::Backend::GLASM::Type::F32:
279 break;
280 case Shader::Backend::GLASM::Type::F64:
281 return format_to(ctx.out(), "{}", value.imm_f64);
229 } 282 }
230 throw Shader::InvalidArgument("Invalid value type {}", value.type); 283 throw Shader::InvalidArgument("Invalid value type {}", value.type);
231 } 284 }