shader: Address Feedback
This commit is contained in:
		| @@ -510,7 +510,8 @@ void EmitContext::DefineOutputs(const Info& info) { | ||||
|         const Id type{TypeArray(F32[1], Constant(U32[1], 8U))}; | ||||
|         clip_distances = DefineOutput(*this, type, spv::BuiltIn::ClipDistance); | ||||
|     } | ||||
|     if (info.stores_viewport_index && !ignore_viewport_layer) { | ||||
|     if (info.stores_viewport_index && | ||||
|         (profile.support_viewport_index_layer_non_geometry || stage == Shader::Stage::Geometry)) { | ||||
|         if (stage == Stage::Fragment) { | ||||
|             throw NotImplementedException("Storing ViewportIndex in Fragment stage"); | ||||
|         } | ||||
|   | ||||
| @@ -134,8 +134,6 @@ public: | ||||
|  | ||||
|     std::vector<Id> interfaces; | ||||
|  | ||||
|     bool ignore_viewport_layer{}; | ||||
|  | ||||
| private: | ||||
|     void DefineCommonTypes(const Info& info); | ||||
|     void DefineCommonConstants(); | ||||
|   | ||||
| @@ -228,11 +228,9 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct | ||||
|     if (info.stores_viewport_index) { | ||||
|         ctx.AddCapability(spv::Capability::MultiViewport); | ||||
|         if (profile.support_viewport_index_layer_non_geometry && | ||||
|             ctx.stage == Shader::Stage::VertexB) { | ||||
|             ctx.stage != Shader::Stage::Geometry) { | ||||
|             ctx.AddExtension("SPV_EXT_shader_viewport_index_layer"); | ||||
|             ctx.AddCapability(spv::Capability::ShaderViewportIndexLayerEXT); | ||||
|         } else { | ||||
|             ctx.ignore_viewport_layer = true; | ||||
|         } | ||||
|     } | ||||
|     if (!profile.support_vertex_instance_id && (info.loads_instance_id || info.loads_vertex_id)) { | ||||
|   | ||||
| @@ -28,7 +28,9 @@ void EmitSelectionMerge(EmitContext& ctx, Id merge_label); | ||||
| void EmitReturn(EmitContext& ctx); | ||||
| void EmitUnreachable(EmitContext& ctx); | ||||
| void EmitDemoteToHelperInvocation(EmitContext& ctx, Id continue_label); | ||||
| void EmitMemoryBarrier(EmitContext& ctx, IR::Inst* inst); | ||||
| void EmitMemoryBarrierWorkgroupLevel(EmitContext& ctx); | ||||
| void EmitMemoryBarrierDeviceLevel(EmitContext& ctx); | ||||
| void EmitMemoryBarrierSystemLevel(EmitContext& ctx); | ||||
| void EmitPrologue(EmitContext& ctx); | ||||
| void EmitEpilogue(EmitContext& ctx); | ||||
| void EmitGetRegister(EmitContext& ctx); | ||||
| @@ -60,14 +62,6 @@ void EmitSetZFlag(EmitContext& ctx); | ||||
| void EmitSetSFlag(EmitContext& ctx); | ||||
| void EmitSetCFlag(EmitContext& ctx); | ||||
| void EmitSetOFlag(EmitContext& ctx); | ||||
| void EmitGetFCSMFlag(EmitContext& ctx); | ||||
| void EmitGetTAFlag(EmitContext& ctx); | ||||
| void EmitGetTRFlag(EmitContext& ctx); | ||||
| void EmitGetMXFlag(EmitContext& ctx); | ||||
| void EmitSetFCSMFlag(EmitContext& ctx); | ||||
| void EmitSetTAFlag(EmitContext& ctx); | ||||
| void EmitSetTRFlag(EmitContext& ctx); | ||||
| void EmitSetMXFlag(EmitContext& ctx); | ||||
| Id EmitWorkgroupId(EmitContext& ctx); | ||||
| Id EmitLocalInvocationId(EmitContext& ctx); | ||||
| Id EmitLoadLocal(EmitContext& ctx, Id word_offset); | ||||
|   | ||||
| @@ -7,34 +7,27 @@ | ||||
|  | ||||
| namespace Shader::Backend::SPIRV { | ||||
| namespace { | ||||
| spv::Scope MemoryScopeToSpirVScope(IR::MemoryScope scope) { | ||||
|     switch (scope) { | ||||
|     case IR::MemoryScope::Warp: | ||||
|         return spv::Scope::Subgroup; | ||||
|     case IR::MemoryScope::Workgroup: | ||||
|         return spv::Scope::Workgroup; | ||||
|     case IR::MemoryScope::Device: | ||||
|         return spv::Scope::Device; | ||||
|     case IR::MemoryScope::System: | ||||
|         return spv::Scope::CrossDevice; | ||||
|     case IR::MemoryScope::DontCare: | ||||
|         return spv::Scope::Invocation; | ||||
|     default: | ||||
|         throw NotImplementedException("Unknown memory scope!"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| } // namespace | ||||
|  | ||||
| void EmitMemoryBarrier(EmitContext& ctx, IR::Inst* inst) { | ||||
|     const auto info{inst->Flags<IR::BarrierInstInfo>()}; | ||||
| void EmitMemoryBarrierImpl(EmitContext& ctx, spv::Scope scope) { | ||||
|     const auto semantics = | ||||
|         spv::MemorySemanticsMask::AcquireRelease | spv::MemorySemanticsMask::UniformMemory | | ||||
|         spv::MemorySemanticsMask::WorkgroupMemory | spv::MemorySemanticsMask::AtomicCounterMemory | | ||||
|         spv::MemorySemanticsMask::ImageMemory; | ||||
|     const auto scope = MemoryScopeToSpirVScope(info.scope); | ||||
|     ctx.OpMemoryBarrier(ctx.Constant(ctx.U32[1], static_cast<u32>(scope)), | ||||
|                         ctx.Constant(ctx.U32[1], static_cast<u32>(semantics))); | ||||
| } | ||||
|  | ||||
| } // Anonymous namespace | ||||
|  | ||||
| void EmitMemoryBarrierWorkgroupLevel(EmitContext& ctx) { | ||||
|     EmitMemoryBarrierImpl(ctx, spv::Scope::Workgroup); | ||||
| } | ||||
|  | ||||
| void EmitMemoryBarrierDeviceLevel(EmitContext& ctx) { | ||||
|     EmitMemoryBarrierImpl(ctx, spv::Scope::Device); | ||||
| } | ||||
|  | ||||
| void EmitMemoryBarrierSystemLevel(EmitContext& ctx) { | ||||
|     EmitMemoryBarrierImpl(ctx, spv::Scope::CrossDevice); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Backend::SPIRV | ||||
|   | ||||
| @@ -58,7 +58,10 @@ std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | ||||
|         return ctx.OpAccessChain(ctx.output_f32, ctx.clip_distances, clip_num); | ||||
|     } | ||||
|     case IR::Attribute::ViewportIndex: | ||||
|         return ctx.ignore_viewport_layer ? std::nullopt : std::optional<Id>{ctx.viewport_index}; | ||||
|         return (ctx.profile.support_viewport_index_layer_non_geometry || | ||||
|                 ctx.stage == Shader::Stage::Geometry) | ||||
|                    ? std::optional<Id>{ctx.viewport_index} | ||||
|                    : std::nullopt; | ||||
|     default: | ||||
|         throw NotImplementedException("Read attribute {}", attr); | ||||
|     } | ||||
| @@ -206,7 +209,7 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr) { | ||||
| } | ||||
|  | ||||
| void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value) { | ||||
|     auto output = OutputAttrPointer(ctx, attr); | ||||
|     const std::optional<Id> output{OutputAttrPointer(ctx, attr)}; | ||||
|     if (!output) { | ||||
|         return; | ||||
|     } | ||||
| @@ -263,38 +266,6 @@ void EmitSetOFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitGetFCSMFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitGetTAFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitGetTRFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitGetMXFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSetFCSMFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSetTAFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSetTRFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSetMXFlag(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| Id EmitWorkgroupId(EmitContext& ctx) { | ||||
|     return ctx.OpLoad(ctx.U32[3], ctx.workgroup_id); | ||||
| } | ||||
|   | ||||
| @@ -82,8 +82,17 @@ void IREmitter::SelectionMerge(Block* merge_block) { | ||||
|     Inst(Opcode::SelectionMerge, merge_block); | ||||
| } | ||||
|  | ||||
| void IREmitter::MemoryBarrier(BarrierInstInfo info) { | ||||
|     Inst(Opcode::MemoryBarrier, Flags{info}); | ||||
| void IREmitter::MemoryBarrier(MemoryScope scope) { | ||||
|     switch (scope) { | ||||
|     case MemoryScope::Workgroup: | ||||
|         Inst(Opcode::MemoryBarrierWorkgroupLevel); | ||||
|     case MemoryScope::Device: | ||||
|         Inst(Opcode::MemoryBarrierDeviceLevel); | ||||
|     case MemoryScope::System: | ||||
|         Inst(Opcode::MemoryBarrierSystemLevel); | ||||
|     default: | ||||
|         throw InvalidArgument("Invalid memory scope {}", scope); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void IREmitter::Return() { | ||||
| @@ -202,38 +211,6 @@ void IREmitter::SetOFlag(const U1& value) { | ||||
|     Inst(Opcode::SetOFlag, value); | ||||
| } | ||||
|  | ||||
| U1 IREmitter::GetFCSMFlag() { | ||||
|     return Inst<U1>(Opcode::GetFCSMFlag); | ||||
| } | ||||
|  | ||||
| U1 IREmitter::GetTAFlag() { | ||||
|     return Inst<U1>(Opcode::GetTAFlag); | ||||
| } | ||||
|  | ||||
| U1 IREmitter::GetTRFlag() { | ||||
|     return Inst<U1>(Opcode::GetTRFlag); | ||||
| } | ||||
|  | ||||
| U1 IREmitter::GetMXFlag() { | ||||
|     return Inst<U1>(Opcode::GetMXFlag); | ||||
| } | ||||
|  | ||||
| void IREmitter::SetFCSMFlag(const U1& value) { | ||||
|     Inst(Opcode::SetFCSMFlag, value); | ||||
| } | ||||
|  | ||||
| void IREmitter::SetTAFlag(const U1& value) { | ||||
|     Inst(Opcode::SetTAFlag, value); | ||||
| } | ||||
|  | ||||
| void IREmitter::SetTRFlag(const U1& value) { | ||||
|     Inst(Opcode::SetTRFlag, value); | ||||
| } | ||||
|  | ||||
| void IREmitter::SetMXFlag(const U1& value) { | ||||
|     Inst(Opcode::SetMXFlag, value); | ||||
| } | ||||
|  | ||||
| static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) { | ||||
|     switch (flow_test) { | ||||
|     case FlowTest::F: | ||||
| @@ -292,9 +269,9 @@ static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) { | ||||
|         return ir.LogicalOr(ir.GetSFlag(), ir.GetZFlag()); | ||||
|     case FlowTest::RGT: | ||||
|         return ir.LogicalAnd(ir.LogicalNot(ir.GetSFlag()), ir.LogicalNot(ir.GetZFlag())); | ||||
|  | ||||
|     case FlowTest::FCSM_TR: | ||||
|         return ir.LogicalAnd(ir.GetFCSMFlag(), ir.GetTRFlag()); | ||||
|         // LOG_WARNING(ShaderDecompiler, "FCSM_TR CC State (Stubbed)"); | ||||
|         return ir.Imm1(false); | ||||
|     case FlowTest::CSM_TA: | ||||
|     case FlowTest::CSM_TR: | ||||
|     case FlowTest::CSM_MX: | ||||
|   | ||||
| @@ -70,16 +70,6 @@ public: | ||||
|     void SetCFlag(const U1& value); | ||||
|     void SetOFlag(const U1& value); | ||||
|  | ||||
|     [[nodiscard]] U1 GetFCSMFlag(); | ||||
|     [[nodiscard]] U1 GetTAFlag(); | ||||
|     [[nodiscard]] U1 GetTRFlag(); | ||||
|     [[nodiscard]] U1 GetMXFlag(); | ||||
|  | ||||
|     void SetFCSMFlag(const U1& value); | ||||
|     void SetTAFlag(const U1& value); | ||||
|     void SetTRFlag(const U1& value); | ||||
|     void SetMXFlag(const U1& value); | ||||
|  | ||||
|     [[nodiscard]] U1 Condition(IR::Condition cond); | ||||
|     [[nodiscard]] U1 GetFlowTestResult(FlowTest test); | ||||
|  | ||||
| @@ -138,7 +128,7 @@ public: | ||||
|     [[nodiscard]] Value Select(const U1& condition, const Value& true_value, | ||||
|                                const Value& false_value); | ||||
|  | ||||
|     [[nodiscard]] void MemoryBarrier(BarrierInstInfo info); | ||||
|     [[nodiscard]] void MemoryBarrier(MemoryScope scope); | ||||
|  | ||||
|     template <typename Dest, typename Source> | ||||
|     [[nodiscard]] Dest BitCast(const Source& value); | ||||
|   | ||||
| @@ -25,13 +25,7 @@ enum class FpRounding : u8 { | ||||
|     RZ,       // Round towards zero | ||||
| }; | ||||
|  | ||||
| enum class MemoryScope : u32 { | ||||
|   DontCare, | ||||
|   Warp, | ||||
|   Workgroup, | ||||
|   Device, | ||||
|   System | ||||
| }; | ||||
| enum class MemoryScope : u32 { DontCare, Warp, Workgroup, Device, System }; | ||||
|  | ||||
| struct FpControl { | ||||
|     bool no_contraction{false}; | ||||
| @@ -40,11 +34,6 @@ struct FpControl { | ||||
| }; | ||||
| static_assert(sizeof(FpControl) <= sizeof(u32)); | ||||
|  | ||||
| union BarrierInstInfo { | ||||
|     u32 raw; | ||||
|     BitField<0, 3, MemoryScope> scope; | ||||
| }; | ||||
|  | ||||
| union TextureInstInfo { | ||||
|     u32 raw; | ||||
|     BitField<0, 8, TextureType> type; | ||||
|   | ||||
| @@ -17,7 +17,9 @@ OPCODE(Unreachable,                                         Void, | ||||
| OPCODE(DemoteToHelperInvocation,                            Void,           Label,                                                                          ) | ||||
|  | ||||
| // Barriers | ||||
| OPCODE(MemoryBarrier,                                       Void,                                                                                           ) | ||||
| OPCODE(MemoryBarrierWorkgroupLevel,                         Void,                                                                                           ) | ||||
| OPCODE(MemoryBarrierDeviceLevel,                            Void,                                                                                           ) | ||||
| OPCODE(MemoryBarrierSystemLevel,                            Void,                                                                                           ) | ||||
|  | ||||
| // Special operations | ||||
| OPCODE(Prologue,                                            Void,                                                                                           ) | ||||
| @@ -49,18 +51,10 @@ OPCODE(GetZFlag,                                            U1,             Void | ||||
| OPCODE(GetSFlag,                                            U1,             Void,                                                                           ) | ||||
| OPCODE(GetCFlag,                                            U1,             Void,                                                                           ) | ||||
| OPCODE(GetOFlag,                                            U1,             Void,                                                                           ) | ||||
| OPCODE(GetFCSMFlag,                                         U1,             Void,                                                                           ) | ||||
| OPCODE(GetTAFlag,                                           U1,             Void,                                                                           ) | ||||
| OPCODE(GetTRFlag,                                           U1,             Void,                                                                           ) | ||||
| OPCODE(GetMXFlag,                                           U1,             Void,                                                                           ) | ||||
| OPCODE(SetZFlag,                                            Void,           U1,                                                                             ) | ||||
| OPCODE(SetSFlag,                                            Void,           U1,                                                                             ) | ||||
| OPCODE(SetCFlag,                                            Void,           U1,                                                                             ) | ||||
| OPCODE(SetOFlag,                                            Void,           U1,                                                                             ) | ||||
| OPCODE(SetFCSMFlag,                                         Void,           U1,                                                                             ) | ||||
| OPCODE(SetTAFlag,                                           Void,           U1,                                                                             ) | ||||
| OPCODE(SetTRFlag,                                           Void,           U1,                                                                             ) | ||||
| OPCODE(SetMXFlag,                                           Void,           U1,                                                                             ) | ||||
| OPCODE(WorkgroupId,                                         U32x3,                                                                                          ) | ||||
| OPCODE(LocalInvocationId,                                   U32x3,                                                                                          ) | ||||
| OPCODE(LaneId,                                              U32,                                                                                            ) | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
| #include "common/bit_field.h" | ||||
| #include "common/common_types.h" | ||||
| #include "shader_recompiler/frontend/ir/modifiers.h" | ||||
| #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||||
| #include "shader_recompiler/frontend/maxwell/opcodes.h" | ||||
| #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||||
|  | ||||
| namespace Shader::Maxwell { | ||||
| namespace { | ||||
| @@ -21,28 +21,24 @@ enum class LocalScope : u64 { | ||||
| IR::MemoryScope LocalScopeToMemoryScope(LocalScope scope) { | ||||
|     switch (scope) { | ||||
|     case LocalScope::CTG: | ||||
|         return IR::MemoryScope::Warp; | ||||
|         return IR::MemoryScope::Workgroup; | ||||
|     case LocalScope::GL: | ||||
|         return IR::MemoryScope::Device; | ||||
|     case LocalScope::SYS: | ||||
|         return IR::MemoryScope::System; | ||||
|     case LocalScope::VC: | ||||
|         return IR::MemoryScope::Workgroup; // or should be device? | ||||
|     default: | ||||
|         throw NotImplementedException("Unimplemented Local Scope {}", scope); | ||||
|     } | ||||
| } | ||||
|  | ||||
| } // namespace | ||||
| } // Anonymous namespace | ||||
|  | ||||
| void TranslatorVisitor::MEMBAR(u64 inst) { | ||||
|     union { | ||||
|         u64 raw; | ||||
|         BitField<8, 2, LocalScope> scope; | ||||
|     } membar{inst}; | ||||
|     IR::BarrierInstInfo info{}; | ||||
|     info.scope.Assign(LocalScopeToMemoryScope(membar.scope)); | ||||
|     ir.MemoryBarrier(info); | ||||
|     ir.MemoryBarrier(LocalScopeToMemoryScope(membar.scope)); | ||||
| } | ||||
|  | ||||
| void TranslatorVisitor::DEPBAR() { | ||||
|   | ||||
| @@ -96,8 +96,10 @@ enum class SpecialRegister : u64 { | ||||
|     case SpecialRegister::SR_CTAID_Z: | ||||
|         return ir.WorkgroupIdZ(); | ||||
|     case SpecialRegister::SR_WSCALEFACTOR_XY: | ||||
|         // LOG_WARNING(ShaderDecompiler, "SR_WSCALEFACTOR_XY (Stubbed)"); | ||||
|         return ir.Imm32(Common::BitCast<u32>(1.0f)); | ||||
|     case SpecialRegister::SR_WSCALEFACTOR_Z: | ||||
|         // LOG_WARNING(ShaderDecompiler, "SR_WSCALEFACTOR_Z (Stubbed)"); | ||||
|         return ir.Imm32(Common::BitCast<u32>(1.0f)); | ||||
|     case SpecialRegister::SR_LANEID: | ||||
|         return ir.LaneId(); | ||||
|   | ||||
| @@ -50,10 +50,7 @@ void TranslatorVisitor::VOTE(u64 insn) { | ||||
| } | ||||
|  | ||||
| void TranslatorVisitor::VOTE_vtg(u64) { | ||||
|     // LOG_WARNING("VOTE.VTG: Stubbed!"); | ||||
|     auto imm = ir.Imm1(false); | ||||
|     ir.SetFCSMFlag(imm); | ||||
|     ir.SetTRFlag(imm); | ||||
|     // LOG_WARNING(ShaderDecompiler, "VOTE.VTG: Stubbed!"); | ||||
| } | ||||
|  | ||||
| } // namespace Shader::Maxwell | ||||
|   | ||||
| @@ -374,17 +374,14 @@ std::optional<IR::Value> FoldCompositeExtractImpl(IR::Value inst_value, IR::Opco | ||||
|     if (inst->Opcode() == construct) { | ||||
|         return inst->Arg(first_index); | ||||
|     } | ||||
|  | ||||
|     if (inst->Opcode() != insert) { | ||||
|         return std::nullopt; | ||||
|     } | ||||
|  | ||||
|     IR::Value value_index{inst->Arg(2)}; | ||||
|     if (!value_index.IsImmediate()) { | ||||
|         return std::nullopt; | ||||
|     } | ||||
|  | ||||
|     const u32 second_index = value_index.U32(); | ||||
|     const u32 second_index{value_index.U32()}; | ||||
|     if (first_index != second_index) { | ||||
|         IR::Value value_composite{inst->Arg(0)}; | ||||
|         if (value_composite.IsImmediate()) { | ||||
| @@ -404,8 +401,8 @@ void FoldCompositeExtract(IR::Inst& inst, IR::Opcode construct, IR::Opcode inser | ||||
|     if (!value_2.IsImmediate()) { | ||||
|         return; | ||||
|     } | ||||
|     const u32 first_index = value_2.U32(); | ||||
|     auto result = FoldCompositeExtractImpl(value_1, insert, construct, first_index); | ||||
|     const u32 first_index{value_2.U32()}; | ||||
|     const std::optional result{FoldCompositeExtractImpl(value_1, insert, construct, first_index)}; | ||||
|     if (!result) { | ||||
|         return; | ||||
|     } | ||||
|   | ||||
| @@ -4,9 +4,9 @@ | ||||
|  | ||||
| #include <algorithm> | ||||
| #include <compare> | ||||
| #include <map> | ||||
| #include <optional> | ||||
| #include <ranges> | ||||
| #include <map> | ||||
|  | ||||
| #include <boost/container/flat_set.hpp> | ||||
| #include <boost/container/small_vector.hpp> | ||||
| @@ -295,8 +295,8 @@ void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageBufferSet& s | ||||
|         } | ||||
|     } | ||||
|     // Collect storage buffer and the instruction | ||||
|     const bool is_a_write = IsGlobalMemoryWrite(inst); | ||||
|     auto it = writes_map.find(*storage_buffer); | ||||
|     const bool is_a_write{IsGlobalMemoryWrite(inst)}; | ||||
|     auto it{writes_map.find(*storage_buffer)}; | ||||
|     if (it == writes_map.end()) { | ||||
|         writes_map[*storage_buffer] = is_a_write; | ||||
|     } else { | ||||
|   | ||||
| @@ -38,10 +38,6 @@ struct ZeroFlagTag : FlagTag {}; | ||||
| struct SignFlagTag : FlagTag {}; | ||||
| struct CarryFlagTag : FlagTag {}; | ||||
| struct OverflowFlagTag : FlagTag {}; | ||||
| struct FCSMFlagTag : FlagTag {}; | ||||
| struct TAFlagTag : FlagTag {}; | ||||
| struct TRFlagTag : FlagTag {}; | ||||
| struct MXFlagTag : FlagTag {}; | ||||
|  | ||||
| struct GotoVariable : FlagTag { | ||||
|     GotoVariable() = default; | ||||
| @@ -57,8 +53,7 @@ struct IndirectBranchVariable { | ||||
| }; | ||||
|  | ||||
| using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag, | ||||
|                              OverflowFlagTag, FCSMFlagTag, TAFlagTag, TRFlagTag, MXFlagTag, | ||||
|                              GotoVariable, IndirectBranchVariable>; | ||||
|                              OverflowFlagTag, GotoVariable, IndirectBranchVariable>; | ||||
| using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>; | ||||
|  | ||||
| struct DefTable { | ||||
| @@ -94,22 +89,6 @@ struct DefTable { | ||||
|         return overflow_flag; | ||||
|     } | ||||
|  | ||||
|     [[nodiscard]] ValueMap& operator[](FCSMFlagTag) noexcept { | ||||
|         return fcsm_flag; | ||||
|     } | ||||
|  | ||||
|     [[nodiscard]] ValueMap& operator[](TAFlagTag) noexcept { | ||||
|         return ta_flag; | ||||
|     } | ||||
|  | ||||
|     [[nodiscard]] ValueMap& operator[](TRFlagTag) noexcept { | ||||
|         return tr_flag; | ||||
|     } | ||||
|  | ||||
|     [[nodiscard]] ValueMap& operator[](MXFlagTag) noexcept { | ||||
|         return mr_flag; | ||||
|     } | ||||
|  | ||||
|     std::array<ValueMap, IR::NUM_USER_REGS> regs; | ||||
|     std::array<ValueMap, IR::NUM_USER_PREDS> preds; | ||||
|     boost::container::flat_map<u32, ValueMap> goto_vars; | ||||
| @@ -118,10 +97,6 @@ struct DefTable { | ||||
|     ValueMap sign_flag; | ||||
|     ValueMap carry_flag; | ||||
|     ValueMap overflow_flag; | ||||
|     ValueMap fcsm_flag; | ||||
|     ValueMap ta_flag; | ||||
|     ValueMap tr_flag; | ||||
|     ValueMap mr_flag; | ||||
| }; | ||||
|  | ||||
| IR::Opcode UndefOpcode(IR::Reg) noexcept { | ||||
| @@ -272,18 +247,6 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) { | ||||
|     case IR::Opcode::SetOFlag: | ||||
|         pass.WriteVariable(OverflowFlagTag{}, block, inst.Arg(0)); | ||||
|         break; | ||||
|     case IR::Opcode::SetFCSMFlag: | ||||
|         pass.WriteVariable(FCSMFlagTag{}, block, inst.Arg(0)); | ||||
|         break; | ||||
|     case IR::Opcode::SetTAFlag: | ||||
|         pass.WriteVariable(TAFlagTag{}, block, inst.Arg(0)); | ||||
|         break; | ||||
|     case IR::Opcode::SetTRFlag: | ||||
|         pass.WriteVariable(TRFlagTag{}, block, inst.Arg(0)); | ||||
|         break; | ||||
|     case IR::Opcode::SetMXFlag: | ||||
|         pass.WriteVariable(MXFlagTag{}, block, inst.Arg(0)); | ||||
|         break; | ||||
|     case IR::Opcode::GetRegister: | ||||
|         if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) { | ||||
|             inst.ReplaceUsesWith(pass.ReadVariable(reg, block)); | ||||
| @@ -312,17 +275,6 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) { | ||||
|     case IR::Opcode::GetOFlag: | ||||
|         inst.ReplaceUsesWith(pass.ReadVariable(OverflowFlagTag{}, block)); | ||||
|         break; | ||||
|     case IR::Opcode::GetFCSMFlag: | ||||
|         inst.ReplaceUsesWith(pass.ReadVariable(FCSMFlagTag{}, block)); | ||||
|         break; | ||||
|     case IR::Opcode::GetTAFlag: | ||||
|         inst.ReplaceUsesWith(pass.ReadVariable(TAFlagTag{}, block)); | ||||
|         break; | ||||
|     case IR::Opcode::GetTRFlag: | ||||
|         inst.ReplaceUsesWith(pass.ReadVariable(TRFlagTag{}, block)); | ||||
|         break; | ||||
|     case IR::Opcode::GetMXFlag: | ||||
|         inst.ReplaceUsesWith(pass.ReadVariable(MXFlagTag{}, block)); | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user