summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorMerryMage <MerryMage@users.noreply.github.com>2020-12-27 14:36:23 +0000
committerMerryMage <MerryMage@users.noreply.github.com>2020-12-27 14:43:51 +0000
commit11643ee2f024c28b0e9735f05a84ae74306ef11f (patch)
treef99d853c602f162e1c78a463af88616ad8664b5b /Source
parent263784639b24d6bae5e7dd97a41075cb0de45090 (diff)
Jit_Integer: rlwinmx: Generalize byte/word extract plus shift case
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp14
1 files changed, 8 insertions, 6 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
index b0a9cf4cf1..4231d64c58 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
@@ -1535,7 +1535,9 @@ void Jit64::rlwinmx(UGeckoInstruction inst)
const bool left_shift = inst.SH && inst.MB == 0 && inst.ME == 31 - inst.SH;
const bool right_shift = inst.SH && inst.ME == 31 && inst.MB == 32 - inst.SH;
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
+ const u32 prerotate_mask = Common::RotateRight(mask, inst.SH);
const bool simple_mask = mask == 0xff || mask == 0xffff;
+ const bool simple_prerotate_mask = prerotate_mask == 0xff || prerotate_mask == 0xffff;
// In case of a merged branch, track whether or not we've set flags.
// If not, we need to do a test later to get them.
bool needs_test = true;
@@ -1557,13 +1559,13 @@ void Jit64::rlwinmx(UGeckoInstruction inst)
MOVZX(32, mask_size, Ra, Rs.ExtractWithByteOffset(inst.SH ? (32 - inst.SH) >> 3 : 0));
needs_sext = false;
}
- // another optimized special case: byte/word extract plus shift
- else if (((mask >> inst.SH) << inst.SH) == mask && !left_shift &&
- ((mask >> inst.SH) == 0xff || (mask >> inst.SH) == 0xffff))
+ // another optimized special case: byte/word extract plus rotate
+ else if (simple_prerotate_mask && !left_shift)
{
- MOVZX(32, mask_size, Ra, Rs);
- SHL(32, Ra, Imm8(inst.SH));
- needs_sext = inst.SH + mask_size >= 32;
+ MOVZX(32, prerotate_mask == 0xff ? 8 : 16, Ra, Rs);
+ if (inst.SH)
+ ROL(32, Ra, Imm8(inst.SH));
+ needs_sext = (mask & 0x80000000) != 0;
}
else
{