summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSubv <subv2112@gmail.com>2018-07-30 20:09:49 -0500
committerSubv <subv2112@gmail.com>2018-07-30 20:38:24 -0500
commit8191273a3de6df8531805fbfb1a9b6e5a18076a2 (patch)
treee0995886afcfab34d09e5addc8322c42bd547ff8 /src
parente119e17d1824cbc41153d8f55d81b76b3da438f6 (diff)
MacroInterpreter: Avoid left shifting negative values.
The branch target is signed, so multiply by 4 instead of left shifting by 2
Diffstat (limited to 'src')
-rw-r--r--src/video_core/macro_interpreter.cpp4
-rw-r--r--src/video_core/macro_interpreter.h4
2 files changed, 6 insertions, 2 deletions
diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp
index 44ece01c1..377bd66ab 100644
--- a/src/video_core/macro_interpreter.cpp
+++ b/src/video_core/macro_interpreter.cpp
@@ -102,11 +102,11 @@ bool MacroInterpreter::Step(const std::vector<u32>& code, bool is_delay_slot) {
if (taken) {
// Ignore the delay slot if the branch has the annul bit.
if (opcode.branch_annul) {
- pc = base_address + (opcode.immediate << 2);
+ pc = base_address + opcode.GetBranchTarget();
return true;
}
- delayed_pc = base_address + (opcode.immediate << 2);
+ delayed_pc = base_address + opcode.GetBranchTarget();
// Execute one more instruction due to the delay slot.
return Step(code, true);
}
diff --git a/src/video_core/macro_interpreter.h b/src/video_core/macro_interpreter.h
index a71e359d8..7d836b816 100644
--- a/src/video_core/macro_interpreter.h
+++ b/src/video_core/macro_interpreter.h
@@ -91,6 +91,10 @@ private:
u32 GetBitfieldMask() const {
return (1 << bf_size) - 1;
}
+
+ s32 GetBranchTarget() const {
+ return static_cast<s32>(immediate * sizeof(u32));
+ }
};
union MethodAddress {