diff options
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp index 5f5d9cf17..cec03e73e 100644 --- a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp +++ b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | |||
| @@ -45,6 +45,7 @@ enum class StatementType { | |||
| 45 | Loop, | 45 | Loop, |
| 46 | Break, | 46 | Break, |
| 47 | Return, | 47 | Return, |
| 48 | Kill, | ||
| 48 | Function, | 49 | Function, |
| 49 | Identity, | 50 | Identity, |
| 50 | Not, | 51 | Not, |
| @@ -70,6 +71,7 @@ struct If {}; | |||
| 70 | struct Loop {}; | 71 | struct Loop {}; |
| 71 | struct Break {}; | 72 | struct Break {}; |
| 72 | struct Return {}; | 73 | struct Return {}; |
| 74 | struct Kill {}; | ||
| 73 | struct FunctionTag {}; | 75 | struct FunctionTag {}; |
| 74 | struct Identity {}; | 76 | struct Identity {}; |
| 75 | struct Not {}; | 77 | struct Not {}; |
| @@ -93,6 +95,7 @@ struct Statement : ListBaseHook { | |||
| 93 | Statement(Break, Statement* cond_, Statement* up_) | 95 | Statement(Break, Statement* cond_, Statement* up_) |
| 94 | : cond{cond_}, up{up_}, type{StatementType::Break} {} | 96 | : cond{cond_}, up{up_}, type{StatementType::Break} {} |
| 95 | Statement(Return) : type{StatementType::Return} {} | 97 | Statement(Return) : type{StatementType::Return} {} |
| 98 | Statement(Kill) : type{StatementType::Kill} {} | ||
| 96 | Statement(FunctionTag) : children{}, type{StatementType::Function} {} | 99 | Statement(FunctionTag) : children{}, type{StatementType::Function} {} |
| 97 | Statement(Identity, IR::Condition cond_) : guest_cond{cond_}, type{StatementType::Identity} {} | 100 | Statement(Identity, IR::Condition cond_) : guest_cond{cond_}, type{StatementType::Identity} {} |
| 98 | Statement(Not, Statement* op_) : op{op_}, type{StatementType::Not} {} | 101 | Statement(Not, Statement* op_) : op{op_}, type{StatementType::Not} {} |
| @@ -174,6 +177,9 @@ std::string DumpTree(const Tree& tree, u32 indentation = 0) { | |||
| 174 | case StatementType::Return: | 177 | case StatementType::Return: |
| 175 | ret += fmt::format("{} return;\n", indent); | 178 | ret += fmt::format("{} return;\n", indent); |
| 176 | break; | 179 | break; |
| 180 | case StatementType::Kill: | ||
| 181 | ret += fmt::format("{} kill;\n", indent); | ||
| 182 | break; | ||
| 177 | case StatementType::SetVariable: | 183 | case StatementType::SetVariable: |
| 178 | ret += fmt::format("{} goto_L{} = {};\n", indent, stmt->id, DumpExpr(stmt->op)); | 184 | ret += fmt::format("{} goto_L{} = {};\n", indent, stmt->id, DumpExpr(stmt->op)); |
| 179 | break; | 185 | break; |
| @@ -424,6 +430,9 @@ private: | |||
| 424 | gotos.push_back(root.insert(ip, *goto_stmt)); | 430 | gotos.push_back(root.insert(ip, *goto_stmt)); |
| 425 | break; | 431 | break; |
| 426 | } | 432 | } |
| 433 | case Flow::EndClass::Kill: | ||
| 434 | root.insert(ip, *pool.Create(Kill{})); | ||
| 435 | break; | ||
| 427 | } | 436 | } |
| 428 | } | 437 | } |
| 429 | } | 438 | } |
| @@ -729,6 +738,15 @@ private: | |||
| 729 | current_block = nullptr; | 738 | current_block = nullptr; |
| 730 | break; | 739 | break; |
| 731 | } | 740 | } |
| 741 | case StatementType::Kill: { | ||
| 742 | if (!current_block) { | ||
| 743 | current_block = block_pool.Create(inst_pool); | ||
| 744 | block_list.push_back(current_block); | ||
| 745 | } | ||
| 746 | IR::IREmitter{*current_block}.DemoteToHelperInvocation(continue_block); | ||
| 747 | current_block = nullptr; | ||
| 748 | break; | ||
| 749 | } | ||
| 732 | default: | 750 | default: |
| 733 | throw NotImplementedException("Statement type {}", stmt.type); | 751 | throw NotImplementedException("Statement type {}", stmt.type); |
| 734 | } | 752 | } |