mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 05:47:56 -07:00
Merge pull request #10041 from lioncash/conv
Interpreter: Make signedness and narrowing conversions explicit
This commit is contained in:
commit
48339afb98
@ -111,9 +111,9 @@ void Interpreter::Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
static int startTrace = 0;
|
||||
static bool s_start_trace = false;
|
||||
|
||||
static void Trace(UGeckoInstruction& inst)
|
||||
static void Trace(const UGeckoInstruction& inst)
|
||||
{
|
||||
std::string regs;
|
||||
for (size_t i = 0; i < std::size(PowerPC::ppcState.gpr); i++)
|
||||
@ -166,12 +166,12 @@ int Interpreter::SingleStepInner()
|
||||
m_prev_inst.hex = PowerPC::Read_Opcode(PC);
|
||||
|
||||
// Uncomment to trace the interpreter
|
||||
// if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624)
|
||||
// startTrace = 1;
|
||||
// if ((PC & 0x00FFFFFF) >= 0x000AB54C && (PC & 0x00FFFFFF) <= 0x000AB624)
|
||||
// s_start_trace = true;
|
||||
// else
|
||||
// startTrace = 0;
|
||||
// s_start_trace = false;
|
||||
|
||||
if (startTrace)
|
||||
if (s_start_trace)
|
||||
{
|
||||
Trace(m_prev_inst);
|
||||
}
|
||||
@ -186,7 +186,7 @@ int Interpreter::SingleStepInner()
|
||||
else if (MSR.FP)
|
||||
{
|
||||
m_op_table[m_prev_inst.OPCD](m_prev_inst);
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
CheckExceptions();
|
||||
}
|
||||
@ -202,7 +202,7 @@ int Interpreter::SingleStepInner()
|
||||
else
|
||||
{
|
||||
m_op_table[m_prev_inst.OPCD](m_prev_inst);
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
CheckExceptions();
|
||||
}
|
||||
@ -234,7 +234,7 @@ void Interpreter::SingleStep()
|
||||
CoreTiming::g.slice_length = 1;
|
||||
PowerPC::ppcState.downcount = 0;
|
||||
|
||||
if (PowerPC::ppcState.Exceptions)
|
||||
if (PowerPC::ppcState.Exceptions != 0)
|
||||
{
|
||||
PowerPC::CheckExceptions();
|
||||
PC = NPC;
|
||||
@ -243,10 +243,10 @@ void Interpreter::SingleStep()
|
||||
|
||||
//#define SHOW_HISTORY
|
||||
#ifdef SHOW_HISTORY
|
||||
std::vector<int> PCVec;
|
||||
std::vector<int> PCBlockVec;
|
||||
int ShowBlocks = 30;
|
||||
int ShowSteps = 300;
|
||||
static std::vector<u32> s_pc_vec;
|
||||
static std::vector<u32> s_pc_block_vec;
|
||||
constexpr u32 s_show_blocks = 30;
|
||||
constexpr u32 s_show_steps = 300;
|
||||
#endif
|
||||
|
||||
// FastRun - inspired by GCemu (to imitate the JIT so that they can be compared).
|
||||
@ -263,9 +263,9 @@ void Interpreter::Run()
|
||||
if (SConfig::GetInstance().bEnableDebugging)
|
||||
{
|
||||
#ifdef SHOW_HISTORY
|
||||
PCBlockVec.push_back(PC);
|
||||
if (PCBlockVec.size() > ShowBlocks)
|
||||
PCBlockVec.erase(PCBlockVec.begin());
|
||||
s_pc_block_vec.push_back(PC);
|
||||
if (s_pc_block_vec.size() > s_show_blocks)
|
||||
s_pc_block_vec.erase(s_pc_block_vec.begin());
|
||||
#endif
|
||||
|
||||
// Debugging friendly version of inner loop. Tries to do the timing as similarly to the
|
||||
@ -277,9 +277,9 @@ void Interpreter::Run()
|
||||
for (i = 0; !m_end_block; i++)
|
||||
{
|
||||
#ifdef SHOW_HISTORY
|
||||
PCVec.push_back(PC);
|
||||
if (PCVec.size() > ShowSteps)
|
||||
PCVec.erase(PCVec.begin());
|
||||
s_pc_vec.push_back(PC);
|
||||
if (s_pc_vec.size() > s_show_steps)
|
||||
s_pc_vec.erase(s_pc_vec.begin());
|
||||
#endif
|
||||
|
||||
// 2: check for breakpoint
|
||||
@ -288,20 +288,20 @@ void Interpreter::Run()
|
||||
#ifdef SHOW_HISTORY
|
||||
NOTICE_LOG_FMT(POWERPC, "----------------------------");
|
||||
NOTICE_LOG_FMT(POWERPC, "Blocks:");
|
||||
for (const int entry : PCBlockVec)
|
||||
for (const u32 entry : s_pc_block_vec)
|
||||
NOTICE_LOG_FMT(POWERPC, "PC: {:#010x}", entry);
|
||||
NOTICE_LOG_FMT(POWERPC, "----------------------------");
|
||||
NOTICE_LOG_FMT(POWERPC, "Steps:");
|
||||
for (size_t j = 0; j < PCVec.size(); j++)
|
||||
for (size_t j = 0; j < s_pc_vec.size(); j++)
|
||||
{
|
||||
// Write space
|
||||
if (j > 0)
|
||||
{
|
||||
if (PCVec[j] != PCVec[(j - 1) + 4]
|
||||
if (s_pc_vec[j] != s_pc_vec[(j - 1) + 4]
|
||||
NOTICE_LOG_FMT(POWERPC, "");
|
||||
}
|
||||
|
||||
NOTICE_LOG_FMT(POWERPC, "PC: {:#010x}", PCVec[j]);
|
||||
NOTICE_LOG_FMT(POWERPC, "PC: {:#010x}", s_pc_vec[j]);
|
||||
}
|
||||
#endif
|
||||
INFO_LOG_FMT(POWERPC, "Hit Breakpoint - {:08x}", PC);
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/PowerPC/Interpreter/ExceptionUtils.h"
|
||||
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
||||
#include "Core/PowerPC/MMU.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
void Interpreter::bx(UGeckoInstruction inst)
|
||||
@ -15,10 +14,12 @@ void Interpreter::bx(UGeckoInstruction inst)
|
||||
if (inst.LK)
|
||||
LR = PC + 4;
|
||||
|
||||
const auto address = u32(SignExt26(inst.LI << 2));
|
||||
|
||||
if (inst.AA)
|
||||
NPC = SignExt26(inst.LI << 2);
|
||||
NPC = address;
|
||||
else
|
||||
NPC = PC + SignExt26(inst.LI << 2);
|
||||
NPC = PC + address;
|
||||
|
||||
m_end_block = true;
|
||||
}
|
||||
@ -29,11 +30,11 @@ void Interpreter::bcx(UGeckoInstruction inst)
|
||||
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
||||
CTR--;
|
||||
|
||||
const bool true_false = ((inst.BO >> 3) & 1);
|
||||
const bool only_counter_check = ((inst.BO >> 4) & 1);
|
||||
const bool only_condition_check = ((inst.BO >> 2) & 1);
|
||||
const bool true_false = ((inst.BO >> 3) & 1) != 0;
|
||||
const bool only_counter_check = ((inst.BO >> 4) & 1) != 0;
|
||||
const bool only_condition_check = ((inst.BO >> 2) & 1) != 0;
|
||||
const u32 ctr_check = ((CTR != 0) ^ (inst.BO >> 1)) & 1;
|
||||
const bool counter = only_condition_check || ctr_check;
|
||||
const bool counter = only_condition_check || ctr_check != 0;
|
||||
const bool condition =
|
||||
only_counter_check || (PowerPC::ppcState.cr.GetBit(inst.BI) == u32(true_false));
|
||||
|
||||
@ -42,10 +43,12 @@ void Interpreter::bcx(UGeckoInstruction inst)
|
||||
if (inst.LK)
|
||||
LR = PC + 4;
|
||||
|
||||
const auto address = u32(SignExt16(s16(inst.BD << 2)));
|
||||
|
||||
if (inst.AA)
|
||||
NPC = SignExt16(inst.BD << 2);
|
||||
NPC = address;
|
||||
else
|
||||
NPC = PC + SignExt16(inst.BD << 2);
|
||||
NPC = PC + address;
|
||||
}
|
||||
|
||||
m_end_block = true;
|
||||
@ -53,13 +56,13 @@ void Interpreter::bcx(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::bcctrx(UGeckoInstruction inst)
|
||||
{
|
||||
DEBUG_ASSERT_MSG(POWERPC, inst.BO_2 & BO_DONT_DECREMENT_FLAG,
|
||||
DEBUG_ASSERT_MSG(POWERPC, (inst.BO_2 & BO_DONT_DECREMENT_FLAG) != 0,
|
||||
"bcctrx with decrement and test CTR option is invalid!");
|
||||
|
||||
const u32 condition =
|
||||
((inst.BO_2 >> 4) | (PowerPC::ppcState.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
|
||||
|
||||
if (condition)
|
||||
if (condition != 0)
|
||||
{
|
||||
NPC = CTR & (~3);
|
||||
if (inst.LK_3)
|
||||
@ -78,7 +81,7 @@ void Interpreter::bclrx(UGeckoInstruction inst)
|
||||
const u32 condition =
|
||||
((inst.BO_2 >> 4) | (PowerPC::ppcState.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
|
||||
|
||||
if (counter & condition)
|
||||
if ((counter & condition) != 0)
|
||||
{
|
||||
NPC = LR & (~3);
|
||||
if (inst.LK_3)
|
||||
|
@ -312,37 +312,39 @@ inline FPResult NI_msub(UReg_FPSCR* fpscr, double a, double c, double b)
|
||||
// used by stfsXX instructions and ps_rsqrte
|
||||
inline u32 ConvertToSingle(u64 x)
|
||||
{
|
||||
u32 exp = (x >> 52) & 0x7ff;
|
||||
const u32 exp = u32((x >> 52) & 0x7ff);
|
||||
|
||||
if (exp > 896 || (x & ~Common::DOUBLE_SIGN) == 0)
|
||||
{
|
||||
return ((x >> 32) & 0xc0000000) | ((x >> 29) & 0x3fffffff);
|
||||
return u32(((x >> 32) & 0xc0000000) | ((x >> 29) & 0x3fffffff));
|
||||
}
|
||||
else if (exp >= 874)
|
||||
{
|
||||
u32 t = (u32)(0x80000000 | ((x & Common::DOUBLE_FRAC) >> 21));
|
||||
u32 t = u32(0x80000000 | ((x & Common::DOUBLE_FRAC) >> 21));
|
||||
t = t >> (905 - exp);
|
||||
t |= (x >> 32) & 0x80000000;
|
||||
t |= u32((x >> 32) & 0x80000000);
|
||||
return t;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is said to be undefined.
|
||||
// The code is based on hardware tests.
|
||||
return ((x >> 32) & 0xc0000000) | ((x >> 29) & 0x3fffffff);
|
||||
return u32(((x >> 32) & 0xc0000000) | ((x >> 29) & 0x3fffffff));
|
||||
}
|
||||
}
|
||||
|
||||
// used by psq_stXX operations.
|
||||
inline u32 ConvertToSingleFTZ(u64 x)
|
||||
{
|
||||
u32 exp = (x >> 52) & 0x7ff;
|
||||
const u32 exp = u32((x >> 52) & 0x7ff);
|
||||
|
||||
if (exp > 896 || (x & ~Common::DOUBLE_SIGN) == 0)
|
||||
{
|
||||
return ((x >> 32) & 0xc0000000) | ((x >> 29) & 0x3fffffff);
|
||||
return u32(((x >> 32) & 0xc0000000) | ((x >> 29) & 0x3fffffff));
|
||||
}
|
||||
else
|
||||
{
|
||||
return (x >> 32) & 0x80000000;
|
||||
return u32((x >> 32) & 0x80000000);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,9 @@ enum class RoundingMode
|
||||
TowardsNegativeInfinity = 0b11
|
||||
};
|
||||
|
||||
static void SetFI(UReg_FPSCR* fpscr, int FI)
|
||||
void SetFI(UReg_FPSCR* fpscr, u32 FI)
|
||||
{
|
||||
if (FI)
|
||||
if (FI != 0)
|
||||
{
|
||||
SetFPException(fpscr, FPSCR_XX);
|
||||
}
|
||||
@ -484,7 +484,7 @@ void Interpreter::fresx(UGeckoInstruction inst)
|
||||
const auto compute_result = [inst](double value) {
|
||||
const double result = Common::ApproximateReciprocal(value);
|
||||
rPS(inst.FD).Fill(result);
|
||||
PowerPC::UpdateFPRFSingle(result);
|
||||
PowerPC::UpdateFPRFSingle(float(result));
|
||||
};
|
||||
|
||||
if (b == 0.0)
|
||||
|
@ -10,10 +10,10 @@
|
||||
|
||||
void Interpreter::Helper_UpdateCR0(u32 value)
|
||||
{
|
||||
s64 sign_extended = (s64)(s32)value;
|
||||
u64 cr_val = (u64)sign_extended;
|
||||
cr_val = (cr_val & ~(1ull << PowerPC::CR_EMU_SO_BIT)) |
|
||||
((u64)PowerPC::GetXER_SO() << PowerPC::CR_EMU_SO_BIT);
|
||||
const s64 sign_extended = s64{s32(value)};
|
||||
u64 cr_val = u64(sign_extended);
|
||||
cr_val = (cr_val & ~(1ULL << PowerPC::CR_EMU_SO_BIT)) |
|
||||
(u64{PowerPC::GetXER_SO()} << PowerPC::CR_EMU_SO_BIT);
|
||||
|
||||
PowerPC::ppcState.cr.fields[0] = cr_val;
|
||||
}
|
||||
@ -26,16 +26,16 @@ u32 Interpreter::Helper_Carry(u32 value1, u32 value2)
|
||||
void Interpreter::addi(UGeckoInstruction inst)
|
||||
{
|
||||
if (inst.RA)
|
||||
rGPR[inst.RD] = rGPR[inst.RA] + inst.SIMM_16;
|
||||
rGPR[inst.RD] = rGPR[inst.RA] + u32(inst.SIMM_16);
|
||||
else
|
||||
rGPR[inst.RD] = inst.SIMM_16;
|
||||
rGPR[inst.RD] = u32(inst.SIMM_16);
|
||||
}
|
||||
|
||||
void Interpreter::addic(UGeckoInstruction inst)
|
||||
{
|
||||
u32 a = rGPR[inst.RA];
|
||||
u32 imm = (u32)(s32)inst.SIMM_16;
|
||||
// TODO(ector): verify this thing
|
||||
const u32 a = rGPR[inst.RA];
|
||||
const u32 imm = u32(s32{inst.SIMM_16});
|
||||
|
||||
rGPR[inst.RD] = a + imm;
|
||||
PowerPC::SetCarry(Helper_Carry(a, imm));
|
||||
}
|
||||
@ -49,9 +49,9 @@ void Interpreter::addic_rc(UGeckoInstruction inst)
|
||||
void Interpreter::addis(UGeckoInstruction inst)
|
||||
{
|
||||
if (inst.RA)
|
||||
rGPR[inst.RD] = rGPR[inst.RA] + (inst.SIMM_16 << 16);
|
||||
rGPR[inst.RD] = rGPR[inst.RA] + u32(inst.SIMM_16 << 16);
|
||||
else
|
||||
rGPR[inst.RD] = (inst.SIMM_16 << 16);
|
||||
rGPR[inst.RD] = u32(inst.SIMM_16 << 16);
|
||||
}
|
||||
|
||||
void Interpreter::andi_rc(UGeckoInstruction inst)
|
||||
@ -62,7 +62,7 @@ void Interpreter::andi_rc(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::andis_rc(UGeckoInstruction inst)
|
||||
{
|
||||
rGPR[inst.RA] = rGPR[inst.RS] & ((u32)inst.UIMM << 16);
|
||||
rGPR[inst.RA] = rGPR[inst.RS] & (u32{inst.UIMM} << 16);
|
||||
Helper_UpdateCR0(rGPR[inst.RA]);
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ void Interpreter::cmpli(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::mulli(UGeckoInstruction inst)
|
||||
{
|
||||
rGPR[inst.RD] = (s32)rGPR[inst.RA] * inst.SIMM_16;
|
||||
rGPR[inst.RD] = u32(s32(rGPR[inst.RA]) * inst.SIMM_16);
|
||||
}
|
||||
|
||||
void Interpreter::ori(UGeckoInstruction inst)
|
||||
@ -110,26 +110,26 @@ void Interpreter::ori(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::oris(UGeckoInstruction inst)
|
||||
{
|
||||
rGPR[inst.RA] = rGPR[inst.RS] | (inst.UIMM << 16);
|
||||
rGPR[inst.RA] = rGPR[inst.RS] | (u32{inst.UIMM} << 16);
|
||||
}
|
||||
|
||||
void Interpreter::subfic(UGeckoInstruction inst)
|
||||
{
|
||||
s32 immediate = inst.SIMM_16;
|
||||
rGPR[inst.RD] = immediate - (int)rGPR[inst.RA];
|
||||
PowerPC::SetCarry((rGPR[inst.RA] == 0) || (Helper_Carry(0 - rGPR[inst.RA], immediate)));
|
||||
const s32 immediate = inst.SIMM_16;
|
||||
rGPR[inst.RD] = u32(immediate - s32(rGPR[inst.RA]));
|
||||
PowerPC::SetCarry((rGPR[inst.RA] == 0) || (Helper_Carry(0 - rGPR[inst.RA], u32(immediate))));
|
||||
}
|
||||
|
||||
void Interpreter::twi(UGeckoInstruction inst)
|
||||
{
|
||||
const s32 a = rGPR[inst.RA];
|
||||
const s32 a = s32(rGPR[inst.RA]);
|
||||
const s32 b = inst.SIMM_16;
|
||||
const s32 TO = inst.TO;
|
||||
const u32 TO = inst.TO;
|
||||
|
||||
DEBUG_LOG_FMT(POWERPC, "twi rA {:x} SIMM {:x} TO {:x}", a, b, TO);
|
||||
|
||||
if (((a < b) && (TO & 0x10)) || ((a > b) && (TO & 0x08)) || ((a == b) && (TO & 0x04)) ||
|
||||
(((u32)a < (u32)b) && (TO & 0x02)) || (((u32)a > (u32)b) && (TO & 0x01)))
|
||||
if ((a < b && (TO & 0x10) != 0) || (a > b && (TO & 0x08) != 0) || (a == b && (TO & 0x04) != 0) ||
|
||||
(u32(a) < u32(b) && (TO & 0x02) != 0) || (u32(a) > u32(b) && (TO & 0x01) != 0))
|
||||
{
|
||||
PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM;
|
||||
PowerPC::CheckExceptions();
|
||||
@ -144,7 +144,7 @@ void Interpreter::xori(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::xoris(UGeckoInstruction inst)
|
||||
{
|
||||
rGPR[inst.RA] = rGPR[inst.RS] ^ (inst.UIMM << 16);
|
||||
rGPR[inst.RA] = rGPR[inst.RS] ^ (u32{inst.UIMM} << 16);
|
||||
}
|
||||
|
||||
void Interpreter::rlwimix(UGeckoInstruction inst)
|
||||
@ -206,7 +206,7 @@ void Interpreter::cmpl(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::cntlzwx(UGeckoInstruction inst)
|
||||
{
|
||||
rGPR[inst.RA] = Common::CountLeadingZeros(rGPR[inst.RS]);
|
||||
rGPR[inst.RA] = u32(Common::CountLeadingZeros(rGPR[inst.RS]));
|
||||
|
||||
if (inst.Rc)
|
||||
Helper_UpdateCR0(rGPR[inst.RA]);
|
||||
@ -222,7 +222,7 @@ void Interpreter::eqvx(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::extsbx(UGeckoInstruction inst)
|
||||
{
|
||||
rGPR[inst.RA] = (u32)(s32)(s8)rGPR[inst.RS];
|
||||
rGPR[inst.RA] = u32(s32(s8(rGPR[inst.RS])));
|
||||
|
||||
if (inst.Rc)
|
||||
Helper_UpdateCR0(rGPR[inst.RA]);
|
||||
@ -230,18 +230,18 @@ void Interpreter::extsbx(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::extshx(UGeckoInstruction inst)
|
||||
{
|
||||
rGPR[inst.RA] = (u32)(s32)(s16)rGPR[inst.RS];
|
||||
rGPR[inst.RA] = u32(s32(s16(rGPR[inst.RS])));
|
||||
|
||||
if (inst.Rc)
|
||||
Helper_UpdateCR0(rGPR[inst.RA]);
|
||||
}
|
||||
|
||||
void Interpreter::nandx(UGeckoInstruction _inst)
|
||||
void Interpreter::nandx(UGeckoInstruction inst)
|
||||
{
|
||||
rGPR[_inst.RA] = ~(rGPR[_inst.RS] & rGPR[_inst.RB]);
|
||||
rGPR[inst.RA] = ~(rGPR[inst.RS] & rGPR[inst.RB]);
|
||||
|
||||
if (_inst.Rc)
|
||||
Helper_UpdateCR0(rGPR[_inst.RA]);
|
||||
if (inst.Rc)
|
||||
Helper_UpdateCR0(rGPR[inst.RA]);
|
||||
}
|
||||
|
||||
void Interpreter::norx(UGeckoInstruction inst)
|
||||
@ -270,8 +270,8 @@ void Interpreter::orcx(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::slwx(UGeckoInstruction inst)
|
||||
{
|
||||
u32 amount = rGPR[inst.RB];
|
||||
rGPR[inst.RA] = (amount & 0x20) ? 0 : rGPR[inst.RS] << (amount & 0x1f);
|
||||
const u32 amount = rGPR[inst.RB];
|
||||
rGPR[inst.RA] = (amount & 0x20) != 0 ? 0 : rGPR[inst.RS] << (amount & 0x1f);
|
||||
|
||||
if (inst.Rc)
|
||||
Helper_UpdateCR0(rGPR[inst.RA]);
|
||||
@ -279,11 +279,11 @@ void Interpreter::slwx(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::srawx(UGeckoInstruction inst)
|
||||
{
|
||||
int rb = rGPR[inst.RB];
|
||||
const u32 rb = rGPR[inst.RB];
|
||||
|
||||
if (rb & 0x20)
|
||||
if ((rb & 0x20) != 0)
|
||||
{
|
||||
if (rGPR[inst.RS] & 0x80000000)
|
||||
if ((rGPR[inst.RS] & 0x80000000) != 0)
|
||||
{
|
||||
rGPR[inst.RA] = 0xFFFFFFFF;
|
||||
PowerPC::SetCarry(1);
|
||||
@ -296,9 +296,9 @@ void Interpreter::srawx(UGeckoInstruction inst)
|
||||
}
|
||||
else
|
||||
{
|
||||
int amount = rb & 0x1f;
|
||||
s32 rrs = rGPR[inst.RS];
|
||||
rGPR[inst.RA] = rrs >> amount;
|
||||
const u32 amount = rb & 0x1f;
|
||||
const s32 rrs = s32(rGPR[inst.RS]);
|
||||
rGPR[inst.RA] = u32(rrs >> amount);
|
||||
|
||||
PowerPC::SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0);
|
||||
}
|
||||
@ -309,11 +309,10 @@ void Interpreter::srawx(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::srawix(UGeckoInstruction inst)
|
||||
{
|
||||
int amount = inst.SH;
|
||||
|
||||
s32 rrs = rGPR[inst.RS];
|
||||
rGPR[inst.RA] = rrs >> amount;
|
||||
const u32 amount = inst.SH;
|
||||
const s32 rrs = s32(rGPR[inst.RS]);
|
||||
|
||||
rGPR[inst.RA] = u32(rrs >> amount);
|
||||
PowerPC::SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0);
|
||||
|
||||
if (inst.Rc)
|
||||
@ -322,8 +321,8 @@ void Interpreter::srawix(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::srwx(UGeckoInstruction inst)
|
||||
{
|
||||
u32 amount = rGPR[inst.RB];
|
||||
rGPR[inst.RA] = (amount & 0x20) ? 0 : (rGPR[inst.RS] >> (amount & 0x1f));
|
||||
const u32 amount = rGPR[inst.RB];
|
||||
rGPR[inst.RA] = (amount & 0x20) != 0 ? 0 : (rGPR[inst.RS] >> (amount & 0x1f));
|
||||
|
||||
if (inst.Rc)
|
||||
Helper_UpdateCR0(rGPR[inst.RA]);
|
||||
@ -331,14 +330,14 @@ void Interpreter::srwx(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::tw(UGeckoInstruction inst)
|
||||
{
|
||||
const s32 a = rGPR[inst.RA];
|
||||
const s32 b = rGPR[inst.RB];
|
||||
const s32 TO = inst.TO;
|
||||
const s32 a = s32(rGPR[inst.RA]);
|
||||
const s32 b = s32(rGPR[inst.RB]);
|
||||
const u32 TO = inst.TO;
|
||||
|
||||
DEBUG_LOG_FMT(POWERPC, "tw rA {:x} rB {:x} TO {:x}", a, b, TO);
|
||||
|
||||
if (((a < b) && (TO & 0x10)) || ((a > b) && (TO & 0x08)) || ((a == b) && (TO & 0x04)) ||
|
||||
(((u32)a < (u32)b) && (TO & 0x02)) || (((u32)a > (u32)b) && (TO & 0x01)))
|
||||
if ((a < b && (TO & 0x10) != 0) || (a > b && (TO & 0x08) != 0) || (a == b && (TO & 0x04) != 0) ||
|
||||
((u32(a) < u32(b)) && (TO & 0x02) != 0) || ((u32(a) > u32(b)) && (TO & 0x01) != 0))
|
||||
{
|
||||
PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM;
|
||||
PowerPC::CheckExceptions();
|
||||
@ -444,8 +443,8 @@ void Interpreter::addzex(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::divwx(UGeckoInstruction inst)
|
||||
{
|
||||
const s32 a = rGPR[inst.RA];
|
||||
const s32 b = rGPR[inst.RB];
|
||||
const auto a = s32(rGPR[inst.RA]);
|
||||
const auto b = s32(rGPR[inst.RB]);
|
||||
const bool overflow = b == 0 || (static_cast<u32>(a) == 0x80000000 && b == -1);
|
||||
|
||||
if (overflow)
|
||||
|
@ -17,12 +17,12 @@
|
||||
|
||||
static u32 Helper_Get_EA(const PowerPC::PowerPCState& ppcs, const UGeckoInstruction inst)
|
||||
{
|
||||
return inst.RA ? (ppcs.gpr[inst.RA] + inst.SIMM_16) : (u32)inst.SIMM_16;
|
||||
return inst.RA ? (ppcs.gpr[inst.RA] + u32(inst.SIMM_16)) : u32(inst.SIMM_16);
|
||||
}
|
||||
|
||||
static u32 Helper_Get_EA_U(const PowerPC::PowerPCState& ppcs, const UGeckoInstruction inst)
|
||||
{
|
||||
return (ppcs.gpr[inst.RA] + inst.SIMM_16);
|
||||
return (ppcs.gpr[inst.RA] + u32(inst.SIMM_16));
|
||||
}
|
||||
|
||||
static u32 Helper_Get_EA_X(const PowerPC::PowerPCState& ppcs, const UGeckoInstruction inst)
|
||||
@ -205,7 +205,7 @@ void Interpreter::lfsx(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::lha(UGeckoInstruction inst)
|
||||
{
|
||||
const u32 temp = (u32)(s32)(s16)PowerPC::Read_U16(Helper_Get_EA(PowerPC::ppcState, inst));
|
||||
const u32 temp = u32(s32(s16(PowerPC::Read_U16(Helper_Get_EA(PowerPC::ppcState, inst)))));
|
||||
|
||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
@ -216,7 +216,7 @@ void Interpreter::lha(UGeckoInstruction inst)
|
||||
void Interpreter::lhau(UGeckoInstruction inst)
|
||||
{
|
||||
const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst);
|
||||
const u32 temp = (u32)(s32)(s16)PowerPC::Read_U16(address);
|
||||
const u32 temp = u32(s32(s16(PowerPC::Read_U16(address))));
|
||||
|
||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
@ -258,11 +258,11 @@ void Interpreter::lmw(UGeckoInstruction inst)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = inst.RD; i <= 31; i++, address += 4)
|
||||
for (u32 i = inst.RD; i <= 31; i++, address += 4)
|
||||
{
|
||||
const u32 temp_reg = PowerPC::Read_U32(address);
|
||||
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
PanicAlertFmt("DSI exception in lmw");
|
||||
NOTICE_LOG_FMT(POWERPC, "DSI exception in lmw");
|
||||
@ -286,10 +286,10 @@ void Interpreter::stmw(UGeckoInstruction inst)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = inst.RS; i <= 31; i++, address += 4)
|
||||
for (u32 i = inst.RS; i <= 31; i++, address += 4)
|
||||
{
|
||||
PowerPC::Write_U32(rGPR[i], address);
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
PanicAlertFmt("DSI exception in stmw");
|
||||
NOTICE_LOG_FMT(POWERPC, "DSI exception in stmw");
|
||||
@ -536,13 +536,13 @@ void Interpreter::eciwx(UGeckoInstruction inst)
|
||||
{
|
||||
const u32 EA = Helper_Get_EA_X(PowerPC::ppcState, inst);
|
||||
|
||||
if (!(PowerPC::ppcState.spr[SPR_EAR] & 0x80000000))
|
||||
if ((PowerPC::ppcState.spr[SPR_EAR] & 0x80000000) == 0)
|
||||
{
|
||||
GenerateDSIException(EA);
|
||||
return;
|
||||
}
|
||||
|
||||
if (EA & 3)
|
||||
if ((EA & 0b11) != 0)
|
||||
{
|
||||
GenerateAlignmentException(EA);
|
||||
return;
|
||||
@ -555,13 +555,13 @@ void Interpreter::ecowx(UGeckoInstruction inst)
|
||||
{
|
||||
const u32 EA = Helper_Get_EA_X(PowerPC::ppcState, inst);
|
||||
|
||||
if (!(PowerPC::ppcState.spr[SPR_EAR] & 0x80000000))
|
||||
if ((PowerPC::ppcState.spr[SPR_EAR] & 0x80000000) == 0)
|
||||
{
|
||||
GenerateDSIException(EA);
|
||||
return;
|
||||
}
|
||||
|
||||
if (EA & 3)
|
||||
if ((EA & 0b11) != 0)
|
||||
{
|
||||
GenerateAlignmentException(EA);
|
||||
return;
|
||||
@ -610,22 +610,22 @@ void Interpreter::lbzx(UGeckoInstruction inst)
|
||||
void Interpreter::lhaux(UGeckoInstruction inst)
|
||||
{
|
||||
const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst);
|
||||
const s32 temp = (s32)(s16)PowerPC::Read_U16(address);
|
||||
const s32 temp = s32{s16(PowerPC::Read_U16(address))};
|
||||
|
||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
rGPR[inst.RD] = temp;
|
||||
rGPR[inst.RD] = u32(temp);
|
||||
rGPR[inst.RA] = address;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::lhax(UGeckoInstruction inst)
|
||||
{
|
||||
const s32 temp = (s32)(s16)PowerPC::Read_U16(Helper_Get_EA_X(PowerPC::ppcState, inst));
|
||||
const s32 temp = s32{s16(PowerPC::Read_U16(Helper_Get_EA_X(PowerPC::ppcState, inst)))};
|
||||
|
||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
rGPR[inst.RD] = temp;
|
||||
rGPR[inst.RD] = u32(temp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,15 +675,15 @@ void Interpreter::lswx(UGeckoInstruction inst)
|
||||
// Confirmed by hardware test that the zero case doesn't zero rGPR[r]
|
||||
for (u32 n = 0; n < static_cast<u8>(PowerPC::ppcState.xer_stringctrl); n++)
|
||||
{
|
||||
const int reg = (inst.RD + (n >> 2)) & 0x1f;
|
||||
const int offset = (n & 3) << 3;
|
||||
const u32 reg = (inst.RD + (n >> 2)) & 0x1f;
|
||||
const u32 offset = (n & 3) << 3;
|
||||
|
||||
if ((n & 3) == 0)
|
||||
if ((n & 0b11) == 0)
|
||||
rGPR[reg] = 0;
|
||||
|
||||
const u32 temp_value = PowerPC::Read_U8(EA) << (24 - offset);
|
||||
// Not64 (Homebrew N64 Emulator for Wii) triggers the following case.
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
NOTICE_LOG_FMT(POWERPC, "DSI exception in lswx");
|
||||
return;
|
||||
@ -842,10 +842,8 @@ void Interpreter::sthx(UGeckoInstruction inst)
|
||||
// FIXME: Should rollback if a DSI occurs
|
||||
void Interpreter::lswi(UGeckoInstruction inst)
|
||||
{
|
||||
u32 EA;
|
||||
if (inst.RA == 0)
|
||||
EA = 0;
|
||||
else
|
||||
u32 EA = 0;
|
||||
if (inst.RA != 0)
|
||||
EA = rGPR[inst.RA];
|
||||
|
||||
if (MSR.LE)
|
||||
@ -854,14 +852,12 @@ void Interpreter::lswi(UGeckoInstruction inst)
|
||||
return;
|
||||
}
|
||||
|
||||
u32 n;
|
||||
if (inst.NB == 0)
|
||||
n = 32;
|
||||
else
|
||||
u32 n = 32;
|
||||
if (inst.NB != 0)
|
||||
n = inst.NB;
|
||||
|
||||
int r = inst.RD - 1;
|
||||
int i = 0;
|
||||
u32 r = u32{inst.RD} - 1;
|
||||
u32 i = 0;
|
||||
while (n > 0)
|
||||
{
|
||||
if (i == 0)
|
||||
@ -872,7 +868,7 @@ void Interpreter::lswi(UGeckoInstruction inst)
|
||||
}
|
||||
|
||||
const u32 temp_value = PowerPC::Read_U8(EA) << (24 - i);
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
PanicAlertFmt("DSI exception in lsw.");
|
||||
return;
|
||||
@ -893,10 +889,8 @@ void Interpreter::lswi(UGeckoInstruction inst)
|
||||
// FIXME: Should rollback if a DSI occurs
|
||||
void Interpreter::stswi(UGeckoInstruction inst)
|
||||
{
|
||||
u32 EA;
|
||||
if (inst.RA == 0)
|
||||
EA = 0;
|
||||
else
|
||||
u32 EA = 0;
|
||||
if (inst.RA != 0)
|
||||
EA = rGPR[inst.RA];
|
||||
|
||||
if (MSR.LE)
|
||||
@ -905,14 +899,12 @@ void Interpreter::stswi(UGeckoInstruction inst)
|
||||
return;
|
||||
}
|
||||
|
||||
u32 n;
|
||||
if (inst.NB == 0)
|
||||
n = 32;
|
||||
else
|
||||
u32 n = 32;
|
||||
if (inst.NB != 0)
|
||||
n = inst.NB;
|
||||
|
||||
int r = inst.RS - 1;
|
||||
int i = 0;
|
||||
u32 r = u32{inst.RS} - 1;
|
||||
u32 i = 0;
|
||||
while (n > 0)
|
||||
{
|
||||
if (i == 0)
|
||||
@ -921,7 +913,7 @@ void Interpreter::stswi(UGeckoInstruction inst)
|
||||
r &= 31;
|
||||
}
|
||||
PowerPC::Write_U8((rGPR[r] >> (24 - i)) & 0xFF, EA);
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -945,9 +937,9 @@ void Interpreter::stswx(UGeckoInstruction inst)
|
||||
return;
|
||||
}
|
||||
|
||||
u32 n = (u8)PowerPC::ppcState.xer_stringctrl;
|
||||
int r = inst.RS;
|
||||
int i = 0;
|
||||
u32 n = u8(PowerPC::ppcState.xer_stringctrl);
|
||||
u32 r = inst.RS;
|
||||
u32 i = 0;
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
|
@ -57,13 +57,13 @@ const float m_quantizeTable[] = {
|
||||
};
|
||||
|
||||
template <typename SType>
|
||||
SType ScaleAndClamp(double ps, u32 stScale)
|
||||
SType ScaleAndClamp(double ps, u32 st_scale)
|
||||
{
|
||||
float convPS = (float)ps * m_quantizeTable[stScale];
|
||||
constexpr float min = (float)std::numeric_limits<SType>::min();
|
||||
constexpr float max = (float)std::numeric_limits<SType>::max();
|
||||
const float conv_ps = float(ps) * m_quantizeTable[st_scale];
|
||||
constexpr float min = float(std::numeric_limits<SType>::min());
|
||||
constexpr float max = float(std::numeric_limits<SType>::max());
|
||||
|
||||
return (SType)std::clamp(convPS, min, max);
|
||||
return SType(std::clamp(conv_ps, min, max));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -93,22 +93,22 @@ static std::pair<T, T> ReadPair(u32 addr);
|
||||
template <>
|
||||
std::pair<u8, u8> ReadPair<u8>(u32 addr)
|
||||
{
|
||||
u16 val = PowerPC::Read_U16(addr);
|
||||
return {(u8)(val >> 8), (u8)val};
|
||||
const u16 val = PowerPC::Read_U16(addr);
|
||||
return {u8(val >> 8), u8(val)};
|
||||
}
|
||||
|
||||
template <>
|
||||
std::pair<u16, u16> ReadPair<u16>(u32 addr)
|
||||
{
|
||||
u32 val = PowerPC::Read_U32(addr);
|
||||
return {(u16)(val >> 16), (u16)val};
|
||||
const u32 val = PowerPC::Read_U32(addr);
|
||||
return {u16(val >> 16), u16(val)};
|
||||
}
|
||||
|
||||
template <>
|
||||
std::pair<u32, u32> ReadPair<u32>(u32 addr)
|
||||
{
|
||||
u64 val = PowerPC::Read_U64(addr);
|
||||
return {(u32)(val >> 32), (u32)val};
|
||||
const u64 val = PowerPC::Read_U64(addr);
|
||||
return {u32(val >> 32), u32(val)};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -138,35 +138,35 @@ static void WritePair(T val1, T val2, u32 addr);
|
||||
template <>
|
||||
void WritePair<u8>(u8 val1, u8 val2, u32 addr)
|
||||
{
|
||||
PowerPC::Write_U16(((u16)val1 << 8) | (u16)val2, addr);
|
||||
PowerPC::Write_U16((u16{val1} << 8) | u16{val2}, addr);
|
||||
}
|
||||
|
||||
template <>
|
||||
void WritePair<u16>(u16 val1, u16 val2, u32 addr)
|
||||
{
|
||||
PowerPC::Write_U32(((u32)val1 << 16) | (u32)val2, addr);
|
||||
PowerPC::Write_U32((u32{val1} << 16) | u32{val2}, addr);
|
||||
}
|
||||
|
||||
template <>
|
||||
void WritePair<u32>(u32 val1, u32 val2, u32 addr)
|
||||
{
|
||||
PowerPC::Write_U64(((u64)val1 << 32) | (u64)val2, addr);
|
||||
PowerPC::Write_U64((u64{val1} << 32) | u64{val2}, addr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void QuantizeAndStore(double ps0, double ps1, u32 addr, u32 instW, u32 stScale)
|
||||
void QuantizeAndStore(double ps0, double ps1, u32 addr, u32 instW, u32 st_scale)
|
||||
{
|
||||
using U = std::make_unsigned_t<T>;
|
||||
|
||||
U convPS0 = (U)ScaleAndClamp<T>(ps0, stScale);
|
||||
const U conv_ps0 = U(ScaleAndClamp<T>(ps0, st_scale));
|
||||
if (instW)
|
||||
{
|
||||
WriteUnpaired<U>(convPS0, addr);
|
||||
WriteUnpaired<U>(conv_ps0, addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
U convPS1 = (U)ScaleAndClamp<T>(ps1, stScale);
|
||||
WritePair<U>(convPS0, convPS1, addr);
|
||||
const U conv_ps1 = U(ScaleAndClamp<T>(ps1, st_scale));
|
||||
WritePair<U>(conv_ps0, conv_ps1, addr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,20 +174,20 @@ static void Helper_Quantize(const PowerPC::PowerPCState* ppcs, u32 addr, u32 ins
|
||||
u32 instW)
|
||||
{
|
||||
const UGQR gqr(ppcs->spr[SPR_GQR0 + instI]);
|
||||
const EQuantizeType stType = gqr.st_type;
|
||||
const unsigned int stScale = gqr.st_scale;
|
||||
const EQuantizeType st_type = gqr.st_type;
|
||||
const u32 st_scale = gqr.st_scale;
|
||||
|
||||
const double ps0 = ppcs->ps[instRS].PS0AsDouble();
|
||||
const double ps1 = ppcs->ps[instRS].PS1AsDouble();
|
||||
|
||||
switch (stType)
|
||||
switch (st_type)
|
||||
{
|
||||
case QUANTIZE_FLOAT:
|
||||
{
|
||||
const u64 integral_ps0 = Common::BitCast<u64>(ps0);
|
||||
const u32 conv_ps0 = ConvertToSingleFTZ(integral_ps0);
|
||||
|
||||
if (instW)
|
||||
if (instW != 0)
|
||||
{
|
||||
WriteUnpaired<u32>(conv_ps0, addr);
|
||||
}
|
||||
@ -202,19 +202,19 @@ static void Helper_Quantize(const PowerPC::PowerPCState* ppcs, u32 addr, u32 ins
|
||||
}
|
||||
|
||||
case QUANTIZE_U8:
|
||||
QuantizeAndStore<u8>(ps0, ps1, addr, instW, stScale);
|
||||
QuantizeAndStore<u8>(ps0, ps1, addr, instW, st_scale);
|
||||
break;
|
||||
|
||||
case QUANTIZE_U16:
|
||||
QuantizeAndStore<u16>(ps0, ps1, addr, instW, stScale);
|
||||
QuantizeAndStore<u16>(ps0, ps1, addr, instW, st_scale);
|
||||
break;
|
||||
|
||||
case QUANTIZE_S8:
|
||||
QuantizeAndStore<s8>(ps0, ps1, addr, instW, stScale);
|
||||
QuantizeAndStore<s8>(ps0, ps1, addr, instW, st_scale);
|
||||
break;
|
||||
|
||||
case QUANTIZE_S16:
|
||||
QuantizeAndStore<s16>(ps0, ps1, addr, instW, stScale);
|
||||
QuantizeAndStore<s16>(ps0, ps1, addr, instW, st_scale);
|
||||
break;
|
||||
|
||||
case QUANTIZE_INVALID1:
|
||||
@ -226,22 +226,22 @@ static void Helper_Quantize(const PowerPC::PowerPCState* ppcs, u32 addr, u32 ins
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::pair<double, double> LoadAndDequantize(u32 addr, u32 instW, u32 ldScale)
|
||||
std::pair<double, double> LoadAndDequantize(u32 addr, u32 instW, u32 ld_scale)
|
||||
{
|
||||
using U = std::make_unsigned_t<T>;
|
||||
|
||||
float ps0, ps1;
|
||||
if (instW)
|
||||
if (instW != 0)
|
||||
{
|
||||
U value = ReadUnpaired<U>(addr);
|
||||
ps0 = (float)(T)(value)*m_dequantizeTable[ldScale];
|
||||
const U value = ReadUnpaired<U>(addr);
|
||||
ps0 = float(T(value)) * m_dequantizeTable[ld_scale];
|
||||
ps1 = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::pair<U, U> value = ReadPair<U>(addr);
|
||||
ps0 = (float)(T)(value.first) * m_dequantizeTable[ldScale];
|
||||
ps1 = (float)(T)(value.second) * m_dequantizeTable[ldScale];
|
||||
const auto [first, second] = ReadPair<U>(addr);
|
||||
ps0 = float(T(first)) * m_dequantizeTable[ld_scale];
|
||||
ps1 = float(T(second)) * m_dequantizeTable[ld_scale];
|
||||
}
|
||||
// ps0 and ps1 always contain finite and normal numbers. So we can just cast them to double
|
||||
return {static_cast<double>(ps0), static_cast<double>(ps1)};
|
||||
@ -250,17 +250,17 @@ std::pair<double, double> LoadAndDequantize(u32 addr, u32 instW, u32 ldScale)
|
||||
static void Helper_Dequantize(PowerPC::PowerPCState* ppcs, u32 addr, u32 instI, u32 instRD,
|
||||
u32 instW)
|
||||
{
|
||||
UGQR gqr(ppcs->spr[SPR_GQR0 + instI]);
|
||||
EQuantizeType ldType = gqr.ld_type;
|
||||
unsigned int ldScale = gqr.ld_scale;
|
||||
const UGQR gqr(ppcs->spr[SPR_GQR0 + instI]);
|
||||
const EQuantizeType ld_type = gqr.ld_type;
|
||||
const u32 ld_scale = gqr.ld_scale;
|
||||
|
||||
double ps0 = 0.0;
|
||||
double ps1 = 0.0;
|
||||
|
||||
switch (ldType)
|
||||
switch (ld_type)
|
||||
{
|
||||
case QUANTIZE_FLOAT:
|
||||
if (instW)
|
||||
if (instW != 0)
|
||||
{
|
||||
const u32 value = ReadUnpaired<u32>(addr);
|
||||
ps0 = Common::BitCast<double>(ConvertToDouble(value));
|
||||
@ -268,26 +268,26 @@ static void Helper_Dequantize(PowerPC::PowerPCState* ppcs, u32 addr, u32 instI,
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::pair<u32, u32> value = ReadPair<u32>(addr);
|
||||
ps0 = Common::BitCast<double>(ConvertToDouble(value.first));
|
||||
ps1 = Common::BitCast<double>(ConvertToDouble(value.second));
|
||||
const auto [first, second] = ReadPair<u32>(addr);
|
||||
ps0 = Common::BitCast<double>(ConvertToDouble(first));
|
||||
ps1 = Common::BitCast<double>(ConvertToDouble(second));
|
||||
}
|
||||
break;
|
||||
|
||||
case QUANTIZE_U8:
|
||||
std::tie(ps0, ps1) = LoadAndDequantize<u8>(addr, instW, ldScale);
|
||||
std::tie(ps0, ps1) = LoadAndDequantize<u8>(addr, instW, ld_scale);
|
||||
break;
|
||||
|
||||
case QUANTIZE_U16:
|
||||
std::tie(ps0, ps1) = LoadAndDequantize<u16>(addr, instW, ldScale);
|
||||
std::tie(ps0, ps1) = LoadAndDequantize<u16>(addr, instW, ld_scale);
|
||||
break;
|
||||
|
||||
case QUANTIZE_S8:
|
||||
std::tie(ps0, ps1) = LoadAndDequantize<s8>(addr, instW, ldScale);
|
||||
std::tie(ps0, ps1) = LoadAndDequantize<s8>(addr, instW, ld_scale);
|
||||
break;
|
||||
|
||||
case QUANTIZE_S16:
|
||||
std::tie(ps0, ps1) = LoadAndDequantize<s16>(addr, instW, ldScale);
|
||||
std::tie(ps0, ps1) = LoadAndDequantize<s16>(addr, instW, ld_scale);
|
||||
break;
|
||||
|
||||
case QUANTIZE_INVALID1:
|
||||
@ -299,7 +299,7 @@ static void Helper_Dequantize(PowerPC::PowerPCState* ppcs, u32 addr, u32 instI,
|
||||
break;
|
||||
}
|
||||
|
||||
if (ppcs->Exceptions & EXCEPTION_DSI)
|
||||
if ((ppcs->Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -315,7 +315,7 @@ void Interpreter::psq_l(UGeckoInstruction inst)
|
||||
return;
|
||||
}
|
||||
|
||||
const u32 EA = inst.RA ? (rGPR[inst.RA] + inst.SIMM_12) : (u32)inst.SIMM_12;
|
||||
const u32 EA = inst.RA ? (rGPR[inst.RA] + u32(inst.SIMM_12)) : u32(inst.SIMM_12);
|
||||
Helper_Dequantize(&PowerPC::ppcState, EA, inst.I, inst.RD, inst.W);
|
||||
}
|
||||
|
||||
@ -327,13 +327,14 @@ void Interpreter::psq_lu(UGeckoInstruction inst)
|
||||
return;
|
||||
}
|
||||
|
||||
const u32 EA = rGPR[inst.RA] + inst.SIMM_12;
|
||||
const u32 EA = rGPR[inst.RA] + u32(inst.SIMM_12);
|
||||
Helper_Dequantize(&PowerPC::ppcState, EA, inst.I, inst.RD, inst.W);
|
||||
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rGPR[inst.RA] = EA;
|
||||
}
|
||||
|
||||
@ -345,7 +346,7 @@ void Interpreter::psq_st(UGeckoInstruction inst)
|
||||
return;
|
||||
}
|
||||
|
||||
const u32 EA = inst.RA ? (rGPR[inst.RA] + inst.SIMM_12) : (u32)inst.SIMM_12;
|
||||
const u32 EA = inst.RA ? (rGPR[inst.RA] + u32(inst.SIMM_12)) : u32(inst.SIMM_12);
|
||||
Helper_Quantize(&PowerPC::ppcState, EA, inst.I, inst.RS, inst.W);
|
||||
}
|
||||
|
||||
@ -357,13 +358,14 @@ void Interpreter::psq_stu(UGeckoInstruction inst)
|
||||
return;
|
||||
}
|
||||
|
||||
const u32 EA = rGPR[inst.RA] + inst.SIMM_12;
|
||||
const u32 EA = rGPR[inst.RA] + u32(inst.SIMM_12);
|
||||
Helper_Quantize(&PowerPC::ppcState, EA, inst.I, inst.RS, inst.W);
|
||||
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rGPR[inst.RA] = EA;
|
||||
}
|
||||
|
||||
@ -384,10 +386,11 @@ void Interpreter::psq_lux(UGeckoInstruction inst)
|
||||
const u32 EA = rGPR[inst.RA] + rGPR[inst.RB];
|
||||
Helper_Dequantize(&PowerPC::ppcState, EA, inst.Ix, inst.RD, inst.Wx);
|
||||
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rGPR[inst.RA] = EA;
|
||||
}
|
||||
|
||||
@ -396,9 +399,10 @@ void Interpreter::psq_stux(UGeckoInstruction inst)
|
||||
const u32 EA = rGPR[inst.RA] + rGPR[inst.RB];
|
||||
Helper_Quantize(&PowerPC::ppcState, EA, inst.Ix, inst.RS, inst.Wx);
|
||||
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rGPR[inst.RA] = EA;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ void Interpreter::ps_res(UGeckoInstruction inst)
|
||||
const double ps1 = Common::ApproximateReciprocal(b);
|
||||
|
||||
rPS(inst.FD).SetBoth(ps0, ps1);
|
||||
PowerPC::UpdateFPRFSingle(ps0);
|
||||
PowerPC::UpdateFPRFSingle(float(ps0));
|
||||
|
||||
if (inst.Rc)
|
||||
PowerPC::ppcState.UpdateCR1();
|
||||
|
@ -61,7 +61,7 @@ void Interpreter::mtfsb1x(UGeckoInstruction inst)
|
||||
const u32 bit = inst.CRBD;
|
||||
const u32 b = 0x80000000 >> bit;
|
||||
|
||||
if (b & FPSCR_ANY_X)
|
||||
if ((b & FPSCR_ANY_X) != 0)
|
||||
SetFPException(&FPSCR, b);
|
||||
else
|
||||
FPSCR |= b;
|
||||
@ -93,7 +93,7 @@ void Interpreter::mtfsfx(UGeckoInstruction inst)
|
||||
u32 m = 0;
|
||||
for (u32 i = 0; i < 8; i++)
|
||||
{
|
||||
if (fm & (1U << i))
|
||||
if ((fm & (1U << i)) != 0)
|
||||
m |= (0xFU << (i * 4));
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ void Interpreter::mtcrf(UGeckoInstruction inst)
|
||||
u32 mask = 0;
|
||||
for (u32 i = 0; i < 8; i++)
|
||||
{
|
||||
if (crm & (1U << i))
|
||||
if ((crm & (1U << i)) != 0)
|
||||
mask |= 0xFU << (i * 4);
|
||||
}
|
||||
|
||||
@ -214,9 +214,8 @@ void Interpreter::mtsrin(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::mftb(UGeckoInstruction inst)
|
||||
{
|
||||
const u32 index = (inst.TBR >> 5) | ((inst.TBR & 0x1F) << 5);
|
||||
[[maybe_unused]] const u32 index = (inst.TBR >> 5) | ((inst.TBR & 0x1F) << 5);
|
||||
DEBUG_ASSERT_MSG(POWERPC, (index == SPR_TL) || (index == SPR_TU), "Invalid mftb");
|
||||
(void)index;
|
||||
mfspr(inst);
|
||||
}
|
||||
|
||||
@ -389,7 +388,8 @@ void Interpreter::mtspr(UGeckoInstruction inst)
|
||||
break;
|
||||
|
||||
case SPR_DEC:
|
||||
if (!(old_value >> 31) && (rGPR[inst.RD] >> 31)) // top bit from 0 to 1
|
||||
// Top bit from 0 to 1
|
||||
if ((old_value >> 31) == 0 && (rGPR[inst.RD] >> 31) != 0)
|
||||
{
|
||||
INFO_LOG_FMT(POWERPC, "Software triggered Decrementer exception");
|
||||
PowerPC::ppcState.Exceptions |= EXCEPTION_DECREMENTER;
|
||||
@ -487,50 +487,66 @@ void Interpreter::mtspr(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::crand(UGeckoInstruction inst)
|
||||
{
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, PowerPC::ppcState.cr.GetBit(inst.CRBA) &
|
||||
PowerPC::ppcState.cr.GetBit(inst.CRBB));
|
||||
const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA);
|
||||
const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB);
|
||||
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, a & b);
|
||||
}
|
||||
|
||||
void Interpreter::crandc(UGeckoInstruction inst)
|
||||
{
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, PowerPC::ppcState.cr.GetBit(inst.CRBA) &
|
||||
(1 ^ PowerPC::ppcState.cr.GetBit(inst.CRBB)));
|
||||
const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA);
|
||||
const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB);
|
||||
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, a & (1 ^ b));
|
||||
}
|
||||
|
||||
void Interpreter::creqv(UGeckoInstruction inst)
|
||||
{
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, 1 ^ (PowerPC::ppcState.cr.GetBit(inst.CRBA) ^
|
||||
PowerPC::ppcState.cr.GetBit(inst.CRBB)));
|
||||
const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA);
|
||||
const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB);
|
||||
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, 1 ^ (a ^ b));
|
||||
}
|
||||
|
||||
void Interpreter::crnand(UGeckoInstruction inst)
|
||||
{
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, 1 ^ (PowerPC::ppcState.cr.GetBit(inst.CRBA) &
|
||||
PowerPC::ppcState.cr.GetBit(inst.CRBB)));
|
||||
const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA);
|
||||
const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB);
|
||||
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, 1 ^ (a & b));
|
||||
}
|
||||
|
||||
void Interpreter::crnor(UGeckoInstruction inst)
|
||||
{
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, 1 ^ (PowerPC::ppcState.cr.GetBit(inst.CRBA) |
|
||||
PowerPC::ppcState.cr.GetBit(inst.CRBB)));
|
||||
const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA);
|
||||
const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB);
|
||||
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, 1 ^ (a | b));
|
||||
}
|
||||
|
||||
void Interpreter::cror(UGeckoInstruction inst)
|
||||
{
|
||||
PowerPC::ppcState.cr.SetBit(
|
||||
inst.CRBD, (PowerPC::ppcState.cr.GetBit(inst.CRBA) | PowerPC::ppcState.cr.GetBit(inst.CRBB)));
|
||||
const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA);
|
||||
const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB);
|
||||
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, a | b);
|
||||
}
|
||||
|
||||
void Interpreter::crorc(UGeckoInstruction inst)
|
||||
{
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, (PowerPC::ppcState.cr.GetBit(inst.CRBA) |
|
||||
(1 ^ PowerPC::ppcState.cr.GetBit(inst.CRBB))));
|
||||
const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA);
|
||||
const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB);
|
||||
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, a | (1 ^ b));
|
||||
}
|
||||
|
||||
void Interpreter::crxor(UGeckoInstruction inst)
|
||||
{
|
||||
PowerPC::ppcState.cr.SetBit(
|
||||
inst.CRBD, (PowerPC::ppcState.cr.GetBit(inst.CRBA) ^ PowerPC::ppcState.cr.GetBit(inst.CRBB)));
|
||||
const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA);
|
||||
const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB);
|
||||
|
||||
PowerPC::ppcState.cr.SetBit(inst.CRBD, a ^ b);
|
||||
}
|
||||
|
||||
void Interpreter::mcrf(UGeckoInstruction inst)
|
||||
|
Loading…
Reference in New Issue
Block a user