diff options
Diffstat (limited to 'src/video_core/macro_interpreter.cpp')
-rw-r--r-- | src/video_core/macro_interpreter.cpp | 29 |
1 files changed, 22 insertions, 7 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: |