summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/backend/glasm/reg_alloc.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-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 {
U32,
S32,
F32,
+ F64,
};
struct Id {
union {
u32 raw;
- BitField<0, 30, u32> index;
+ BitField<0, 29, u32> index;
+ BitField<29, 1, u32> is_long;
BitField<30, 1, u32> is_spill;
BitField<31, 1, u32> is_condition_code;
};
@@ -53,6 +55,7 @@ struct Value {
u32 imm_u32;
s32 imm_s32;
f32 imm_f32;
+ f64 imm_f64;
};
bool operator==(const Value& rhs) const noexcept {
@@ -68,6 +71,8 @@ struct Value {
return imm_s32 == rhs.imm_s32;
case Type::F32:
return Common::BitCast<u32>(imm_f32) == Common::BitCast<u32>(rhs.imm_f32);
+ case Type::F64:
+ return Common::BitCast<u64>(imm_f64) == Common::BitCast<u64>(rhs.imm_f64);
}
return false;
}
@@ -80,6 +85,7 @@ struct ScalarRegister : Value {};
struct ScalarU32 : Value {};
struct ScalarS32 : Value {};
struct ScalarF32 : Value {};
+struct ScalarF64 : Value {};
class RegAlloc {
public:
@@ -87,9 +93,13 @@ public:
Register Define(IR::Inst& inst);
+ Register LongDefine(IR::Inst& inst);
+
Value Consume(const IR::Value& value);
- Register AllocReg();
+ [[nodiscard]] Register AllocReg();
+
+ [[nodiscard]] Register AllocLongReg();
void FreeReg(Register reg);
@@ -97,19 +107,27 @@ public:
return num_used_registers;
}
+ [[nodiscard]] size_t NumUsedLongRegisters() const noexcept {
+ return num_used_long_registers;
+ }
+
private:
static constexpr size_t NUM_REGS = 4096;
static constexpr size_t NUM_ELEMENTS = 4;
+ Register Define(IR::Inst& inst, bool is_long);
+
Value Consume(IR::Inst& inst);
- Id Alloc();
+ Id Alloc(bool is_long);
void Free(Id id);
EmitContext& ctx;
size_t num_used_registers{};
+ size_t num_used_long_registers{};
std::bitset<NUM_REGS> register_use{};
+ std::bitset<NUM_REGS> long_register_use{};
};
template <bool scalar, typename FormatContext>
@@ -121,9 +139,17 @@ auto FormatTo(FormatContext& ctx, Id id) {
throw NotImplementedException("Spill emission");
}
if constexpr (scalar) {
- return fmt::format_to(ctx.out(), "R{}.x", id.index.Value());
+ if (id.is_long != 0) {
+ return fmt::format_to(ctx.out(), "D{}.x", id.index.Value());
+ } else {
+ return fmt::format_to(ctx.out(), "R{}.x", id.index.Value());
+ }
} else {
- return fmt::format_to(ctx.out(), "R{}", id.index.Value());
+ if (id.is_long != 0) {
+ return fmt::format_to(ctx.out(), "D{}", id.index.Value());
+ } else {
+ return fmt::format_to(ctx.out(), "R{}", id.index.Value());
+ }
}
}
@@ -184,6 +210,8 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarU32> {
return fmt::format_to(ctx.out(), "{}", static_cast<u32>(value.imm_s32));
case Shader::Backend::GLASM::Type::F32:
return fmt::format_to(ctx.out(), "{}", Common::BitCast<u32>(value.imm_f32));
+ case Shader::Backend::GLASM::Type::F64:
+ break;
}
throw Shader::InvalidArgument("Invalid value type {}", value.type);
}
@@ -205,6 +233,8 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarS32> {
return fmt::format_to(ctx.out(), "{}", value.imm_s32);
case Shader::Backend::GLASM::Type::F32:
return fmt::format_to(ctx.out(), "{}", Common::BitCast<s32>(value.imm_f32));
+ case Shader::Backend::GLASM::Type::F64:
+ break;
}
throw Shader::InvalidArgument("Invalid value type {}", value.type);
}
@@ -226,6 +256,29 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarF32> {
return fmt::format_to(ctx.out(), "{}", Common::BitCast<s32>(value.imm_s32));
case Shader::Backend::GLASM::Type::F32:
return fmt::format_to(ctx.out(), "{}", value.imm_f32);
+ case Shader::Backend::GLASM::Type::F64:
+ break;
+ }
+ throw Shader::InvalidArgument("Invalid value type {}", value.type);
+ }
+};
+
+template <>
+struct fmt::formatter<Shader::Backend::GLASM::ScalarF64> {
+ constexpr auto parse(format_parse_context& ctx) {
+ return ctx.begin();
+ }
+ template <typename FormatContext>
+ auto format(const Shader::Backend::GLASM::ScalarF64& value, FormatContext& ctx) {
+ switch (value.type) {
+ case Shader::Backend::GLASM::Type::Register:
+ return Shader::Backend::GLASM::FormatTo<true>(ctx, value.id);
+ case Shader::Backend::GLASM::Type::U32:
+ case Shader::Backend::GLASM::Type::S32:
+ case Shader::Backend::GLASM::Type::F32:
+ break;
+ case Shader::Backend::GLASM::Type::F64:
+ return format_to(ctx.out(), "{}", value.imm_f64);
}
throw Shader::InvalidArgument("Invalid value type {}", value.type);
}