8 changed files with 80 additions and 18 deletions
-
1src/shader_recompiler/CMakeLists.txt
-
5src/shader_recompiler/backend/spirv/emit_spirv.h
-
12src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
-
4src/shader_recompiler/frontend/ir/ir_emitter.cpp
-
1src/shader_recompiler/frontend/ir/ir_emitter.h
-
1src/shader_recompiler/frontend/ir/opcodes.inc
-
62src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_right.cpp
-
12src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@ -0,0 +1,62 @@ |
|||
// 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 { |
|||
void SHR(TranslatorVisitor& v, u64 insn, const IR::U32& shift) { |
|||
union { |
|||
u64 insn; |
|||
BitField<0, 8, IR::Reg> dest_reg; |
|||
BitField<8, 8, IR::Reg> src_reg_a; |
|||
BitField<39, 1, u64> is_wrapped; |
|||
BitField<40, 1, u64> brev; |
|||
BitField<43, 1, u64> xmode; |
|||
BitField<48, 1, u64> is_arithmetic; |
|||
} const shr{insn}; |
|||
|
|||
if (shr.xmode != 0) { |
|||
throw NotImplementedException("SHR.XMODE"); |
|||
} |
|||
|
|||
IR::U32 base{v.X(shr.src_reg_a)}; |
|||
if (shr.brev == 1) { |
|||
base = v.ir.BitReverse(base); |
|||
} |
|||
IR::U32 result; |
|||
const IR::U32 safe_shift = shr.is_wrapped == 0 ? shift : v.ir.BitwiseAnd(shift, v.ir.Imm32(31)); |
|||
if (shr.is_arithmetic == 1) { |
|||
result = IR::U32{v.ir.ShiftRightArithmetic(base, safe_shift)}; |
|||
} else { |
|||
result = IR::U32{v.ir.ShiftRightLogical(base, safe_shift)}; |
|||
} |
|||
|
|||
if (shr.is_wrapped == 0) { |
|||
const IR::U32 zero{v.ir.Imm32(0)}; |
|||
const IR::U32 safe_bits{v.ir.Imm32(32)}; |
|||
|
|||
const IR::U1 is_negative{v.ir.ILessThan(result, zero, true)}; |
|||
const IR::U1 is_safe{v.ir.ILessThan(shift, safe_bits, false)}; |
|||
const IR::U32 clamped_value{v.ir.Select(is_negative, v.ir.Imm32(-1), zero)}; |
|||
result = IR::U32{v.ir.Select(is_safe, result, clamped_value)}; |
|||
} |
|||
v.X(shr.dest_reg, result); |
|||
} |
|||
} // Anonymous namespace
|
|||
|
|||
void TranslatorVisitor::SHR_reg(u64 insn) { |
|||
SHR(*this, insn, GetReg20(insn)); |
|||
} |
|||
|
|||
void TranslatorVisitor::SHR_cbuf(u64 insn) { |
|||
SHR(*this, insn, GetCbuf(insn)); |
|||
} |
|||
|
|||
void TranslatorVisitor::SHR_imm(u64 insn) { |
|||
SHR(*this, insn, GetImm20(insn)); |
|||
} |
|||
} // namespace Shader::Maxwell
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue