opcodes.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <algorithm>
  7. #include <string_view>
  8. #include <fmt/format.h>
  9. #include "shader_recompiler/frontend/ir/type.h"
  10. namespace Shader::IR {
  11. enum class Opcode {
  12. #define OPCODE(name, ...) name,
  13. #include "opcodes.inc"
  14. #undef OPCODE
  15. };
  16. namespace Detail {
  17. struct OpcodeMeta {
  18. std::string_view name;
  19. Type type;
  20. std::array<Type, 5> arg_types;
  21. };
  22. // using enum Type;
  23. constexpr Type Void{Type::Void};
  24. constexpr Type Opaque{Type::Opaque};
  25. constexpr Type Label{Type::Label};
  26. constexpr Type Reg{Type::Reg};
  27. constexpr Type Pred{Type::Pred};
  28. constexpr Type Attribute{Type::Attribute};
  29. constexpr Type Patch{Type::Patch};
  30. constexpr Type U1{Type::U1};
  31. constexpr Type U8{Type::U8};
  32. constexpr Type U16{Type::U16};
  33. constexpr Type U32{Type::U32};
  34. constexpr Type U64{Type::U64};
  35. constexpr Type F16{Type::F16};
  36. constexpr Type F32{Type::F32};
  37. constexpr Type F64{Type::F64};
  38. constexpr Type U32x2{Type::U32x2};
  39. constexpr Type U32x3{Type::U32x3};
  40. constexpr Type U32x4{Type::U32x4};
  41. constexpr Type F16x2{Type::F16x2};
  42. constexpr Type F16x3{Type::F16x3};
  43. constexpr Type F16x4{Type::F16x4};
  44. constexpr Type F32x2{Type::F32x2};
  45. constexpr Type F32x3{Type::F32x3};
  46. constexpr Type F32x4{Type::F32x4};
  47. constexpr Type F64x2{Type::F64x2};
  48. constexpr Type F64x3{Type::F64x3};
  49. constexpr Type F64x4{Type::F64x4};
  50. constexpr std::array META_TABLE{
  51. #define OPCODE(name_token, type_token, ...) \
  52. OpcodeMeta{ \
  53. .name{#name_token}, \
  54. .type = type_token, \
  55. .arg_types{__VA_ARGS__}, \
  56. },
  57. #include "opcodes.inc"
  58. #undef OPCODE
  59. };
  60. constexpr size_t CalculateNumArgsOf(Opcode op) {
  61. const auto& arg_types{META_TABLE[static_cast<size_t>(op)].arg_types};
  62. return std::distance(arg_types.begin(), std::ranges::find(arg_types, Type::Void));
  63. }
  64. constexpr std::array NUM_ARGS{
  65. #define OPCODE(name_token, type_token, ...) CalculateNumArgsOf(Opcode::name_token),
  66. #include "opcodes.inc"
  67. #undef OPCODE
  68. };
  69. } // namespace Detail
  70. /// Get return type of an opcode
  71. [[nodiscard]] inline Type TypeOf(Opcode op) noexcept {
  72. return Detail::META_TABLE[static_cast<size_t>(op)].type;
  73. }
  74. /// Get the number of arguments an opcode accepts
  75. [[nodiscard]] inline size_t NumArgsOf(Opcode op) noexcept {
  76. return Detail::NUM_ARGS[static_cast<size_t>(op)];
  77. }
  78. /// Get the required type of an argument of an opcode
  79. [[nodiscard]] inline Type ArgTypeOf(Opcode op, size_t arg_index) noexcept {
  80. return Detail::META_TABLE[static_cast<size_t>(op)].arg_types[arg_index];
  81. }
  82. /// Get the name of an opcode
  83. [[nodiscard]] std::string_view NameOf(Opcode op);
  84. } // namespace Shader::IR
  85. template <>
  86. struct fmt::formatter<Shader::IR::Opcode> {
  87. constexpr auto parse(format_parse_context& ctx) {
  88. return ctx.begin();
  89. }
  90. template <typename FormatContext>
  91. auto format(const Shader::IR::Opcode& op, FormatContext& ctx) {
  92. return format_to(ctx.out(), "{}", Shader::IR::NameOf(op));
  93. }
  94. };