diff options
Diffstat (limited to '')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/load_effective_address.cpp | 100 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | 20 |
2 files changed, 100 insertions, 20 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/load_effective_address.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/load_effective_address.cpp new file mode 100644 index 000000000..784588e83 --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/load_effective_address.cpp | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/bit_field.h" | ||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||
| 8 | |||
| 9 | namespace Shader::Maxwell { | ||
| 10 | namespace { | ||
| 11 | void LEA_hi(TranslatorVisitor& v, u64 insn, const IR::U32& base, IR::U32 offset_hi, u64 scale, | ||
| 12 | bool neg, bool x) { | ||
| 13 | union { | ||
| 14 | u64 insn; | ||
| 15 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 16 | BitField<8, 8, IR::Reg> offset_lo_reg; | ||
| 17 | BitField<48, 3, IR::Pred> pred; | ||
| 18 | } const lea{insn}; | ||
| 19 | |||
| 20 | if (x) { | ||
| 21 | throw NotImplementedException("LEA.HI X"); | ||
| 22 | } | ||
| 23 | if (lea.pred != IR::Pred::PT) { | ||
| 24 | throw NotImplementedException("LEA.LO Pred"); | ||
| 25 | } | ||
| 26 | |||
| 27 | const IR::U32 offset_lo{v.X(lea.offset_lo_reg)}; | ||
| 28 | const IR::U64 packed_offset{v.ir.PackUint2x32(v.ir.CompositeConstruct(offset_lo, offset_hi))}; | ||
| 29 | const IR::U64 offset{neg ? IR::U64{v.ir.INeg(packed_offset)} : packed_offset}; | ||
| 30 | |||
| 31 | const s32 hi_scale{32 - static_cast<s32>(scale)}; | ||
| 32 | const IR::U64 scaled_offset{v.ir.ShiftRightLogical(offset, v.ir.Imm32(hi_scale))}; | ||
| 33 | const IR::U32 scaled_offset_w0{v.ir.CompositeExtract(v.ir.UnpackUint2x32(scaled_offset), 0)}; | ||
| 34 | |||
| 35 | IR::U32 result{v.ir.IAdd(base, scaled_offset_w0)}; | ||
| 36 | v.X(lea.dest_reg, result); | ||
| 37 | } | ||
| 38 | |||
| 39 | void LEA_lo(TranslatorVisitor& v, u64 insn, const IR::U32& base) { | ||
| 40 | union { | ||
| 41 | u64 insn; | ||
| 42 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 43 | BitField<8, 8, IR::Reg> offset_lo_reg; | ||
| 44 | BitField<39, 5, u64> scale; | ||
| 45 | BitField<45, 1, u64> neg; | ||
| 46 | BitField<46, 1, u64> x; | ||
| 47 | BitField<48, 3, IR::Pred> pred; | ||
| 48 | } const lea{insn}; | ||
| 49 | if (lea.x != 0) { | ||
| 50 | throw NotImplementedException("LEA.LO X"); | ||
| 51 | } | ||
| 52 | if (lea.pred != IR::Pred::PT) { | ||
| 53 | throw NotImplementedException("LEA.LO Pred"); | ||
| 54 | } | ||
| 55 | |||
| 56 | const IR::U32 offset_lo{v.X(lea.offset_lo_reg)}; | ||
| 57 | const s32 scale{static_cast<s32>(lea.scale)}; | ||
| 58 | const IR::U32 offset{lea.neg != 0 ? IR::U32{v.ir.INeg(offset_lo)} : offset_lo}; | ||
| 59 | const IR::U32 scaled_offset{v.ir.ShiftLeftLogical(offset, v.ir.Imm32(scale))}; | ||
| 60 | |||
| 61 | IR::U32 result{v.ir.IAdd(base, scaled_offset)}; | ||
| 62 | v.X(lea.dest_reg, result); | ||
| 63 | } | ||
| 64 | } // Anonymous namespace | ||
| 65 | |||
| 66 | void TranslatorVisitor::LEA_hi_reg(u64 insn) { | ||
| 67 | union { | ||
| 68 | u64 insn; | ||
| 69 | BitField<28, 5, u64> scale; | ||
| 70 | BitField<37, 1, u64> neg; | ||
| 71 | BitField<38, 1, u64> x; | ||
| 72 | } const lea{insn}; | ||
| 73 | |||
| 74 | LEA_hi(*this, insn, GetReg20(insn), GetReg39(insn), lea.scale, lea.neg != 0, lea.x != 0); | ||
| 75 | } | ||
| 76 | |||
| 77 | void TranslatorVisitor::LEA_hi_cbuf(u64 insn) { | ||
| 78 | union { | ||
| 79 | u64 insn; | ||
| 80 | BitField<51, 5, u64> scale; | ||
| 81 | BitField<56, 1, u64> neg; | ||
| 82 | BitField<57, 1, u64> x; | ||
| 83 | } const lea{insn}; | ||
| 84 | |||
| 85 | LEA_hi(*this, insn, GetCbuf(insn), GetReg39(insn), lea.scale, lea.neg != 0, lea.x != 0); | ||
| 86 | } | ||
| 87 | |||
| 88 | void TranslatorVisitor::LEA_lo_reg(u64 insn) { | ||
| 89 | LEA_lo(*this, insn, GetReg20(insn)); | ||
| 90 | } | ||
| 91 | |||
| 92 | void TranslatorVisitor::LEA_lo_cbuf(u64 insn) { | ||
| 93 | LEA_lo(*this, insn, GetCbuf(insn)); | ||
| 94 | } | ||
| 95 | |||
| 96 | void TranslatorVisitor::LEA_lo_imm(u64 insn) { | ||
| 97 | LEA_lo(*this, insn, GetImm20(insn)); | ||
| 98 | } | ||
| 99 | |||
| 100 | } // namespace Shader::Maxwell | ||
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp index bd7a7a8b7..62863aff6 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | |||
| @@ -437,26 +437,6 @@ void TranslatorVisitor::LDS(u64) { | |||
| 437 | ThrowNotImplemented(Opcode::LDS); | 437 | ThrowNotImplemented(Opcode::LDS); |
| 438 | } | 438 | } |
| 439 | 439 | ||
| 440 | void TranslatorVisitor::LEA_hi_reg(u64) { | ||
| 441 | ThrowNotImplemented(Opcode::LEA_hi_reg); | ||
| 442 | } | ||
| 443 | |||
| 444 | void TranslatorVisitor::LEA_hi_cbuf(u64) { | ||
| 445 | ThrowNotImplemented(Opcode::LEA_hi_cbuf); | ||
| 446 | } | ||
| 447 | |||
| 448 | void TranslatorVisitor::LEA_lo_reg(u64) { | ||
| 449 | ThrowNotImplemented(Opcode::LEA_lo_reg); | ||
| 450 | } | ||
| 451 | |||
| 452 | void TranslatorVisitor::LEA_lo_cbuf(u64) { | ||
| 453 | ThrowNotImplemented(Opcode::LEA_lo_cbuf); | ||
| 454 | } | ||
| 455 | |||
| 456 | void TranslatorVisitor::LEA_lo_imm(u64) { | ||
| 457 | ThrowNotImplemented(Opcode::LEA_lo_imm); | ||
| 458 | } | ||
| 459 | |||
| 460 | void TranslatorVisitor::LEPC(u64) { | 440 | void TranslatorVisitor::LEPC(u64) { |
| 461 | ThrowNotImplemented(Opcode::LEPC); | 441 | ThrowNotImplemented(Opcode::LEPC); |
| 462 | } | 442 | } |