diff options
author | bunnei <bunneidev@gmail.com> | 2018-11-21 20:32:21 +0100 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2018-11-22 06:58:00 +0100 |
commit | 033b46253e6c7de33c5f8b51adb9d96ca606669d (patch) | |
tree | af5ad3a30c91e3e769e55eb542f8455bed694ccf /src | |
parent | Merge pull request #1754 from ReinUsesLisp/zero-register (diff) | |
download | yuzu-033b46253e6c7de33c5f8b51adb9d96ca606669d.tar yuzu-033b46253e6c7de33c5f8b51adb9d96ca606669d.tar.gz yuzu-033b46253e6c7de33c5f8b51adb9d96ca606669d.tar.bz2 yuzu-033b46253e6c7de33c5f8b51adb9d96ca606669d.tar.lz yuzu-033b46253e6c7de33c5f8b51adb9d96ca606669d.tar.xz yuzu-033b46253e6c7de33c5f8b51adb9d96ca606669d.tar.zst yuzu-033b46253e6c7de33c5f8b51adb9d96ca606669d.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/video_core/macro_interpreter.cpp | 29 | ||||
-rw-r--r-- | src/video_core/macro_interpreter.h | 4 |
2 files changed, 25 insertions, 8 deletions
diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp index 335a8d407..2b0dea5cd 100644 --- a/src/video_core/macro_interpreter.cpp +++ b/src/video_core/macro_interpreter.cpp @@ -35,6 +35,7 @@ void MacroInterpreter::Reset() { // The next parameter index starts at 1, because $r1 already has the value of the first // parameter. next_parameter_index = 1; + carry_flag = false; } bool MacroInterpreter::Step(u32 offset, bool is_delay_slot) { @@ -135,14 +136,28 @@ MacroInterpreter::Opcode MacroInterpreter::GetOpcode(u32 offset) const { return {macro_memory[offset + pc / sizeof(u32)]}; } -u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const { +u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) { switch (operation) { - case ALUOperation::Add: - return src_a + src_b; - // TODO(Subv): Implement AddWithCarry - case ALUOperation::Subtract: - return src_a - src_b; - // TODO(Subv): Implement SubtractWithBorrow + case ALUOperation::Add: { + const u64 result{static_cast<u64>(src_a) + src_b}; + carry_flag = result > 0xffffffff; + return static_cast<u32>(result); + } + case ALUOperation::AddWithCarry: { + const u64 result{static_cast<u64>(src_a) + src_b + (carry_flag ? 1ULL : 0ULL)}; + carry_flag = result > 0xffffffff; + return static_cast<u32>(result); + } + case ALUOperation::Subtract: { + const u64 result{static_cast<u64>(src_a) - src_b}; + carry_flag = result < 0x100000000; + return static_cast<u32>(result); + } + case ALUOperation::SubtractWithBorrow: { + const u64 result{static_cast<u64>(src_a) - src_b - (carry_flag ? 0ULL : 1ULL)}; + carry_flag = result < 0x100000000; + return static_cast<u32>(result); + } case ALUOperation::Xor: return src_a ^ src_b; case ALUOperation::Or: diff --git a/src/video_core/macro_interpreter.h b/src/video_core/macro_interpreter.h index 62d1ce289..cde360288 100644 --- a/src/video_core/macro_interpreter.h +++ b/src/video_core/macro_interpreter.h @@ -117,7 +117,7 @@ private: bool Step(u32 offset, bool is_delay_slot); /// Calculates the result of an ALU operation. src_a OP src_b; - u32 GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const; + u32 GetALUResult(ALUOperation operation, u32 src_a, u32 src_b); /// Performs the result operation on the input result and stores it in the specified register /// (if necessary). @@ -165,5 +165,7 @@ private: std::vector<u32> parameters; /// Index of the next parameter that will be fetched by the 'parm' instruction. u32 next_parameter_index = 0; + + bool carry_flag{}; }; } // namespace Tegra |