8 changed files with 119 additions and 31 deletions
-
1src/shader_recompiler/CMakeLists.txt
-
8src/shader_recompiler/backend/spirv/emit_spirv.h
-
20src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
-
22src/shader_recompiler/frontend/ir/ir_emitter.cpp
-
4src/shader_recompiler/frontend/ir/ir_emitter.h
-
2src/shader_recompiler/frontend/ir/opcodes.inc
-
77src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp
-
16src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@ -0,0 +1,77 @@ |
|||
// Copyright 2021 yuzu Emulator Project
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include "common/bit_field.h"
|
|||
#include "common/common_types.h"
|
|||
#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
|
|||
|
|||
namespace Shader::Maxwell { |
|||
namespace { |
|||
enum class MaxShift : u64 { |
|||
U32, |
|||
Undefined, |
|||
U64, |
|||
S64, |
|||
}; |
|||
|
|||
IR::U64 PackedShift(IR::IREmitter& ir, const IR::U64& packed_int, const IR::U32& safe_shift, |
|||
bool right_shift, bool is_signed) { |
|||
if (!right_shift) { |
|||
return ir.ShiftLeftLogical(packed_int, safe_shift); |
|||
} |
|||
if (is_signed) { |
|||
return ir.ShiftRightArithmetic(packed_int, safe_shift); |
|||
} |
|||
return ir.ShiftRightLogical(packed_int, safe_shift); |
|||
} |
|||
|
|||
void SHF(TranslatorVisitor& v, u64 insn, const IR::U32& shift, const IR::U32& high_bits, |
|||
bool right_shift) { |
|||
union { |
|||
u64 insn; |
|||
BitField<0, 8, IR::Reg> dest_reg; |
|||
BitField<0, 8, IR::Reg> lo_bits_reg; |
|||
BitField<37, 2, MaxShift> max_shift; |
|||
BitField<48, 2, u64> x_mode; |
|||
BitField<50, 1, u64> wrap; |
|||
} const shf{insn}; |
|||
if (shf.x_mode != 0) { |
|||
throw NotImplementedException("SHF X Mode"); |
|||
} |
|||
if (shf.max_shift == MaxShift::Undefined) { |
|||
throw NotImplementedException("SHF Use of undefined MaxShift value"); |
|||
} |
|||
const IR::U32 low_bits{v.X(shf.lo_bits_reg)}; |
|||
const IR::U64 packed_int{v.ir.PackUint2x32(v.ir.CompositeConstruct(low_bits, high_bits))}; |
|||
const IR::U32 max_shift{shf.max_shift == MaxShift::U32 ? v.ir.Imm32(32) : v.ir.Imm32(63)}; |
|||
const IR::U32 safe_shift{shf.wrap != 0 |
|||
? v.ir.BitwiseAnd(shift, v.ir.ISub(max_shift, v.ir.Imm32(1))) |
|||
: v.ir.UMin(shift, max_shift)}; |
|||
|
|||
const bool is_signed{shf.max_shift == MaxShift::S64}; |
|||
const IR::U64 shifted_value{PackedShift(v.ir, packed_int, safe_shift, right_shift, is_signed)}; |
|||
const IR::Value unpacked_value{v.ir.UnpackUint2x32(shifted_value)}; |
|||
|
|||
const IR::U32 result{v.ir.CompositeExtract(unpacked_value, right_shift ? 0 : 1)}; |
|||
v.X(shf.dest_reg, result); |
|||
} |
|||
} // Anonymous namespace
|
|||
|
|||
void TranslatorVisitor::SHF_l_reg(u64 insn) { |
|||
SHF(*this, insn, GetReg20(insn), GetReg39(insn), false); |
|||
} |
|||
|
|||
void TranslatorVisitor::SHF_l_imm(u64 insn) { |
|||
SHF(*this, insn, GetImm20(insn), GetReg39(insn), false); |
|||
} |
|||
|
|||
void TranslatorVisitor::SHF_r_reg(u64 insn) { |
|||
SHF(*this, insn, GetReg20(insn), GetReg39(insn), true); |
|||
} |
|||
|
|||
void TranslatorVisitor::SHF_r_imm(u64 insn) { |
|||
SHF(*this, insn, GetImm20(insn), GetReg39(insn), true); |
|||
} |
|||
|
|||
} // namespace Shader::Maxwell
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue