summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glasm/emit_glasm.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-05-09 03:11:34 -0300
committerGravatar ameerj2021-07-22 21:51:30 -0400
commit1c9307969c4e3f6206947f1360acae33f95a4a86 (patch)
tree86ccd9c88333327d7659a396f66301955a088f45 /src/shader_recompiler/backend/glasm/emit_glasm.cpp
parentglasm: Use CMP.S for Select32 (diff)
downloadyuzu-1c9307969c4e3f6206947f1360acae33f95a4a86.tar.gz
yuzu-1c9307969c4e3f6206947f1360acae33f95a4a86.tar.xz
yuzu-1c9307969c4e3f6206947f1360acae33f95a4a86.zip
glasm: Make GLASM aware of types
Diffstat (limited to 'src/shader_recompiler/backend/glasm/emit_glasm.cpp')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm.cpp95
1 files changed, 77 insertions, 18 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
index 7ec880c81..8981cf300 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
@@ -27,22 +27,80 @@ struct FuncTraits<ReturnType_ (*)(Args...)> {
27 using ArgType = std::tuple_element_t<I, std::tuple<Args...>>; 27 using ArgType = std::tuple_element_t<I, std::tuple<Args...>>;
28}; 28};
29 29
30template <typename T>
31struct Identity {
32 Identity(const T& data_) : data{data_} {}
33
34 const T& Extract() {
35 return data;
36 }
37
38 T data;
39};
40
41template <bool scalar>
42struct RegWrapper {
43 RegWrapper(EmitContext& ctx, Value value)
44 : reg_alloc{ctx.reg_alloc}, allocated{value.type != Type::Register} {
45 reg = allocated ? reg_alloc.AllocReg() : Register{value};
46 switch (value.type) {
47 case Type::Register:
48 break;
49 case Type::U32:
50 ctx.Add("MOV.U {}.x,{};", reg, value.imm_u32);
51 break;
52 case Type::S32:
53 ctx.Add("MOV.S {}.x,{};", reg, value.imm_s32);
54 break;
55 case Type::F32:
56 ctx.Add("MOV.F {}.x,{};", reg, value.imm_f32);
57 break;
58 }
59 }
60 ~RegWrapper() {
61 if (allocated) {
62 reg_alloc.FreeReg(reg);
63 }
64 }
65
66 auto Extract() {
67 return std::conditional_t<scalar, ScalarRegister, Register>{Value{reg}};
68 }
69
70 RegAlloc& reg_alloc;
71 Register reg{};
72 bool allocated{};
73};
74
30template <typename ArgType> 75template <typename ArgType>
31auto Arg(EmitContext& ctx, const IR::Value& arg) { 76auto Arg(EmitContext& ctx, const IR::Value& arg) {
32 if constexpr (std::is_same_v<ArgType, std::string_view>) { 77 if constexpr (std::is_same_v<ArgType, Register>) {
33 return ctx.reg_alloc.Consume(arg); 78 return RegWrapper<false>{ctx, ctx.reg_alloc.Consume(arg)};
79 } else if constexpr (std::is_same_v<ArgType, ScalarRegister>) {
80 return RegWrapper<true>{ctx, ctx.reg_alloc.Consume(arg)};
81 } else if constexpr (std::is_base_of_v<Value, ArgType>) {
82 return Identity{ArgType{ctx.reg_alloc.Consume(arg)}};
34 } else if constexpr (std::is_same_v<ArgType, const IR::Value&>) { 83 } else if constexpr (std::is_same_v<ArgType, const IR::Value&>) {
35 return arg; 84 return Identity{arg};
36 } else if constexpr (std::is_same_v<ArgType, u32>) { 85 } else if constexpr (std::is_same_v<ArgType, u32>) {
37 return arg.U32(); 86 return Identity{arg.U32()};
38 } else if constexpr (std::is_same_v<ArgType, IR::Block*>) { 87 } else if constexpr (std::is_same_v<ArgType, IR::Block*>) {
39 return arg.Label(); 88 return Identity{arg.Label()};
40 } else if constexpr (std::is_same_v<ArgType, IR::Attribute>) { 89 } else if constexpr (std::is_same_v<ArgType, IR::Attribute>) {
41 return arg.Attribute(); 90 return Identity{arg.Attribute()};
42 } else if constexpr (std::is_same_v<ArgType, IR::Patch>) { 91 } else if constexpr (std::is_same_v<ArgType, IR::Patch>) {
43 return arg.Patch(); 92 return Identity{arg.Patch()};
44 } else if constexpr (std::is_same_v<ArgType, IR::Reg>) { 93 } else if constexpr (std::is_same_v<ArgType, IR::Reg>) {
45 return arg.Reg(); 94 return Identity{arg.Reg()};
95 }
96}
97
98template <auto func, bool is_first_arg_inst, typename... Args>
99void InvokeCall(EmitContext& ctx, IR::Inst* inst, Args&&... args) {
100 if constexpr (is_first_arg_inst) {
101 func(ctx, *inst, std::forward<Args>(args.Extract())...);
102 } else {
103 func(ctx, std::forward<Args>(args.Extract())...);
46 } 104 }
47} 105}
48 106
@@ -50,9 +108,10 @@ template <auto func, bool is_first_arg_inst, size_t... I>
50void Invoke(EmitContext& ctx, IR::Inst* inst, std::index_sequence<I...>) { 108void Invoke(EmitContext& ctx, IR::Inst* inst, std::index_sequence<I...>) {
51 using Traits = FuncTraits<decltype(func)>; 109 using Traits = FuncTraits<decltype(func)>;
52 if constexpr (is_first_arg_inst) { 110 if constexpr (is_first_arg_inst) {
53 func(ctx, *inst, Arg<typename Traits::template ArgType<I + 2>>(ctx, inst->Arg(I))...); 111 func(ctx, *inst,
112 Arg<typename Traits::template ArgType<I + 2>>(ctx, inst->Arg(I)).Extract()...);
54 } else { 113 } else {
55 func(ctx, Arg<typename Traits::template ArgType<I + 1>>(ctx, inst->Arg(I))...); 114 func(ctx, Arg<typename Traits::template ArgType<I + 1>>(ctx, inst->Arg(I)).Extract()...);
56 } 115 }
57} 116}
58 117
@@ -81,7 +140,7 @@ void EmitInst(EmitContext& ctx, IR::Inst* inst) {
81 throw LogicError("Invalid opcode {}", inst->GetOpcode()); 140 throw LogicError("Invalid opcode {}", inst->GetOpcode());
82} 141}
83 142
84void Identity(IR::Inst& inst, const IR::Value& value) { 143void Alias(IR::Inst& inst, const IR::Value& value) {
85 if (value.IsImmediate()) { 144 if (value.IsImmediate()) {
86 return; 145 return;
87 } 146 }
@@ -125,31 +184,31 @@ std::string EmitGLASM(const Profile&, IR::Program& program, Bindings&) {
125} 184}
126 185
127void EmitIdentity(EmitContext&, IR::Inst& inst, const IR::Value& value) { 186void EmitIdentity(EmitContext&, IR::Inst& inst, const IR::Value& value) {
128 Identity(inst, value); 187 Alias(inst, value);
129} 188}
130 189
131void EmitBitCastU16F16(EmitContext&, IR::Inst& inst, const IR::Value& value) { 190void EmitBitCastU16F16(EmitContext&, IR::Inst& inst, const IR::Value& value) {
132 Identity(inst, value); 191 Alias(inst, value);
133} 192}
134 193
135void EmitBitCastU32F32(EmitContext&, IR::Inst& inst, const IR::Value& value) { 194void EmitBitCastU32F32(EmitContext&, IR::Inst& inst, const IR::Value& value) {
136 Identity(inst, value); 195 Alias(inst, value);
137} 196}
138 197
139void EmitBitCastU64F64(EmitContext&, IR::Inst& inst, const IR::Value& value) { 198void EmitBitCastU64F64(EmitContext&, IR::Inst& inst, const IR::Value& value) {
140 Identity(inst, value); 199 Alias(inst, value);
141} 200}
142 201
143void EmitBitCastF16U16(EmitContext&, IR::Inst& inst, const IR::Value& value) { 202void EmitBitCastF16U16(EmitContext&, IR::Inst& inst, const IR::Value& value) {
144 Identity(inst, value); 203 Alias(inst, value);
145} 204}
146 205
147void EmitBitCastF32U32(EmitContext&, IR::Inst& inst, const IR::Value& value) { 206void EmitBitCastF32U32(EmitContext&, IR::Inst& inst, const IR::Value& value) {
148 Identity(inst, value); 207 Alias(inst, value);
149} 208}
150 209
151void EmitBitCastF64U64(EmitContext&, IR::Inst& inst, const IR::Value& value) { 210void EmitBitCastF64U64(EmitContext&, IR::Inst& inst, const IR::Value& value) {
152 Identity(inst, value); 211 Alias(inst, value);
153} 212}
154 213
155} // namespace Shader::Backend::GLASM 214} // namespace Shader::Backend::GLASM