diff options
| author | 2018-12-19 00:43:23 -0300 | |
|---|---|---|
| committer | 2019-01-15 17:54:52 -0300 | |
| commit | c9cf899d1852da73e90ead3d5c0eeee58de6152d (patch) | |
| tree | 3932950be46bde427c6c538a2a180e7d0a5bac4d /src | |
| parent | shader_decode: Implement IADD3 (diff) | |
| download | yuzu-c9cf899d1852da73e90ead3d5c0eeee58de6152d.tar.gz yuzu-c9cf899d1852da73e90ead3d5c0eeee58de6152d.tar.xz yuzu-c9cf899d1852da73e90ead3d5c0eeee58de6152d.zip | |
shader_decode: Implement LEA
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/arithmetic_integer.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp index 3b9b9d6d9..b12dc5ba8 100644 --- a/src/video_core/shader/decode/arithmetic_integer.cpp +++ b/src/video_core/shader/decode/arithmetic_integer.cpp | |||
| @@ -12,6 +12,7 @@ namespace VideoCommon::Shader { | |||
| 12 | using Tegra::Shader::IAdd3Height; | 12 | using Tegra::Shader::IAdd3Height; |
| 13 | using Tegra::Shader::Instruction; | 13 | using Tegra::Shader::Instruction; |
| 14 | using Tegra::Shader::OpCode; | 14 | using Tegra::Shader::OpCode; |
| 15 | using Tegra::Shader::Pred; | ||
| 15 | using Tegra::Shader::Register; | 16 | using Tegra::Shader::Register; |
| 16 | 17 | ||
| 17 | u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, u32 pc) { | 18 | u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, u32 pc) { |
| @@ -175,6 +176,60 @@ u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, u32 pc) { | |||
| 175 | SetRegister(bb, instr.gpr0, value); | 176 | SetRegister(bb, instr.gpr0, value); |
| 176 | break; | 177 | break; |
| 177 | } | 178 | } |
| 179 | case OpCode::Id::LEA_R2: | ||
| 180 | case OpCode::Id::LEA_R1: | ||
| 181 | case OpCode::Id::LEA_IMM: | ||
| 182 | case OpCode::Id::LEA_RZ: | ||
| 183 | case OpCode::Id::LEA_HI: { | ||
| 184 | const auto [op_a, op_b, op_c] = [&]() -> std::tuple<Node, Node, Node> { | ||
| 185 | switch (opcode->get().GetId()) { | ||
| 186 | case OpCode::Id::LEA_R2: { | ||
| 187 | return {GetRegister(instr.gpr20), GetRegister(instr.gpr39), | ||
| 188 | Immediate(static_cast<u32>(instr.lea.r2.entry_a))}; | ||
| 189 | } | ||
| 190 | |||
| 191 | case OpCode::Id::LEA_R1: { | ||
| 192 | const bool neg = instr.lea.r1.neg != 0; | ||
| 193 | return {GetOperandAbsNegInteger(GetRegister(instr.gpr8), false, neg, true), | ||
| 194 | GetRegister(instr.gpr20), | ||
| 195 | Immediate(static_cast<u32>(instr.lea.r1.entry_a))}; | ||
| 196 | } | ||
| 197 | |||
| 198 | case OpCode::Id::LEA_IMM: { | ||
| 199 | const bool neg = instr.lea.imm.neg != 0; | ||
| 200 | return {Immediate(static_cast<u32>(instr.lea.imm.entry_a)), | ||
| 201 | GetOperandAbsNegInteger(GetRegister(instr.gpr8), false, neg, true), | ||
| 202 | Immediate(static_cast<u32>(instr.lea.imm.entry_b))}; | ||
| 203 | } | ||
| 204 | |||
| 205 | case OpCode::Id::LEA_RZ: { | ||
| 206 | const bool neg = instr.lea.rz.neg != 0; | ||
| 207 | return {GetConstBuffer(instr.lea.rz.cb_index, instr.lea.rz.cb_offset), | ||
| 208 | GetOperandAbsNegInteger(GetRegister(instr.gpr8), false, neg, true), | ||
| 209 | Immediate(static_cast<u32>(instr.lea.rz.entry_a))}; | ||
| 210 | } | ||
| 211 | |||
| 212 | case OpCode::Id::LEA_HI: | ||
| 213 | default: | ||
| 214 | UNIMPLEMENTED_MSG("Unhandled LEA subinstruction: {}", opcode->get().GetName()); | ||
| 215 | |||
| 216 | return {Immediate(static_cast<u32>(instr.lea.imm.entry_a)), GetRegister(instr.gpr8), | ||
| 217 | Immediate(static_cast<u32>(instr.lea.imm.entry_b))}; | ||
| 218 | } | ||
| 219 | }(); | ||
| 220 | |||
| 221 | UNIMPLEMENTED_IF_MSG(instr.lea.pred48 != static_cast<u64>(Pred::UnusedIndex), | ||
| 222 | "Unhandled LEA Predicate"); | ||
| 223 | |||
| 224 | const Node shifted_c = | ||
| 225 | Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, Immediate(1), op_c); | ||
| 226 | const Node mul_bc = Operation(OperationCode::IMul, NO_PRECISE, op_b, shifted_c); | ||
| 227 | const Node value = Operation(OperationCode::IAdd, NO_PRECISE, op_a, mul_bc); | ||
| 228 | |||
| 229 | SetRegister(bb, instr.gpr0, value); | ||
| 230 | |||
| 231 | break; | ||
| 232 | } | ||
| 178 | default: | 233 | default: |
| 179 | UNIMPLEMENTED_MSG("Unhandled ArithmeticInteger instruction: {}", opcode->get().GetName()); | 234 | UNIMPLEMENTED_MSG("Unhandled ArithmeticInteger instruction: {}", opcode->get().GetName()); |
| 180 | } | 235 | } |