diff options
Diffstat (limited to 'src/shader_recompiler')
9 files changed, 136 insertions, 29 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index 51c245a63..a8df03f90 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt | |||
| @@ -86,6 +86,7 @@ add_library(shader_recompiler STATIC | |||
| 86 | frontend/maxwell/translate/impl/integer_shift_right.cpp | 86 | frontend/maxwell/translate/impl/integer_shift_right.cpp |
| 87 | frontend/maxwell/translate/impl/integer_short_multiply_add.cpp | 87 | frontend/maxwell/translate/impl/integer_short_multiply_add.cpp |
| 88 | frontend/maxwell/translate/impl/integer_to_integer_conversion.cpp | 88 | frontend/maxwell/translate/impl/integer_to_integer_conversion.cpp |
| 89 | frontend/maxwell/translate/impl/load_effective_address.cpp | ||
| 89 | frontend/maxwell/translate/impl/load_store_attribute.cpp | 90 | frontend/maxwell/translate/impl/load_store_attribute.cpp |
| 90 | frontend/maxwell/translate/impl/load_store_memory.cpp | 91 | frontend/maxwell/translate/impl/load_store_memory.cpp |
| 91 | frontend/maxwell/translate/impl/logic_operation.cpp | 92 | frontend/maxwell/translate/impl/logic_operation.cpp |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index bed43c094..1f7d84871 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -132,7 +132,7 @@ void EmitBitCastU64F64(EmitContext& ctx); | |||
| 132 | void EmitBitCastF16U16(EmitContext& ctx); | 132 | void EmitBitCastF16U16(EmitContext& ctx); |
| 133 | Id EmitBitCastF32U32(EmitContext& ctx, Id value); | 133 | Id EmitBitCastF32U32(EmitContext& ctx, Id value); |
| 134 | void EmitBitCastF64U64(EmitContext& ctx); | 134 | void EmitBitCastF64U64(EmitContext& ctx); |
| 135 | void EmitPackUint2x32(EmitContext& ctx); | 135 | Id EmitPackUint2x32(EmitContext& ctx, Id value); |
| 136 | Id EmitUnpackUint2x32(EmitContext& ctx, Id value); | 136 | Id EmitUnpackUint2x32(EmitContext& ctx, Id value); |
| 137 | Id EmitPackFloat2x16(EmitContext& ctx, Id value); | 137 | Id EmitPackFloat2x16(EmitContext& ctx, Id value); |
| 138 | Id EmitUnpackFloat2x16(EmitContext& ctx, Id value); | 138 | Id EmitUnpackFloat2x16(EmitContext& ctx, Id value); |
| @@ -229,9 +229,11 @@ Id EmitISub32(EmitContext& ctx, Id a, Id b); | |||
| 229 | void EmitISub64(EmitContext& ctx); | 229 | void EmitISub64(EmitContext& ctx); |
| 230 | Id EmitIMul32(EmitContext& ctx, Id a, Id b); | 230 | Id EmitIMul32(EmitContext& ctx, Id a, Id b); |
| 231 | Id EmitINeg32(EmitContext& ctx, Id value); | 231 | Id EmitINeg32(EmitContext& ctx, Id value); |
| 232 | Id EmitINeg64(EmitContext& ctx, Id value); | ||
| 232 | Id EmitIAbs32(EmitContext& ctx, Id value); | 233 | Id EmitIAbs32(EmitContext& ctx, Id value); |
| 233 | Id EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift); | 234 | Id EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift); |
| 234 | Id EmitShiftRightLogical32(EmitContext& ctx, Id a, Id b); | 235 | Id EmitShiftRightLogical32(EmitContext& ctx, Id a, Id b); |
| 236 | Id EmitShiftRightLogical64(EmitContext& ctx, Id a, Id b); | ||
| 235 | Id EmitShiftRightArithmetic32(EmitContext& ctx, Id a, Id b); | 237 | Id EmitShiftRightArithmetic32(EmitContext& ctx, Id a, Id b); |
| 236 | Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b); | 238 | Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b); |
| 237 | Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b); | 239 | Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp index e0d1ba413..93a45d834 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp | |||
| @@ -30,8 +30,8 @@ void EmitBitCastF64U64(EmitContext&) { | |||
| 30 | throw NotImplementedException("SPIR-V Instruction"); | 30 | throw NotImplementedException("SPIR-V Instruction"); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | void EmitPackUint2x32(EmitContext&) { | 33 | Id EmitPackUint2x32(EmitContext& ctx, Id value) { |
| 34 | throw NotImplementedException("SPIR-V Instruction"); | 34 | return ctx.OpBitcast(ctx.U64, value); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | Id EmitUnpackUint2x32(EmitContext& ctx, Id value) { | 37 | Id EmitUnpackUint2x32(EmitContext& ctx, Id value) { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp index 162fb6a91..f5001cdaa 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp | |||
| @@ -62,6 +62,10 @@ Id EmitINeg32(EmitContext& ctx, Id value) { | |||
| 62 | return ctx.OpSNegate(ctx.U32[1], value); | 62 | return ctx.OpSNegate(ctx.U32[1], value); |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | Id EmitINeg64(EmitContext& ctx, Id value) { | ||
| 66 | return ctx.OpSNegate(ctx.U64, value); | ||
| 67 | } | ||
| 68 | |||
| 65 | Id EmitIAbs32(EmitContext& ctx, Id value) { | 69 | Id EmitIAbs32(EmitContext& ctx, Id value) { |
| 66 | return ctx.OpSAbs(ctx.U32[1], value); | 70 | return ctx.OpSAbs(ctx.U32[1], value); |
| 67 | } | 71 | } |
| @@ -74,6 +78,10 @@ Id EmitShiftRightLogical32(EmitContext& ctx, Id a, Id b) { | |||
| 74 | return ctx.OpShiftRightLogical(ctx.U32[1], a, b); | 78 | return ctx.OpShiftRightLogical(ctx.U32[1], a, b); |
| 75 | } | 79 | } |
| 76 | 80 | ||
| 81 | Id EmitShiftRightLogical64(EmitContext& ctx, Id a, Id b) { | ||
| 82 | return ctx.OpShiftRightLogical(ctx.U64, a, b); | ||
| 83 | } | ||
| 84 | |||
| 77 | Id EmitShiftRightArithmetic32(EmitContext& ctx, Id a, Id b) { | 85 | Id EmitShiftRightArithmetic32(EmitContext& ctx, Id a, Id b) { |
| 78 | return ctx.OpShiftRightArithmetic(ctx.U32[1], a, b); | 86 | return ctx.OpShiftRightArithmetic(ctx.U32[1], a, b); |
| 79 | } | 87 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 186920d8f..01f52183c 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -798,8 +798,15 @@ U32 IREmitter::IMul(const U32& a, const U32& b) { | |||
| 798 | return Inst<U32>(Opcode::IMul32, a, b); | 798 | return Inst<U32>(Opcode::IMul32, a, b); |
| 799 | } | 799 | } |
| 800 | 800 | ||
| 801 | U32 IREmitter::INeg(const U32& value) { | 801 | U32U64 IREmitter::INeg(const U32U64& value) { |
| 802 | return Inst<U32>(Opcode::INeg32, value); | 802 | switch (value.Type()) { |
| 803 | case Type::U32: | ||
| 804 | return Inst<U32>(Opcode::INeg32, value); | ||
| 805 | case Type::U64: | ||
| 806 | return Inst<U64>(Opcode::INeg64, value); | ||
| 807 | default: | ||
| 808 | ThrowInvalidType(value.Type()); | ||
| 809 | } | ||
| 803 | } | 810 | } |
| 804 | 811 | ||
| 805 | U32 IREmitter::IAbs(const U32& value) { | 812 | U32 IREmitter::IAbs(const U32& value) { |
| @@ -810,8 +817,15 @@ U32 IREmitter::ShiftLeftLogical(const U32& base, const U32& shift) { | |||
| 810 | return Inst<U32>(Opcode::ShiftLeftLogical32, base, shift); | 817 | return Inst<U32>(Opcode::ShiftLeftLogical32, base, shift); |
| 811 | } | 818 | } |
| 812 | 819 | ||
| 813 | U32 IREmitter::ShiftRightLogical(const U32& base, const U32& shift) { | 820 | U32U64 IREmitter::ShiftRightLogical(const U32U64& base, const U32& shift) { |
| 814 | return Inst<U32>(Opcode::ShiftRightLogical32, base, shift); | 821 | switch (base.Type()) { |
| 822 | case Type::U32: | ||
| 823 | return Inst<U32>(Opcode::ShiftRightLogical32, base, shift); | ||
| 824 | case Type::U64: | ||
| 825 | return Inst<U64>(Opcode::ShiftRightLogical64, base, shift); | ||
| 826 | default: | ||
| 827 | ThrowInvalidType(base.Type()); | ||
| 828 | } | ||
| 815 | } | 829 | } |
| 816 | 830 | ||
| 817 | U32 IREmitter::ShiftRightArithmetic(const U32& base, const U32& shift) { | 831 | U32 IREmitter::ShiftRightArithmetic(const U32& base, const U32& shift) { |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index 5beb99895..33bf2a7d0 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -148,10 +148,10 @@ public: | |||
| 148 | [[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b); | 148 | [[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b); |
| 149 | [[nodiscard]] U32U64 ISub(const U32U64& a, const U32U64& b); | 149 | [[nodiscard]] U32U64 ISub(const U32U64& a, const U32U64& b); |
| 150 | [[nodiscard]] U32 IMul(const U32& a, const U32& b); | 150 | [[nodiscard]] U32 IMul(const U32& a, const U32& b); |
| 151 | [[nodiscard]] U32 INeg(const U32& value); | 151 | [[nodiscard]] U32U64 INeg(const U32U64& value); |
| 152 | [[nodiscard]] U32 IAbs(const U32& value); | 152 | [[nodiscard]] U32 IAbs(const U32& value); |
| 153 | [[nodiscard]] U32 ShiftLeftLogical(const U32& base, const U32& shift); | 153 | [[nodiscard]] U32 ShiftLeftLogical(const U32& base, const U32& shift); |
| 154 | [[nodiscard]] U32 ShiftRightLogical(const U32& base, const U32& shift); | 154 | [[nodiscard]] U32U64 ShiftRightLogical(const U32U64& base, const U32& shift); |
| 155 | [[nodiscard]] U32 ShiftRightArithmetic(const U32& base, const U32& shift); | 155 | [[nodiscard]] U32 ShiftRightArithmetic(const U32& base, const U32& shift); |
| 156 | [[nodiscard]] U32 BitwiseAnd(const U32& a, const U32& b); | 156 | [[nodiscard]] U32 BitwiseAnd(const U32& a, const U32& b); |
| 157 | [[nodiscard]] U32 BitwiseOr(const U32& a, const U32& b); | 157 | [[nodiscard]] U32 BitwiseOr(const U32& a, const U32& b); |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index acfc0a829..b51aaaef5 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -233,9 +233,11 @@ OPCODE(ISub32, U32, U32, | |||
| 233 | OPCODE(ISub64, U64, U64, U64, ) | 233 | OPCODE(ISub64, U64, U64, U64, ) |
| 234 | OPCODE(IMul32, U32, U32, U32, ) | 234 | OPCODE(IMul32, U32, U32, U32, ) |
| 235 | OPCODE(INeg32, U32, U32, ) | 235 | OPCODE(INeg32, U32, U32, ) |
| 236 | OPCODE(INeg64, U64, U64, ) | ||
| 236 | OPCODE(IAbs32, U32, U32, ) | 237 | OPCODE(IAbs32, U32, U32, ) |
| 237 | OPCODE(ShiftLeftLogical32, U32, U32, U32, ) | 238 | OPCODE(ShiftLeftLogical32, U32, U32, U32, ) |
| 238 | OPCODE(ShiftRightLogical32, U32, U32, U32, ) | 239 | OPCODE(ShiftRightLogical32, U32, U32, U32, ) |
| 240 | OPCODE(ShiftRightLogical64, U64, U64, U32, ) | ||
| 239 | OPCODE(ShiftRightArithmetic32, U32, U32, U32, ) | 241 | OPCODE(ShiftRightArithmetic32, U32, U32, U32, ) |
| 240 | OPCODE(BitwiseAnd32, U32, U32, U32, ) | 242 | OPCODE(BitwiseAnd32, U32, U32, U32, ) |
| 241 | OPCODE(BitwiseOr32, U32, U32, U32, ) | 243 | OPCODE(BitwiseOr32, U32, U32, U32, ) |
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 | } |