diff options
| author | 2018-12-21 02:31:46 -0300 | |
|---|---|---|
| committer | 2019-01-15 17:54:52 -0300 | |
| commit | 68c99d2597717e5717e725efcfdb2bd53146d08c (patch) | |
| tree | f150c0116bc68f76934ba73c0cd3a9b26bb78de2 /src | |
| parent | shader_decode: Implement HADD2_IMM and HMUL2_IMM (diff) | |
| download | yuzu-68c99d2597717e5717e725efcfdb2bd53146d08c.tar.gz yuzu-68c99d2597717e5717e725efcfdb2bd53146d08c.tar.xz yuzu-68c99d2597717e5717e725efcfdb2bd53146d08c.zip | |
shader_decode: Implement HADD2 and HMUL2
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/arithmetic_half.cpp | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/src/video_core/shader/decode/arithmetic_half.cpp b/src/video_core/shader/decode/arithmetic_half.cpp index 3b189b0d1..a6c6f3174 100644 --- a/src/video_core/shader/decode/arithmetic_half.cpp +++ b/src/video_core/shader/decode/arithmetic_half.cpp | |||
| @@ -16,7 +16,54 @@ u32 ShaderIR::DecodeArithmeticHalf(BasicBlock& bb, u32 pc) { | |||
| 16 | const Instruction instr = {program_code[pc]}; | 16 | const Instruction instr = {program_code[pc]}; |
| 17 | const auto opcode = OpCode::Decode(instr); | 17 | const auto opcode = OpCode::Decode(instr); |
| 18 | 18 | ||
| 19 | UNIMPLEMENTED(); | 19 | if (opcode->get().GetId() == OpCode::Id::HADD2_C || |
| 20 | opcode->get().GetId() == OpCode::Id::HADD2_R) { | ||
| 21 | UNIMPLEMENTED_IF(instr.alu_half.ftz != 0); | ||
| 22 | } | ||
| 23 | UNIMPLEMENTED_IF_MSG(instr.alu_half.saturate != 0, | ||
| 24 | "Half float saturation not implemented"); | ||
| 25 | |||
| 26 | const bool negate_a = | ||
| 27 | opcode->get().GetId() != OpCode::Id::HMUL2_R && instr.alu_half.negate_a != 0; | ||
| 28 | const bool negate_b = | ||
| 29 | opcode->get().GetId() != OpCode::Id::HMUL2_C && instr.alu_half.negate_b != 0; | ||
| 30 | |||
| 31 | const Node op_a = GetOperandAbsNegHalf(GetRegister(instr.gpr8), instr.alu_half.abs_a, negate_a); | ||
| 32 | |||
| 33 | // instr.alu_half.type_a | ||
| 34 | |||
| 35 | Node op_b = [&]() { | ||
| 36 | switch (opcode->get().GetId()) { | ||
| 37 | case OpCode::Id::HADD2_C: | ||
| 38 | case OpCode::Id::HMUL2_C: | ||
| 39 | return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); | ||
| 40 | case OpCode::Id::HADD2_R: | ||
| 41 | case OpCode::Id::HMUL2_R: | ||
| 42 | return GetRegister(instr.gpr20); | ||
| 43 | default: | ||
| 44 | UNREACHABLE(); | ||
| 45 | return Immediate(0); | ||
| 46 | } | ||
| 47 | }(); | ||
| 48 | op_b = GetOperandAbsNegHalf(op_b, instr.alu_half.abs_b, negate_b); | ||
| 49 | |||
| 50 | Node value = [&]() { | ||
| 51 | MetaHalfArithmetic meta{true, {instr.alu_half_imm.type_a, instr.alu_half.type_b}}; | ||
| 52 | switch (opcode->get().GetId()) { | ||
| 53 | case OpCode::Id::HADD2_C: | ||
| 54 | case OpCode::Id::HADD2_R: | ||
| 55 | return Operation(OperationCode::HAdd, meta, op_a, op_b); | ||
| 56 | case OpCode::Id::HMUL2_C: | ||
| 57 | case OpCode::Id::HMUL2_R: | ||
| 58 | return Operation(OperationCode::HMul, meta, op_a, op_b); | ||
| 59 | default: | ||
| 60 | UNIMPLEMENTED_MSG("Unhandled half float instruction: {}", opcode->get().GetName()); | ||
| 61 | return Immediate(0); | ||
| 62 | } | ||
| 63 | }(); | ||
| 64 | value = HalfMerge(GetRegister(instr.gpr0), value, instr.alu_half.merge); | ||
| 65 | |||
| 66 | SetRegister(bb, instr.gpr0, value); | ||
| 20 | 67 | ||
| 21 | return pc; | 68 | return pc; |
| 22 | } | 69 | } |