summaryrefslogtreecommitdiff
path: root/src/shader_recompiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler')
-rw-r--r--src/shader_recompiler/CMakeLists.txt2
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.cpp4
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.cpp19
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_image.cpp11
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp2
-rw-r--r--src/shader_recompiler/file_environment.h2
-rw-r--r--src/shader_recompiler/frontend/ir/attribute.cpp4
-rw-r--r--src/shader_recompiler/frontend/ir/basic_block.cpp2
-rw-r--r--src/shader_recompiler/frontend/ir/condition.cpp6
-rw-r--r--src/shader_recompiler/frontend/ir/condition.h4
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp4
-rw-r--r--src/shader_recompiler/frontend/ir/microinstruction.cpp16
-rw-r--r--src/shader_recompiler/frontend/ir/microinstruction.h4
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.cpp2
-rw-r--r--src/shader_recompiler/frontend/ir/program.cpp2
-rw-r--r--src/shader_recompiler/frontend/ir/value.cpp4
-rw-r--r--src/shader_recompiler/frontend/ir/value.h2
-rw-r--r--src/shader_recompiler/frontend/maxwell/control_flow.cpp140
-rw-r--r--src/shader_recompiler/frontend/maxwell/decode.cpp10
-rw-r--r--src/shader_recompiler/frontend/maxwell/indirect_branch_table_track.cpp10
-rw-r--r--src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp3
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/double_add.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/double_fused_multiply_add.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/double_multiply.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp3
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare_and_set.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_floating_point.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp11
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp8
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_set_predicate.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_swizzled_add.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_add.cpp11
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_fused_multiply_add.cpp11
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_multiply.cpp11
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set.cpp11
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set_predicate.cpp12
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp8
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp1
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp4
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/load_constant.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/load_store_local_shared.cpp9
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/load_store_memory.cpp4
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/texture_query.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/video_set_predicate.cpp1
-rw-r--r--src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp20
-rw-r--r--src/shader_recompiler/ir_opt/constant_propagation_pass.cpp49
-rw-r--r--src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp42
-rw-r--r--src/shader_recompiler/ir_opt/identity_removal_pass.cpp3
-rw-r--r--src/shader_recompiler/ir_opt/lower_fp16_to_fp32.cpp2
-rw-r--r--src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp4
-rw-r--r--src/shader_recompiler/ir_opt/texture_pass.cpp32
-rw-r--r--src/shader_recompiler/ir_opt/verification_pass.cpp4
59 files changed, 289 insertions, 297 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt
index 22639fe13..551bf1c58 100644
--- a/src/shader_recompiler/CMakeLists.txt
+++ b/src/shader_recompiler/CMakeLists.txt
@@ -196,6 +196,8 @@ else()
196 $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> 196 $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter>
197 $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> 197 $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable>
198 -Werror=unused-variable 198 -Werror=unused-variable
199
200 $<$<CXX_COMPILER_ID:Clang>:-fbracket-depth=1024>
199 ) 201 )
200endif() 202endif()
201 203
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp
index b738e00cc..0c114402b 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_context.cpp
@@ -4,6 +4,7 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <array> 6#include <array>
7#include <climits>
7#include <string_view> 8#include <string_view>
8 9
9#include <fmt/format.h> 10#include <fmt/format.h>
@@ -116,7 +117,8 @@ void VectorTypes::Define(Sirit::Module& sirit_ctx, Id base_type, std::string_vie
116 const std::string_view def_name_view( 117 const std::string_view def_name_view(
117 def_name.data(), 118 def_name.data(),
118 fmt::format_to_n(def_name.data(), def_name.size(), "{}x{}", name, i + 1).size); 119 fmt::format_to_n(def_name.data(), def_name.size(), "{}x{}", name, i + 1).size);
119 defs[i] = sirit_ctx.Name(sirit_ctx.TypeVector(base_type, i + 1), def_name_view); 120 defs[static_cast<size_t>(i)] =
121 sirit_ctx.Name(sirit_ctx.TypeVector(base_type, i + 1), def_name_view);
120 } 122 }
121} 123}
122 124
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
index 32512a0e5..355cf0ca8 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
@@ -16,7 +16,7 @@
16namespace Shader::Backend::SPIRV { 16namespace Shader::Backend::SPIRV {
17namespace { 17namespace {
18template <class Func> 18template <class Func>
19struct FuncTraits : FuncTraits<Func> {}; 19struct FuncTraits {};
20 20
21template <class ReturnType_, class... Args> 21template <class ReturnType_, class... Args>
22struct FuncTraits<ReturnType_ (*)(Args...)> { 22struct FuncTraits<ReturnType_ (*)(Args...)> {
@@ -64,17 +64,20 @@ ArgType Arg(EmitContext& ctx, const IR::Value& arg) {
64template <auto func, bool is_first_arg_inst, size_t... I> 64template <auto func, bool is_first_arg_inst, size_t... I>
65void Invoke(EmitContext& ctx, IR::Inst* inst, std::index_sequence<I...>) { 65void Invoke(EmitContext& ctx, IR::Inst* inst, std::index_sequence<I...>) {
66 using Traits = FuncTraits<decltype(func)>; 66 using Traits = FuncTraits<decltype(func)>;
67 if constexpr (std::is_same_v<Traits::ReturnType, Id>) { 67 if constexpr (std::is_same_v<typename Traits::ReturnType, Id>) {
68 if constexpr (is_first_arg_inst) { 68 if constexpr (is_first_arg_inst) {
69 SetDefinition<func>(ctx, inst, inst, Arg<Traits::ArgType<I + 2>>(ctx, inst->Arg(I))...); 69 SetDefinition<func>(
70 ctx, inst, inst,
71 Arg<typename Traits::template ArgType<I + 2>>(ctx, inst->Arg(I))...);
70 } else { 72 } else {
71 SetDefinition<func>(ctx, inst, Arg<Traits::ArgType<I + 1>>(ctx, inst->Arg(I))...); 73 SetDefinition<func>(
74 ctx, inst, Arg<typename Traits::template ArgType<I + 1>>(ctx, inst->Arg(I))...);
72 } 75 }
73 } else { 76 } else {
74 if constexpr (is_first_arg_inst) { 77 if constexpr (is_first_arg_inst) {
75 func(ctx, inst, Arg<Traits::ArgType<I + 2>>(ctx, inst->Arg(I))...); 78 func(ctx, inst, Arg<typename Traits::template ArgType<I + 2>>(ctx, inst->Arg(I))...);
76 } else { 79 } else {
77 func(ctx, Arg<Traits::ArgType<I + 1>>(ctx, inst->Arg(I))...); 80 func(ctx, Arg<typename Traits::template ArgType<I + 1>>(ctx, inst->Arg(I))...);
78 } 81 }
79 } 82 }
80} 83}
@@ -94,14 +97,14 @@ void Invoke(EmitContext& ctx, IR::Inst* inst) {
94} 97}
95 98
96void EmitInst(EmitContext& ctx, IR::Inst* inst) { 99void EmitInst(EmitContext& ctx, IR::Inst* inst) {
97 switch (inst->Opcode()) { 100 switch (inst->GetOpcode()) {
98#define OPCODE(name, result_type, ...) \ 101#define OPCODE(name, result_type, ...) \
99 case IR::Opcode::name: \ 102 case IR::Opcode::name: \
100 return Invoke<&Emit##name>(ctx, inst); 103 return Invoke<&Emit##name>(ctx, inst);
101#include "shader_recompiler/frontend/ir/opcodes.inc" 104#include "shader_recompiler/frontend/ir/opcodes.inc"
102#undef OPCODE 105#undef OPCODE
103 } 106 }
104 throw LogicError("Invalid opcode {}", inst->Opcode()); 107 throw LogicError("Invalid opcode {}", inst->GetOpcode());
105} 108}
106 109
107Id TypeId(const EmitContext& ctx, IR::Type type) { 110Id TypeId(const EmitContext& ctx, IR::Type type) {
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
index f0f8db8c3..815ca6299 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
@@ -43,11 +43,13 @@ public:
43 // LOG_WARNING("Not all arguments in PTP are immediate, STUBBING"); 43 // LOG_WARNING("Not all arguments in PTP are immediate, STUBBING");
44 return; 44 return;
45 } 45 }
46 const IR::Opcode opcode{values[0]->Opcode()}; 46 const IR::Opcode opcode{values[0]->GetOpcode()};
47 if (opcode != values[1]->Opcode() || opcode != IR::Opcode::CompositeConstructU32x4) { 47 if (opcode != values[1]->GetOpcode() || opcode != IR::Opcode::CompositeConstructU32x4) {
48 throw LogicError("Invalid PTP arguments"); 48 throw LogicError("Invalid PTP arguments");
49 } 49 }
50 auto read{[&](int a, int b) { return ctx.Constant(ctx.U32[1], values[a]->Arg(b).U32()); }}; 50 auto read{[&](unsigned int a, unsigned int b) {
51 return ctx.Constant(ctx.U32[1], values[a]->Arg(b).U32());
52 }};
51 53
52 const Id offsets{ 54 const Id offsets{
53 ctx.ConstantComposite(ctx.TypeArray(ctx.U32[2], ctx.Constant(ctx.U32[1], 4)), 55 ctx.ConstantComposite(ctx.TypeArray(ctx.U32[2], ctx.Constant(ctx.U32[1], 4)),
@@ -297,13 +299,14 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id
297 299
298Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 300Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
299 const IR::Value& offset, const IR::Value& offset2, Id dref) { 301 const IR::Value& offset, const IR::Value& offset2, Id dref) {
300 const auto info{inst->Flags<IR::TextureInstInfo>()};
301 const ImageOperands operands(ctx, offset, offset2); 302 const ImageOperands operands(ctx, offset, offset2);
302 return Emit(&EmitContext::OpImageSparseDrefGather, &EmitContext::OpImageDrefGather, ctx, inst, 303 return Emit(&EmitContext::OpImageSparseDrefGather, &EmitContext::OpImageDrefGather, ctx, inst,
303 ctx.F32[4], Texture(ctx, index), coords, dref, operands.Mask(), operands.Span()); 304 ctx.F32[4], Texture(ctx, index), coords, dref, operands.Mask(), operands.Span());
304} 305}
305 306
307#ifdef _WIN32
306#pragma optimize("", off) 308#pragma optimize("", off)
309#endif
307 310
308Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, 311Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset,
309 Id lod, Id ms) { 312 Id lod, Id ms) {
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
index c57bd291d..12a03ed6e 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
@@ -7,7 +7,7 @@
7namespace Shader::Backend::SPIRV { 7namespace Shader::Backend::SPIRV {
8namespace { 8namespace {
9Id WarpExtract(EmitContext& ctx, Id value) { 9Id WarpExtract(EmitContext& ctx, Id value) {
10 const Id shift{ctx.Constant(ctx.U32[1], 5)}; 10 [[maybe_unused]] const Id shift{ctx.Constant(ctx.U32[1], 5)};
11 const Id local_index{ctx.OpLoad(ctx.U32[1], ctx.subgroup_local_invocation_id)}; 11 const Id local_index{ctx.OpLoad(ctx.U32[1], ctx.subgroup_local_invocation_id)};
12 return ctx.OpVectorExtractDynamic(ctx.U32[1], value, local_index); 12 return ctx.OpVectorExtractDynamic(ctx.U32[1], value, local_index);
13} 13}
diff --git a/src/shader_recompiler/file_environment.h b/src/shader_recompiler/file_environment.h
index 17640a622..71601f8fd 100644
--- a/src/shader_recompiler/file_environment.h
+++ b/src/shader_recompiler/file_environment.h
@@ -7,7 +7,7 @@
7 7
8namespace Shader { 8namespace Shader {
9 9
10class FileEnvironment final : public Environment { 10class FileEnvironment : public Environment {
11public: 11public:
12 explicit FileEnvironment(const char* path); 12 explicit FileEnvironment(const char* path);
13 ~FileEnvironment() override; 13 ~FileEnvironment() override;
diff --git a/src/shader_recompiler/frontend/ir/attribute.cpp b/src/shader_recompiler/frontend/ir/attribute.cpp
index 4811242ea..7993e5c43 100644
--- a/src/shader_recompiler/frontend/ir/attribute.cpp
+++ b/src/shader_recompiler/frontend/ir/attribute.cpp
@@ -17,7 +17,7 @@ u32 GenericAttributeIndex(Attribute attribute) {
17 if (!IsGeneric(attribute)) { 17 if (!IsGeneric(attribute)) {
18 throw InvalidArgument("Attribute is not generic {}", attribute); 18 throw InvalidArgument("Attribute is not generic {}", attribute);
19 } 19 }
20 return (static_cast<int>(attribute) - static_cast<int>(Attribute::Generic0X)) / 4; 20 return (static_cast<u32>(attribute) - static_cast<u32>(Attribute::Generic0X)) / 4u;
21} 21}
22 22
23std::string NameOf(Attribute attribute) { 23std::string NameOf(Attribute attribute) {
@@ -444,4 +444,4 @@ std::string NameOf(Attribute attribute) {
444 return fmt::format("<reserved attribute {}>", static_cast<int>(attribute)); 444 return fmt::format("<reserved attribute {}>", static_cast<int>(attribute));
445} 445}
446 446
447} // namespace Shader::IR \ No newline at end of file 447} // namespace Shader::IR
diff --git a/src/shader_recompiler/frontend/ir/basic_block.cpp b/src/shader_recompiler/frontend/ir/basic_block.cpp
index ec029dfd6..e1f0191f4 100644
--- a/src/shader_recompiler/frontend/ir/basic_block.cpp
+++ b/src/shader_recompiler/frontend/ir/basic_block.cpp
@@ -155,7 +155,7 @@ std::string DumpBlock(const Block& block, const std::map<const Block*, size_t>&
155 ret += fmt::format(": begin={:04x} end={:04x}\n", block.LocationBegin(), block.LocationEnd()); 155 ret += fmt::format(": begin={:04x} end={:04x}\n", block.LocationBegin(), block.LocationEnd());
156 156
157 for (const Inst& inst : block) { 157 for (const Inst& inst : block) {
158 const Opcode op{inst.Opcode()}; 158 const Opcode op{inst.GetOpcode()};
159 ret += fmt::format("[{:016x}] ", reinterpret_cast<u64>(&inst)); 159 ret += fmt::format("[{:016x}] ", reinterpret_cast<u64>(&inst));
160 if (TypeOf(op) != Type::Void) { 160 if (TypeOf(op) != Type::Void) {
161 ret += fmt::format("%{:<5} = {}", InstIndex(inst_to_index, inst_index, &inst), op); 161 ret += fmt::format("%{:<5} = {}", InstIndex(inst_to_index, inst_index, &inst), op);
diff --git a/src/shader_recompiler/frontend/ir/condition.cpp b/src/shader_recompiler/frontend/ir/condition.cpp
index ec1659e2b..fc18ea2a2 100644
--- a/src/shader_recompiler/frontend/ir/condition.cpp
+++ b/src/shader_recompiler/frontend/ir/condition.cpp
@@ -12,10 +12,10 @@ namespace Shader::IR {
12 12
13std::string NameOf(Condition condition) { 13std::string NameOf(Condition condition) {
14 std::string ret; 14 std::string ret;
15 if (condition.FlowTest() != FlowTest::T) { 15 if (condition.GetFlowTest() != FlowTest::T) {
16 ret = fmt::to_string(condition.FlowTest()); 16 ret = fmt::to_string(condition.GetFlowTest());
17 } 17 }
18 const auto [pred, negated]{condition.Pred()}; 18 const auto [pred, negated]{condition.GetPred()};
19 if (!ret.empty()) { 19 if (!ret.empty()) {
20 ret += '&'; 20 ret += '&';
21 } 21 }
diff --git a/src/shader_recompiler/frontend/ir/condition.h b/src/shader_recompiler/frontend/ir/condition.h
index 51c2f15cf..aa8597c60 100644
--- a/src/shader_recompiler/frontend/ir/condition.h
+++ b/src/shader_recompiler/frontend/ir/condition.h
@@ -30,11 +30,11 @@ public:
30 30
31 auto operator<=>(const Condition&) const noexcept = default; 31 auto operator<=>(const Condition&) const noexcept = default;
32 32
33 [[nodiscard]] IR::FlowTest FlowTest() const noexcept { 33 [[nodiscard]] IR::FlowTest GetFlowTest() const noexcept {
34 return static_cast<IR::FlowTest>(flow_test); 34 return static_cast<IR::FlowTest>(flow_test);
35 } 35 }
36 36
37 [[nodiscard]] std::pair<IR::Pred, bool> Pred() const noexcept { 37 [[nodiscard]] std::pair<IR::Pred, bool> GetPred() const noexcept {
38 return {static_cast<IR::Pred>(pred), pred_negated != 0}; 38 return {static_cast<IR::Pred>(pred), pred_negated != 0};
39 } 39 }
40 40
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index 13eb2de4c..a2104bdb3 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -290,8 +290,8 @@ static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) {
290} 290}
291 291
292U1 IREmitter::Condition(IR::Condition cond) { 292U1 IREmitter::Condition(IR::Condition cond) {
293 const FlowTest flow_test{cond.FlowTest()}; 293 const FlowTest flow_test{cond.GetFlowTest()};
294 const auto [pred, is_negated]{cond.Pred()}; 294 const auto [pred, is_negated]{cond.GetPred()};
295 return LogicalAnd(GetPred(pred, is_negated), GetFlowTest(*this, flow_test)); 295 return LogicalAnd(GetPred(pred, is_negated), GetFlowTest(*this, flow_test));
296} 296}
297 297
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp
index 481202d94..ceb44e604 100644
--- a/src/shader_recompiler/frontend/ir/microinstruction.cpp
+++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp
@@ -12,7 +12,7 @@
12namespace Shader::IR { 12namespace Shader::IR {
13namespace { 13namespace {
14void CheckPseudoInstruction(IR::Inst* inst, IR::Opcode opcode) { 14void CheckPseudoInstruction(IR::Inst* inst, IR::Opcode opcode) {
15 if (inst && inst->Opcode() != opcode) { 15 if (inst && inst->GetOpcode() != opcode) {
16 throw LogicError("Invalid pseudo-instruction"); 16 throw LogicError("Invalid pseudo-instruction");
17 } 17 }
18} 18}
@@ -25,11 +25,17 @@ void SetPseudoInstruction(IR::Inst*& dest_inst, IR::Inst* pseudo_inst) {
25} 25}
26 26
27void RemovePseudoInstruction(IR::Inst*& inst, IR::Opcode expected_opcode) { 27void RemovePseudoInstruction(IR::Inst*& inst, IR::Opcode expected_opcode) {
28 if (inst->Opcode() != expected_opcode) { 28 if (inst->GetOpcode() != expected_opcode) {
29 throw LogicError("Undoing use of invalid pseudo-op"); 29 throw LogicError("Undoing use of invalid pseudo-op");
30 } 30 }
31 inst = nullptr; 31 inst = nullptr;
32} 32}
33
34void AllocAssociatedInsts(std::unique_ptr<AssociatedInsts>& associated_insts) {
35 if (!associated_insts) {
36 associated_insts = std::make_unique<AssociatedInsts>();
37 }
38}
33} // Anonymous namespace 39} // Anonymous namespace
34 40
35Inst::Inst(IR::Opcode op_, u32 flags_) noexcept : op{op_}, flags{flags_} { 41Inst::Inst(IR::Opcode op_, u32 flags_) noexcept : op{op_}, flags{flags_} {
@@ -249,12 +255,6 @@ void Inst::ReplaceOpcode(IR::Opcode opcode) {
249 op = opcode; 255 op = opcode;
250} 256}
251 257
252void AllocAssociatedInsts(std::unique_ptr<AssociatedInsts>& associated_insts) {
253 if (!associated_insts) {
254 associated_insts = std::make_unique<AssociatedInsts>();
255 }
256}
257
258void Inst::Use(const Value& value) { 258void Inst::Use(const Value& value) {
259 Inst* const inst{value.Inst()}; 259 Inst* const inst{value.Inst()};
260 ++inst->use_count; 260 ++inst->use_count;
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.h b/src/shader_recompiler/frontend/ir/microinstruction.h
index 6658dc674..97dc91d85 100644
--- a/src/shader_recompiler/frontend/ir/microinstruction.h
+++ b/src/shader_recompiler/frontend/ir/microinstruction.h
@@ -46,7 +46,7 @@ public:
46 } 46 }
47 47
48 /// Get the opcode this microinstruction represents. 48 /// Get the opcode this microinstruction represents.
49 [[nodiscard]] IR::Opcode Opcode() const noexcept { 49 [[nodiscard]] IR::Opcode GetOpcode() const noexcept {
50 return op; 50 return op;
51 } 51 }
52 52
@@ -95,7 +95,7 @@ public:
95 requires(sizeof(FlagsType) <= sizeof(u32) && std::is_trivially_copyable_v<FlagsType>) 95 requires(sizeof(FlagsType) <= sizeof(u32) && std::is_trivially_copyable_v<FlagsType>)
96 [[nodiscard]] FlagsType Flags() const noexcept { 96 [[nodiscard]] FlagsType Flags() const noexcept {
97 FlagsType ret; 97 FlagsType ret;
98 std::memcpy(&ret, &flags, sizeof(ret)); 98 std::memcpy(reinterpret_cast<char*>(&ret), &flags, sizeof(ret));
99 return ret; 99 return ret;
100 } 100 }
101 101
diff --git a/src/shader_recompiler/frontend/ir/opcodes.cpp b/src/shader_recompiler/frontend/ir/opcodes.cpp
index 1cb9db6c9..002dbf94e 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.cpp
+++ b/src/shader_recompiler/frontend/ir/opcodes.cpp
@@ -49,7 +49,7 @@ constexpr std::array META_TABLE{
49#define OPCODE(name_token, type_token, ...) \ 49#define OPCODE(name_token, type_token, ...) \
50 OpcodeMeta{ \ 50 OpcodeMeta{ \
51 .name{#name_token}, \ 51 .name{#name_token}, \
52 .type{type_token}, \ 52 .type = type_token, \
53 .arg_types{__VA_ARGS__}, \ 53 .arg_types{__VA_ARGS__}, \
54 }, 54 },
55#include "opcodes.inc" 55#include "opcodes.inc"
diff --git a/src/shader_recompiler/frontend/ir/program.cpp b/src/shader_recompiler/frontend/ir/program.cpp
index 5f51aeb5f..89a17fb1b 100644
--- a/src/shader_recompiler/frontend/ir/program.cpp
+++ b/src/shader_recompiler/frontend/ir/program.cpp
@@ -2,8 +2,6 @@
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
6
7#include <map> 5#include <map>
8#include <string> 6#include <string>
9 7
diff --git a/src/shader_recompiler/frontend/ir/value.cpp b/src/shader_recompiler/frontend/ir/value.cpp
index 837c1b487..1e7ffb86d 100644
--- a/src/shader_recompiler/frontend/ir/value.cpp
+++ b/src/shader_recompiler/frontend/ir/value.cpp
@@ -33,11 +33,11 @@ Value::Value(u64 value) noexcept : type{Type::U64}, imm_u64{value} {}
33Value::Value(f64 value) noexcept : type{Type::F64}, imm_f64{value} {} 33Value::Value(f64 value) noexcept : type{Type::F64}, imm_f64{value} {}
34 34
35bool Value::IsIdentity() const noexcept { 35bool Value::IsIdentity() const noexcept {
36 return type == Type::Opaque && inst->Opcode() == Opcode::Identity; 36 return type == Type::Opaque && inst->GetOpcode() == Opcode::Identity;
37} 37}
38 38
39bool Value::IsPhi() const noexcept { 39bool Value::IsPhi() const noexcept {
40 return type == Type::Opaque && inst->Opcode() == Opcode::Phi; 40 return type == Type::Opaque && inst->GetOpcode() == Opcode::Phi;
41} 41}
42 42
43bool Value::IsEmpty() const noexcept { 43bool Value::IsEmpty() const noexcept {
diff --git a/src/shader_recompiler/frontend/ir/value.h b/src/shader_recompiler/frontend/ir/value.h
index b27601e70..a0962863d 100644
--- a/src/shader_recompiler/frontend/ir/value.h
+++ b/src/shader_recompiler/frontend/ir/value.h
@@ -94,7 +94,7 @@ public:
94 } 94 }
95 } 95 }
96 96
97 explicit TypedValue(IR::Inst* inst) : TypedValue(Value(inst)) {} 97 explicit TypedValue(IR::Inst* inst_) : TypedValue(Value(inst_)) {}
98}; 98};
99 99
100using U1 = TypedValue<Type::U1>; 100using U1 = TypedValue<Type::U1>;
diff --git a/src/shader_recompiler/frontend/maxwell/control_flow.cpp b/src/shader_recompiler/frontend/maxwell/control_flow.cpp
index 847bb1986..cb8ec7eaa 100644
--- a/src/shader_recompiler/frontend/maxwell/control_flow.cpp
+++ b/src/shader_recompiler/frontend/maxwell/control_flow.cpp
@@ -34,41 +34,37 @@ struct Compare {
34}; 34};
35 35
36u32 BranchOffset(Location pc, Instruction inst) { 36u32 BranchOffset(Location pc, Instruction inst) {
37 return pc.Offset() + inst.branch.Offset() + 8; 37 return pc.Offset() + static_cast<u32>(inst.branch.Offset()) + 8u;
38} 38}
39 39
40void Split(Block* old_block, Block* new_block, Location pc) { 40void Split(Block* old_block, Block* new_block, Location pc) {
41 if (pc <= old_block->begin || pc >= old_block->end) { 41 if (pc <= old_block->begin || pc >= old_block->end) {
42 throw InvalidArgument("Invalid address to split={}", pc); 42 throw InvalidArgument("Invalid address to split={}", pc);
43 } 43 }
44 *new_block = Block{ 44 *new_block = Block{};
45 .begin{pc}, 45 new_block->begin = pc;
46 .end{old_block->end}, 46 new_block->end = old_block->end;
47 .end_class{old_block->end_class}, 47 new_block->end_class = old_block->end_class,
48 .cond{old_block->cond}, 48 new_block->cond = old_block->cond;
49 .stack{old_block->stack}, 49 new_block->stack = old_block->stack;
50 .branch_true{old_block->branch_true}, 50 new_block->branch_true = old_block->branch_true;
51 .branch_false{old_block->branch_false}, 51 new_block->branch_false = old_block->branch_false;
52 .function_call{old_block->function_call}, 52 new_block->function_call = old_block->function_call;
53 .return_block{old_block->return_block}, 53 new_block->return_block = old_block->return_block;
54 .branch_reg{old_block->branch_reg}, 54 new_block->branch_reg = old_block->branch_reg;
55 .branch_offset{old_block->branch_offset}, 55 new_block->branch_offset = old_block->branch_offset;
56 .indirect_branches{std::move(old_block->indirect_branches)}, 56 new_block->indirect_branches = std::move(old_block->indirect_branches);
57 }; 57
58 *old_block = Block{ 58 const Location old_begin{old_block->begin};
59 .begin{old_block->begin}, 59 Stack old_stack{std::move(old_block->stack)};
60 .end{pc}, 60 *old_block = Block{};
61 .end_class{EndClass::Branch}, 61 old_block->begin = old_begin;
62 .cond{true}, 62 old_block->end = pc;
63 .stack{std::move(old_block->stack)}, 63 old_block->end_class = EndClass::Branch;
64 .branch_true{new_block}, 64 old_block->cond = IR::Condition(true);
65 .branch_false{nullptr}, 65 old_block->stack = old_stack;
66 .function_call{}, 66 old_block->branch_true = new_block;
67 .return_block{}, 67 old_block->branch_false = nullptr;
68 .branch_reg{},
69 .branch_offset{},
70 .indirect_branches{},
71 };
72} 68}
73 69
74Token OpcodeToken(Opcode opcode) { 70Token OpcodeToken(Opcode opcode) {
@@ -141,7 +137,7 @@ std::string NameOf(const Block& block) {
141 137
142void Stack::Push(Token token, Location target) { 138void Stack::Push(Token token, Location target) {
143 entries.push_back({ 139 entries.push_back({
144 .token{token}, 140 .token = token,
145 .target{target}, 141 .target{target},
146 }); 142 });
147} 143}
@@ -177,24 +173,17 @@ bool Block::Contains(Location pc) const noexcept {
177} 173}
178 174
179Function::Function(ObjectPool<Block>& block_pool, Location start_address) 175Function::Function(ObjectPool<Block>& block_pool, Location start_address)
180 : entrypoint{start_address}, labels{{ 176 : entrypoint{start_address} {
181 .address{start_address}, 177 Label& label{labels.emplace_back()};
182 .block{block_pool.Create(Block{ 178 label.address = start_address;
183 .begin{start_address}, 179 label.block = block_pool.Create(Block{});
184 .end{start_address}, 180 label.block->begin = start_address;
185 .end_class{EndClass::Branch}, 181 label.block->end = start_address;
186 .cond{true}, 182 label.block->end_class = EndClass::Branch;
187 .stack{}, 183 label.block->cond = IR::Condition(true);
188 .branch_true{nullptr}, 184 label.block->branch_true = nullptr;
189 .branch_false{nullptr}, 185 label.block->branch_false = nullptr;
190 .function_call{}, 186}
191 .return_block{},
192 .branch_reg{},
193 .branch_offset{},
194 .indirect_branches{},
195 })},
196 .stack{},
197 }} {}
198 187
199CFG::CFG(Environment& env_, ObjectPool<Block>& block_pool_, Location start_address) 188CFG::CFG(Environment& env_, ObjectPool<Block>& block_pool_, Location start_address)
200 : env{env_}, block_pool{block_pool_}, program_start{start_address} { 189 : env{env_}, block_pool{block_pool_}, program_start{start_address} {
@@ -327,7 +316,8 @@ CFG::AnalysisState CFG::AnalyzeInst(Block* block, FunctionId function_id, Locati
327 // Insert the function into the list if it doesn't exist 316 // Insert the function into the list if it doesn't exist
328 const auto it{std::ranges::find(functions, cal_pc, &Function::entrypoint)}; 317 const auto it{std::ranges::find(functions, cal_pc, &Function::entrypoint)};
329 const bool exists{it != functions.end()}; 318 const bool exists{it != functions.end()};
330 const FunctionId call_id{exists ? std::distance(functions.begin(), it) : functions.size()}; 319 const FunctionId call_id{exists ? static_cast<size_t>(std::distance(functions.begin(), it))
320 : functions.size()};
331 if (!exists) { 321 if (!exists) {
332 functions.emplace_back(block_pool, cal_pc); 322 functions.emplace_back(block_pool, cal_pc);
333 } 323 }
@@ -362,20 +352,14 @@ void CFG::AnalyzeCondInst(Block* block, FunctionId function_id, Location pc,
362 } 352 }
363 // Create a virtual block and a conditional block 353 // Create a virtual block and a conditional block
364 Block* const conditional_block{block_pool.Create()}; 354 Block* const conditional_block{block_pool.Create()};
365 Block virtual_block{ 355 Block virtual_block{};
366 .begin{block->begin.Virtual()}, 356 virtual_block.begin = block->begin.Virtual();
367 .end{block->begin.Virtual()}, 357 virtual_block.end = block->begin.Virtual();
368 .end_class{EndClass::Branch}, 358 virtual_block.end_class = EndClass::Branch;
369 .cond{cond}, 359 virtual_block.stack = block->stack;
370 .stack{block->stack}, 360 virtual_block.cond = cond;
371 .branch_true{conditional_block}, 361 virtual_block.branch_true = conditional_block;
372 .branch_false{nullptr}, 362 virtual_block.branch_false = nullptr;
373 .function_call{},
374 .return_block{},
375 .branch_reg{},
376 .branch_offset{},
377 .indirect_branches{},
378 };
379 // Save the contents of the visited block in the conditional block 363 // Save the contents of the visited block in the conditional block
380 *conditional_block = std::move(*block); 364 *conditional_block = std::move(*block);
381 // Impersonate the visited block with a virtual block 365 // Impersonate the visited block with a virtual block
@@ -444,7 +428,7 @@ CFG::AnalysisState CFG::AnalyzeBRX(Block* block, Location pc, Instruction inst,
444 if (!is_absolute) { 428 if (!is_absolute) {
445 target += pc.Offset(); 429 target += pc.Offset();
446 } 430 }
447 target += brx_table->branch_offset; 431 target += static_cast<unsigned int>(brx_table->branch_offset);
448 target += 8; 432 target += 8;
449 targets.push_back(target); 433 targets.push_back(target);
450 } 434 }
@@ -455,8 +439,8 @@ CFG::AnalysisState CFG::AnalyzeBRX(Block* block, Location pc, Instruction inst,
455 for (const u32 target : targets) { 439 for (const u32 target : targets) {
456 Block* const branch{AddLabel(block, block->stack, target, function_id)}; 440 Block* const branch{AddLabel(block, block->stack, target, function_id)};
457 block->indirect_branches.push_back({ 441 block->indirect_branches.push_back({
458 .block{branch}, 442 .block = branch,
459 .address{target}, 443 .address = target,
460 }); 444 });
461 } 445 }
462 block->cond = IR::Condition{true}; 446 block->cond = IR::Condition{true};
@@ -523,23 +507,17 @@ Block* CFG::AddLabel(Block* block, Stack stack, Location pc, FunctionId function
523 if (label_it != function.labels.end()) { 507 if (label_it != function.labels.end()) {
524 return label_it->block; 508 return label_it->block;
525 } 509 }
526 Block* const new_block{block_pool.Create(Block{ 510 Block* const new_block{block_pool.Create()};
527 .begin{pc}, 511 new_block->begin = pc;
528 .end{pc}, 512 new_block->end = pc;
529 .end_class{EndClass::Branch}, 513 new_block->end_class = EndClass::Branch;
530 .cond{true}, 514 new_block->cond = IR::Condition(true);
531 .stack{stack}, 515 new_block->stack = stack;
532 .branch_true{nullptr}, 516 new_block->branch_true = nullptr;
533 .branch_false{nullptr}, 517 new_block->branch_false = nullptr;
534 .function_call{},
535 .return_block{},
536 .branch_reg{},
537 .branch_offset{},
538 .indirect_branches{},
539 })};
540 function.labels.push_back(Label{ 518 function.labels.push_back(Label{
541 .address{pc}, 519 .address{pc},
542 .block{new_block}, 520 .block = new_block,
543 .stack{std::move(stack)}, 521 .stack{std::move(stack)},
544 }); 522 });
545 return new_block; 523 return new_block;
diff --git a/src/shader_recompiler/frontend/maxwell/decode.cpp b/src/shader_recompiler/frontend/maxwell/decode.cpp
index bd85afa1e..932d19c1d 100644
--- a/src/shader_recompiler/frontend/maxwell/decode.cpp
+++ b/src/shader_recompiler/frontend/maxwell/decode.cpp
@@ -45,7 +45,7 @@ constexpr MaskValue MaskValueFromEncoding(const char* encoding) {
45 bit >>= 1; 45 bit >>= 1;
46 } 46 }
47 } 47 }
48 return MaskValue{.mask{mask}, .value{value}}; 48 return MaskValue{.mask = mask, .value = value};
49} 49}
50 50
51struct InstEncoding { 51struct InstEncoding {
@@ -56,7 +56,7 @@ constexpr std::array UNORDERED_ENCODINGS{
56#define INST(name, cute, encode) \ 56#define INST(name, cute, encode) \
57 InstEncoding{ \ 57 InstEncoding{ \
58 .mask_value{MaskValueFromEncoding(encode)}, \ 58 .mask_value{MaskValueFromEncoding(encode)}, \
59 .opcode{Opcode::name}, \ 59 .opcode = Opcode::name, \
60 }, 60 },
61#include "maxwell.inc" 61#include "maxwell.inc"
62#undef INST 62#undef INST
@@ -116,9 +116,9 @@ constexpr auto MakeFastLookupTableIndex(size_t index) {
116 const size_t value{ToFastLookupIndex(encoding.mask_value.value)}; 116 const size_t value{ToFastLookupIndex(encoding.mask_value.value)};
117 if ((index & mask) == value) { 117 if ((index & mask) == value) {
118 encodings.at(element) = InstInfo{ 118 encodings.at(element) = InstInfo{
119 .high_mask{static_cast<u16>(encoding.mask_value.mask >> MASK_SHIFT)}, 119 .high_mask = static_cast<u16>(encoding.mask_value.mask >> MASK_SHIFT),
120 .high_value{static_cast<u16>(encoding.mask_value.value >> MASK_SHIFT)}, 120 .high_value = static_cast<u16>(encoding.mask_value.value >> MASK_SHIFT),
121 .opcode{encoding.opcode}, 121 .opcode = encoding.opcode,
122 }; 122 };
123 ++element; 123 ++element;
124 } 124 }
diff --git a/src/shader_recompiler/frontend/maxwell/indirect_branch_table_track.cpp b/src/shader_recompiler/frontend/maxwell/indirect_branch_table_track.cpp
index 96453509d..008625cb3 100644
--- a/src/shader_recompiler/frontend/maxwell/indirect_branch_table_track.cpp
+++ b/src/shader_recompiler/frontend/maxwell/indirect_branch_table_track.cpp
@@ -97,11 +97,11 @@ std::optional<IndirectBranchTableInfo> TrackIndirectBranchTable(Environment& env
97 } 97 }
98 const u32 imnmx_immediate{static_cast<u32>(imnmx.immediate.Value())}; 98 const u32 imnmx_immediate{static_cast<u32>(imnmx.immediate.Value())};
99 return IndirectBranchTableInfo{ 99 return IndirectBranchTableInfo{
100 .cbuf_index{cbuf_index}, 100 .cbuf_index = cbuf_index,
101 .cbuf_offset{cbuf_offset}, 101 .cbuf_offset = cbuf_offset,
102 .num_entries{imnmx_immediate + 1}, 102 .num_entries = imnmx_immediate + 1,
103 .branch_offset{brx_offset}, 103 .branch_offset = brx_offset,
104 .branch_reg{brx_reg}, 104 .branch_reg = brx_reg,
105 }; 105 };
106} 106}
107 107
diff --git a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp
index c804c2a8e..02cef2645 100644
--- a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp
+++ b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp
@@ -558,7 +558,6 @@ private:
558 const Node label{goto_stmt->label}; 558 const Node label{goto_stmt->label};
559 const u32 label_id{label->id}; 559 const u32 label_id{label->id};
560 const Node label_nested_stmt{FindStatementWithLabel(body, goto_stmt)}; 560 const Node label_nested_stmt{FindStatementWithLabel(body, goto_stmt)};
561 const auto type{label_nested_stmt->type};
562 561
563 Tree loop_body; 562 Tree loop_body;
564 loop_body.splice(loop_body.begin(), body, label_nested_stmt, goto_stmt); 563 loop_body.splice(loop_body.begin(), body, label_nested_stmt, goto_stmt);
@@ -566,7 +565,7 @@ private:
566 Statement* const variable{pool.Create(Variable{}, label_id)}; 565 Statement* const variable{pool.Create(Variable{}, label_id)};
567 Statement* const loop_stmt{pool.Create(Loop{}, variable, std::move(loop_body), parent)}; 566 Statement* const loop_stmt{pool.Create(Loop{}, variable, std::move(loop_body), parent)};
568 UpdateTreeUp(loop_stmt); 567 UpdateTreeUp(loop_stmt);
569 const Node loop_node{body.insert(goto_stmt, *loop_stmt)}; 568 body.insert(goto_stmt, *loop_stmt);
570 569
571 Statement* const new_goto{pool.Create(Goto{}, variable, label, loop_stmt)}; 570 Statement* const new_goto{pool.Create(Goto{}, variable, label, loop_stmt)};
572 loop_stmt->children.push_front(*new_goto); 571 loop_stmt->children.push_front(*new_goto);
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/double_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/double_add.cpp
index ac1433dea..5a1b3a8fc 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/double_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/double_add.cpp
@@ -31,9 +31,9 @@ void DADD(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) {
31 const IR::F64 op_b{v.ir.FPAbsNeg(src_b, dadd.abs_b != 0, dadd.neg_b != 0)}; 31 const IR::F64 op_b{v.ir.FPAbsNeg(src_b, dadd.abs_b != 0, dadd.neg_b != 0)};
32 32
33 const IR::FpControl control{ 33 const IR::FpControl control{
34 .no_contraction{true}, 34 .no_contraction = true,
35 .rounding{CastFpRounding(dadd.fp_rounding)}, 35 .rounding = CastFpRounding(dadd.fp_rounding),
36 .fmz_mode{IR::FmzMode::None}, 36 .fmz_mode = IR::FmzMode::None,
37 }; 37 };
38 38
39 v.D(dadd.dest_reg, v.ir.FPAdd(op_a, op_b, control)); 39 v.D(dadd.dest_reg, v.ir.FPAdd(op_a, op_b, control));
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/double_fused_multiply_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/double_fused_multiply_add.cpp
index ff7321862..723841496 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/double_fused_multiply_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/double_fused_multiply_add.cpp
@@ -25,9 +25,9 @@ void DFMA(TranslatorVisitor& v, u64 insn, const IR::F64& src_b, const IR::F64& s
25 const IR::F64 op_c{v.ir.FPAbsNeg(src_c, false, dfma.neg_c != 0)}; 25 const IR::F64 op_c{v.ir.FPAbsNeg(src_c, false, dfma.neg_c != 0)};
26 26
27 const IR::FpControl control{ 27 const IR::FpControl control{
28 .no_contraction{true}, 28 .no_contraction = true,
29 .rounding{CastFpRounding(dfma.fp_rounding)}, 29 .rounding = CastFpRounding(dfma.fp_rounding),
30 .fmz_mode{IR::FmzMode::None}, 30 .fmz_mode = IR::FmzMode::None,
31 }; 31 };
32 32
33 v.D(dfma.dest_reg, v.ir.FPFma(src_a, op_b, op_c, control)); 33 v.D(dfma.dest_reg, v.ir.FPFma(src_a, op_b, op_c, control));
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/double_multiply.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/double_multiply.cpp
index 3e83d1c95..4a49299a0 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/double_multiply.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/double_multiply.cpp
@@ -21,9 +21,9 @@ void DMUL(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) {
21 21
22 const IR::F64 src_a{v.ir.FPAbsNeg(v.D(dmul.src_a_reg), false, dmul.neg != 0)}; 22 const IR::F64 src_a{v.ir.FPAbsNeg(v.D(dmul.src_a_reg), false, dmul.neg != 0)};
23 const IR::FpControl control{ 23 const IR::FpControl control{
24 .no_contraction{true}, 24 .no_contraction = true,
25 .rounding{CastFpRounding(dmul.fp_rounding)}, 25 .rounding = CastFpRounding(dmul.fp_rounding),
26 .fmz_mode{IR::FmzMode::None}, 26 .fmz_mode = IR::FmzMode::None,
27 }; 27 };
28 28
29 v.D(dmul.dest_reg, v.ir.FPMul(src_a, src_b, control)); 29 v.D(dmul.dest_reg, v.ir.FPMul(src_a, src_b, control));
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp
index b39950c84..b8c89810c 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp
@@ -23,9 +23,9 @@ void FADD(TranslatorVisitor& v, u64 insn, bool sat, bool cc, bool ftz, FpRoundin
23 const IR::F32 op_a{v.ir.FPAbsNeg(v.F(fadd.src_a), abs_a, neg_a)}; 23 const IR::F32 op_a{v.ir.FPAbsNeg(v.F(fadd.src_a), abs_a, neg_a)};
24 const IR::F32 op_b{v.ir.FPAbsNeg(src_b, abs_b, neg_b)}; 24 const IR::F32 op_b{v.ir.FPAbsNeg(src_b, abs_b, neg_b)};
25 IR::FpControl control{ 25 IR::FpControl control{
26 .no_contraction{true}, 26 .no_contraction = true,
27 .rounding{CastFpRounding(fp_rounding)}, 27 .rounding = CastFpRounding(fp_rounding),
28 .fmz_mode{ftz ? IR::FmzMode::FTZ : IR::FmzMode::None}, 28 .fmz_mode = (ftz ? IR::FmzMode::FTZ : IR::FmzMode::None),
29 }; 29 };
30 IR::F32 value{v.ir.FPAdd(op_a, op_b, control)}; 30 IR::F32 value{v.ir.FPAdd(op_a, op_b, control)};
31 if (sat) { 31 if (sat) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp
index c02a40209..80109ca0e 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp
@@ -19,8 +19,7 @@ void FCMP(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::F32& o
19 } const fcmp{insn}; 19 } const fcmp{insn};
20 20
21 const IR::F32 zero{v.ir.Imm32(0.0f)}; 21 const IR::F32 zero{v.ir.Imm32(0.0f)};
22 const IR::F32 neg_zero{v.ir.Imm32(-0.0f)}; 22 const IR::FpControl control{.fmz_mode = (fcmp.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None)};
23 const IR::FpControl control{.fmz_mode{fcmp.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None}};
24 const IR::U1 cmp_result{FloatingPointCompare(v.ir, operand, zero, fcmp.compare_op, control)}; 23 const IR::U1 cmp_result{FloatingPointCompare(v.ir, operand, zero, fcmp.compare_op, control)};
25 const IR::U32 src_reg{v.X(fcmp.src_reg)}; 24 const IR::U32 src_reg{v.X(fcmp.src_reg)};
26 const IR::U32 result{v.ir.Select(cmp_result, src_reg, src_a)}; 25 const IR::U32 result{v.ir.Select(cmp_result, src_reg, src_a)};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare_and_set.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare_and_set.cpp
index c5417775e..b9f4ee0d9 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare_and_set.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare_and_set.cpp
@@ -29,9 +29,9 @@ void FSET(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
29 const IR::F32 op_a{v.ir.FPAbsNeg(v.F(fset.src_a_reg), fset.abs_a != 0, fset.negate_a != 0)}; 29 const IR::F32 op_a{v.ir.FPAbsNeg(v.F(fset.src_a_reg), fset.abs_a != 0, fset.negate_a != 0)};
30 const IR::F32 op_b = v.ir.FPAbsNeg(src_b, fset.abs_b != 0, fset.negate_b != 0); 30 const IR::F32 op_b = v.ir.FPAbsNeg(src_b, fset.abs_b != 0, fset.negate_b != 0);
31 const IR::FpControl control{ 31 const IR::FpControl control{
32 .no_contraction{false}, 32 .no_contraction = false,
33 .rounding{IR::FpRounding::DontCare}, 33 .rounding = IR::FpRounding::DontCare,
34 .fmz_mode{fset.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None}, 34 .fmz_mode = (fset.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None),
35 }; 35 };
36 36
37 IR::U1 pred{v.ir.GetPred(fset.pred)}; 37 IR::U1 pred{v.ir.GetPred(fset.pred)};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_floating_point.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_floating_point.cpp
index 1e366fde0..035f8782a 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_floating_point.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_floating_point.cpp
@@ -57,9 +57,9 @@ void F2F(TranslatorVisitor& v, u64 insn, const IR::F16F32F64& src_a, bool abs) {
57 57
58 const bool any_fp64{f2f.src_size == FloatFormat::F64 || f2f.dst_size == FloatFormat::F64}; 58 const bool any_fp64{f2f.src_size == FloatFormat::F64 || f2f.dst_size == FloatFormat::F64};
59 IR::FpControl fp_control{ 59 IR::FpControl fp_control{
60 .no_contraction{false}, 60 .no_contraction = false,
61 .rounding{IR::FpRounding::DontCare}, 61 .rounding = IR::FpRounding::DontCare,
62 .fmz_mode{f2f.ftz != 0 && !any_fp64 ? IR::FmzMode::FTZ : IR::FmzMode::None}, 62 .fmz_mode = (f2f.ftz != 0 && !any_fp64 ? IR::FmzMode::FTZ : IR::FmzMode::None),
63 }; 63 };
64 if (f2f.src_size != f2f.dst_size) { 64 if (f2f.src_size != f2f.dst_size) {
65 fp_control.rounding = CastFpRounding(f2f.rounding); 65 fp_control.rounding = CastFpRounding(f2f.rounding);
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp
index 21ae92be1..cf3cf1ba6 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp
@@ -123,9 +123,9 @@ void TranslateF2I(TranslatorVisitor& v, u64 insn, const IR::F16F32F64& src_a) {
123 fmz_mode = f2i.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None; 123 fmz_mode = f2i.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None;
124 } 124 }
125 const IR::FpControl fp_control{ 125 const IR::FpControl fp_control{
126 .no_contraction{true}, 126 .no_contraction = true,
127 .rounding{IR::FpRounding::DontCare}, 127 .rounding = IR::FpRounding::DontCare,
128 .fmz_mode{fmz_mode}, 128 .fmz_mode = fmz_mode,
129 }; 129 };
130 const IR::F16F32F64 op_a{v.ir.FPAbsNeg(src_a, f2i.abs != 0, f2i.neg != 0)}; 130 const IR::F16F32F64 op_a{v.ir.FPAbsNeg(src_a, f2i.abs != 0, f2i.neg != 0)};
131 const IR::F16F32F64 rounded_value{[&] { 131 const IR::F16F32F64 rounded_value{[&] {
@@ -186,14 +186,14 @@ void TranslateF2I(TranslatorVisitor& v, u64 insn, const IR::F16F32F64& src_a) {
186 } else if (f2i.dest_format == DestFormat::I64) { 186 } else if (f2i.dest_format == DestFormat::I64) {
187 handled_special_case = true; 187 handled_special_case = true;
188 result = IR::U64{ 188 result = IR::U64{
189 v.ir.Select(v.ir.FPIsNan(op_a), v.ir.Imm64(0x8000'0000'0000'0000ULL), result)}; 189 v.ir.Select(v.ir.FPIsNan(op_a), v.ir.Imm64(0x8000'0000'0000'0000UL), result)};
190 } 190 }
191 } 191 }
192 if (!handled_special_case && is_signed) { 192 if (!handled_special_case && is_signed) {
193 if (bitsize != 64) { 193 if (bitsize != 64) {
194 result = IR::U32{v.ir.Select(v.ir.FPIsNan(op_a), v.ir.Imm32(0U), result)}; 194 result = IR::U32{v.ir.Select(v.ir.FPIsNan(op_a), v.ir.Imm32(0U), result)};
195 } else { 195 } else {
196 result = IR::U64{v.ir.Select(v.ir.FPIsNan(op_a), v.ir.Imm64(0ULL), result)}; 196 result = IR::U64{v.ir.Select(v.ir.FPIsNan(op_a), v.ir.Imm64(0UL), result)};
197 } 197 }
198 } 198 }
199 199
@@ -211,6 +211,7 @@ void TranslateF2I(TranslatorVisitor& v, u64 insn, const IR::F16F32F64& src_a) {
211 211
212void TranslatorVisitor::F2I_reg(u64 insn) { 212void TranslatorVisitor::F2I_reg(u64 insn) {
213 union { 213 union {
214 u64 raw;
214 F2I base; 215 F2I base;
215 BitField<20, 8, IR::Reg> src_reg; 216 BitField<20, 8, IR::Reg> src_reg;
216 } const f2i{insn}; 217 } const f2i{insn};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp
index 18561bc9c..fa2a7807b 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp
@@ -24,9 +24,9 @@ void FFMA(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, const IR::F32& s
24 const IR::F32 op_b{v.ir.FPAbsNeg(src_b, false, neg_b)}; 24 const IR::F32 op_b{v.ir.FPAbsNeg(src_b, false, neg_b)};
25 const IR::F32 op_c{v.ir.FPAbsNeg(src_c, false, neg_c)}; 25 const IR::F32 op_c{v.ir.FPAbsNeg(src_c, false, neg_c)};
26 const IR::FpControl fp_control{ 26 const IR::FpControl fp_control{
27 .no_contraction{true}, 27 .no_contraction = true,
28 .rounding{CastFpRounding(fp_rounding)}, 28 .rounding = CastFpRounding(fp_rounding),
29 .fmz_mode{CastFmzMode(fmz_mode)}, 29 .fmz_mode = CastFmzMode(fmz_mode),
30 }; 30 };
31 IR::F32 value{v.ir.FPFma(op_a, op_b, op_c, fp_control)}; 31 IR::F32 value{v.ir.FPFma(op_a, op_b, op_c, fp_control)};
32 if (fmz_mode == FmzMode::FMZ && !sat) { 32 if (fmz_mode == FmzMode::FMZ && !sat) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp
index 343d91032..8ae437528 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp
@@ -27,9 +27,9 @@ void FMNMX(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
27 const IR::F32 op_b{v.ir.FPAbsNeg(src_b, fmnmx.abs_b != 0, fmnmx.negate_b != 0)}; 27 const IR::F32 op_b{v.ir.FPAbsNeg(src_b, fmnmx.abs_b != 0, fmnmx.negate_b != 0)};
28 28
29 const IR::FpControl control{ 29 const IR::FpControl control{
30 .no_contraction{false}, 30 .no_contraction = false,
31 .rounding{IR::FpRounding::DontCare}, 31 .rounding = IR::FpRounding::DontCare,
32 .fmz_mode{fmnmx.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None}, 32 .fmz_mode = (fmnmx.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None),
33 }; 33 };
34 IR::F32 max{v.ir.FPMax(op_a, op_b, control)}; 34 IR::F32 max{v.ir.FPMax(op_a, op_b, control)};
35 IR::F32 min{v.ir.FPMin(op_a, op_b, control)}; 35 IR::F32 min{v.ir.FPMin(op_a, op_b, control)};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp
index 72f0a18ae..06226b7ce 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp
@@ -64,9 +64,9 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, FmzMode fmz_mode
64 } 64 }
65 const IR::F32 op_b{v.ir.FPAbsNeg(src_b, false, neg_b)}; 65 const IR::F32 op_b{v.ir.FPAbsNeg(src_b, false, neg_b)};
66 const IR::FpControl fp_control{ 66 const IR::FpControl fp_control{
67 .no_contraction{true}, 67 .no_contraction = true,
68 .rounding{CastFpRounding(fp_rounding)}, 68 .rounding = CastFpRounding(fp_rounding),
69 .fmz_mode{CastFmzMode(fmz_mode)}, 69 .fmz_mode = CastFmzMode(fmz_mode),
70 }; 70 };
71 IR::F32 value{v.ir.FPMul(op_a, op_b, fp_control)}; 71 IR::F32 value{v.ir.FPMul(op_a, op_b, fp_control)};
72 if (fmz_mode == FmzMode::FMZ && !sat) { 72 if (fmz_mode == FmzMode::FMZ && !sat) {
@@ -124,4 +124,4 @@ void TranslatorVisitor::FMUL32I(u64 insn) {
124 fmul32i.sat != 0, fmul32i.cc != 0, false); 124 fmul32i.sat != 0, fmul32i.cc != 0, false);
125} 125}
126 126
127} // namespace Shader::Maxwell \ No newline at end of file 127} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_set_predicate.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_set_predicate.cpp
index 8ff9db843..5f93a1513 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_set_predicate.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_set_predicate.cpp
@@ -29,9 +29,9 @@ void FSETP(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
29 const IR::F32 op_a{v.ir.FPAbsNeg(v.F(fsetp.src_a_reg), fsetp.abs_a != 0, fsetp.negate_a != 0)}; 29 const IR::F32 op_a{v.ir.FPAbsNeg(v.F(fsetp.src_a_reg), fsetp.abs_a != 0, fsetp.negate_a != 0)};
30 const IR::F32 op_b = v.ir.FPAbsNeg(src_b, fsetp.abs_b != 0, fsetp.negate_b != 0); 30 const IR::F32 op_b = v.ir.FPAbsNeg(src_b, fsetp.abs_b != 0, fsetp.negate_b != 0);
31 const IR::FpControl control{ 31 const IR::FpControl control{
32 .no_contraction{false}, 32 .no_contraction = false,
33 .rounding{IR::FpRounding::DontCare}, 33 .rounding = IR::FpRounding::DontCare,
34 .fmz_mode{fsetp.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None}, 34 .fmz_mode = (fsetp.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None),
35 }; 35 };
36 36
37 const BooleanOp bop{fsetp.bop}; 37 const BooleanOp bop{fsetp.bop};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_swizzled_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_swizzled_add.cpp
index e42921a21..7550a8d4c 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_swizzled_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_swizzled_add.cpp
@@ -28,9 +28,9 @@ void TranslatorVisitor::FSWZADD(u64 insn) {
28 const IR::U32 swizzle{ir.Imm32(static_cast<u32>(fswzadd.swizzle))}; 28 const IR::U32 swizzle{ir.Imm32(static_cast<u32>(fswzadd.swizzle))};
29 29
30 const IR::FpControl fp_control{ 30 const IR::FpControl fp_control{
31 .no_contraction{false}, 31 .no_contraction = false,
32 .rounding{CastFpRounding(fswzadd.round)}, 32 .rounding = CastFpRounding(fswzadd.round),
33 .fmz_mode{fswzadd.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None}, 33 .fmz_mode = (fswzadd.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None),
34 }; 34 };
35 35
36 const IR::F32 result{ir.FSwizzleAdd(src_a, src_b, swizzle, fp_control)}; 36 const IR::F32 result{ir.FSwizzleAdd(src_a, src_b, swizzle, fp_control)};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_add.cpp
index 03e7bf047..f2738a93b 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_add.cpp
@@ -34,9 +34,9 @@ void HADD2(TranslatorVisitor& v, u64 insn, Merge merge, bool ftz, bool sat, bool
34 rhs_b = v.ir.FPAbsNeg(rhs_b, abs_b, neg_b); 34 rhs_b = v.ir.FPAbsNeg(rhs_b, abs_b, neg_b);
35 35
36 const IR::FpControl fp_control{ 36 const IR::FpControl fp_control{
37 .no_contraction{true}, 37 .no_contraction = true,
38 .rounding{IR::FpRounding::DontCare}, 38 .rounding = IR::FpRounding::DontCare,
39 .fmz_mode{ftz ? IR::FmzMode::FTZ : IR::FmzMode::None}, 39 .fmz_mode = (ftz ? IR::FmzMode::FTZ : IR::FmzMode::None),
40 }; 40 };
41 IR::F16F32F64 lhs{v.ir.FPAdd(lhs_a, lhs_b, fp_control)}; 41 IR::F16F32F64 lhs{v.ir.FPAdd(lhs_a, lhs_b, fp_control)};
42 IR::F16F32F64 rhs{v.ir.FPAdd(rhs_a, rhs_b, fp_control)}; 42 IR::F16F32F64 rhs{v.ir.FPAdd(rhs_a, rhs_b, fp_control)};
@@ -102,8 +102,9 @@ void TranslatorVisitor::HADD2_imm(u64 insn) {
102 BitField<20, 9, u64> low; 102 BitField<20, 9, u64> low;
103 } const hadd2{insn}; 103 } const hadd2{insn};
104 104
105 const u32 imm{static_cast<u32>(hadd2.low << 6) | ((hadd2.neg_low != 0 ? 1 : 0) << 15) | 105 const u32 imm{
106 static_cast<u32>(hadd2.high << 22) | ((hadd2.neg_high != 0 ? 1 : 0) << 31)}; 106 static_cast<u32>(hadd2.low << 6) | static_cast<u32>((hadd2.neg_low != 0 ? 1 : 0) << 15) |
107 static_cast<u32>(hadd2.high << 22) | static_cast<u32>((hadd2.neg_high != 0 ? 1 : 0) << 31)};
107 HADD2(*this, insn, hadd2.sat != 0, false, false, Swizzle::H1_H0, ir.Imm32(imm)); 108 HADD2(*this, insn, hadd2.sat != 0, false, false, Swizzle::H1_H0, ir.Imm32(imm));
108} 109}
109 110
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_fused_multiply_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_fused_multiply_add.cpp
index 8b234bd6a..fd7986701 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_fused_multiply_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_fused_multiply_add.cpp
@@ -41,9 +41,9 @@ void HFMA2(TranslatorVisitor& v, u64 insn, Merge merge, Swizzle swizzle_a, bool
41 rhs_c = v.ir.FPAbsNeg(rhs_c, false, neg_c); 41 rhs_c = v.ir.FPAbsNeg(rhs_c, false, neg_c);
42 42
43 const IR::FpControl fp_control{ 43 const IR::FpControl fp_control{
44 .no_contraction{true}, 44 .no_contraction = true,
45 .rounding{IR::FpRounding::DontCare}, 45 .rounding = IR::FpRounding::DontCare,
46 .fmz_mode{HalfPrecision2FmzMode(precision)}, 46 .fmz_mode = HalfPrecision2FmzMode(precision),
47 }; 47 };
48 IR::F16F32F64 lhs{v.ir.FPFma(lhs_a, lhs_b, lhs_c, fp_control)}; 48 IR::F16F32F64 lhs{v.ir.FPFma(lhs_a, lhs_b, lhs_c, fp_control)};
49 IR::F16F32F64 rhs{v.ir.FPFma(rhs_a, rhs_b, rhs_c, fp_control)}; 49 IR::F16F32F64 rhs{v.ir.FPFma(rhs_a, rhs_b, rhs_c, fp_control)};
@@ -143,8 +143,9 @@ void TranslatorVisitor::HFMA2_imm(u64 insn) {
143 BitField<57, 2, HalfPrecision> precision; 143 BitField<57, 2, HalfPrecision> precision;
144 } const hfma2{insn}; 144 } const hfma2{insn};
145 145
146 const u32 imm{static_cast<u32>(hfma2.low << 6) | ((hfma2.neg_low != 0 ? 1 : 0) << 15) | 146 const u32 imm{
147 static_cast<u32>(hfma2.high << 22) | ((hfma2.neg_high != 0 ? 1 : 0) << 31)}; 147 static_cast<u32>(hfma2.low << 6) | static_cast<u32>((hfma2.neg_low != 0 ? 1 : 0) << 15) |
148 static_cast<u32>(hfma2.high << 22) | static_cast<u32>((hfma2.neg_high != 0 ? 1 : 0) << 31)};
148 149
149 HFMA2(*this, insn, false, hfma2.neg_c != 0, Swizzle::H1_H0, hfma2.swizzle_c, ir.Imm32(imm), 150 HFMA2(*this, insn, false, hfma2.neg_c != 0, Swizzle::H1_H0, hfma2.swizzle_c, ir.Imm32(imm),
150 GetReg39(insn), hfma2.saturate != 0, hfma2.precision); 151 GetReg39(insn), hfma2.saturate != 0, hfma2.precision);
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_multiply.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_multiply.cpp
index 2451a6ef6..3f548ce76 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_multiply.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_multiply.cpp
@@ -35,9 +35,9 @@ void HMUL2(TranslatorVisitor& v, u64 insn, Merge merge, bool sat, bool abs_a, bo
35 rhs_b = v.ir.FPAbsNeg(rhs_b, abs_b, neg_b); 35 rhs_b = v.ir.FPAbsNeg(rhs_b, abs_b, neg_b);
36 36
37 const IR::FpControl fp_control{ 37 const IR::FpControl fp_control{
38 .no_contraction{true}, 38 .no_contraction = true,
39 .rounding{IR::FpRounding::DontCare}, 39 .rounding = IR::FpRounding::DontCare,
40 .fmz_mode{HalfPrecision2FmzMode(precision)}, 40 .fmz_mode = HalfPrecision2FmzMode(precision),
41 }; 41 };
42 IR::F16F32F64 lhs{v.ir.FPMul(lhs_a, lhs_b, fp_control)}; 42 IR::F16F32F64 lhs{v.ir.FPMul(lhs_a, lhs_b, fp_control)};
43 IR::F16F32F64 rhs{v.ir.FPMul(rhs_a, rhs_b, fp_control)}; 43 IR::F16F32F64 rhs{v.ir.FPMul(rhs_a, rhs_b, fp_control)};
@@ -119,8 +119,9 @@ void TranslatorVisitor::HMUL2_imm(u64 insn) {
119 BitField<44, 1, u64> abs_a; 119 BitField<44, 1, u64> abs_a;
120 } const hmul2{insn}; 120 } const hmul2{insn};
121 121
122 const u32 imm{static_cast<u32>(hmul2.low << 6) | ((hmul2.neg_low != 0 ? 1 : 0) << 15) | 122 const u32 imm{
123 static_cast<u32>(hmul2.high << 22) | ((hmul2.neg_high != 0 ? 1 : 0) << 31)}; 123 static_cast<u32>(hmul2.low << 6) | static_cast<u32>((hmul2.neg_low != 0 ? 1 : 0) << 15) |
124 static_cast<u32>(hmul2.high << 22) | static_cast<u32>((hmul2.neg_high != 0 ? 1 : 0) << 31)};
124 HMUL2(*this, insn, hmul2.sat != 0, hmul2.abs_a != 0, hmul2.neg_a != 0, false, false, 125 HMUL2(*this, insn, hmul2.sat != 0, hmul2.abs_a != 0, hmul2.neg_a != 0, false, false,
125 Swizzle::H1_H0, ir.Imm32(imm)); 126 Swizzle::H1_H0, ir.Imm32(imm));
126} 127}
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set.cpp
index 7f1f4b88c..cca5b831f 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set.cpp
@@ -41,9 +41,9 @@ void HSET2(TranslatorVisitor& v, u64 insn, const IR::U32& src_b, bool bf, bool f
41 rhs_b = v.ir.FPAbsNeg(rhs_b, abs_b, neg_b); 41 rhs_b = v.ir.FPAbsNeg(rhs_b, abs_b, neg_b);
42 42
43 const IR::FpControl control{ 43 const IR::FpControl control{
44 .no_contraction{false}, 44 .no_contraction = false,
45 .rounding{IR::FpRounding::DontCare}, 45 .rounding = IR::FpRounding::DontCare,
46 .fmz_mode{ftz ? IR::FmzMode::FTZ : IR::FmzMode::None}, 46 .fmz_mode = (ftz ? IR::FmzMode::FTZ : IR::FmzMode::None),
47 }; 47 };
48 48
49 IR::U1 pred{v.ir.GetPred(hset2.pred)}; 49 IR::U1 pred{v.ir.GetPred(hset2.pred)};
@@ -106,8 +106,9 @@ void TranslatorVisitor::HSET2_imm(u64 insn) {
106 BitField<20, 9, u64> low; 106 BitField<20, 9, u64> low;
107 } const hset2{insn}; 107 } const hset2{insn};
108 108
109 const u32 imm{static_cast<u32>(hset2.low << 6) | ((hset2.neg_low != 0 ? 1 : 0) << 15) | 109 const u32 imm{
110 static_cast<u32>(hset2.high << 22) | ((hset2.neg_high != 0 ? 1 : 0) << 31)}; 110 static_cast<u32>(hset2.low << 6) | static_cast<u32>((hset2.neg_low != 0 ? 1 : 0) << 15) |
111 static_cast<u32>(hset2.high << 22) | static_cast<u32>((hset2.neg_high != 0 ? 1 : 0) << 31)};
111 112
112 HSET2(*this, insn, ir.Imm32(imm), hset2.bf != 0, hset2.ftz != 0, false, false, hset2.compare_op, 113 HSET2(*this, insn, ir.Imm32(imm), hset2.bf != 0, hset2.ftz != 0, false, false, hset2.compare_op,
113 Swizzle::H1_H0); 114 Swizzle::H1_H0);
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set_predicate.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set_predicate.cpp
index 3e2a23c92..b3931dae3 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set_predicate.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set_predicate.cpp
@@ -43,9 +43,9 @@ void HSETP2(TranslatorVisitor& v, u64 insn, const IR::U32& src_b, bool neg_b, bo
43 rhs_b = v.ir.FPAbsNeg(rhs_b, abs_b, neg_b); 43 rhs_b = v.ir.FPAbsNeg(rhs_b, abs_b, neg_b);
44 44
45 const IR::FpControl control{ 45 const IR::FpControl control{
46 .no_contraction{false}, 46 .no_contraction = false,
47 .rounding{IR::FpRounding::DontCare}, 47 .rounding = IR::FpRounding::DontCare,
48 .fmz_mode{hsetp2.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None}, 48 .fmz_mode = (hsetp2.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None),
49 }; 49 };
50 50
51 IR::U1 pred{v.ir.GetPred(hsetp2.pred)}; 51 IR::U1 pred{v.ir.GetPred(hsetp2.pred)};
@@ -106,8 +106,10 @@ void TranslatorVisitor::HSETP2_imm(u64 insn) {
106 BitField<20, 9, u64> low; 106 BitField<20, 9, u64> low;
107 } const hsetp2{insn}; 107 } const hsetp2{insn};
108 108
109 const u32 imm{static_cast<u32>(hsetp2.low << 6) | ((hsetp2.neg_low != 0 ? 1 : 0) << 15) | 109 const u32 imm{static_cast<u32>(hsetp2.low << 6) |
110 static_cast<u32>(hsetp2.high << 22) | ((hsetp2.neg_high != 0 ? 1 : 0) << 31)}; 110 static_cast<u32>((hsetp2.neg_low != 0 ? 1 : 0) << 15) |
111 static_cast<u32>(hsetp2.high << 22) |
112 static_cast<u32>((hsetp2.neg_high != 0 ? 1 : 0) << 31)};
111 113
112 HSETP2(*this, insn, ir.Imm32(imm), false, false, Swizzle::H1_H0, hsetp2.compare_op, 114 HSETP2(*this, insn, ir.Imm32(imm), false, false, Swizzle::H1_H0, hsetp2.compare_op,
113 hsetp2.h_and != 0); 115 hsetp2.h_and != 0);
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
index 30b570ce4..88bbac0a5 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
@@ -49,7 +49,7 @@ void TranslatorVisitor::L(IR::Reg dest_reg, const IR::U64& value) {
49 } 49 }
50 const IR::Value result{ir.UnpackUint2x32(value)}; 50 const IR::Value result{ir.UnpackUint2x32(value)};
51 for (int i = 0; i < 2; i++) { 51 for (int i = 0; i < 2; i++) {
52 X(dest_reg + i, IR::U32{ir.CompositeExtract(result, i)}); 52 X(dest_reg + i, IR::U32{ir.CompositeExtract(result, static_cast<size_t>(i))});
53 } 53 }
54} 54}
55 55
@@ -63,7 +63,7 @@ void TranslatorVisitor::D(IR::Reg dest_reg, const IR::F64& value) {
63 } 63 }
64 const IR::Value result{ir.UnpackDouble2x32(value)}; 64 const IR::Value result{ir.UnpackDouble2x32(value)};
65 for (int i = 0; i < 2; i++) { 65 for (int i = 0; i < 2; i++) {
66 X(dest_reg + i, IR::U32{ir.CompositeExtract(result, i)}); 66 X(dest_reg + i, IR::U32{ir.CompositeExtract(result, static_cast<size_t>(i))});
67 } 67 }
68} 68}
69 69
@@ -156,7 +156,7 @@ IR::F64 TranslatorVisitor::GetDoubleCbuf(u64 insn) {
156 const auto [binding, offset_value]{CbufAddr(insn)}; 156 const auto [binding, offset_value]{CbufAddr(insn)};
157 const bool unaligned{cbuf.unaligned != 0}; 157 const bool unaligned{cbuf.unaligned != 0};
158 const u32 offset{offset_value.U32()}; 158 const u32 offset{offset_value.U32()};
159 const IR::Value addr{unaligned ? offset | 4 : (offset & ~7) | 4}; 159 const IR::Value addr{unaligned ? offset | 4u : (offset & ~7u) | 4u};
160 160
161 const IR::U32 value{ir.GetCbuf(binding, IR::U32{addr})}; 161 const IR::U32 value{ir.GetCbuf(binding, IR::U32{addr})};
162 const IR::U32 lower_bits{CbufLowerBits(ir, unaligned, binding, offset)}; 162 const IR::U32 lower_bits{CbufLowerBits(ir, unaligned, binding, offset)};
@@ -200,7 +200,7 @@ IR::F32 TranslatorVisitor::GetFloatImm20(u64 insn) {
200 BitField<20, 19, u64> value; 200 BitField<20, 19, u64> value;
201 BitField<56, 1, u64> is_negative; 201 BitField<56, 1, u64> is_negative;
202 } const imm{insn}; 202 } const imm{insn};
203 const u32 sign_bit{imm.is_negative != 0 ? (1ULL << 31) : 0}; 203 const u32 sign_bit{static_cast<u32>(imm.is_negative != 0 ? (1ULL << 31) : 0)};
204 const u32 value{static_cast<u32>(imm.value) << 12}; 204 const u32 value{static_cast<u32>(imm.value) << 12};
205 return ir.Imm32(Common::BitCast<f32>(value | sign_bit)); 205 return ir.Imm32(Common::BitCast<f32>(value | sign_bit));
206} 206}
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp
index 1493e1815..8ffd84867 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add.cpp
@@ -68,7 +68,6 @@ void IADD(TranslatorVisitor& v, u64 insn, IR::U32 op_b) {
68 } const iadd{insn}; 68 } const iadd{insn};
69 69
70 const bool po{iadd.three_for_po == 3}; 70 const bool po{iadd.three_for_po == 3};
71 const bool neg_a{!po && iadd.neg_a != 0};
72 if (!po && iadd.neg_b != 0) { 71 if (!po && iadd.neg_b != 0) {
73 op_b = v.ir.INeg(op_b); 72 op_b = v.ir.INeg(op_b);
74 } 73 }
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp
index e8b5ae1d2..5a0fc36a0 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp
@@ -131,7 +131,7 @@ void I2F(TranslatorVisitor& v, u64 insn, IR::U32U64 src) {
131 } 131 }
132 const IR::Value vector{v.ir.UnpackDouble2x32(value)}; 132 const IR::Value vector{v.ir.UnpackDouble2x32(value)};
133 for (int i = 0; i < 2; ++i) { 133 for (int i = 0; i < 2; ++i) {
134 v.X(i2f.dest_reg + i, IR::U32{v.ir.CompositeExtract(vector, i)}); 134 v.X(i2f.dest_reg + i, IR::U32{v.ir.CompositeExtract(vector, static_cast<size_t>(i))});
135 } 135 }
136 break; 136 break;
137 } 137 }
@@ -170,4 +170,4 @@ void TranslatorVisitor::I2F_imm(u64 insn) {
170 } 170 }
171} 171}
172 172
173} // namespace Shader::Maxwell \ No newline at end of file 173} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/load_constant.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/load_constant.cpp
index ae3ecea32..2300088e3 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/load_constant.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/load_constant.cpp
@@ -50,7 +50,7 @@ void TranslatorVisitor::LDC(u64 insn) {
50 } 50 }
51 const IR::Value vector{ir.GetCbuf(index, offset, 64, false)}; 51 const IR::Value vector{ir.GetCbuf(index, offset, 64, false)};
52 for (int i = 0; i < 2; ++i) { 52 for (int i = 0; i < 2; ++i) {
53 X(ldc.dest_reg + i, IR::U32{ir.CompositeExtract(vector, i)}); 53 X(ldc.dest_reg + i, IR::U32{ir.CompositeExtract(vector, static_cast<size_t>(i))});
54 } 54 }
55 break; 55 break;
56 } 56 }
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_local_shared.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_local_shared.cpp
index 68963c8ea..e24b49721 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_local_shared.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_local_shared.cpp
@@ -40,7 +40,6 @@ std::pair<int, bool> GetSize(u64 insn) {
40 BitField<48, 3, Size> size; 40 BitField<48, 3, Size> size;
41 } const encoding{insn}; 41 } const encoding{insn};
42 42
43 const Size nnn = encoding.size;
44 switch (encoding.size) { 43 switch (encoding.size) {
45 case Size::U8: 44 case Size::U8:
46 return {8, false}; 45 return {8, false};
@@ -99,7 +98,7 @@ void TranslatorVisitor::LDL(u64 insn) {
99 case 32: 98 case 32:
100 case 64: 99 case 64:
101 case 128: 100 case 128:
102 if (!IR::IsAligned(dest, bit_size / 32)) { 101 if (!IR::IsAligned(dest, static_cast<size_t>(bit_size / 32))) {
103 throw NotImplementedException("Unaligned destination register {}", dest); 102 throw NotImplementedException("Unaligned destination register {}", dest);
104 } 103 }
105 X(dest, ir.LoadLocal(word_offset)); 104 X(dest, ir.LoadLocal(word_offset));
@@ -123,11 +122,11 @@ void TranslatorVisitor::LDS(u64 insn) {
123 break; 122 break;
124 case 64: 123 case 64:
125 case 128: 124 case 128:
126 if (!IR::IsAligned(dest, bit_size / 32)) { 125 if (!IR::IsAligned(dest, static_cast<size_t>(bit_size / 32))) {
127 throw NotImplementedException("Unaligned destination register {}", dest); 126 throw NotImplementedException("Unaligned destination register {}", dest);
128 } 127 }
129 for (int element = 0; element < bit_size / 32; ++element) { 128 for (int element = 0; element < bit_size / 32; ++element) {
130 X(dest + element, IR::U32{ir.CompositeExtract(value, element)}); 129 X(dest + element, IR::U32{ir.CompositeExtract(value, static_cast<size_t>(element))});
131 } 130 }
132 break; 131 break;
133 } 132 }
@@ -156,7 +155,7 @@ void TranslatorVisitor::STL(u64 insn) {
156 case 32: 155 case 32:
157 case 64: 156 case 64:
158 case 128: 157 case 128:
159 if (!IR::IsAligned(reg, bit_size / 32)) { 158 if (!IR::IsAligned(reg, static_cast<size_t>(bit_size / 32))) {
160 throw NotImplementedException("Unaligned source register"); 159 throw NotImplementedException("Unaligned source register");
161 } 160 }
162 ir.WriteLocal(word_offset, src); 161 ir.WriteLocal(word_offset, src);
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_memory.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_memory.cpp
index 71688b1d7..36c5cff2f 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_memory.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_memory.cpp
@@ -114,7 +114,7 @@ void TranslatorVisitor::LDG(u64 insn) {
114 } 114 }
115 const IR::Value vector{ir.LoadGlobal64(address)}; 115 const IR::Value vector{ir.LoadGlobal64(address)};
116 for (int i = 0; i < 2; ++i) { 116 for (int i = 0; i < 2; ++i) {
117 X(dest_reg + i, IR::U32{ir.CompositeExtract(vector, i)}); 117 X(dest_reg + i, IR::U32{ir.CompositeExtract(vector, static_cast<size_t>(i))});
118 } 118 }
119 break; 119 break;
120 } 120 }
@@ -125,7 +125,7 @@ void TranslatorVisitor::LDG(u64 insn) {
125 } 125 }
126 const IR::Value vector{ir.LoadGlobal128(address)}; 126 const IR::Value vector{ir.LoadGlobal128(address)};
127 for (int i = 0; i < 4; ++i) { 127 for (int i = 0; i < 4; ++i) {
128 X(dest_reg + i, IR::U32{ir.CompositeExtract(vector, i)}); 128 X(dest_reg + i, IR::U32{ir.CompositeExtract(vector, static_cast<size_t>(i))});
129 } 129 }
130 break; 130 break;
131 } 131 }
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch.cpp
index b2da079f9..95d416586 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch.cpp
@@ -199,7 +199,7 @@ void Impl(TranslatorVisitor& v, u64 insn, bool aoffi, Blod blod, bool lc,
199 if (tex.dc != 0) { 199 if (tex.dc != 0) {
200 value = element < 3 ? IR::F32{sample} : v.ir.Imm32(1.0f); 200 value = element < 3 ? IR::F32{sample} : v.ir.Imm32(1.0f);
201 } else { 201 } else {
202 value = IR::F32{v.ir.CompositeExtract(sample, element)}; 202 value = IR::F32{v.ir.CompositeExtract(sample, static_cast<size_t>(element))};
203 } 203 }
204 v.F(dest_reg, value); 204 v.F(dest_reg, value);
205 ++dest_reg; 205 ++dest_reg;
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp
index d5fda20f4..fe2c7db85 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp
@@ -53,7 +53,7 @@ constexpr std::array RGBA_LUT{
53 R | G | B | A, // 53 R | G | B | A, //
54}; 54};
55 55
56void CheckAlignment(IR::Reg reg, int alignment) { 56void CheckAlignment(IR::Reg reg, size_t alignment) {
57 if (!IR::IsAligned(reg, alignment)) { 57 if (!IR::IsAligned(reg, alignment)) {
58 throw NotImplementedException("Unaligned source register {}", reg); 58 throw NotImplementedException("Unaligned source register {}", reg);
59 } 59 }
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp
index beab515ad..2ba9c1018 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp
@@ -37,7 +37,7 @@ union Encoding {
37 BitField<36, 13, u64> cbuf_offset; 37 BitField<36, 13, u64> cbuf_offset;
38}; 38};
39 39
40void CheckAlignment(IR::Reg reg, int alignment) { 40void CheckAlignment(IR::Reg reg, size_t alignment) {
41 if (!IR::IsAligned(reg, alignment)) { 41 if (!IR::IsAligned(reg, alignment)) {
42 throw NotImplementedException("Unaligned source register {}", reg); 42 throw NotImplementedException("Unaligned source register {}", reg);
43 } 43 }
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp
index 623b8fc23..0863bdfcd 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp
@@ -56,7 +56,7 @@ union Encoding {
56 BitField<53, 4, u64> encoding; 56 BitField<53, 4, u64> encoding;
57}; 57};
58 58
59void CheckAlignment(IR::Reg reg, int alignment) { 59void CheckAlignment(IR::Reg reg, size_t alignment) {
60 if (!IR::IsAligned(reg, alignment)) { 60 if (!IR::IsAligned(reg, alignment)) {
61 throw NotImplementedException("Unaligned source register {}", reg); 61 throw NotImplementedException("Unaligned source register {}", reg);
62 } 62 }
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_query.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_query.cpp
index 8c7e04bca..0459e5473 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_query.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_query.cpp
@@ -54,7 +54,7 @@ void Impl(TranslatorVisitor& v, u64 insn, std::optional<u32> cbuf_offset) {
54 if (((txq.mask >> element) & 1) == 0) { 54 if (((txq.mask >> element) & 1) == 0) {
55 continue; 55 continue;
56 } 56 }
57 v.X(dest_reg, IR::U32{v.ir.CompositeExtract(query, element)}); 57 v.X(dest_reg, IR::U32{v.ir.CompositeExtract(query, static_cast<size_t>(element))});
58 ++dest_reg; 58 ++dest_reg;
59 } 59 }
60} 60}
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/video_set_predicate.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/video_set_predicate.cpp
index af13b3fcc..ec5e74f6d 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/video_set_predicate.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/video_set_predicate.cpp
@@ -69,7 +69,6 @@ void TranslatorVisitor::VSETP(u64 insn) {
69 const IR::U32 src_b{is_b_imm ? ir.Imm32(static_cast<u32>(vsetp.src_b_imm)) : GetReg20(insn)}; 69 const IR::U32 src_b{is_b_imm ? ir.Imm32(static_cast<u32>(vsetp.src_b_imm)) : GetReg20(insn)};
70 70
71 const u32 a_selector{static_cast<u32>(vsetp.src_a_selector)}; 71 const u32 a_selector{static_cast<u32>(vsetp.src_a_selector)};
72 const u32 b_selector{is_b_imm ? 0U : static_cast<u32>(vsetp.src_b_selector)};
73 const VideoWidth a_width{vsetp.src_a_width}; 72 const VideoWidth a_width{vsetp.src_a_width};
74 const VideoWidth b_width{GetVideoSourceWidth(vsetp.src_b_width, is_b_imm)}; 73 const VideoWidth b_width{GetVideoSourceWidth(vsetp.src_b_width, is_b_imm)};
75 74
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
index 1c03ee82a..edbfcd308 100644
--- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
+++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
@@ -6,6 +6,7 @@
6#include "shader_recompiler/frontend/ir/microinstruction.h" 6#include "shader_recompiler/frontend/ir/microinstruction.h"
7#include "shader_recompiler/frontend/ir/modifiers.h" 7#include "shader_recompiler/frontend/ir/modifiers.h"
8#include "shader_recompiler/frontend/ir/program.h" 8#include "shader_recompiler/frontend/ir/program.h"
9#include "shader_recompiler/ir_opt/passes.h"
9#include "shader_recompiler/shader_info.h" 10#include "shader_recompiler/shader_info.h"
10 11
11namespace Shader::Optimization { 12namespace Shader::Optimization {
@@ -22,8 +23,8 @@ void AddConstantBufferDescriptor(Info& info, u32 index, u32 count) {
22 auto& cbufs{info.constant_buffer_descriptors}; 23 auto& cbufs{info.constant_buffer_descriptors};
23 cbufs.insert(std::ranges::lower_bound(cbufs, index, {}, &ConstantBufferDescriptor::index), 24 cbufs.insert(std::ranges::lower_bound(cbufs, index, {}, &ConstantBufferDescriptor::index),
24 ConstantBufferDescriptor{ 25 ConstantBufferDescriptor{
25 .index{index}, 26 .index = index,
26 .count{1}, 27 .count = 1,
27 }); 28 });
28} 29}
29 30
@@ -91,7 +92,7 @@ void SetAttribute(Info& info, IR::Attribute attribute) {
91} 92}
92 93
93void VisitUsages(Info& info, IR::Inst& inst) { 94void VisitUsages(Info& info, IR::Inst& inst) {
94 switch (inst.Opcode()) { 95 switch (inst.GetOpcode()) {
95 case IR::Opcode::CompositeConstructF16x2: 96 case IR::Opcode::CompositeConstructF16x2:
96 case IR::Opcode::CompositeConstructF16x3: 97 case IR::Opcode::CompositeConstructF16x3:
97 case IR::Opcode::CompositeConstructF16x4: 98 case IR::Opcode::CompositeConstructF16x4:
@@ -209,7 +210,7 @@ void VisitUsages(Info& info, IR::Inst& inst) {
209 default: 210 default:
210 break; 211 break;
211 } 212 }
212 switch (inst.Opcode()) { 213 switch (inst.GetOpcode()) {
213 case IR::Opcode::GetCbufU8: 214 case IR::Opcode::GetCbufU8:
214 case IR::Opcode::GetCbufS8: 215 case IR::Opcode::GetCbufS8:
215 case IR::Opcode::UndefU8: 216 case IR::Opcode::UndefU8:
@@ -236,7 +237,7 @@ void VisitUsages(Info& info, IR::Inst& inst) {
236 default: 237 default:
237 break; 238 break;
238 } 239 }
239 switch (inst.Opcode()) { 240 switch (inst.GetOpcode()) {
240 case IR::Opcode::GetCbufU16: 241 case IR::Opcode::GetCbufU16:
241 case IR::Opcode::GetCbufS16: 242 case IR::Opcode::GetCbufS16:
242 case IR::Opcode::UndefU16: 243 case IR::Opcode::UndefU16:
@@ -271,7 +272,7 @@ void VisitUsages(Info& info, IR::Inst& inst) {
271 default: 272 default:
272 break; 273 break;
273 } 274 }
274 switch (inst.Opcode()) { 275 switch (inst.GetOpcode()) {
275 case IR::Opcode::UndefU64: 276 case IR::Opcode::UndefU64:
276 case IR::Opcode::LoadGlobalU8: 277 case IR::Opcode::LoadGlobalU8:
277 case IR::Opcode::LoadGlobalS8: 278 case IR::Opcode::LoadGlobalS8:
@@ -314,7 +315,7 @@ void VisitUsages(Info& info, IR::Inst& inst) {
314 default: 315 default:
315 break; 316 break;
316 } 317 }
317 switch (inst.Opcode()) { 318 switch (inst.GetOpcode()) {
318 case IR::Opcode::DemoteToHelperInvocation: 319 case IR::Opcode::DemoteToHelperInvocation:
319 info.uses_demote_to_helper_invocation = true; 320 info.uses_demote_to_helper_invocation = true;
320 break; 321 break;
@@ -361,7 +362,7 @@ void VisitUsages(Info& info, IR::Inst& inst) {
361 } else { 362 } else {
362 throw NotImplementedException("Constant buffer with non-immediate index"); 363 throw NotImplementedException("Constant buffer with non-immediate index");
363 } 364 }
364 switch (inst.Opcode()) { 365 switch (inst.GetOpcode()) {
365 case IR::Opcode::GetCbufU8: 366 case IR::Opcode::GetCbufU8:
366 case IR::Opcode::GetCbufS8: 367 case IR::Opcode::GetCbufS8:
367 info.used_constant_buffer_types |= IR::Type::U8; 368 info.used_constant_buffer_types |= IR::Type::U8;
@@ -443,7 +444,7 @@ void VisitUsages(Info& info, IR::Inst& inst) {
443} 444}
444 445
445void VisitFpModifiers(Info& info, IR::Inst& inst) { 446void VisitFpModifiers(Info& info, IR::Inst& inst) {
446 switch (inst.Opcode()) { 447 switch (inst.GetOpcode()) {
447 case IR::Opcode::FPAdd16: 448 case IR::Opcode::FPAdd16:
448 case IR::Opcode::FPFma16: 449 case IR::Opcode::FPFma16:
449 case IR::Opcode::FPMul16: 450 case IR::Opcode::FPMul16:
@@ -540,7 +541,6 @@ void GatherInfoFromHeader(Environment& env, Info& info) {
540 info.stores_position |= header.vtg.omap_systemb.position != 0; 541 info.stores_position |= header.vtg.omap_systemb.position != 0;
541 } 542 }
542} 543}
543
544} // Anonymous namespace 544} // Anonymous namespace
545 545
546void CollectShaderInfoPass(Environment& env, IR::Program& program) { 546void CollectShaderInfoPass(Environment& env, IR::Program& program) {
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
index 1720d7a09..61fbbe04c 100644
--- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
+++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
@@ -58,7 +58,7 @@ bool FoldCommutative(IR::Inst& inst, ImmFn&& imm_fn) {
58 } 58 }
59 if (is_lhs_immediate && !is_rhs_immediate) { 59 if (is_lhs_immediate && !is_rhs_immediate) {
60 IR::Inst* const rhs_inst{rhs.InstRecursive()}; 60 IR::Inst* const rhs_inst{rhs.InstRecursive()};
61 if (rhs_inst->Opcode() == inst.Opcode() && rhs_inst->Arg(1).IsImmediate()) { 61 if (rhs_inst->GetOpcode() == inst.GetOpcode() && rhs_inst->Arg(1).IsImmediate()) {
62 const auto combined{imm_fn(Arg<T>(lhs), Arg<T>(rhs_inst->Arg(1)))}; 62 const auto combined{imm_fn(Arg<T>(lhs), Arg<T>(rhs_inst->Arg(1)))};
63 inst.SetArg(0, rhs_inst->Arg(0)); 63 inst.SetArg(0, rhs_inst->Arg(0));
64 inst.SetArg(1, IR::Value{combined}); 64 inst.SetArg(1, IR::Value{combined});
@@ -70,7 +70,7 @@ bool FoldCommutative(IR::Inst& inst, ImmFn&& imm_fn) {
70 } 70 }
71 if (!is_lhs_immediate && is_rhs_immediate) { 71 if (!is_lhs_immediate && is_rhs_immediate) {
72 const IR::Inst* const lhs_inst{lhs.InstRecursive()}; 72 const IR::Inst* const lhs_inst{lhs.InstRecursive()};
73 if (lhs_inst->Opcode() == inst.Opcode() && lhs_inst->Arg(1).IsImmediate()) { 73 if (lhs_inst->GetOpcode() == inst.GetOpcode() && lhs_inst->Arg(1).IsImmediate()) {
74 const auto combined{imm_fn(Arg<T>(rhs), Arg<T>(lhs_inst->Arg(1)))}; 74 const auto combined{imm_fn(Arg<T>(rhs), Arg<T>(lhs_inst->Arg(1)))};
75 inst.SetArg(0, lhs_inst->Arg(0)); 75 inst.SetArg(0, lhs_inst->Arg(0));
76 inst.SetArg(1, IR::Value{combined}); 76 inst.SetArg(1, IR::Value{combined});
@@ -123,7 +123,8 @@ bool FoldXmadMultiply(IR::Block& block, IR::Inst& inst) {
123 return false; 123 return false;
124 } 124 }
125 IR::Inst* const lhs_shl{lhs_arg.InstRecursive()}; 125 IR::Inst* const lhs_shl{lhs_arg.InstRecursive()};
126 if (lhs_shl->Opcode() != IR::Opcode::ShiftLeftLogical32 || lhs_shl->Arg(1) != IR::Value{16U}) { 126 if (lhs_shl->GetOpcode() != IR::Opcode::ShiftLeftLogical32 ||
127 lhs_shl->Arg(1) != IR::Value{16U}) {
127 return false; 128 return false;
128 } 129 }
129 if (lhs_shl->Arg(0).IsImmediate()) { 130 if (lhs_shl->Arg(0).IsImmediate()) {
@@ -131,7 +132,7 @@ bool FoldXmadMultiply(IR::Block& block, IR::Inst& inst) {
131 } 132 }
132 IR::Inst* const lhs_mul{lhs_shl->Arg(0).InstRecursive()}; 133 IR::Inst* const lhs_mul{lhs_shl->Arg(0).InstRecursive()};
133 IR::Inst* const rhs_mul{rhs_arg.InstRecursive()}; 134 IR::Inst* const rhs_mul{rhs_arg.InstRecursive()};
134 if (lhs_mul->Opcode() != IR::Opcode::IMul32 || rhs_mul->Opcode() != IR::Opcode::IMul32) { 135 if (lhs_mul->GetOpcode() != IR::Opcode::IMul32 || rhs_mul->GetOpcode() != IR::Opcode::IMul32) {
135 return false; 136 return false;
136 } 137 }
137 if (lhs_mul->Arg(1).Resolve() != rhs_mul->Arg(1).Resolve()) { 138 if (lhs_mul->Arg(1).Resolve() != rhs_mul->Arg(1).Resolve()) {
@@ -143,10 +144,10 @@ bool FoldXmadMultiply(IR::Block& block, IR::Inst& inst) {
143 } 144 }
144 IR::Inst* const lhs_bfe{lhs_mul->Arg(0).InstRecursive()}; 145 IR::Inst* const lhs_bfe{lhs_mul->Arg(0).InstRecursive()};
145 IR::Inst* const rhs_bfe{rhs_mul->Arg(0).InstRecursive()}; 146 IR::Inst* const rhs_bfe{rhs_mul->Arg(0).InstRecursive()};
146 if (lhs_bfe->Opcode() != IR::Opcode::BitFieldUExtract) { 147 if (lhs_bfe->GetOpcode() != IR::Opcode::BitFieldUExtract) {
147 return false; 148 return false;
148 } 149 }
149 if (rhs_bfe->Opcode() != IR::Opcode::BitFieldUExtract) { 150 if (rhs_bfe->GetOpcode() != IR::Opcode::BitFieldUExtract) {
150 return false; 151 return false;
151 } 152 }
152 if (lhs_bfe->Arg(1) != IR::Value{16U} || lhs_bfe->Arg(2) != IR::Value{16U}) { 153 if (lhs_bfe->Arg(1) != IR::Value{16U} || lhs_bfe->Arg(2) != IR::Value{16U}) {
@@ -194,8 +195,9 @@ void FoldISub32(IR::Inst& inst) {
194 // ISub32 is generally used to subtract two constant buffers, compare and replace this with 195 // ISub32 is generally used to subtract two constant buffers, compare and replace this with
195 // zero if they equal. 196 // zero if they equal.
196 const auto equal_cbuf{[](IR::Inst* a, IR::Inst* b) { 197 const auto equal_cbuf{[](IR::Inst* a, IR::Inst* b) {
197 return a->Opcode() == IR::Opcode::GetCbufU32 && b->Opcode() == IR::Opcode::GetCbufU32 && 198 return a->GetOpcode() == IR::Opcode::GetCbufU32 &&
198 a->Arg(0) == b->Arg(0) && a->Arg(1) == b->Arg(1); 199 b->GetOpcode() == IR::Opcode::GetCbufU32 && a->Arg(0) == b->Arg(0) &&
200 a->Arg(1) == b->Arg(1);
199 }}; 201 }};
200 IR::Inst* op_a{inst.Arg(0).InstRecursive()}; 202 IR::Inst* op_a{inst.Arg(0).InstRecursive()};
201 IR::Inst* op_b{inst.Arg(1).InstRecursive()}; 203 IR::Inst* op_b{inst.Arg(1).InstRecursive()};
@@ -204,15 +206,15 @@ void FoldISub32(IR::Inst& inst) {
204 return; 206 return;
205 } 207 }
206 // It's also possible a value is being added to a cbuf and then subtracted 208 // It's also possible a value is being added to a cbuf and then subtracted
207 if (op_b->Opcode() == IR::Opcode::IAdd32) { 209 if (op_b->GetOpcode() == IR::Opcode::IAdd32) {
208 // Canonicalize local variables to simplify the following logic 210 // Canonicalize local variables to simplify the following logic
209 std::swap(op_a, op_b); 211 std::swap(op_a, op_b);
210 } 212 }
211 if (op_b->Opcode() != IR::Opcode::GetCbufU32) { 213 if (op_b->GetOpcode() != IR::Opcode::GetCbufU32) {
212 return; 214 return;
213 } 215 }
214 IR::Inst* const inst_cbuf{op_b}; 216 IR::Inst* const inst_cbuf{op_b};
215 if (op_a->Opcode() != IR::Opcode::IAdd32) { 217 if (op_a->GetOpcode() != IR::Opcode::IAdd32) {
216 return; 218 return;
217 } 219 }
218 IR::Value add_op_a{op_a->Arg(0)}; 220 IR::Value add_op_a{op_a->Arg(0)};
@@ -250,7 +252,8 @@ void FoldFPMul32(IR::Inst& inst) {
250 } 252 }
251 IR::Inst* const lhs_op{lhs_value.InstRecursive()}; 253 IR::Inst* const lhs_op{lhs_value.InstRecursive()};
252 IR::Inst* const rhs_op{rhs_value.InstRecursive()}; 254 IR::Inst* const rhs_op{rhs_value.InstRecursive()};
253 if (lhs_op->Opcode() != IR::Opcode::FPMul32 || rhs_op->Opcode() != IR::Opcode::FPRecip32) { 255 if (lhs_op->GetOpcode() != IR::Opcode::FPMul32 ||
256 rhs_op->GetOpcode() != IR::Opcode::FPRecip32) {
254 return; 257 return;
255 } 258 }
256 const IR::Value recip_source{rhs_op->Arg(0)}; 259 const IR::Value recip_source{rhs_op->Arg(0)};
@@ -260,8 +263,8 @@ void FoldFPMul32(IR::Inst& inst) {
260 } 263 }
261 IR::Inst* const attr_a{recip_source.InstRecursive()}; 264 IR::Inst* const attr_a{recip_source.InstRecursive()};
262 IR::Inst* const attr_b{lhs_mul_source.InstRecursive()}; 265 IR::Inst* const attr_b{lhs_mul_source.InstRecursive()};
263 if (attr_a->Opcode() != IR::Opcode::GetAttribute || 266 if (attr_a->GetOpcode() != IR::Opcode::GetAttribute ||
264 attr_b->Opcode() != IR::Opcode::GetAttribute) { 267 attr_b->GetOpcode() != IR::Opcode::GetAttribute) {
265 return; 268 return;
266 } 269 }
267 if (attr_a->Arg(0).Attribute() == attr_b->Arg(0).Attribute()) { 270 if (attr_a->Arg(0).Attribute() == attr_b->Arg(0).Attribute()) {
@@ -304,7 +307,7 @@ void FoldLogicalNot(IR::Inst& inst) {
304 return; 307 return;
305 } 308 }
306 IR::Inst* const arg{value.InstRecursive()}; 309 IR::Inst* const arg{value.InstRecursive()};
307 if (arg->Opcode() == IR::Opcode::LogicalNot) { 310 if (arg->GetOpcode() == IR::Opcode::LogicalNot) {
308 inst.ReplaceUsesWith(arg->Arg(0)); 311 inst.ReplaceUsesWith(arg->Arg(0));
309 } 312 }
310} 313}
@@ -317,12 +320,12 @@ void FoldBitCast(IR::Inst& inst, IR::Opcode reverse) {
317 return; 320 return;
318 } 321 }
319 IR::Inst* const arg_inst{value.InstRecursive()}; 322 IR::Inst* const arg_inst{value.InstRecursive()};
320 if (arg_inst->Opcode() == reverse) { 323 if (arg_inst->GetOpcode() == reverse) {
321 inst.ReplaceUsesWith(arg_inst->Arg(0)); 324 inst.ReplaceUsesWith(arg_inst->Arg(0));
322 return; 325 return;
323 } 326 }
324 if constexpr (op == IR::Opcode::BitCastF32U32) { 327 if constexpr (op == IR::Opcode::BitCastF32U32) {
325 if (arg_inst->Opcode() == IR::Opcode::GetCbufU32) { 328 if (arg_inst->GetOpcode() == IR::Opcode::GetCbufU32) {
326 // Replace the bitcast with a typed constant buffer read 329 // Replace the bitcast with a typed constant buffer read
327 inst.ReplaceOpcode(IR::Opcode::GetCbufF32); 330 inst.ReplaceOpcode(IR::Opcode::GetCbufF32);
328 inst.SetArg(0, arg_inst->Arg(0)); 331 inst.SetArg(0, arg_inst->Arg(0));
@@ -338,7 +341,7 @@ void FoldInverseFunc(IR::Inst& inst, IR::Opcode reverse) {
338 return; 341 return;
339 } 342 }
340 IR::Inst* const arg_inst{value.InstRecursive()}; 343 IR::Inst* const arg_inst{value.InstRecursive()};
341 if (arg_inst->Opcode() == reverse) { 344 if (arg_inst->GetOpcode() == reverse) {
342 inst.ReplaceUsesWith(arg_inst->Arg(0)); 345 inst.ReplaceUsesWith(arg_inst->Arg(0));
343 return; 346 return;
344 } 347 }
@@ -347,7 +350,7 @@ void FoldInverseFunc(IR::Inst& inst, IR::Opcode reverse) {
347template <typename Func, size_t... I> 350template <typename Func, size_t... I>
348IR::Value EvalImmediates(const IR::Inst& inst, Func&& func, std::index_sequence<I...>) { 351IR::Value EvalImmediates(const IR::Inst& inst, Func&& func, std::index_sequence<I...>) {
349 using Traits = LambdaTraits<decltype(func)>; 352 using Traits = LambdaTraits<decltype(func)>;
350 return IR::Value{func(Arg<Traits::ArgType<I>>(inst.Arg(I))...)}; 353 return IR::Value{func(Arg<typename Traits::template ArgType<I>>(inst.Arg(I))...)};
351} 354}
352 355
353void FoldBranchConditional(IR::Inst& inst) { 356void FoldBranchConditional(IR::Inst& inst) {
@@ -357,7 +360,7 @@ void FoldBranchConditional(IR::Inst& inst) {
357 return; 360 return;
358 } 361 }
359 const IR::Inst* cond_inst{cond.InstRecursive()}; 362 const IR::Inst* cond_inst{cond.InstRecursive()};
360 if (cond_inst->Opcode() == IR::Opcode::LogicalNot) { 363 if (cond_inst->GetOpcode() == IR::Opcode::LogicalNot) {
361 const IR::Value true_label{inst.Arg(1)}; 364 const IR::Value true_label{inst.Arg(1)};
362 const IR::Value false_label{inst.Arg(2)}; 365 const IR::Value false_label{inst.Arg(2)};
363 // Remove negation on the conditional (take the parameter out of LogicalNot) and swap 366 // Remove negation on the conditional (take the parameter out of LogicalNot) and swap
@@ -371,10 +374,10 @@ void FoldBranchConditional(IR::Inst& inst) {
371std::optional<IR::Value> FoldCompositeExtractImpl(IR::Value inst_value, IR::Opcode insert, 374std::optional<IR::Value> FoldCompositeExtractImpl(IR::Value inst_value, IR::Opcode insert,
372 IR::Opcode construct, u32 first_index) { 375 IR::Opcode construct, u32 first_index) {
373 IR::Inst* const inst{inst_value.InstRecursive()}; 376 IR::Inst* const inst{inst_value.InstRecursive()};
374 if (inst->Opcode() == construct) { 377 if (inst->GetOpcode() == construct) {
375 return inst->Arg(first_index); 378 return inst->Arg(first_index);
376 } 379 }
377 if (inst->Opcode() != insert) { 380 if (inst->GetOpcode() != insert) {
378 return std::nullopt; 381 return std::nullopt;
379 } 382 }
380 IR::Value value_index{inst->Arg(2)}; 383 IR::Value value_index{inst->Arg(2)};
@@ -410,7 +413,7 @@ void FoldCompositeExtract(IR::Inst& inst, IR::Opcode construct, IR::Opcode inser
410} 413}
411 414
412void ConstantPropagation(IR::Block& block, IR::Inst& inst) { 415void ConstantPropagation(IR::Block& block, IR::Inst& inst) {
413 switch (inst.Opcode()) { 416 switch (inst.GetOpcode()) {
414 case IR::Opcode::GetRegister: 417 case IR::Opcode::GetRegister:
415 return FoldGetRegister(inst); 418 return FoldGetRegister(inst);
416 case IR::Opcode::GetPred: 419 case IR::Opcode::GetPred:
diff --git a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp
index 0858a0bdd..90a65dd16 100644
--- a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp
+++ b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp
@@ -57,7 +57,7 @@ struct StorageInfo {
57 57
58/// Returns true when the instruction is a global memory instruction 58/// Returns true when the instruction is a global memory instruction
59bool IsGlobalMemory(const IR::Inst& inst) { 59bool IsGlobalMemory(const IR::Inst& inst) {
60 switch (inst.Opcode()) { 60 switch (inst.GetOpcode()) {
61 case IR::Opcode::LoadGlobalS8: 61 case IR::Opcode::LoadGlobalS8:
62 case IR::Opcode::LoadGlobalU8: 62 case IR::Opcode::LoadGlobalU8:
63 case IR::Opcode::LoadGlobalS16: 63 case IR::Opcode::LoadGlobalS16:
@@ -80,7 +80,7 @@ bool IsGlobalMemory(const IR::Inst& inst) {
80 80
81/// Returns true when the instruction is a global memory instruction 81/// Returns true when the instruction is a global memory instruction
82bool IsGlobalMemoryWrite(const IR::Inst& inst) { 82bool IsGlobalMemoryWrite(const IR::Inst& inst) {
83 switch (inst.Opcode()) { 83 switch (inst.GetOpcode()) {
84 case IR::Opcode::WriteGlobalS8: 84 case IR::Opcode::WriteGlobalS8:
85 case IR::Opcode::WriteGlobalU8: 85 case IR::Opcode::WriteGlobalU8:
86 case IR::Opcode::WriteGlobalS16: 86 case IR::Opcode::WriteGlobalS16:
@@ -140,7 +140,7 @@ bool MeetsBias(const StorageBufferAddr& storage_buffer, const Bias& bias) noexce
140void DiscardGlobalMemory(IR::Block& block, IR::Inst& inst) { 140void DiscardGlobalMemory(IR::Block& block, IR::Inst& inst) {
141 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; 141 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
142 const IR::Value zero{u32{0}}; 142 const IR::Value zero{u32{0}};
143 switch (inst.Opcode()) { 143 switch (inst.GetOpcode()) {
144 case IR::Opcode::LoadGlobalS8: 144 case IR::Opcode::LoadGlobalS8:
145 case IR::Opcode::LoadGlobalU8: 145 case IR::Opcode::LoadGlobalU8:
146 case IR::Opcode::LoadGlobalS16: 146 case IR::Opcode::LoadGlobalS16:
@@ -164,7 +164,7 @@ void DiscardGlobalMemory(IR::Block& block, IR::Inst& inst) {
164 inst.Invalidate(); 164 inst.Invalidate();
165 break; 165 break;
166 default: 166 default:
167 throw LogicError("Invalid opcode to discard its global memory operation {}", inst.Opcode()); 167 throw LogicError("Invalid opcode to discard its global memory operation {}", inst.GetOpcode());
168 } 168 }
169} 169}
170 170
@@ -184,7 +184,7 @@ std::optional<LowAddrInfo> TrackLowAddress(IR::Inst* inst) {
184 // This address is expected to either be a PackUint2x32 or a IAdd64 184 // This address is expected to either be a PackUint2x32 or a IAdd64
185 IR::Inst* addr_inst{addr.InstRecursive()}; 185 IR::Inst* addr_inst{addr.InstRecursive()};
186 s32 imm_offset{0}; 186 s32 imm_offset{0};
187 if (addr_inst->Opcode() == IR::Opcode::IAdd64) { 187 if (addr_inst->GetOpcode() == IR::Opcode::IAdd64) {
188 // If it's an IAdd64, get the immediate offset it is applying and grab the address 188 // If it's an IAdd64, get the immediate offset it is applying and grab the address
189 // instruction. This expects for the instruction to be canonicalized having the address on 189 // instruction. This expects for the instruction to be canonicalized having the address on
190 // the first argument and the immediate offset on the second one. 190 // the first argument and the immediate offset on the second one.
@@ -200,7 +200,7 @@ std::optional<LowAddrInfo> TrackLowAddress(IR::Inst* inst) {
200 addr_inst = iadd_addr.Inst(); 200 addr_inst = iadd_addr.Inst();
201 } 201 }
202 // With IAdd64 handled, now PackUint2x32 is expected without exceptions 202 // With IAdd64 handled, now PackUint2x32 is expected without exceptions
203 if (addr_inst->Opcode() != IR::Opcode::PackUint2x32) { 203 if (addr_inst->GetOpcode() != IR::Opcode::PackUint2x32) {
204 return std::nullopt; 204 return std::nullopt;
205 } 205 }
206 // PackUint2x32 is expected to be generated from a vector 206 // PackUint2x32 is expected to be generated from a vector
@@ -210,20 +210,20 @@ std::optional<LowAddrInfo> TrackLowAddress(IR::Inst* inst) {
210 } 210 }
211 // This vector is expected to be a CompositeConstructU32x2 211 // This vector is expected to be a CompositeConstructU32x2
212 IR::Inst* const vector_inst{vector.InstRecursive()}; 212 IR::Inst* const vector_inst{vector.InstRecursive()};
213 if (vector_inst->Opcode() != IR::Opcode::CompositeConstructU32x2) { 213 if (vector_inst->GetOpcode() != IR::Opcode::CompositeConstructU32x2) {
214 return std::nullopt; 214 return std::nullopt;
215 } 215 }
216 // Grab the first argument from the CompositeConstructU32x2, this is the low address. 216 // Grab the first argument from the CompositeConstructU32x2, this is the low address.
217 return LowAddrInfo{ 217 return LowAddrInfo{
218 .value{IR::U32{vector_inst->Arg(0)}}, 218 .value{IR::U32{vector_inst->Arg(0)}},
219 .imm_offset{imm_offset}, 219 .imm_offset = imm_offset,
220 }; 220 };
221} 221}
222 222
223/// Tries to track the storage buffer address used by a global memory instruction 223/// Tries to track the storage buffer address used by a global memory instruction
224std::optional<StorageBufferAddr> Track(const IR::Value& value, const Bias* bias) { 224std::optional<StorageBufferAddr> Track(const IR::Value& value, const Bias* bias) {
225 const auto pred{[bias](const IR::Inst* inst) -> std::optional<StorageBufferAddr> { 225 const auto pred{[bias](const IR::Inst* inst) -> std::optional<StorageBufferAddr> {
226 if (inst->Opcode() != IR::Opcode::GetCbufU32) { 226 if (inst->GetOpcode() != IR::Opcode::GetCbufU32) {
227 return std::nullopt; 227 return std::nullopt;
228 } 228 }
229 const IR::Value index{inst->Arg(0)}; 229 const IR::Value index{inst->Arg(0)};
@@ -256,9 +256,9 @@ void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageInfo& info)
256 // NVN puts storage buffers in a specific range, we have to bias towards these addresses to 256 // NVN puts storage buffers in a specific range, we have to bias towards these addresses to
257 // avoid getting false positives 257 // avoid getting false positives
258 static constexpr Bias nvn_bias{ 258 static constexpr Bias nvn_bias{
259 .index{0}, 259 .index = 0,
260 .offset_begin{0x110}, 260 .offset_begin = 0x110,
261 .offset_end{0x610}, 261 .offset_end = 0x610,
262 }; 262 };
263 // Track the low address of the instruction 263 // Track the low address of the instruction
264 const std::optional<LowAddrInfo> low_addr_info{TrackLowAddress(&inst)}; 264 const std::optional<LowAddrInfo> low_addr_info{TrackLowAddress(&inst)};
@@ -286,8 +286,8 @@ void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageInfo& info)
286 info.set.insert(*storage_buffer); 286 info.set.insert(*storage_buffer);
287 info.to_replace.push_back(StorageInst{ 287 info.to_replace.push_back(StorageInst{
288 .storage_buffer{*storage_buffer}, 288 .storage_buffer{*storage_buffer},
289 .inst{&inst}, 289 .inst = &inst,
290 .block{&block}, 290 .block = &block,
291 }); 291 });
292} 292}
293 293
@@ -312,7 +312,7 @@ IR::U32 StorageOffset(IR::Block& block, IR::Inst& inst, StorageBufferAddr buffer
312/// Replace a global memory load instruction with its storage buffer equivalent 312/// Replace a global memory load instruction with its storage buffer equivalent
313void ReplaceLoad(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index, 313void ReplaceLoad(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index,
314 const IR::U32& offset) { 314 const IR::U32& offset) {
315 const IR::Opcode new_opcode{GlobalToStorage(inst.Opcode())}; 315 const IR::Opcode new_opcode{GlobalToStorage(inst.GetOpcode())};
316 const auto it{IR::Block::InstructionList::s_iterator_to(inst)}; 316 const auto it{IR::Block::InstructionList::s_iterator_to(inst)};
317 const IR::Value value{&*block.PrependNewInst(it, new_opcode, {storage_index, offset})}; 317 const IR::Value value{&*block.PrependNewInst(it, new_opcode, {storage_index, offset})};
318 inst.ReplaceUsesWith(value); 318 inst.ReplaceUsesWith(value);
@@ -321,7 +321,7 @@ void ReplaceLoad(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index,
321/// Replace a global memory write instruction with its storage buffer equivalent 321/// Replace a global memory write instruction with its storage buffer equivalent
322void ReplaceWrite(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index, 322void ReplaceWrite(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index,
323 const IR::U32& offset) { 323 const IR::U32& offset) {
324 const IR::Opcode new_opcode{GlobalToStorage(inst.Opcode())}; 324 const IR::Opcode new_opcode{GlobalToStorage(inst.GetOpcode())};
325 const auto it{IR::Block::InstructionList::s_iterator_to(inst)}; 325 const auto it{IR::Block::InstructionList::s_iterator_to(inst)};
326 block.PrependNewInst(it, new_opcode, {storage_index, offset, inst.Arg(1)}); 326 block.PrependNewInst(it, new_opcode, {storage_index, offset, inst.Arg(1)});
327 inst.Invalidate(); 327 inst.Invalidate();
@@ -330,7 +330,7 @@ void ReplaceWrite(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index
330/// Replace a global memory instruction with its storage buffer equivalent 330/// Replace a global memory instruction with its storage buffer equivalent
331void Replace(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index, 331void Replace(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index,
332 const IR::U32& offset) { 332 const IR::U32& offset) {
333 switch (inst.Opcode()) { 333 switch (inst.GetOpcode()) {
334 case IR::Opcode::LoadGlobalS8: 334 case IR::Opcode::LoadGlobalS8:
335 case IR::Opcode::LoadGlobalU8: 335 case IR::Opcode::LoadGlobalU8:
336 case IR::Opcode::LoadGlobalS16: 336 case IR::Opcode::LoadGlobalS16:
@@ -348,7 +348,7 @@ void Replace(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index,
348 case IR::Opcode::WriteGlobal128: 348 case IR::Opcode::WriteGlobal128:
349 return ReplaceWrite(block, inst, storage_index, offset); 349 return ReplaceWrite(block, inst, storage_index, offset);
350 default: 350 default:
351 throw InvalidArgument("Invalid global memory opcode {}", inst.Opcode()); 351 throw InvalidArgument("Invalid global memory opcode {}", inst.GetOpcode());
352 } 352 }
353} 353}
354} // Anonymous namespace 354} // Anonymous namespace
@@ -366,9 +366,9 @@ void GlobalMemoryToStorageBufferPass(IR::Program& program) {
366 u32 storage_index{}; 366 u32 storage_index{};
367 for (const StorageBufferAddr& storage_buffer : info.set) { 367 for (const StorageBufferAddr& storage_buffer : info.set) {
368 program.info.storage_buffers_descriptors.push_back({ 368 program.info.storage_buffers_descriptors.push_back({
369 .cbuf_index{storage_buffer.index}, 369 .cbuf_index = storage_buffer.index,
370 .cbuf_offset{storage_buffer.offset}, 370 .cbuf_offset = storage_buffer.offset,
371 .count{1}, 371 .count = 1,
372 .is_written{info.writes.contains(storage_buffer)}, 372 .is_written{info.writes.contains(storage_buffer)},
373 }); 373 });
374 ++storage_index; 374 ++storage_index;
diff --git a/src/shader_recompiler/ir_opt/identity_removal_pass.cpp b/src/shader_recompiler/ir_opt/identity_removal_pass.cpp
index 8790b48f2..38af72dfe 100644
--- a/src/shader_recompiler/ir_opt/identity_removal_pass.cpp
+++ b/src/shader_recompiler/ir_opt/identity_removal_pass.cpp
@@ -22,7 +22,8 @@ void IdentityRemovalPass(IR::Program& program) {
22 inst->SetArg(i, arg.Inst()->Arg(0)); 22 inst->SetArg(i, arg.Inst()->Arg(0));
23 } 23 }
24 } 24 }
25 if (inst->Opcode() == IR::Opcode::Identity || inst->Opcode() == IR::Opcode::Void) { 25 if (inst->GetOpcode() == IR::Opcode::Identity ||
26 inst->GetOpcode() == IR::Opcode::Void) {
26 to_invalidate.push_back(&*inst); 27 to_invalidate.push_back(&*inst);
27 inst = block->Instructions().erase(inst); 28 inst = block->Instructions().erase(inst);
28 } else { 29 } else {
diff --git a/src/shader_recompiler/ir_opt/lower_fp16_to_fp32.cpp b/src/shader_recompiler/ir_opt/lower_fp16_to_fp32.cpp
index 0d2c91ed6..52576b07f 100644
--- a/src/shader_recompiler/ir_opt/lower_fp16_to_fp32.cpp
+++ b/src/shader_recompiler/ir_opt/lower_fp16_to_fp32.cpp
@@ -123,7 +123,7 @@ IR::Opcode Replace(IR::Opcode op) {
123void LowerFp16ToFp32(IR::Program& program) { 123void LowerFp16ToFp32(IR::Program& program) {
124 for (IR::Block* const block : program.blocks) { 124 for (IR::Block* const block : program.blocks) {
125 for (IR::Inst& inst : block->Instructions()) { 125 for (IR::Inst& inst : block->Instructions()) {
126 inst.ReplaceOpcode(Replace(inst.Opcode())); 126 inst.ReplaceOpcode(Replace(inst.GetOpcode()));
127 } 127 }
128 } 128 }
129} 129}
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
index ca36253d1..346fcc377 100644
--- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
+++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
@@ -116,7 +116,7 @@ IR::Opcode UndefOpcode(IndirectBranchVariable) noexcept {
116} 116}
117 117
118[[nodiscard]] bool IsPhi(const IR::Inst& inst) noexcept { 118[[nodiscard]] bool IsPhi(const IR::Inst& inst) noexcept {
119 return inst.Opcode() == IR::Opcode::Phi; 119 return inst.GetOpcode() == IR::Opcode::Phi;
120} 120}
121 121
122enum class Status { 122enum class Status {
@@ -278,7 +278,7 @@ private:
278}; 278};
279 279
280void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) { 280void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) {
281 switch (inst.Opcode()) { 281 switch (inst.GetOpcode()) {
282 case IR::Opcode::SetRegister: 282 case IR::Opcode::SetRegister:
283 if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) { 283 if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) {
284 pass.WriteVariable(reg, block, inst.Arg(1)); 284 pass.WriteVariable(reg, block, inst.Arg(1));
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp
index 290ce4179..c8aee3d3d 100644
--- a/src/shader_recompiler/ir_opt/texture_pass.cpp
+++ b/src/shader_recompiler/ir_opt/texture_pass.cpp
@@ -30,7 +30,7 @@ struct TextureInst {
30using TextureInstVector = boost::container::small_vector<TextureInst, 24>; 30using TextureInstVector = boost::container::small_vector<TextureInst, 24>;
31 31
32IR::Opcode IndexedInstruction(const IR::Inst& inst) { 32IR::Opcode IndexedInstruction(const IR::Inst& inst) {
33 switch (inst.Opcode()) { 33 switch (inst.GetOpcode()) {
34 case IR::Opcode::BindlessImageSampleImplicitLod: 34 case IR::Opcode::BindlessImageSampleImplicitLod:
35 case IR::Opcode::BoundImageSampleImplicitLod: 35 case IR::Opcode::BoundImageSampleImplicitLod:
36 return IR::Opcode::ImageSampleImplicitLod; 36 return IR::Opcode::ImageSampleImplicitLod;
@@ -67,7 +67,7 @@ IR::Opcode IndexedInstruction(const IR::Inst& inst) {
67} 67}
68 68
69bool IsBindless(const IR::Inst& inst) { 69bool IsBindless(const IR::Inst& inst) {
70 switch (inst.Opcode()) { 70 switch (inst.GetOpcode()) {
71 case IR::Opcode::BindlessImageSampleImplicitLod: 71 case IR::Opcode::BindlessImageSampleImplicitLod:
72 case IR::Opcode::BindlessImageSampleExplicitLod: 72 case IR::Opcode::BindlessImageSampleExplicitLod:
73 case IR::Opcode::BindlessImageSampleDrefImplicitLod: 73 case IR::Opcode::BindlessImageSampleDrefImplicitLod:
@@ -91,7 +91,7 @@ bool IsBindless(const IR::Inst& inst) {
91 case IR::Opcode::BoundImageGradient: 91 case IR::Opcode::BoundImageGradient:
92 return false; 92 return false;
93 default: 93 default:
94 throw InvalidArgument("Invalid opcode {}", inst.Opcode()); 94 throw InvalidArgument("Invalid opcode {}", inst.GetOpcode());
95 } 95 }
96} 96}
97 97
@@ -100,7 +100,7 @@ bool IsTextureInstruction(const IR::Inst& inst) {
100} 100}
101 101
102std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) { 102std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) {
103 if (inst->Opcode() != IR::Opcode::GetCbufU32) { 103 if (inst->GetOpcode() != IR::Opcode::GetCbufU32) {
104 return std::nullopt; 104 return std::nullopt;
105 } 105 }
106 const IR::Value index{inst->Arg(0)}; 106 const IR::Value index{inst->Arg(0)};
@@ -134,14 +134,14 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) {
134 addr = *track_addr; 134 addr = *track_addr;
135 } else { 135 } else {
136 addr = ConstBufferAddr{ 136 addr = ConstBufferAddr{
137 .index{env.TextureBoundBuffer()}, 137 .index = env.TextureBoundBuffer(),
138 .offset{inst.Arg(0).U32()}, 138 .offset = inst.Arg(0).U32(),
139 }; 139 };
140 } 140 }
141 return TextureInst{ 141 return TextureInst{
142 .cbuf{addr}, 142 .cbuf{addr},
143 .inst{&inst}, 143 .inst = &inst,
144 .block{block}, 144 .block = block,
145 }; 145 };
146} 146}
147 147
@@ -211,7 +211,7 @@ void TexturePass(Environment& env, IR::Program& program) {
211 211
212 const auto& cbuf{texture_inst.cbuf}; 212 const auto& cbuf{texture_inst.cbuf};
213 auto flags{inst->Flags<IR::TextureInstInfo>()}; 213 auto flags{inst->Flags<IR::TextureInstInfo>()};
214 switch (inst->Opcode()) { 214 switch (inst->GetOpcode()) {
215 case IR::Opcode::ImageQueryDimensions: 215 case IR::Opcode::ImageQueryDimensions:
216 flags.type.Assign(env.ReadTextureType(cbuf.index, cbuf.offset)); 216 flags.type.Assign(env.ReadTextureType(cbuf.index, cbuf.offset));
217 inst->SetFlags(flags); 217 inst->SetFlags(flags);
@@ -235,16 +235,16 @@ void TexturePass(Environment& env, IR::Program& program) {
235 u32 index; 235 u32 index;
236 if (flags.type == TextureType::Buffer) { 236 if (flags.type == TextureType::Buffer) {
237 index = descriptors.Add(TextureBufferDescriptor{ 237 index = descriptors.Add(TextureBufferDescriptor{
238 .cbuf_index{cbuf.index}, 238 .cbuf_index = cbuf.index,
239 .cbuf_offset{cbuf.offset}, 239 .cbuf_offset = cbuf.offset,
240 .count{1}, 240 .count = 1,
241 }); 241 });
242 } else { 242 } else {
243 index = descriptors.Add(TextureDescriptor{ 243 index = descriptors.Add(TextureDescriptor{
244 .type{flags.type}, 244 .type = flags.type,
245 .cbuf_index{cbuf.index}, 245 .cbuf_index = cbuf.index,
246 .cbuf_offset{cbuf.offset}, 246 .cbuf_offset = cbuf.offset,
247 .count{1}, 247 .count = 1,
248 }); 248 });
249 } 249 }
250 inst->SetArg(0, IR::Value{index}); 250 inst->SetArg(0, IR::Value{index});
diff --git a/src/shader_recompiler/ir_opt/verification_pass.cpp b/src/shader_recompiler/ir_opt/verification_pass.cpp
index 4080b37cc..dbec96d84 100644
--- a/src/shader_recompiler/ir_opt/verification_pass.cpp
+++ b/src/shader_recompiler/ir_opt/verification_pass.cpp
@@ -14,14 +14,14 @@ namespace Shader::Optimization {
14static void ValidateTypes(const IR::Program& program) { 14static void ValidateTypes(const IR::Program& program) {
15 for (const auto& block : program.blocks) { 15 for (const auto& block : program.blocks) {
16 for (const IR::Inst& inst : *block) { 16 for (const IR::Inst& inst : *block) {
17 if (inst.Opcode() == IR::Opcode::Phi) { 17 if (inst.GetOpcode() == IR::Opcode::Phi) {
18 // Skip validation on phi nodes 18 // Skip validation on phi nodes
19 continue; 19 continue;
20 } 20 }
21 const size_t num_args{inst.NumArgs()}; 21 const size_t num_args{inst.NumArgs()};
22 for (size_t i = 0; i < num_args; ++i) { 22 for (size_t i = 0; i < num_args; ++i) {
23 const IR::Type t1{inst.Arg(i).Type()}; 23 const IR::Type t1{inst.Arg(i).Type()};
24 const IR::Type t2{IR::ArgTypeOf(inst.Opcode(), i)}; 24 const IR::Type t2{IR::ArgTypeOf(inst.GetOpcode(), i)};
25 if (!IR::AreTypesCompatible(t1, t2)) { 25 if (!IR::AreTypesCompatible(t1, t2)) {
26 throw LogicError("Invalid types in block:\n{}", IR::DumpBlock(*block)); 26 throw LogicError("Invalid types in block:\n{}", IR::DumpBlock(*block));
27 } 27 }