// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include #include #include #include "shader_recompiler/frontend/ir/type.h" namespace Shader::IR { enum class Opcode { #define OPCODE(name, ...) name, #include "opcodes.inc" #undef OPCODE }; namespace Detail { struct OpcodeMeta { std::string_view name; Type type; std::array arg_types; }; // using enum Type; static constexpr Type Void{Type::Void}; static constexpr Type Opaque{Type::Opaque}; static constexpr Type Reg{Type::Reg}; static constexpr Type Pred{Type::Pred}; static constexpr Type Attribute{Type::Attribute}; static constexpr Type Patch{Type::Patch}; static constexpr Type U1{Type::U1}; static constexpr Type U8{Type::U8}; static constexpr Type U16{Type::U16}; static constexpr Type U32{Type::U32}; static constexpr Type U64{Type::U64}; static constexpr Type F16{Type::F16}; static constexpr Type F32{Type::F32}; static constexpr Type F64{Type::F64}; static constexpr Type U32x2{Type::U32x2}; static constexpr Type U32x3{Type::U32x3}; static constexpr Type U32x4{Type::U32x4}; static constexpr Type F16x2{Type::F16x2}; static constexpr Type F16x3{Type::F16x3}; static constexpr Type F16x4{Type::F16x4}; static constexpr Type F32x2{Type::F32x2}; static constexpr Type F32x3{Type::F32x3}; static constexpr Type F32x4{Type::F32x4}; static constexpr Type F64x2{Type::F64x2}; static constexpr Type F64x3{Type::F64x3}; static constexpr Type F64x4{Type::F64x4}; extern OpcodeMeta META_TABLE[]; constexpr size_t CalculateNumArgsOf(Opcode op) noexcept { const auto& arg_types = META_TABLE[size_t(op)].arg_types; return size_t(std::distance(arg_types.begin(), std::ranges::find(arg_types, Type::Void))); } extern u8 NUM_ARGS[]; } // namespace Detail /// Get return type of an opcode [[nodiscard]] inline Type TypeOf(Opcode op) noexcept { return Detail::META_TABLE[size_t(op)].type; } /// Get the number of arguments an opcode accepts [[nodiscard]] inline size_t NumArgsOf(Opcode op) noexcept { return size_t(Detail::NUM_ARGS[size_t(op)]); } /// Get the required type of an argument of an opcode [[nodiscard]] inline Type ArgTypeOf(Opcode op, size_t arg_index) noexcept { return Detail::META_TABLE[size_t(op)].arg_types[arg_index]; } /// Get the name of an opcode [[nodiscard]] std::string_view NameOf(Opcode op); } // namespace Shader::IR template <> struct fmt::formatter { constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } template auto format(const Shader::IR::Opcode& op, FormatContext& ctx) const { return fmt::format_to(ctx.out(), "{}", Shader::IR::NameOf(op)); } };