PowerPC: Deduplicate Helper_Mask() code
We can share this across all implementations instead of duplicating it in different ways.
This commit is contained in:
parent
3d0ea980a6
commit
a4110ad958
|
@ -294,6 +294,23 @@ union UGeckoInstruction
|
|||
};
|
||||
};
|
||||
|
||||
// Used in implementations of rlwimi, rlwinm, and rlwnm
|
||||
inline u32 MakeRotationMask(u32 mb, u32 me)
|
||||
{
|
||||
// first make 001111111111111 part
|
||||
const u32 begin = 0xFFFFFFFF >> mb;
|
||||
// then make 000000000001111 part, which is used to flip the bits of the first one
|
||||
const u32 end = 0x7FFFFFFF >> me;
|
||||
// do the bitflip
|
||||
const u32 mask = begin ^ end;
|
||||
|
||||
// and invert if backwards
|
||||
if (me < mb)
|
||||
return ~mask;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
//
|
||||
// --- Gekko Special Registers ---
|
||||
//
|
||||
|
|
|
@ -299,9 +299,6 @@ private:
|
|||
static void Helper_Dequantize(u32 addr, u32 instI, u32 instRD, u32 instW);
|
||||
static void Helper_Quantize(u32 addr, u32 instI, u32 instRS, u32 instW);
|
||||
|
||||
// other helper
|
||||
static u32 Helper_Mask(int mb, int me);
|
||||
|
||||
static void Helper_FloatCompareOrdered(UGeckoInstruction inst, double a, double b);
|
||||
static void Helper_FloatCompareUnordered(UGeckoInstruction inst, double a, double b);
|
||||
|
||||
|
|
|
@ -23,21 +23,6 @@ u32 Interpreter::Helper_Carry(u32 value1, u32 value2)
|
|||
return value2 > (~value1);
|
||||
}
|
||||
|
||||
u32 Interpreter::Helper_Mask(int mb, int me)
|
||||
{
|
||||
// first make 001111111111111 part
|
||||
u32 begin = 0xFFFFFFFF >> mb;
|
||||
// then make 000000000001111 part, which is used to flip the bits of the first one
|
||||
u32 end = 0x7FFFFFFF >> me;
|
||||
// do the bitflip
|
||||
u32 mask = begin ^ end;
|
||||
// and invert if backwards
|
||||
if (me < mb)
|
||||
return ~mask;
|
||||
else
|
||||
return mask;
|
||||
}
|
||||
|
||||
void Interpreter::addi(UGeckoInstruction inst)
|
||||
{
|
||||
if (inst.RA)
|
||||
|
@ -170,7 +155,7 @@ void Interpreter::xoris(UGeckoInstruction inst)
|
|||
|
||||
void Interpreter::rlwimix(UGeckoInstruction inst)
|
||||
{
|
||||
u32 mask = Helper_Mask(inst.MB, inst.ME);
|
||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||
rGPR[inst.RA] = (rGPR[inst.RA] & ~mask) | (Common::RotateLeft(rGPR[inst.RS], inst.SH) & mask);
|
||||
|
||||
if (inst.Rc)
|
||||
|
@ -179,7 +164,7 @@ void Interpreter::rlwimix(UGeckoInstruction inst)
|
|||
|
||||
void Interpreter::rlwinmx(UGeckoInstruction inst)
|
||||
{
|
||||
u32 mask = Helper_Mask(inst.MB, inst.ME);
|
||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||
rGPR[inst.RA] = Common::RotateLeft(rGPR[inst.RS], inst.SH) & mask;
|
||||
|
||||
if (inst.Rc)
|
||||
|
@ -188,7 +173,7 @@ void Interpreter::rlwinmx(UGeckoInstruction inst)
|
|||
|
||||
void Interpreter::rlwnmx(UGeckoInstruction inst)
|
||||
{
|
||||
u32 mask = Helper_Mask(inst.MB, inst.ME);
|
||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||
rGPR[inst.RA] = Common::RotateLeft(rGPR[inst.RS], rGPR[inst.RB] & 0x1F) & mask;
|
||||
|
||||
if (inst.Rc)
|
||||
|
|
|
@ -1437,17 +1437,17 @@ void Jit64::rlwinmx(UGeckoInstruction inst)
|
|||
u32 result = gpr.R(s).Imm32();
|
||||
if (inst.SH != 0)
|
||||
result = Common::RotateLeft(result, inst.SH);
|
||||
result &= Helper_Mask(inst.MB, inst.ME);
|
||||
result &= MakeRotationMask(inst.MB, inst.ME);
|
||||
gpr.SetImmediate32(a, result);
|
||||
if (inst.Rc)
|
||||
ComputeRC(gpr.R(a));
|
||||
}
|
||||
else
|
||||
{
|
||||
bool left_shift = inst.SH && inst.MB == 0 && inst.ME == 31 - inst.SH;
|
||||
bool right_shift = inst.SH && inst.ME == 31 && inst.MB == 32 - inst.SH;
|
||||
u32 mask = Helper_Mask(inst.MB, inst.ME);
|
||||
bool simple_mask = mask == 0xff || mask == 0xffff;
|
||||
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 bool simple_mask = mask == 0xff || 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;
|
||||
|
@ -1520,7 +1520,7 @@ void Jit64::rlwimix(UGeckoInstruction inst)
|
|||
|
||||
if (gpr.R(a).IsImm() && gpr.R(s).IsImm())
|
||||
{
|
||||
u32 mask = Helper_Mask(inst.MB, inst.ME);
|
||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||
gpr.SetImmediate32(a, (gpr.R(a).Imm32() & ~mask) |
|
||||
(Common::RotateLeft(gpr.R(s).Imm32(), inst.SH) & mask));
|
||||
if (inst.Rc)
|
||||
|
@ -1529,7 +1529,7 @@ void Jit64::rlwimix(UGeckoInstruction inst)
|
|||
else
|
||||
{
|
||||
gpr.Lock(a, s);
|
||||
u32 mask = Helper_Mask(inst.MB, inst.ME);
|
||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||
bool needs_test = false;
|
||||
if (mask == 0 || (a == s && inst.SH == 0))
|
||||
{
|
||||
|
@ -1619,7 +1619,7 @@ void Jit64::rlwnmx(UGeckoInstruction inst)
|
|||
JITDISABLE(bJITIntegerOff);
|
||||
int a = inst.RA, b = inst.RB, s = inst.RS;
|
||||
|
||||
u32 mask = Helper_Mask(inst.MB, inst.ME);
|
||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||
if (gpr.R(b).IsImm() && gpr.R(s).IsImm())
|
||||
{
|
||||
gpr.SetImmediate32(a, Common::RotateLeft(gpr.R(s).Imm32(), gpr.R(b).Imm32() & 0x1F) & mask);
|
||||
|
|
|
@ -532,7 +532,7 @@ void JitArm64::rlwinmx(UGeckoInstruction inst)
|
|||
JITDISABLE(bJITIntegerOff);
|
||||
u32 a = inst.RA, s = inst.RS;
|
||||
|
||||
u32 mask = Helper_Mask(inst.MB, inst.ME);
|
||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||
if (gpr.IsImm(inst.RS))
|
||||
{
|
||||
gpr.SetImmediate(a, Common::RotateLeft(gpr.GetImm(s), inst.SH) & mask);
|
||||
|
@ -579,8 +579,8 @@ void JitArm64::rlwnmx(UGeckoInstruction inst)
|
|||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
u32 a = inst.RA, b = inst.RB, s = inst.RS;
|
||||
u32 mask = Helper_Mask(inst.MB, inst.ME);
|
||||
const u32 a = inst.RA, b = inst.RB, s = inst.RS;
|
||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||
|
||||
if (gpr.IsImm(b) && gpr.IsImm(s))
|
||||
{
|
||||
|
@ -1431,8 +1431,8 @@ void JitArm64::rlwimix(UGeckoInstruction inst)
|
|||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
|
||||
int a = inst.RA, s = inst.RS;
|
||||
u32 mask = Helper_Mask(inst.MB, inst.ME);
|
||||
const int a = inst.RA, s = inst.RS;
|
||||
const u32 mask = MakeRotationMask(inst.MB, inst.ME);
|
||||
|
||||
if (gpr.IsImm(a) && gpr.IsImm(s))
|
||||
{
|
||||
|
|
|
@ -22,12 +22,6 @@ void JitTrampoline(JitBase& jit, u32 em_address)
|
|||
jit.Jit(em_address);
|
||||
}
|
||||
|
||||
u32 Helper_Mask(u8 mb, u8 me)
|
||||
{
|
||||
u32 mask = ((u32)-1 >> mb) ^ (me >= 31 ? 0 : (u32)-1 >> (me + 1));
|
||||
return mb > me ? ~mask : mask;
|
||||
}
|
||||
|
||||
JitBase::JitBase() : m_code_buffer(code_buffer_size)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -131,6 +131,3 @@ public:
|
|||
};
|
||||
|
||||
void JitTrampoline(JitBase& jit, u32 em_address);
|
||||
|
||||
// Merged routines that should be moved somewhere better
|
||||
u32 Helper_Mask(u8 mb, u8 me);
|
||||
|
|
Loading…
Reference in New Issue