summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/frontend/ir/opcode.cpp
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-01-09 07:30:07 +0100
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:21 +0200
commit2d48a7b4d0666ad16d03a22d85712617a0849046 (patch)
treedd1069afca86f66e77e3438da77421a43adf5091 /src/shader_recompiler/frontend/ir/opcode.cpp
parentthread_worker: Fix compile time error (diff)
downloadyuzu-2d48a7b4d0666ad16d03a22d85712617a0849046.tar
yuzu-2d48a7b4d0666ad16d03a22d85712617a0849046.tar.gz
yuzu-2d48a7b4d0666ad16d03a22d85712617a0849046.tar.bz2
yuzu-2d48a7b4d0666ad16d03a22d85712617a0849046.tar.lz
yuzu-2d48a7b4d0666ad16d03a22d85712617a0849046.tar.xz
yuzu-2d48a7b4d0666ad16d03a22d85712617a0849046.tar.zst
yuzu-2d48a7b4d0666ad16d03a22d85712617a0849046.zip
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/frontend/ir/opcode.cpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/shader_recompiler/frontend/ir/opcode.cpp b/src/shader_recompiler/frontend/ir/opcode.cpp
new file mode 100644
index 000000000..65d074029
--- /dev/null
+++ b/src/shader_recompiler/frontend/ir/opcode.cpp
@@ -0,0 +1,67 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <algorithm>
+#include <array>
+#include <string_view>
+
+#include "shader_recompiler/exception.h"
+#include "shader_recompiler/frontend/ir/opcode.h"
+
+namespace Shader::IR {
+namespace {
+struct OpcodeMeta {
+ std::string_view name;
+ Type type;
+ std::array<Type, 4> arg_types;
+};
+
+using enum Type;
+
+constexpr std::array META_TABLE{
+#define OPCODE(name_token, type_token, ...) \
+ OpcodeMeta{ \
+ .name{#name_token}, \
+ .type{type_token}, \
+ .arg_types{__VA_ARGS__}, \
+ },
+#include "opcode.inc"
+#undef OPCODE
+};
+
+void ValidateOpcode(Opcode op) {
+ const size_t raw{static_cast<size_t>(op)};
+ if (raw >= META_TABLE.size()) {
+ throw InvalidArgument("Invalid opcode with raw value {}", raw);
+ }
+}
+} // Anonymous namespace
+
+Type TypeOf(Opcode op) {
+ ValidateOpcode(op);
+ return META_TABLE[static_cast<size_t>(op)].type;
+}
+
+size_t NumArgsOf(Opcode op) {
+ ValidateOpcode(op);
+ const auto& arg_types{META_TABLE[static_cast<size_t>(op)].arg_types};
+ const auto distance{std::distance(arg_types.begin(), std::ranges::find(arg_types, Type::Void))};
+ return static_cast<size_t>(distance);
+}
+
+Type ArgTypeOf(Opcode op, size_t arg_index) {
+ ValidateOpcode(op);
+ const auto& arg_types{META_TABLE[static_cast<size_t>(op)].arg_types};
+ if (arg_index >= arg_types.size() || arg_types[arg_index] == Type::Void) {
+ throw InvalidArgument("Out of bounds argument");
+ }
+ return arg_types[arg_index];
+}
+
+std::string_view NameOf(Opcode op) {
+ ValidateOpcode(op);
+ return META_TABLE[static_cast<size_t>(op)].name;
+}
+
+} // namespace Shader::IR