Interpreter: Make signedness and narrowing conversions explicit
Makes our conversions between the different signs explicit to indicate that they're intentional and also silences compiler warnings when compiling with sign conversion or stricter truncation warnings enabled.
This commit is contained in:
parent
33154de614
commit
b7b45eb111
|
@ -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