diff options
| author | 2018-12-20 23:54:47 -0300 | |
|---|---|---|
| committer | 2019-01-15 17:54:50 -0300 | |
| commit | 7c192ec43fb6a08baea5d55aa47fcf3fa98d4343 (patch) | |
| tree | 5d2db428128c0972877566bc6fc685e2a3a43525 /src | |
| parent | shader_decode: Implement MOV_C and MOV_R (diff) | |
| download | yuzu-7c192ec43fb6a08baea5d55aa47fcf3fa98d4343.tar.gz yuzu-7c192ec43fb6a08baea5d55aa47fcf3fa98d4343.tar.xz yuzu-7c192ec43fb6a08baea5d55aa47fcf3fa98d4343.zip | |
shader_decode: Implement FMUL_C, FMUL_R and FMUL_IMM
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/arithmetic.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/video_core/shader/decode/arithmetic.cpp b/src/video_core/shader/decode/arithmetic.cpp index c297f729e..78bca79e3 100644 --- a/src/video_core/shader/decode/arithmetic.cpp +++ b/src/video_core/shader/decode/arithmetic.cpp | |||
| @@ -36,6 +36,48 @@ u32 ShaderIR::DecodeArithmetic(BasicBlock& bb, u32 pc) { | |||
| 36 | SetRegister(bb, instr.gpr0, op_b); | 36 | SetRegister(bb, instr.gpr0, op_b); |
| 37 | break; | 37 | break; |
| 38 | } | 38 | } |
| 39 | case OpCode::Id::FMUL_C: | ||
| 40 | case OpCode::Id::FMUL_R: | ||
| 41 | case OpCode::Id::FMUL_IMM: { | ||
| 42 | // FMUL does not have 'abs' bits and only the second operand has a 'neg' bit. | ||
| 43 | UNIMPLEMENTED_IF_MSG(instr.fmul.tab5cb8_2 != 0, "FMUL tab5cb8_2({}) is not implemented", | ||
| 44 | instr.fmul.tab5cb8_2.Value()); | ||
| 45 | UNIMPLEMENTED_IF_MSG( | ||
| 46 | instr.fmul.tab5c68_0 != 1, "FMUL tab5cb8_0({}) is not implemented", | ||
| 47 | instr.fmul.tab5c68_0.Value()); // SMO typical sends 1 here which seems to be the default | ||
| 48 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, | ||
| 49 | "Condition codes generation in FMUL is not implemented"); | ||
| 50 | |||
| 51 | op_b = GetOperandAbsNegFloat(op_b, false, instr.fmul.negate_b); | ||
| 52 | |||
| 53 | // TODO(Rodrigo): Should precise be used when there's a postfactor? | ||
| 54 | Node value = Operation(OperationCode::FMul, PRECISE, op_a, op_b); | ||
| 55 | |||
| 56 | if (instr.fmul.postfactor != 0) { | ||
| 57 | auto postfactor = static_cast<s32>(instr.fmul.postfactor); | ||
| 58 | |||
| 59 | // Postfactor encoded as 3-bit 1's complement in instruction, interpreted with below | ||
| 60 | // logic. | ||
| 61 | if (postfactor >= 4) { | ||
| 62 | postfactor = 7 - postfactor; | ||
| 63 | } else { | ||
| 64 | postfactor = 0 - postfactor; | ||
| 65 | } | ||
| 66 | |||
| 67 | if (postfactor > 0) { | ||
| 68 | value = Operation(OperationCode::FMul, NO_PRECISE, value, | ||
| 69 | Immediate(static_cast<f32>(1 << postfactor))); | ||
| 70 | } else { | ||
| 71 | value = Operation(OperationCode::FDiv, NO_PRECISE, value, | ||
| 72 | Immediate(static_cast<f32>(1 << -postfactor))); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | value = GetSaturatedFloat(value, instr.alu.saturate_d); | ||
| 77 | |||
| 78 | SetRegister(bb, instr.gpr0, value); | ||
| 79 | break; | ||
| 80 | } | ||
| 39 | default: | 81 | default: |
| 40 | UNIMPLEMENTED_MSG("Unhandled arithmetic instruction: {}", opcode->get().GetName()); | 82 | UNIMPLEMENTED_MSG("Unhandled arithmetic instruction: {}", opcode->get().GetName()); |
| 41 | } | 83 | } |