summaryrefslogtreecommitdiff
path: root/Source/Core/Common/Arm64Emitter.cpp
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2014-09-12 05:45:10 -0500
committerRyan Houdek <Sonicadvance1@gmail.com>2014-09-12 05:45:10 -0500
commit17d31ecd6c7dc342fdd27a3bc3841e1c08f1f5bb (patch)
treeb99dc7fed87ca4afde057f1e0ee0c8b4b4b2ec5d /Source/Core/Common/Arm64Emitter.cpp
parent64b21a4812eb4d6912746d6cacabacd96e6875a2 (diff)
Fix AArch64 MOVI2R helper function.
In the case of a zero immediate, it wouldn't generate code at all. Also in the case of max u32/u64, use ORN to optimize it.
Diffstat (limited to 'Source/Core/Common/Arm64Emitter.cpp')
-rw-r--r--Source/Core/Common/Arm64Emitter.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/Source/Core/Common/Arm64Emitter.cpp b/Source/Core/Common/Arm64Emitter.cpp
index 3db7b2587a..83e194efef 100644
--- a/Source/Core/Common/Arm64Emitter.cpp
+++ b/Source/Core/Common/Arm64Emitter.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
+#include <limits>
+
#include "Arm64Emitter.h"
namespace Arm64Gen
@@ -1341,6 +1343,23 @@ void ARM64XEmitter::MOVI2R(ARM64Reg Rd, u64 imm, bool optimize)
if (!Is64Bit(Rd))
_assert_msg_(DYNA_REC, !(imm >> 32), "%s: immediate doesn't fit in 32bit register: %lx", __FUNCTION__, imm);
+ if (!imm)
+ {
+ // Zero immediate, just clear the register
+ EOR(Rd, Rd, Rd, ArithOption(Rd, ST_LSL, 0));
+ return;
+ }
+
+ if ((Is64Bit(Rd) && imm == std::numeric_limits<u64>::max()) ||
+ (!Is64Bit(Rd) && imm == std::numeric_limits<u32>::max()))
+ {
+ // Max unsigned value
+ // Set to ~ZR
+ ARM64Reg ZR = Is64Bit(Rd) ? SP : WSP;
+ ORN(Rd, Rd, ZR, ArithOption(ZR, ST_LSL, 0));
+ return;
+ }
+
// XXX: Optimize more
// XXX: Support rotating immediates to save instructions
if (optimize)