summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/ir/ir_emitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend/ir/ir_emitter.cpp')
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp43
1 files changed, 34 insertions, 9 deletions
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index ada0be834..30932043f 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 {
44 return F64{Value{value}}; 44 return F64{Value{value}};
45} 45}
46 46
47void IREmitter::Branch(IR::Block* label) { 47void IREmitter::Branch(Block* label) {
48 label->AddImmediatePredecessor(block);
48 Inst(Opcode::Branch, label); 49 Inst(Opcode::Branch, label);
49} 50}
50 51
51void IREmitter::BranchConditional(const U1& cond, IR::Block* true_label, IR::Block* false_label) { 52void IREmitter::BranchConditional(const U1& condition, Block* true_label, Block* false_label) {
52 Inst(Opcode::BranchConditional, cond, true_label, false_label); 53 true_label->AddImmediatePredecessor(block);
54 false_label->AddImmediatePredecessor(block);
55 Inst(Opcode::BranchConditional, condition, true_label, false_label);
53} 56}
54 57
55void IREmitter::Exit() { 58void IREmitter::LoopMerge(Block* merge_block, Block* continue_target) {
56 Inst(Opcode::Exit); 59 Inst(Opcode::LoopMerge, merge_block, continue_target);
57} 60}
58 61
59void IREmitter::Return() { 62void IREmitter::SelectionMerge(Block* merge_block) {
60 Inst(Opcode::Return); 63 Inst(Opcode::SelectionMerge, merge_block);
61} 64}
62 65
63void IREmitter::Unreachable() { 66void IREmitter::Return() {
64 Inst(Opcode::Unreachable); 67 Inst(Opcode::Return);
65} 68}
66 69
67U32 IREmitter::GetReg(IR::Reg reg) { 70U32 IREmitter::GetReg(IR::Reg reg) {
@@ -81,6 +84,14 @@ U1 IREmitter::GetPred(IR::Pred pred, bool is_negated) {
81 } 84 }
82} 85}
83 86
87U1 IREmitter::GetGotoVariable(u32 id) {
88 return Inst<U1>(Opcode::GetGotoVariable, id);
89}
90
91void IREmitter::SetGotoVariable(u32 id, const U1& value) {
92 Inst(Opcode::SetGotoVariable, id, value);
93}
94
84void IREmitter::SetPred(IR::Pred pred, const U1& value) { 95void IREmitter::SetPred(IR::Pred pred, const U1& value) {
85 Inst(Opcode::SetPred, pred, value); 96 Inst(Opcode::SetPred, pred, value);
86} 97}
@@ -121,6 +132,20 @@ void IREmitter::SetOFlag(const U1& value) {
121 Inst(Opcode::SetOFlag, value); 132 Inst(Opcode::SetOFlag, value);
122} 133}
123 134
135U1 IREmitter::Condition(IR::Condition cond) {
136 if (cond == IR::Condition{true}) {
137 return Imm1(true);
138 } else if (cond == IR::Condition{false}) {
139 return Imm1(false);
140 }
141 const FlowTest flow_test{cond.FlowTest()};
142 const auto [pred, is_negated]{cond.Pred()};
143 if (flow_test == FlowTest::T) {
144 return GetPred(pred, is_negated);
145 }
146 throw NotImplementedException("Condition {}", cond);
147}
148
124F32 IREmitter::GetAttribute(IR::Attribute attribute) { 149F32 IREmitter::GetAttribute(IR::Attribute attribute) {
125 return Inst<F32>(Opcode::GetAttribute, attribute); 150 return Inst<F32>(Opcode::GetAttribute, attribute);
126} 151}