diff options
Diffstat (limited to 'src/shader_recompiler/backend/glasm')
4 files changed, 42 insertions, 39 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp index 056d8cbf8..51ca83d18 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp | |||
| @@ -117,8 +117,6 @@ auto Arg(EmitContext& ctx, const IR::Value& arg) { | |||
| 117 | return Identity<const IR::Value&>{arg}; | 117 | return Identity<const IR::Value&>{arg}; |
| 118 | } else if constexpr (std::is_same_v<ArgType, u32>) { | 118 | } else if constexpr (std::is_same_v<ArgType, u32>) { |
| 119 | return Identity{arg.U32()}; | 119 | return Identity{arg.U32()}; |
| 120 | } else if constexpr (std::is_same_v<ArgType, IR::Block*>) { | ||
| 121 | return Identity{arg.Label()}; | ||
| 122 | } else if constexpr (std::is_same_v<ArgType, IR::Attribute>) { | 120 | } else if constexpr (std::is_same_v<ArgType, IR::Attribute>) { |
| 123 | return Identity{arg.Attribute()}; | 121 | return Identity{arg.Attribute()}; |
| 124 | } else if constexpr (std::is_same_v<ArgType, IR::Patch>) { | 122 | } else if constexpr (std::is_same_v<ArgType, IR::Patch>) { |
| @@ -177,6 +175,39 @@ void EmitInst(EmitContext& ctx, IR::Inst* inst) { | |||
| 177 | throw LogicError("Invalid opcode {}", inst->GetOpcode()); | 175 | throw LogicError("Invalid opcode {}", inst->GetOpcode()); |
| 178 | } | 176 | } |
| 179 | 177 | ||
| 178 | void EmitCode(EmitContext& ctx, const IR::Program& program) { | ||
| 179 | const auto eval{ | ||
| 180 | [&](const IR::U1& cond) { return ScalarS32{ctx.reg_alloc.Consume(IR::Value{cond})}; }}; | ||
| 181 | for (const IR::AbstractSyntaxNode& node : program.syntax_list) { | ||
| 182 | switch (node.type) { | ||
| 183 | case IR::AbstractSyntaxNode::Type::Block: | ||
| 184 | for (IR::Inst& inst : node.block->Instructions()) { | ||
| 185 | EmitInst(ctx, &inst); | ||
| 186 | } | ||
| 187 | break; | ||
| 188 | case IR::AbstractSyntaxNode::Type::If: | ||
| 189 | ctx.Add("MOV.S.CC RC,{};IF NE.x;", eval(node.if_node.cond)); | ||
| 190 | break; | ||
| 191 | case IR::AbstractSyntaxNode::Type::EndIf: | ||
| 192 | ctx.Add("ENDIF;"); | ||
| 193 | break; | ||
| 194 | case IR::AbstractSyntaxNode::Type::Loop: | ||
| 195 | ctx.Add("REP;"); | ||
| 196 | break; | ||
| 197 | case IR::AbstractSyntaxNode::Type::Repeat: | ||
| 198 | ctx.Add("MOV.S.CC RC,{};BRK NE.x;ENDREP;", eval(node.repeat.cond)); | ||
| 199 | break; | ||
| 200 | case IR::AbstractSyntaxNode::Type::Break: | ||
| 201 | ctx.Add("MOV.S.CC RC,{};BRK NE.x;", eval(node.repeat.cond)); | ||
| 202 | break; | ||
| 203 | case IR::AbstractSyntaxNode::Type::Return: | ||
| 204 | case IR::AbstractSyntaxNode::Type::Unreachable: | ||
| 205 | ctx.Add("RET;"); | ||
| 206 | break; | ||
| 207 | } | ||
| 208 | } | ||
| 209 | } | ||
| 210 | |||
| 180 | void SetupOptions(std::string& header, Info info) { | 211 | void SetupOptions(std::string& header, Info info) { |
| 181 | if (info.uses_int64_bit_atomics) { | 212 | if (info.uses_int64_bit_atomics) { |
| 182 | header += "OPTION NV_shader_atomic_int64;"; | 213 | header += "OPTION NV_shader_atomic_int64;"; |
| @@ -201,11 +232,7 @@ void SetupOptions(std::string& header, Info info) { | |||
| 201 | 232 | ||
| 202 | std::string EmitGLASM(const Profile&, IR::Program& program, Bindings&) { | 233 | std::string EmitGLASM(const Profile&, IR::Program& program, Bindings&) { |
| 203 | EmitContext ctx{program}; | 234 | EmitContext ctx{program}; |
| 204 | for (IR::Block* const block : program.blocks) { | 235 | EmitCode(ctx, program); |
| 205 | for (IR::Inst& inst : block->Instructions()) { | ||
| 206 | EmitInst(ctx, &inst); | ||
| 207 | } | ||
| 208 | } | ||
| 209 | std::string header = "!!NVcp5.0\n" | 236 | std::string header = "!!NVcp5.0\n" |
| 210 | "OPTION NV_internal;"; | 237 | "OPTION NV_internal;"; |
| 211 | SetupOptions(header, program.info); | 238 | SetupOptions(header, program.info); |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h index 8202354fe..0f7f16e6e 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h +++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h | |||
| @@ -22,13 +22,8 @@ class EmitContext; | |||
| 22 | void EmitPhi(EmitContext& ctx, IR::Inst& inst); | 22 | void EmitPhi(EmitContext& ctx, IR::Inst& inst); |
| 23 | void EmitVoid(EmitContext& ctx); | 23 | void EmitVoid(EmitContext& ctx); |
| 24 | void EmitIdentity(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); | 24 | void EmitIdentity(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); |
| 25 | void EmitBranch(EmitContext& ctx); | 25 | void EmitBranchConditionRef(EmitContext&); |
| 26 | void EmitBranchConditional(EmitContext& ctx); | ||
| 27 | void EmitLoopMerge(EmitContext& ctx); | ||
| 28 | void EmitSelectionMerge(EmitContext& ctx); | ||
| 29 | void EmitReturn(EmitContext& ctx); | ||
| 30 | void EmitJoin(EmitContext& ctx); | 26 | void EmitJoin(EmitContext& ctx); |
| 31 | void EmitUnreachable(EmitContext& ctx); | ||
| 32 | void EmitDemoteToHelperInvocation(EmitContext& ctx); | 27 | void EmitDemoteToHelperInvocation(EmitContext& ctx); |
| 33 | void EmitBarrier(EmitContext& ctx); | 28 | void EmitBarrier(EmitContext& ctx); |
| 34 | void EmitWorkgroupMemoryBarrier(EmitContext& ctx); | 29 | void EmitWorkgroupMemoryBarrier(EmitContext& ctx); |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp index 15fd23356..adcc0404b 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp | |||
| @@ -91,7 +91,8 @@ void EmitBitFieldInsert(EmitContext& ctx, IR::Inst& inst, ScalarS32 base, Scalar | |||
| 91 | if (count.type != Type::Register && offset.type != Type::Register) { | 91 | if (count.type != Type::Register && offset.type != Type::Register) { |
| 92 | ctx.Add("BFI.S {},{{{},{},0,0}},{},{};", ret, count, offset, insert, base); | 92 | ctx.Add("BFI.S {},{{{},{},0,0}},{},{};", ret, count, offset, insert, base); |
| 93 | } else { | 93 | } else { |
| 94 | ctx.Add("MOV.S RC.x,{};MOV.U RC.y,{};" | 94 | ctx.Add("MOV.S RC.x,{};" |
| 95 | "MOV.S RC.y,{};" | ||
| 95 | "BFI.S {},RC,{},{};", | 96 | "BFI.S {},RC,{},{};", |
| 96 | count, offset, ret, insert, base); | 97 | count, offset, ret, insert, base); |
| 97 | } | 98 | } |
| @@ -103,7 +104,8 @@ void EmitBitFieldSExtract(EmitContext& ctx, IR::Inst& inst, ScalarS32 base, Scal | |||
| 103 | if (count.type != Type::Register && offset.type != Type::Register) { | 104 | if (count.type != Type::Register && offset.type != Type::Register) { |
| 104 | ctx.Add("BFE.S {},{{{},{},0,0}},{};", ret, count, offset, base); | 105 | ctx.Add("BFE.S {},{{{},{},0,0}},{};", ret, count, offset, base); |
| 105 | } else { | 106 | } else { |
| 106 | ctx.Add("MOV.S RC.x,{};MOV.U RC.y,{};" | 107 | ctx.Add("MOV.S RC.x,{};" |
| 108 | "MOV.S RC.y,{};" | ||
| 107 | "BFE.S {},RC,{};", | 109 | "BFE.S {},RC,{};", |
| 108 | count, offset, ret, base); | 110 | count, offset, ret, base); |
| 109 | } | 111 | } |
| @@ -115,7 +117,8 @@ void EmitBitFieldUExtract(EmitContext& ctx, IR::Inst& inst, ScalarU32 base, Scal | |||
| 115 | if (count.type != Type::Register && offset.type != Type::Register) { | 117 | if (count.type != Type::Register && offset.type != Type::Register) { |
| 116 | ctx.Add("BFE.U {},{{{},{},0,0}},{};", ret, count, offset, base); | 118 | ctx.Add("BFE.U {},{{{},{},0,0}},{};", ret, count, offset, base); |
| 117 | } else { | 119 | } else { |
| 118 | ctx.Add("MOV.U RC.x,{};MOV.U RC.y,{};" | 120 | ctx.Add("MOV.U RC.x,{};" |
| 121 | "MOV.U RC.y,{};" | ||
| 119 | "BFE.U {},RC,{};", | 122 | "BFE.U {},RC,{};", |
| 120 | count, offset, ret, base); | 123 | count, offset, ret, base); |
| 121 | } | 124 | } |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp index b40d09f8c..f37ad5587 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp | |||
| @@ -23,34 +23,12 @@ void EmitPhi(EmitContext& ctx, IR::Inst& inst) { | |||
| 23 | 23 | ||
| 24 | void EmitVoid(EmitContext&) {} | 24 | void EmitVoid(EmitContext&) {} |
| 25 | 25 | ||
| 26 | void EmitBranch(EmitContext& ctx) { | 26 | void EmitBranchConditionRef(EmitContext&) {} |
| 27 | NotImplemented(); | ||
| 28 | } | ||
| 29 | |||
| 30 | void EmitBranchConditional(EmitContext& ctx) { | ||
| 31 | NotImplemented(); | ||
| 32 | } | ||
| 33 | |||
| 34 | void EmitLoopMerge(EmitContext& ctx) { | ||
| 35 | NotImplemented(); | ||
| 36 | } | ||
| 37 | |||
| 38 | void EmitSelectionMerge(EmitContext& ctx) { | ||
| 39 | NotImplemented(); | ||
| 40 | } | ||
| 41 | |||
| 42 | void EmitReturn(EmitContext& ctx) { | ||
| 43 | ctx.Add("RET;"); | ||
| 44 | } | ||
| 45 | 27 | ||
| 46 | void EmitJoin(EmitContext& ctx) { | 28 | void EmitJoin(EmitContext& ctx) { |
| 47 | NotImplemented(); | 29 | NotImplemented(); |
| 48 | } | 30 | } |
| 49 | 31 | ||
| 50 | void EmitUnreachable(EmitContext& ctx) { | ||
| 51 | NotImplemented(); | ||
| 52 | } | ||
| 53 | |||
| 54 | void EmitDemoteToHelperInvocation(EmitContext& ctx) { | 32 | void EmitDemoteToHelperInvocation(EmitContext& ctx) { |
| 55 | NotImplemented(); | 33 | NotImplemented(); |
| 56 | } | 34 | } |