summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/frontend/ir/value.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/frontend/ir/value.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/shader_recompiler/frontend/ir/value.cpp b/src/shader_recompiler/frontend/ir/value.cpp
new file mode 100644
index 000000000..7b5b35d6c
--- /dev/null
+++ b/src/shader_recompiler/frontend/ir/value.cpp
@@ -0,0 +1,124 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "shader_recompiler/frontend/ir/microinstruction.h"
+#include "shader_recompiler/frontend/ir/opcode.h"
+#include "shader_recompiler/frontend/ir/value.h"
+
+namespace Shader::IR {
+
+Value::Value(IR::Inst* value) noexcept : type{Type::Opaque}, inst{value} {}
+
+Value::Value(IR::Block* value) noexcept : type{Type::Label}, label{value} {}
+
+Value::Value(IR::Reg value) noexcept : type{Type::Reg}, reg{value} {}
+
+Value::Value(IR::Pred value) noexcept : type{Type::Pred}, pred{value} {}
+
+Value::Value(IR::Attribute value) noexcept : type{Type::Attribute}, attribute{value} {}
+
+Value::Value(bool value) noexcept : type{Type::U1}, imm_u1{value} {}
+
+Value::Value(u8 value) noexcept : type{Type::U8}, imm_u8{value} {}
+
+Value::Value(u16 value) noexcept : type{Type::U16}, imm_u16{value} {}
+
+Value::Value(u32 value) noexcept : type{Type::U32}, imm_u32{value} {}
+
+Value::Value(u64 value) noexcept : type{Type::U64}, imm_u64{value} {}
+
+bool Value::IsIdentity() const noexcept {
+ return type == Type::Opaque && inst->Opcode() == Opcode::Identity;
+}
+
+bool Value::IsEmpty() const noexcept {
+ return type == Type::Void;
+}
+
+bool Value::IsImmediate() const noexcept {
+ if (IsIdentity()) {
+ return inst->Arg(0).IsImmediate();
+ }
+ return type != Type::Opaque;
+}
+
+bool Value::IsLabel() const noexcept {
+ return type == Type::Label;
+}
+
+IR::Type Value::Type() const noexcept {
+ if (IsIdentity()) {
+ return inst->Arg(0).Type();
+ }
+ if (type == Type::Opaque) {
+ return inst->Type();
+ }
+ return type;
+}
+
+IR::Inst* Value::Inst() const {
+ ValidateAccess(Type::Opaque);
+ return inst;
+}
+
+IR::Block* Value::Label() const {
+ ValidateAccess(Type::Label);
+ return label;
+}
+
+IR::Inst* Value::InstRecursive() const {
+ ValidateAccess(Type::Opaque);
+ if (IsIdentity()) {
+ return inst->Arg(0).InstRecursive();
+ }
+ return inst;
+}
+
+IR::Reg Value::Reg() const {
+ ValidateAccess(Type::Reg);
+ return reg;
+}
+
+IR::Pred Value::Pred() const {
+ ValidateAccess(Type::Pred);
+ return pred;
+}
+
+IR::Attribute Value::Attribute() const {
+ ValidateAccess(Type::Attribute);
+ return attribute;
+}
+
+bool Value::U1() const {
+ ValidateAccess(Type::U1);
+ return imm_u1;
+}
+
+u8 Value::U8() const {
+ ValidateAccess(Type::U8);
+ return imm_u8;
+}
+
+u16 Value::U16() const {
+ ValidateAccess(Type::U16);
+ return imm_u16;
+}
+
+u32 Value::U32() const {
+ ValidateAccess(Type::U32);
+ return imm_u32;
+}
+
+u64 Value::U64() const {
+ ValidateAccess(Type::U64);
+ return imm_u64;
+}
+
+void Value::ValidateAccess(IR::Type expected) const {
+ if (type != expected) {
+ throw LogicError("Reading {} out of {}", expected, type);
+ }
+}
+
+} // namespace Shader::IR