summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2019-09-10 11:56:17 -0400
committerGravatar GitHub2019-09-10 11:56:17 -0400
commit34b2c60f95c964354f00546385684fc9c8726d76 (patch)
tree365887554f8b0ddf08bf98b00b1b6bad5f36f073 /src
parentMerge pull request #2810 from ReinUsesLisp/mme-opt (diff)
parentshader/shift: Implement SHR wrapped and clamped variants (diff)
downloadyuzu-34b2c60f95c964354f00546385684fc9c8726d76.tar.gz
yuzu-34b2c60f95c964354f00546385684fc9c8726d76.tar.xz
yuzu-34b2c60f95c964354f00546385684fc9c8726d76.zip
Merge pull request #2823 from ReinUsesLisp/shr-clamp
shader/shift: Implement SHR wrapped and clamped variants
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h4
-rw-r--r--src/video_core/shader/decode/shift.cpp19
2 files changed, 17 insertions, 6 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index c3678b9ea..bd8c1ada0 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -675,6 +675,10 @@ union Instruction {
675 } shift; 675 } shift;
676 676
677 union { 677 union {
678 BitField<39, 1, u64> wrap;
679 } shr;
680
681 union {
678 BitField<39, 5, u64> shift_amount; 682 BitField<39, 5, u64> shift_amount;
679 BitField<48, 1, u64> negate_b; 683 BitField<48, 1, u64> negate_b;
680 BitField<49, 1, u64> negate_a; 684 BitField<49, 1, u64> negate_a;
diff --git a/src/video_core/shader/decode/shift.cpp b/src/video_core/shader/decode/shift.cpp
index 2ac16eeb0..f6ee68a54 100644
--- a/src/video_core/shader/decode/shift.cpp
+++ b/src/video_core/shader/decode/shift.cpp
@@ -17,8 +17,8 @@ u32 ShaderIR::DecodeShift(NodeBlock& bb, u32 pc) {
17 const Instruction instr = {program_code[pc]}; 17 const Instruction instr = {program_code[pc]};
18 const auto opcode = OpCode::Decode(instr); 18 const auto opcode = OpCode::Decode(instr);
19 19
20 const Node op_a = GetRegister(instr.gpr8); 20 Node op_a = GetRegister(instr.gpr8);
21 const Node op_b = [&]() { 21 Node op_b = [&]() {
22 if (instr.is_b_imm) { 22 if (instr.is_b_imm) {
23 return Immediate(instr.alu.GetSignedImm20_20()); 23 return Immediate(instr.alu.GetSignedImm20_20());
24 } else if (instr.is_b_gpr) { 24 } else if (instr.is_b_gpr) {
@@ -32,16 +32,23 @@ u32 ShaderIR::DecodeShift(NodeBlock& bb, u32 pc) {
32 case OpCode::Id::SHR_C: 32 case OpCode::Id::SHR_C:
33 case OpCode::Id::SHR_R: 33 case OpCode::Id::SHR_R:
34 case OpCode::Id::SHR_IMM: { 34 case OpCode::Id::SHR_IMM: {
35 const Node value = SignedOperation(OperationCode::IArithmeticShiftRight, 35 if (instr.shr.wrap) {
36 instr.shift.is_signed, PRECISE, op_a, op_b); 36 op_b = Operation(OperationCode::UBitwiseAnd, std::move(op_b), Immediate(0x1f));
37 } else {
38 op_b = Operation(OperationCode::IMax, std::move(op_b), Immediate(0));
39 op_b = Operation(OperationCode::IMin, std::move(op_b), Immediate(31));
40 }
41
42 Node value = SignedOperation(OperationCode::IArithmeticShiftRight, instr.shift.is_signed,
43 std::move(op_a), std::move(op_b));
37 SetInternalFlagsFromInteger(bb, value, instr.generates_cc); 44 SetInternalFlagsFromInteger(bb, value, instr.generates_cc);
38 SetRegister(bb, instr.gpr0, value); 45 SetRegister(bb, instr.gpr0, std::move(value));
39 break; 46 break;
40 } 47 }
41 case OpCode::Id::SHL_C: 48 case OpCode::Id::SHL_C:
42 case OpCode::Id::SHL_R: 49 case OpCode::Id::SHL_R:
43 case OpCode::Id::SHL_IMM: { 50 case OpCode::Id::SHL_IMM: {
44 const Node value = Operation(OperationCode::ILogicalShiftLeft, PRECISE, op_a, op_b); 51 const Node value = Operation(OperationCode::ILogicalShiftLeft, op_a, op_b);
45 SetInternalFlagsFromInteger(bb, value, instr.generates_cc); 52 SetInternalFlagsFromInteger(bb, value, instr.generates_cc);
46 SetRegister(bb, instr.gpr0, value); 53 SetRegister(bb, instr.gpr0, value);
47 break; 54 break;