summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/frontend/ir/ir_emitter.h
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/ir_emitter.h
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/ir_emitter.h123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h
new file mode 100644
index 000000000..1af79f41c
--- /dev/null
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.h
@@ -0,0 +1,123 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "shader_recompiler/frontend/ir/attribute.h"
+#include "shader_recompiler/frontend/ir/basic_block.h"
+#include "shader_recompiler/frontend/ir/value.h"
+
+namespace Shader::IR {
+
+class IREmitter {
+public:
+ explicit IREmitter(Block& block_) : block{block_}, insertion_point{block.end()} {}
+
+ Block& block;
+
+ [[nodiscard]] U1 Imm1(bool value) const;
+ [[nodiscard]] U8 Imm8(u8 value) const;
+ [[nodiscard]] U16 Imm16(u16 value) const;
+ [[nodiscard]] U32 Imm32(u32 value) const;
+ [[nodiscard]] U32 Imm32(s32 value) const;
+ [[nodiscard]] U32 Imm32(f32 value) const;
+ [[nodiscard]] U64 Imm64(u64 value) const;
+ [[nodiscard]] U64 Imm64(f64 value) const;
+
+ void Branch(IR::Block* label);
+ void BranchConditional(const U1& cond, IR::Block* true_label, IR::Block* false_label);
+ void Exit();
+ void Return();
+ void Unreachable();
+
+ [[nodiscard]] U32 GetReg(IR::Reg reg);
+ void SetReg(IR::Reg reg, const U32& value);
+
+ [[nodiscard]] U1 GetPred(IR::Pred pred, bool is_negated = false);
+ void SetPred(IR::Pred pred, const U1& value);
+
+ [[nodiscard]] U32 GetCbuf(const U32& binding, const U32& byte_offset);
+
+ [[nodiscard]] U1 GetZFlag();
+ [[nodiscard]] U1 GetSFlag();
+ [[nodiscard]] U1 GetCFlag();
+ [[nodiscard]] U1 GetOFlag();
+
+ void SetZFlag(const U1& value);
+ void SetSFlag(const U1& value);
+ void SetCFlag(const U1& value);
+ void SetOFlag(const U1& value);
+
+ [[nodiscard]] U32 GetAttribute(IR::Attribute attribute);
+ void SetAttribute(IR::Attribute attribute, const U32& value);
+
+ void WriteGlobalU8(const U64& address, const U32& value);
+ void WriteGlobalS8(const U64& address, const U32& value);
+ void WriteGlobalU16(const U64& address, const U32& value);
+ void WriteGlobalS16(const U64& address, const U32& value);
+ void WriteGlobal32(const U64& address, const U32& value);
+ void WriteGlobal64(const U64& address, const IR::Value& vector);
+ void WriteGlobal128(const U64& address, const IR::Value& vector);
+
+ [[nodiscard]] U1 GetZeroFromOp(const Value& op);
+ [[nodiscard]] U1 GetSignFromOp(const Value& op);
+ [[nodiscard]] U1 GetCarryFromOp(const Value& op);
+ [[nodiscard]] U1 GetOverflowFromOp(const Value& op);
+
+ [[nodiscard]] Value CompositeConstruct(const UAny& e1, const UAny& e2);
+ [[nodiscard]] Value CompositeConstruct(const UAny& e1, const UAny& e2, const UAny& e3);
+ [[nodiscard]] Value CompositeConstruct(const UAny& e1, const UAny& e2, const UAny& e3,
+ const UAny& e4);
+ [[nodiscard]] UAny CompositeExtract(const Value& vector, size_t element);
+
+ [[nodiscard]] U64 PackUint2x32(const Value& vector);
+ [[nodiscard]] Value UnpackUint2x32(const U64& value);
+
+ [[nodiscard]] U32 PackFloat2x16(const Value& vector);
+ [[nodiscard]] Value UnpackFloat2x16(const U32& value);
+
+ [[nodiscard]] U64 PackDouble2x32(const Value& vector);
+ [[nodiscard]] Value UnpackDouble2x32(const U64& value);
+
+ [[nodiscard]] U16U32U64 FPAdd(const U16U32U64& a, const U16U32U64& b);
+ [[nodiscard]] U16U32U64 FPMul(const U16U32U64& a, const U16U32U64& b);
+
+ [[nodiscard]] U16U32U64 FPAbs(const U16U32U64& value);
+ [[nodiscard]] U16U32U64 FPNeg(const U16U32U64& value);
+ [[nodiscard]] U16U32U64 FPAbsNeg(const U16U32U64& value, bool abs, bool neg);
+
+ [[nodiscard]] U32 FPCosNotReduced(const U32& value);
+ [[nodiscard]] U32 FPExp2NotReduced(const U32& value);
+ [[nodiscard]] U32 FPLog2(const U32& value);
+ [[nodiscard]] U32U64 FPRecip(const U32U64& value);
+ [[nodiscard]] U32U64 FPRecipSqrt(const U32U64& value);
+ [[nodiscard]] U32 FPSinNotReduced(const U32& value);
+ [[nodiscard]] U32 FPSqrt(const U32& value);
+ [[nodiscard]] U16U32U64 FPSaturate(const U16U32U64& value);
+ [[nodiscard]] U16U32U64 FPRoundEven(const U16U32U64& value);
+ [[nodiscard]] U16U32U64 FPFloor(const U16U32U64& value);
+ [[nodiscard]] U16U32U64 FPCeil(const U16U32U64& value);
+ [[nodiscard]] U16U32U64 FPTrunc(const U16U32U64& value);
+
+ [[nodiscard]] U1 LogicalOr(const U1& a, const U1& b);
+ [[nodiscard]] U1 LogicalAnd(const U1& a, const U1& b);
+ [[nodiscard]] U1 LogicalNot(const U1& value);
+
+ [[nodiscard]] U32U64 ConvertFToS(size_t bitsize, const U16U32U64& value);
+ [[nodiscard]] U32U64 ConvertFToU(size_t bitsize, const U16U32U64& value);
+ [[nodiscard]] U32U64 ConvertFToI(size_t bitsize, bool is_signed, const U16U32U64& value);
+
+ [[nodiscard]] U32U64 ConvertU(size_t bitsize, const U32U64& value);
+
+private:
+ IR::Block::iterator insertion_point;
+
+ template <typename T = Value, typename... Args>
+ T Inst(Opcode op, Args... args) {
+ auto it{block.PrependNewInst(insertion_point, op, {Value{args}...})};
+ return T{Value{&*it}};
+ }
+};
+
+} // namespace Shader::IR