From 9170200a11715d131645d1ffb92e86e6ef0d7e88 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Thu, 11 Feb 2021 16:39:06 -0300
Subject: shader: Initial implementation of an AST

---
 src/shader_recompiler/frontend/ir/ir_emitter.cpp | 43 +++++++++++++++++++-----
 1 file changed, 34 insertions(+), 9 deletions(-)

(limited to 'src/shader_recompiler/frontend/ir/ir_emitter.cpp')

diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index ada0be8343..30932043f9 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -44,24 +44,27 @@ F64 IREmitter::Imm64(f64 value) const {
     return F64{Value{value}};
 }
 
-void IREmitter::Branch(IR::Block* label) {
+void IREmitter::Branch(Block* label) {
+    label->AddImmediatePredecessor(block);
     Inst(Opcode::Branch, label);
 }
 
-void IREmitter::BranchConditional(const U1& cond, IR::Block* true_label, IR::Block* false_label) {
-    Inst(Opcode::BranchConditional, cond, true_label, false_label);
+void IREmitter::BranchConditional(const U1& condition, Block* true_label, Block* false_label) {
+    true_label->AddImmediatePredecessor(block);
+    false_label->AddImmediatePredecessor(block);
+    Inst(Opcode::BranchConditional, condition, true_label, false_label);
 }
 
-void IREmitter::Exit() {
-    Inst(Opcode::Exit);
+void IREmitter::LoopMerge(Block* merge_block, Block* continue_target) {
+    Inst(Opcode::LoopMerge, merge_block, continue_target);
 }
 
-void IREmitter::Return() {
-    Inst(Opcode::Return);
+void IREmitter::SelectionMerge(Block* merge_block) {
+    Inst(Opcode::SelectionMerge, merge_block);
 }
 
-void IREmitter::Unreachable() {
-    Inst(Opcode::Unreachable);
+void IREmitter::Return() {
+    Inst(Opcode::Return);
 }
 
 U32 IREmitter::GetReg(IR::Reg reg) {
@@ -81,6 +84,14 @@ U1 IREmitter::GetPred(IR::Pred pred, bool is_negated) {
     }
 }
 
+U1 IREmitter::GetGotoVariable(u32 id) {
+    return Inst<U1>(Opcode::GetGotoVariable, id);
+}
+
+void IREmitter::SetGotoVariable(u32 id, const U1& value) {
+    Inst(Opcode::SetGotoVariable, id, value);
+}
+
 void IREmitter::SetPred(IR::Pred pred, const U1& value) {
     Inst(Opcode::SetPred, pred, value);
 }
@@ -121,6 +132,20 @@ void IREmitter::SetOFlag(const U1& value) {
     Inst(Opcode::SetOFlag, value);
 }
 
+U1 IREmitter::Condition(IR::Condition cond) {
+    if (cond == IR::Condition{true}) {
+        return Imm1(true);
+    } else if (cond == IR::Condition{false}) {
+        return Imm1(false);
+    }
+    const FlowTest flow_test{cond.FlowTest()};
+    const auto [pred, is_negated]{cond.Pred()};
+    if (flow_test == FlowTest::T) {
+        return GetPred(pred, is_negated);
+    }
+    throw NotImplementedException("Condition {}", cond);
+}
+
 F32 IREmitter::GetAttribute(IR::Attribute attribute) {
     return Inst<F32>(Opcode::GetAttribute, attribute);
 }
-- 
cgit v1.2.3-70-g09d2