summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/CMakeLists.txt1
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h8
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp20
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp22
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h4
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp77
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp16
8 files changed, 119 insertions, 31 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt
index a8df03f90..ddd34e915 100644
--- a/src/shader_recompiler/CMakeLists.txt
+++ b/src/shader_recompiler/CMakeLists.txt
@@ -78,6 +78,7 @@ add_library(shader_recompiler STATIC
78 frontend/maxwell/translate/impl/integer_add_three_input.cpp 78 frontend/maxwell/translate/impl/integer_add_three_input.cpp
79 frontend/maxwell/translate/impl/integer_compare.cpp 79 frontend/maxwell/translate/impl/integer_compare.cpp
80 frontend/maxwell/translate/impl/integer_compare_and_set.cpp 80 frontend/maxwell/translate/impl/integer_compare_and_set.cpp
81 frontend/maxwell/translate/impl/integer_funnel_shift.cpp
81 frontend/maxwell/translate/impl/integer_minimum_maximum.cpp 82 frontend/maxwell/translate/impl/integer_minimum_maximum.cpp
82 frontend/maxwell/translate/impl/integer_popcount.cpp 83 frontend/maxwell/translate/impl/integer_popcount.cpp
83 frontend/maxwell/translate/impl/integer_scaled_add.cpp 84 frontend/maxwell/translate/impl/integer_scaled_add.cpp
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h
index 1f7d84871..bf1b5ace6 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.h
@@ -232,9 +232,11 @@ Id EmitINeg32(EmitContext& ctx, Id value);
232Id EmitINeg64(EmitContext& ctx, Id value); 232Id EmitINeg64(EmitContext& ctx, Id value);
233Id EmitIAbs32(EmitContext& ctx, Id value); 233Id EmitIAbs32(EmitContext& ctx, Id value);
234Id EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift); 234Id EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift);
235Id EmitShiftRightLogical32(EmitContext& ctx, Id a, Id b); 235Id EmitShiftLeftLogical64(EmitContext& ctx, Id base, Id shift);
236Id EmitShiftRightLogical64(EmitContext& ctx, Id a, Id b); 236Id EmitShiftRightLogical32(EmitContext& ctx, Id base, Id shift);
237Id EmitShiftRightArithmetic32(EmitContext& ctx, Id a, Id b); 237Id EmitShiftRightLogical64(EmitContext& ctx, Id base, Id shift);
238Id EmitShiftRightArithmetic32(EmitContext& ctx, Id base, Id shift);
239Id EmitShiftRightArithmetic64(EmitContext& ctx, Id base, Id shift);
238Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b); 240Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b);
239Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b); 241Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b);
240Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b); 242Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b);
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
index f5001cdaa..5ab3b5e86 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
@@ -74,16 +74,24 @@ Id EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift) {
74 return ctx.OpShiftLeftLogical(ctx.U32[1], base, shift); 74 return ctx.OpShiftLeftLogical(ctx.U32[1], base, shift);
75} 75}
76 76
77Id EmitShiftRightLogical32(EmitContext& ctx, Id a, Id b) { 77Id EmitShiftLeftLogical64(EmitContext& ctx, Id base, Id shift) {
78 return ctx.OpShiftRightLogical(ctx.U32[1], a, b); 78 return ctx.OpShiftLeftLogical(ctx.U64, base, shift);
79} 79}
80 80
81Id EmitShiftRightLogical64(EmitContext& ctx, Id a, Id b) { 81Id EmitShiftRightLogical32(EmitContext& ctx, Id base, Id shift) {
82 return ctx.OpShiftRightLogical(ctx.U64, a, b); 82 return ctx.OpShiftRightLogical(ctx.U32[1], base, shift);
83} 83}
84 84
85Id EmitShiftRightArithmetic32(EmitContext& ctx, Id a, Id b) { 85Id EmitShiftRightLogical64(EmitContext& ctx, Id base, Id shift) {
86 return ctx.OpShiftRightArithmetic(ctx.U32[1], a, b); 86 return ctx.OpShiftRightLogical(ctx.U64, base, shift);
87}
88
89Id EmitShiftRightArithmetic32(EmitContext& ctx, Id base, Id shift) {
90 return ctx.OpShiftRightArithmetic(ctx.U32[1], base, shift);
91}
92
93Id EmitShiftRightArithmetic64(EmitContext& ctx, Id base, Id shift) {
94 return ctx.OpShiftRightArithmetic(ctx.U64, base, shift);
87} 95}
88 96
89Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b) { 97Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b) {
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index 01f52183c..1659b7f3b 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -813,8 +813,15 @@ U32 IREmitter::IAbs(const U32& value) {
813 return Inst<U32>(Opcode::IAbs32, value); 813 return Inst<U32>(Opcode::IAbs32, value);
814} 814}
815 815
816U32 IREmitter::ShiftLeftLogical(const U32& base, const U32& shift) { 816U32U64 IREmitter::ShiftLeftLogical(const U32U64& base, const U32& shift) {
817 return Inst<U32>(Opcode::ShiftLeftLogical32, base, shift); 817 switch (base.Type()) {
818 case Type::U32:
819 return Inst<U32>(Opcode::ShiftLeftLogical32, base, shift);
820 case Type::U64:
821 return Inst<U64>(Opcode::ShiftLeftLogical64, base, shift);
822 default:
823 ThrowInvalidType(base.Type());
824 }
818} 825}
819 826
820U32U64 IREmitter::ShiftRightLogical(const U32U64& base, const U32& shift) { 827U32U64 IREmitter::ShiftRightLogical(const U32U64& base, const U32& shift) {
@@ -828,8 +835,15 @@ U32U64 IREmitter::ShiftRightLogical(const U32U64& base, const U32& shift) {
828 } 835 }
829} 836}
830 837
831U32 IREmitter::ShiftRightArithmetic(const U32& base, const U32& shift) { 838U32U64 IREmitter::ShiftRightArithmetic(const U32U64& base, const U32& shift) {
832 return Inst<U32>(Opcode::ShiftRightArithmetic32, base, shift); 839 switch (base.Type()) {
840 case Type::U32:
841 return Inst<U32>(Opcode::ShiftRightArithmetic32, base, shift);
842 case Type::U64:
843 return Inst<U64>(Opcode::ShiftRightArithmetic64, base, shift);
844 default:
845 ThrowInvalidType(base.Type());
846 }
833} 847}
834 848
835U32 IREmitter::BitwiseAnd(const U32& a, const U32& b) { 849U32 IREmitter::BitwiseAnd(const U32& a, const U32& b) {
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h
index 33bf2a7d0..6e29bf0e2 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.h
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.h
@@ -150,9 +150,9 @@ public:
150 [[nodiscard]] U32 IMul(const U32& a, const U32& b); 150 [[nodiscard]] U32 IMul(const U32& a, const U32& b);
151 [[nodiscard]] U32U64 INeg(const U32U64& 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]] U32U64 ShiftLeftLogical(const U32U64& base, const U32& shift);
154 [[nodiscard]] U32U64 ShiftRightLogical(const U32U64& 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]] U32U64 ShiftRightArithmetic(const U32U64& 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);
158 [[nodiscard]] U32 BitwiseXor(const U32& a, const U32& b); 158 [[nodiscard]] U32 BitwiseXor(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 b51aaaef5..75f09ebfc 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.inc
+++ b/src/shader_recompiler/frontend/ir/opcodes.inc
@@ -236,9 +236,11 @@ OPCODE(INeg32, U32, U32,
236OPCODE(INeg64, U64, U64, ) 236OPCODE(INeg64, U64, U64, )
237OPCODE(IAbs32, U32, U32, ) 237OPCODE(IAbs32, U32, U32, )
238OPCODE(ShiftLeftLogical32, U32, U32, U32, ) 238OPCODE(ShiftLeftLogical32, U32, U32, U32, )
239OPCODE(ShiftLeftLogical64, U64, U64, U32, )
239OPCODE(ShiftRightLogical32, U32, U32, U32, ) 240OPCODE(ShiftRightLogical32, U32, U32, U32, )
240OPCODE(ShiftRightLogical64, U64, U64, U32, ) 241OPCODE(ShiftRightLogical64, U64, U64, U32, )
241OPCODE(ShiftRightArithmetic32, U32, U32, U32, ) 242OPCODE(ShiftRightArithmetic32, U32, U32, U32, )
243OPCODE(ShiftRightArithmetic64, U64, U64, U32, )
242OPCODE(BitwiseAnd32, U32, U32, U32, ) 244OPCODE(BitwiseAnd32, U32, U32, U32, )
243OPCODE(BitwiseOr32, U32, U32, U32, ) 245OPCODE(BitwiseOr32, U32, U32, U32, )
244OPCODE(BitwiseXor32, U32, U32, U32, ) 246OPCODE(BitwiseXor32, U32, U32, U32, )
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp
new file mode 100644
index 000000000..d8d6c939e
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp
@@ -0,0 +1,77 @@
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
9namespace Shader::Maxwell {
10namespace {
11enum class MaxShift : u64 {
12 U32,
13 Undefined,
14 U64,
15 S64,
16};
17
18IR::U64 PackedShift(IR::IREmitter& ir, const IR::U64& packed_int, const IR::U32& safe_shift,
19 bool right_shift, bool is_signed) {
20 if (!right_shift) {
21 return ir.ShiftLeftLogical(packed_int, safe_shift);
22 }
23 if (is_signed) {
24 return ir.ShiftRightArithmetic(packed_int, safe_shift);
25 }
26 return ir.ShiftRightLogical(packed_int, safe_shift);
27}
28
29void SHF(TranslatorVisitor& v, u64 insn, const IR::U32& shift, const IR::U32& high_bits,
30 bool right_shift) {
31 union {
32 u64 insn;
33 BitField<0, 8, IR::Reg> dest_reg;
34 BitField<0, 8, IR::Reg> lo_bits_reg;
35 BitField<37, 2, MaxShift> max_shift;
36 BitField<48, 2, u64> x_mode;
37 BitField<50, 1, u64> wrap;
38 } const shf{insn};
39 if (shf.x_mode != 0) {
40 throw NotImplementedException("SHF X Mode");
41 }
42 if (shf.max_shift == MaxShift::Undefined) {
43 throw NotImplementedException("SHF Use of undefined MaxShift value");
44 }
45 const IR::U32 low_bits{v.X(shf.lo_bits_reg)};
46 const IR::U64 packed_int{v.ir.PackUint2x32(v.ir.CompositeConstruct(low_bits, high_bits))};
47 const IR::U32 max_shift{shf.max_shift == MaxShift::U32 ? v.ir.Imm32(32) : v.ir.Imm32(63)};
48 const IR::U32 safe_shift{shf.wrap != 0
49 ? v.ir.BitwiseAnd(shift, v.ir.ISub(max_shift, v.ir.Imm32(1)))
50 : v.ir.UMin(shift, max_shift)};
51
52 const bool is_signed{shf.max_shift == MaxShift::S64};
53 const IR::U64 shifted_value{PackedShift(v.ir, packed_int, safe_shift, right_shift, is_signed)};
54 const IR::Value unpacked_value{v.ir.UnpackUint2x32(shifted_value)};
55
56 const IR::U32 result{v.ir.CompositeExtract(unpacked_value, right_shift ? 0 : 1)};
57 v.X(shf.dest_reg, result);
58}
59} // Anonymous namespace
60
61void TranslatorVisitor::SHF_l_reg(u64 insn) {
62 SHF(*this, insn, GetReg20(insn), GetReg39(insn), false);
63}
64
65void TranslatorVisitor::SHF_l_imm(u64 insn) {
66 SHF(*this, insn, GetImm20(insn), GetReg39(insn), false);
67}
68
69void TranslatorVisitor::SHF_r_reg(u64 insn) {
70 SHF(*this, insn, GetReg20(insn), GetReg39(insn), true);
71}
72
73void TranslatorVisitor::SHF_r_imm(u64 insn) {
74 SHF(*this, insn, GetImm20(insn), GetReg39(insn), true);
75}
76
77} // 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 62863aff6..2ab90d1bf 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -553,22 +553,6 @@ void TranslatorVisitor::SETLMEMBASE(u64) {
553 ThrowNotImplemented(Opcode::SETLMEMBASE); 553 ThrowNotImplemented(Opcode::SETLMEMBASE);
554} 554}
555 555
556void TranslatorVisitor::SHF_l_reg(u64) {
557 ThrowNotImplemented(Opcode::SHF_l_reg);
558}
559
560void TranslatorVisitor::SHF_l_imm(u64) {
561 ThrowNotImplemented(Opcode::SHF_l_imm);
562}
563
564void TranslatorVisitor::SHF_r_reg(u64) {
565 ThrowNotImplemented(Opcode::SHF_r_reg);
566}
567
568void TranslatorVisitor::SHF_r_imm(u64) {
569 ThrowNotImplemented(Opcode::SHF_r_imm);
570}
571
572void TranslatorVisitor::SHFL(u64) { 556void TranslatorVisitor::SHFL(u64) {
573 ThrowNotImplemented(Opcode::SHFL); 557 ThrowNotImplemented(Opcode::SHFL);
574} 558}