summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/frontend/ir/opcodes.cpp
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-02-06 03:11:23 +0100
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:21 +0200
commit16cb00c521cae6e93ec49d10e15b575b7bc4857e (patch)
tree3b283895510af56fced7e62031c6beda999c0a1c /src/shader_recompiler/frontend/ir/opcodes.cpp
parentshader: Make typed IR (diff)
downloadyuzu-16cb00c521cae6e93ec49d10e15b575b7bc4857e.tar
yuzu-16cb00c521cae6e93ec49d10e15b575b7bc4857e.tar.gz
yuzu-16cb00c521cae6e93ec49d10e15b575b7bc4857e.tar.bz2
yuzu-16cb00c521cae6e93ec49d10e15b575b7bc4857e.tar.lz
yuzu-16cb00c521cae6e93ec49d10e15b575b7bc4857e.tar.xz
yuzu-16cb00c521cae6e93ec49d10e15b575b7bc4857e.tar.zst
yuzu-16cb00c521cae6e93ec49d10e15b575b7bc4857e.zip
Diffstat (limited to 'src/shader_recompiler/frontend/ir/opcodes.cpp')
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.cpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/shader_recompiler/frontend/ir/opcodes.cpp b/src/shader_recompiler/frontend/ir/opcodes.cpp
new file mode 100644
index 000000000..1f188411a
--- /dev/null
+++ b/src/shader_recompiler/frontend/ir/opcodes.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/opcodes.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 "opcodes.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