diff options
author | David <25727384+ogniK5377@users.noreply.github.com> | 2019-10-05 21:52:20 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-05 21:52:20 +1000 |
commit | 3728bbc22a9224ff75fff22487a47bcaaf6ac2be (patch) | |
tree | 80809634787307002bf9e07b710a4aa968019f26 /src/video_core/shader/expr.cpp | |
parent | 0a662d009b1567bde5b0aa91e07365224858ca18 (diff) | |
parent | e6eae4b815bf4bc480d62677fdf9bdbf5d6cba82 (diff) |
Merge pull request #2888 from FernandoS27/decompiler2
Shader_IR: Implement a full control flow decompiler for the shader IR.
Diffstat (limited to 'src/video_core/shader/expr.cpp')
-rw-r--r-- | src/video_core/shader/expr.cpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/video_core/shader/expr.cpp b/src/video_core/shader/expr.cpp new file mode 100644 index 0000000000..ca633ffb10 --- /dev/null +++ b/src/video_core/shader/expr.cpp @@ -0,0 +1,82 @@ +// Copyright 2019 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <memory> +#include <variant> + +#include "video_core/shader/expr.h" + +namespace VideoCommon::Shader { + +bool ExprAnd::operator==(const ExprAnd& b) const { + return (*operand1 == *b.operand1) && (*operand2 == *b.operand2); +} + +bool ExprOr::operator==(const ExprOr& b) const { + return (*operand1 == *b.operand1) && (*operand2 == *b.operand2); +} + +bool ExprNot::operator==(const ExprNot& b) const { + return (*operand1 == *b.operand1); +} + +bool ExprIsBoolean(Expr expr) { + return std::holds_alternative<ExprBoolean>(*expr); +} + +bool ExprBooleanGet(Expr expr) { + return std::get_if<ExprBoolean>(expr.get())->value; +} + +Expr MakeExprNot(Expr first) { + if (std::holds_alternative<ExprNot>(*first)) { + return std::get_if<ExprNot>(first.get())->operand1; + } + return MakeExpr<ExprNot>(first); +} + +Expr MakeExprAnd(Expr first, Expr second) { + if (ExprIsBoolean(first)) { + return ExprBooleanGet(first) ? second : first; + } + if (ExprIsBoolean(second)) { + return ExprBooleanGet(second) ? first : second; + } + return MakeExpr<ExprAnd>(first, second); +} + +Expr MakeExprOr(Expr first, Expr second) { + if (ExprIsBoolean(first)) { + return ExprBooleanGet(first) ? first : second; + } + if (ExprIsBoolean(second)) { + return ExprBooleanGet(second) ? second : first; + } + return MakeExpr<ExprOr>(first, second); +} + +bool ExprAreEqual(Expr first, Expr second) { + return (*first) == (*second); +} + +bool ExprAreOpposite(Expr first, Expr second) { + if (std::holds_alternative<ExprNot>(*first)) { + return ExprAreEqual(std::get_if<ExprNot>(first.get())->operand1, second); + } + if (std::holds_alternative<ExprNot>(*second)) { + return ExprAreEqual(std::get_if<ExprNot>(second.get())->operand1, first); + } + return false; +} + +bool ExprIsTrue(Expr first) { + if (ExprIsBoolean(first)) { + return ExprBooleanGet(first); + } + return false; +} + +} // namespace VideoCommon::Shader |