Skip to content
Permalink
Browse files
Merge pull request #10041 from lioncash/conv
Interpreter: Make signedness and narrowing conversions explicit
  • Loading branch information
leoetlino committed Aug 30, 2021
2 parents 95fcede + b7b45eb commit 48339af
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 219 deletions.
@@ -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,18 +7,19 @@
#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)
{
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,24 +43,26 @@ 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;
}

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)

0 comments on commit 48339af

Please sign in to comment.