summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-04-25 22:41:20 -0300
committerGravatar ReinUsesLisp2020-04-25 22:56:11 -0300
commitc788f9c0bd9cb0b0cb66f7424a65032cca3731cc (patch)
tree3dd3116449d8f00ea19ab4debe1fd39dffbe7973 /src
parentshader/arithmetic_integer: Implement CC for IADD (diff)
downloadyuzu-c788f9c0bd9cb0b0cb66f7424a65032cca3731cc.tar.gz
yuzu-c788f9c0bd9cb0b0cb66f7424a65032cca3731cc.tar.xz
yuzu-c788f9c0bd9cb0b0cb66f7424a65032cca3731cc.zip
shader/arithmetic_integer: Implement IADD.X
IADD.X takes the carry flag and adds it to the result. This is generally used to emulate 64-bit operations with 32-bit registers.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h4
-rw-r--r--src/video_core/shader/decode/arithmetic_integer.cpp6
2 files changed, 10 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index cde3a26b9..8dae754d4 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -814,6 +814,10 @@ union Instruction {
814 } alu_integer; 814 } alu_integer;
815 815
816 union { 816 union {
817 BitField<43, 1, u64> x;
818 } iadd;
819
820 union {
817 BitField<39, 1, u64> ftz; 821 BitField<39, 1, u64> ftz;
818 BitField<32, 1, u64> saturate; 822 BitField<32, 1, u64> saturate;
819 BitField<49, 2, HalfMerge> merge; 823 BitField<49, 2, HalfMerge> merge;
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp
index 99b4b6342..2a3311cb8 100644
--- a/src/video_core/shader/decode/arithmetic_integer.cpp
+++ b/src/video_core/shader/decode/arithmetic_integer.cpp
@@ -42,6 +42,12 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) {
42 42
43 Node value = Operation(OperationCode::IAdd, op_a, op_b); 43 Node value = Operation(OperationCode::IAdd, op_a, op_b);
44 44
45 if (instr.iadd.x) {
46 Node carry = GetInternalFlag(InternalFlag::Carry);
47 Node x = Operation(OperationCode::Select, std::move(carry), Immediate(1), Immediate(0));
48 value = Operation(OperationCode::IAdd, std::move(value), std::move(x));
49 }
50
45 if (instr.generates_cc) { 51 if (instr.generates_cc) {
46 const Node i0 = Immediate(0); 52 const Node i0 = Immediate(0);
47 53