Merge pull request #4693 from lioncash/interp-naming

Interpreter: Amend parameter naming
This commit is contained in:
Matthew Parlane
2017-01-21 12:31:51 +13:00
committed by GitHub
10 changed files with 1163 additions and 1161 deletions
@@ -40,25 +40,25 @@ std::array<Interpreter::Instruction, 1024> Interpreter::m_op_table31;
std::array<Interpreter::Instruction, 32> Interpreter::m_op_table59;
std::array<Interpreter::Instruction, 1024> Interpreter::m_op_table63;
void Interpreter::RunTable4(UGeckoInstruction _inst)
void Interpreter::RunTable4(UGeckoInstruction inst)
{
m_op_table4[_inst.SUBOP10](_inst);
m_op_table4[inst.SUBOP10](inst);
}
void Interpreter::RunTable19(UGeckoInstruction _inst)
void Interpreter::RunTable19(UGeckoInstruction inst)
{
m_op_table19[_inst.SUBOP10](_inst);
m_op_table19[inst.SUBOP10](inst);
}
void Interpreter::RunTable31(UGeckoInstruction _inst)
void Interpreter::RunTable31(UGeckoInstruction inst)
{
m_op_table31[_inst.SUBOP10](_inst);
m_op_table31[inst.SUBOP10](inst);
}
void Interpreter::RunTable59(UGeckoInstruction _inst)
void Interpreter::RunTable59(UGeckoInstruction inst)
{
m_op_table59[_inst.SUBOP5](_inst);
m_op_table59[inst.SUBOP5](inst);
}
void Interpreter::RunTable63(UGeckoInstruction _inst)
void Interpreter::RunTable63(UGeckoInstruction inst)
{
m_op_table63[_inst.SUBOP10](_inst);
m_op_table63[inst.SUBOP10](inst);
}
void Interpreter::Init()
@@ -73,7 +73,7 @@ void Interpreter::Shutdown()
static int startTrace = 0;
static void Trace(UGeckoInstruction& instCode)
static void Trace(UGeckoInstruction& inst)
{
std::string regs = "";
for (int i = 0; i < 32; i++)
@@ -88,11 +88,11 @@ static void Trace(UGeckoInstruction& instCode)
PowerPC::ppcState.ps[i][1]);
}
std::string ppc_inst = GekkoDisassembler::Disassemble(instCode.hex, PC);
std::string ppc_inst = GekkoDisassembler::Disassemble(inst.hex, PC);
DEBUG_LOG(POWERPC, "INTER PC: %08x SRR0: %08x SRR1: %08x CRval: %016lx FPSCR: %08x MSR: %08x LR: "
"%08x %s %08x %s",
PC, SRR0, SRR1, (unsigned long)PowerPC::ppcState.cr_val[0], PowerPC::ppcState.fpscr,
PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs.c_str(), instCode.hex,
PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs.c_str(), inst.hex,
ppc_inst.c_str());
}
@@ -306,20 +306,20 @@ void Interpreter::Run()
}
}
void Interpreter::unknown_instruction(UGeckoInstruction _inst)
void Interpreter::unknown_instruction(UGeckoInstruction inst)
{
std::string disasm = GekkoDisassembler::Disassemble(PowerPC::HostRead_U32(last_pc), last_pc);
NOTICE_LOG(POWERPC, "Last PC = %08x : %s", last_pc, disasm.c_str());
Dolphin_Debugger::PrintCallstack();
NOTICE_LOG(POWERPC,
"\nIntCPU: Unknown instruction %08x at PC = %08x last_PC = %08x LR = %08x\n",
_inst.hex, PC, last_pc, LR);
inst.hex, PC, last_pc, LR);
for (int i = 0; i < 32; i += 4)
NOTICE_LOG(POWERPC, "r%d: 0x%08x r%d: 0x%08x r%d:0x%08x r%d: 0x%08x", i, rGPR[i], i + 1,
rGPR[i + 1], i + 2, rGPR[i + 2], i + 3, rGPR[i + 3]);
_assert_msg_(POWERPC, 0,
"\nIntCPU: Unknown instruction %08x at PC = %08x last_PC = %08x LR = %08x\n",
_inst.hex, PC, last_pc, LR);
inst.hex, PC, last_pc, LR);
}
void Interpreter::ClearCache()
File diff suppressed because it is too large Load Diff
@@ -10,15 +10,15 @@
#include "Core/HLE/HLE.h"
#include "Core/PowerPC/PowerPC.h"
void Interpreter::bx(UGeckoInstruction _inst)
void Interpreter::bx(UGeckoInstruction inst)
{
if (_inst.LK)
if (inst.LK)
LR = PC + 4;
if (_inst.AA)
NPC = SignExt26(_inst.LI << 2);
if (inst.AA)
NPC = SignExt26(inst.LI << 2);
else
NPC = PC + SignExt26(_inst.LI << 2);
NPC = PC + SignExt26(inst.LI << 2);
m_end_block = true;
@@ -29,27 +29,27 @@ void Interpreter::bx(UGeckoInstruction _inst)
}
// bcx - ugly, straight from PPC manual equations :)
void Interpreter::bcx(UGeckoInstruction _inst)
void Interpreter::bcx(UGeckoInstruction inst)
{
if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
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);
int ctr_check = ((CTR != 0) ^ (_inst.BO >> 1)) & 1;
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);
int ctr_check = ((CTR != 0) ^ (inst.BO >> 1)) & 1;
bool counter = only_condition_check || ctr_check;
bool condition = only_counter_check || (GetCRBit(_inst.BI) == u32(true_false));
bool condition = only_counter_check || (GetCRBit(inst.BI) == u32(true_false));
if (counter && condition)
{
if (_inst.LK)
if (inst.LK)
LR = PC + 4;
if (_inst.AA)
NPC = SignExt16(_inst.BD << 2);
if (inst.AA)
NPC = SignExt16(inst.BD << 2);
else
NPC = PC + SignExt16(_inst.BD << 2);
NPC = PC + SignExt16(inst.BD << 2);
}
m_end_block = true;
@@ -58,7 +58,7 @@ void Interpreter::bcx(UGeckoInstruction _inst)
// lwz r0, XXXX(r13)
// cmpXwi r0,0
// beq -8
if (NPC == PC - 8 && _inst.hex == 0x4182fff8 /* beq */)
if (NPC == PC - 8 && inst.hex == 0x4182fff8 /* beq */)
{
if (PowerPC::HostRead_U32(PC - 8) >> 16 == 0x800D /* lwz */)
{
@@ -73,48 +73,48 @@ void Interpreter::bcx(UGeckoInstruction _inst)
}
}
void Interpreter::bcctrx(UGeckoInstruction _inst)
void Interpreter::bcctrx(UGeckoInstruction inst)
{
_dbg_assert_msg_(POWERPC, _inst.BO_2 & BO_DONT_DECREMENT_FLAG,
_dbg_assert_msg_(POWERPC, inst.BO_2 & BO_DONT_DECREMENT_FLAG,
"bcctrx with decrement and test CTR option is invalid!");
int condition = ((_inst.BO_2 >> 4) | (GetCRBit(_inst.BI_2) == ((_inst.BO_2 >> 3) & 1))) & 1;
int condition = ((inst.BO_2 >> 4) | (GetCRBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
if (condition)
{
NPC = CTR & (~3);
if (_inst.LK_3)
if (inst.LK_3)
LR = PC + 4;
}
m_end_block = true;
}
void Interpreter::bclrx(UGeckoInstruction _inst)
void Interpreter::bclrx(UGeckoInstruction inst)
{
if ((_inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0)
if ((inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0)
CTR--;
int counter = ((_inst.BO_2 >> 2) | ((CTR != 0) ^ (_inst.BO_2 >> 1))) & 1;
int condition = ((_inst.BO_2 >> 4) | (GetCRBit(_inst.BI_2) == ((_inst.BO_2 >> 3) & 1))) & 1;
int counter = ((inst.BO_2 >> 2) | ((CTR != 0) ^ (inst.BO_2 >> 1))) & 1;
int condition = ((inst.BO_2 >> 4) | (GetCRBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
if (counter & condition)
{
NPC = LR & (~3);
if (_inst.LK_3)
if (inst.LK_3)
LR = PC + 4;
}
m_end_block = true;
}
void Interpreter::HLEFunction(UGeckoInstruction _inst)
void Interpreter::HLEFunction(UGeckoInstruction inst)
{
m_end_block = true;
HLE::Execute(PC, _inst.hex);
HLE::Execute(PC, inst.hex);
}
void Interpreter::rfi(UGeckoInstruction _inst)
void Interpreter::rfi(UGeckoInstruction inst)
{
// Restore saved bits from SRR1 to MSR.
// Gecko/Broadway can save more bits than explicitly defined in ppc spec
@@ -135,7 +135,7 @@ void Interpreter::rfi(UGeckoInstruction _inst)
// sc isn't really used for anything important in GameCube games (just for a write barrier) so we
// really don't have to emulate it.
// We do it anyway, though :P
void Interpreter::sc(UGeckoInstruction _inst)
void Interpreter::sc(UGeckoInstruction inst)
{
PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL;
PowerPC::CheckExceptions();
@@ -49,10 +49,10 @@ inline void UpdateFPSCR()
FPSCR.FEX = 0; // we assume that "?E" bits are always 0
}
inline double ForceSingle(double _x)
inline double ForceSingle(double value)
{
// convert to float...
float x = (float)_x;
float x = (float)value;
if (!cpu_info.bFlushToZero && FPSCR.NI)
{
x = MathUtil::FlushToZero(x);
@@ -247,14 +247,14 @@ inline u32 ConvertToSingleFTZ(u64 x)
}
}
inline u64 ConvertToDouble(u32 _x)
inline u64 ConvertToDouble(u32 value)
{
// This is a little-endian re-implementation of the algorithm described in
// the PowerPC Programming Environments Manual for loading single
// precision floating point numbers.
// See page 566 of http://www.freescale.com/files/product/doc/MPCFPE32B.pdf
u64 x = _x;
u64 x = value;
u64 exp = (x >> 23) & 0xff;
u64 frac = x & 0x007fffff;
@@ -20,7 +20,7 @@ void Interpreter::Helper_UpdateCR1()
SetCRField(1, (FPSCR.FX << 3) | (FPSCR.FEX << 2) | (FPSCR.VX << 1) | FPSCR.OX);
}
void Interpreter::Helper_FloatCompareOrdered(UGeckoInstruction _inst, double fa, double fb)
void Interpreter::Helper_FloatCompareOrdered(UGeckoInstruction inst, double fa, double fb)
{
int compareResult;
@@ -56,10 +56,10 @@ void Interpreter::Helper_FloatCompareOrdered(UGeckoInstruction _inst, double fa,
// Clear and set the FPCC bits accordingly.
FPSCR.FPRF = (FPSCR.FPRF & ~0xF) | compareResult;
SetCRField(_inst.CRFD, compareResult);
SetCRField(inst.CRFD, compareResult);
}
void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction _inst, double fa, double fb)
void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction inst, double fa, double fb)
{
int compareResult;
@@ -88,23 +88,23 @@ void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction _inst, double f
// Clear and set the FPCC bits accordingly.
FPSCR.FPRF = (FPSCR.FPRF & ~0xF) | compareResult;
SetCRField(_inst.CRFD, compareResult);
SetCRField(inst.CRFD, compareResult);
}
void Interpreter::fcmpo(UGeckoInstruction _inst)
void Interpreter::fcmpo(UGeckoInstruction inst)
{
Helper_FloatCompareOrdered(_inst, rPS0(_inst.FA), rPS0(_inst.FB));
Helper_FloatCompareOrdered(inst, rPS0(inst.FA), rPS0(inst.FB));
}
void Interpreter::fcmpu(UGeckoInstruction _inst)
void Interpreter::fcmpu(UGeckoInstruction inst)
{
Helper_FloatCompareUnordered(_inst, rPS0(_inst.FA), rPS0(_inst.FB));
Helper_FloatCompareUnordered(inst, rPS0(inst.FA), rPS0(inst.FB));
}
// Apply current rounding mode
void Interpreter::fctiwx(UGeckoInstruction _inst)
void Interpreter::fctiwx(UGeckoInstruction inst)
{
const double b = rPS0(_inst.FB);
const double b = rPS0(inst.FB);
u32 value;
if (b > (double)0x7fffffff)
@@ -171,17 +171,17 @@ void Interpreter::fctiwx(UGeckoInstruction _inst)
// based on HW tests
// FPRF is not affected
riPS0(_inst.FD) = 0xfff8000000000000ull | value;
riPS0(inst.FD) = 0xfff8000000000000ull | value;
if (value == 0 && std::signbit(b))
riPS0(_inst.FD) |= 0x100000000ull;
if (_inst.Rc)
riPS0(inst.FD) |= 0x100000000ull;
if (inst.Rc)
Helper_UpdateCR1();
}
// Always round toward zero
void Interpreter::fctiwzx(UGeckoInstruction _inst)
void Interpreter::fctiwzx(UGeckoInstruction inst)
{
const double b = rPS0(_inst.FB);
const double b = rPS0(inst.FB);
u32 value;
if (b > (double)0x7fffffff)
@@ -217,55 +217,55 @@ void Interpreter::fctiwzx(UGeckoInstruction _inst)
// based on HW tests
// FPRF is not affected
riPS0(_inst.FD) = 0xfff8000000000000ull | value;
riPS0(inst.FD) = 0xfff8000000000000ull | value;
if (value == 0 && std::signbit(b))
riPS0(_inst.FD) |= 0x100000000ull;
if (_inst.Rc)
riPS0(inst.FD) |= 0x100000000ull;
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fmrx(UGeckoInstruction _inst)
void Interpreter::fmrx(UGeckoInstruction inst)
{
riPS0(_inst.FD) = riPS0(_inst.FB);
riPS0(inst.FD) = riPS0(inst.FB);
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fabsx(UGeckoInstruction _inst)
void Interpreter::fabsx(UGeckoInstruction inst)
{
rPS0(_inst.FD) = fabs(rPS0(_inst.FB));
rPS0(inst.FD) = fabs(rPS0(inst.FB));
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fnabsx(UGeckoInstruction _inst)
void Interpreter::fnabsx(UGeckoInstruction inst)
{
riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63);
riPS0(inst.FD) = riPS0(inst.FB) | (1ULL << 63);
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fnegx(UGeckoInstruction _inst)
void Interpreter::fnegx(UGeckoInstruction inst)
{
riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63);
riPS0(inst.FD) = riPS0(inst.FB) ^ (1ULL << 63);
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fselx(UGeckoInstruction _inst)
void Interpreter::fselx(UGeckoInstruction inst)
{
rPS0(_inst.FD) = (rPS0(_inst.FA) >= -0.0) ? rPS0(_inst.FC) : rPS0(_inst.FB);
rPS0(inst.FD) = (rPS0(inst.FA) >= -0.0) ? rPS0(inst.FC) : rPS0(inst.FB);
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
@@ -285,108 +285,108 @@ void Interpreter::frspx(UGeckoInstruction inst) // round to single
Helper_UpdateCR1();
}
void Interpreter::fmulx(UGeckoInstruction _inst)
void Interpreter::fmulx(UGeckoInstruction inst)
{
rPS0(_inst.FD) = ForceDouble(NI_mul(rPS0(_inst.FA), rPS0(_inst.FC)));
rPS0(inst.FD) = ForceDouble(NI_mul(rPS0(inst.FA), rPS0(inst.FC)));
FPSCR.FI = 0; // are these flags important?
FPSCR.FR = 0;
UpdateFPRF(rPS0(_inst.FD));
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fmulsx(UGeckoInstruction _inst)
void Interpreter::fmulsx(UGeckoInstruction inst)
{
double c_value = Force25Bit(rPS0(_inst.FC));
double d_value = NI_mul(rPS0(_inst.FA), c_value);
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(d_value);
double c_value = Force25Bit(rPS0(inst.FC));
double d_value = NI_mul(rPS0(inst.FA), c_value);
rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(d_value);
// FPSCR.FI = d_value != rPS0(_inst.FD);
FPSCR.FI = 0;
FPSCR.FR = 0;
UpdateFPRF(rPS0(_inst.FD));
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fmaddx(UGeckoInstruction _inst)
void Interpreter::fmaddx(UGeckoInstruction inst)
{
double result = ForceDouble(NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
rPS0(_inst.FD) = result;
double result = ForceDouble(NI_madd(rPS0(inst.FA), rPS0(inst.FC), rPS0(inst.FB)));
rPS0(inst.FD) = result;
UpdateFPRF(result);
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fmaddsx(UGeckoInstruction _inst)
void Interpreter::fmaddsx(UGeckoInstruction inst)
{
double c_value = Force25Bit(rPS0(_inst.FC));
double d_value = NI_madd(rPS0(_inst.FA), c_value, rPS0(_inst.FB));
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(d_value);
FPSCR.FI = d_value != rPS0(_inst.FD);
double c_value = Force25Bit(rPS0(inst.FC));
double d_value = NI_madd(rPS0(inst.FA), c_value, rPS0(inst.FB));
rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(d_value);
FPSCR.FI = d_value != rPS0(inst.FD);
FPSCR.FR = 0;
UpdateFPRF(rPS0(_inst.FD));
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::faddx(UGeckoInstruction _inst)
void Interpreter::faddx(UGeckoInstruction inst)
{
rPS0(_inst.FD) = ForceDouble(NI_add(rPS0(_inst.FA), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
rPS0(inst.FD) = ForceDouble(NI_add(rPS0(inst.FA), rPS0(inst.FB)));
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::faddsx(UGeckoInstruction _inst)
void Interpreter::faddsx(UGeckoInstruction inst)
{
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(NI_add(rPS0(inst.FA), rPS0(inst.FB)));
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fdivx(UGeckoInstruction _inst)
void Interpreter::fdivx(UGeckoInstruction inst)
{
rPS0(_inst.FD) = ForceDouble(NI_div(rPS0(_inst.FA), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
rPS0(inst.FD) = ForceDouble(NI_div(rPS0(inst.FA), rPS0(inst.FB)));
UpdateFPRF(rPS0(inst.FD));
// FR,FI,OX,UX???
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fdivsx(UGeckoInstruction _inst)
void Interpreter::fdivsx(UGeckoInstruction inst)
{
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_div(rPS0(_inst.FA), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(NI_div(rPS0(inst.FA), rPS0(inst.FB)));
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
// Single precision only.
void Interpreter::fresx(UGeckoInstruction _inst)
void Interpreter::fresx(UGeckoInstruction inst)
{
double b = rPS0(_inst.FB);
rPS0(_inst.FD) = rPS1(_inst.FD) = ApproximateReciprocal(b);
double b = rPS0(inst.FB);
rPS0(inst.FD) = rPS1(inst.FD) = ApproximateReciprocal(b);
if (b == 0.0)
{
SetFPException(FPSCR_ZX);
}
UpdateFPRF(rPS0(_inst.FD));
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::frsqrtex(UGeckoInstruction _inst)
void Interpreter::frsqrtex(UGeckoInstruction inst)
{
double b = rPS0(_inst.FB);
double b = rPS0(inst.FB);
if (b < 0.0)
{
@@ -397,10 +397,10 @@ void Interpreter::frsqrtex(UGeckoInstruction _inst)
SetFPException(FPSCR_ZX);
}
rPS0(_inst.FD) = ApproximateReciprocalSquareRoot(b);
UpdateFPRF(rPS0(_inst.FD));
rPS0(inst.FD) = ApproximateReciprocalSquareRoot(b);
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
@@ -413,72 +413,72 @@ void Interpreter::fmsubx(UGeckoInstruction _inst)
Helper_UpdateCR1();
}
void Interpreter::fmsubsx(UGeckoInstruction _inst)
void Interpreter::fmsubsx(UGeckoInstruction inst)
{
double c_value = Force25Bit(rPS0(_inst.FC));
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_msub(rPS0(_inst.FA), c_value, rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
double c_value = Force25Bit(rPS0(inst.FC));
rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(NI_msub(rPS0(inst.FA), c_value, rPS0(inst.FB)));
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fnmaddx(UGeckoInstruction _inst)
void Interpreter::fnmaddx(UGeckoInstruction inst)
{
double result = ForceDouble(NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
rPS0(_inst.FD) = std::isnan(result) ? result : -result;
UpdateFPRF(rPS0(_inst.FD));
double result = ForceDouble(NI_madd(rPS0(inst.FA), rPS0(inst.FC), rPS0(inst.FB)));
rPS0(inst.FD) = std::isnan(result) ? result : -result;
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fnmaddsx(UGeckoInstruction _inst)
void Interpreter::fnmaddsx(UGeckoInstruction inst)
{
double c_value = Force25Bit(rPS0(_inst.FC));
double result = ForceSingle(NI_madd(rPS0(_inst.FA), c_value, rPS0(_inst.FB)));
rPS0(_inst.FD) = rPS1(_inst.FD) = std::isnan(result) ? result : -result;
UpdateFPRF(rPS0(_inst.FD));
double c_value = Force25Bit(rPS0(inst.FC));
double result = ForceSingle(NI_madd(rPS0(inst.FA), c_value, rPS0(inst.FB)));
rPS0(inst.FD) = rPS1(inst.FD) = std::isnan(result) ? result : -result;
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fnmsubx(UGeckoInstruction _inst)
void Interpreter::fnmsubx(UGeckoInstruction inst)
{
double result = ForceDouble(NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
rPS0(_inst.FD) = std::isnan(result) ? result : -result;
UpdateFPRF(rPS0(_inst.FD));
double result = ForceDouble(NI_msub(rPS0(inst.FA), rPS0(inst.FC), rPS0(inst.FB)));
rPS0(inst.FD) = std::isnan(result) ? result : -result;
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fnmsubsx(UGeckoInstruction _inst)
void Interpreter::fnmsubsx(UGeckoInstruction inst)
{
double c_value = Force25Bit(rPS0(_inst.FC));
double result = ForceSingle(NI_msub(rPS0(_inst.FA), c_value, rPS0(_inst.FB)));
rPS0(_inst.FD) = rPS1(_inst.FD) = std::isnan(result) ? result : -result;
UpdateFPRF(rPS0(_inst.FD));
double c_value = Force25Bit(rPS0(inst.FC));
double result = ForceSingle(NI_msub(rPS0(inst.FA), c_value, rPS0(inst.FB)));
rPS0(inst.FD) = rPS1(inst.FD) = std::isnan(result) ? result : -result;
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fsubx(UGeckoInstruction _inst)
void Interpreter::fsubx(UGeckoInstruction inst)
{
rPS0(_inst.FD) = ForceDouble(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
rPS0(inst.FD) = ForceDouble(NI_sub(rPS0(inst.FA), rPS0(inst.FB)));
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fsubsx(UGeckoInstruction _inst)
void Interpreter::fsubsx(UGeckoInstruction inst)
{
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(NI_sub(rPS0(inst.FA), rPS0(inst.FB)));
UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc)
if (inst.Rc)
Helper_UpdateCR1();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -295,74 +295,74 @@ void Interpreter::Helper_Dequantize(u32 addr, u32 instI, u32 instRD, u32 instW)
rPS1(instRD) = ps1;
}
void Interpreter::psq_l(UGeckoInstruction _inst)
void Interpreter::psq_l(UGeckoInstruction inst)
{
const u32 EA = _inst.RA ? (rGPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12;
Helper_Dequantize(EA, _inst.I, _inst.RD, _inst.W);
const u32 EA = inst.RA ? (rGPR[inst.RA] + inst.SIMM_12) : (u32)inst.SIMM_12;
Helper_Dequantize(EA, inst.I, inst.RD, inst.W);
}
void Interpreter::psq_lu(UGeckoInstruction _inst)
void Interpreter::psq_lu(UGeckoInstruction inst)
{
const u32 EA = rGPR[_inst.RA] + _inst.SIMM_12;
Helper_Dequantize(EA, _inst.I, _inst.RD, _inst.W);
const u32 EA = rGPR[inst.RA] + inst.SIMM_12;
Helper_Dequantize(EA, inst.I, inst.RD, inst.W);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{
return;
}
rGPR[_inst.RA] = EA;
rGPR[inst.RA] = EA;
}
void Interpreter::psq_st(UGeckoInstruction _inst)
void Interpreter::psq_st(UGeckoInstruction inst)
{
const u32 EA = _inst.RA ? (rGPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12;
Helper_Quantize(EA, _inst.I, _inst.RS, _inst.W);
const u32 EA = inst.RA ? (rGPR[inst.RA] + inst.SIMM_12) : (u32)inst.SIMM_12;
Helper_Quantize(EA, inst.I, inst.RS, inst.W);
}
void Interpreter::psq_stu(UGeckoInstruction _inst)
void Interpreter::psq_stu(UGeckoInstruction inst)
{
const u32 EA = rGPR[_inst.RA] + _inst.SIMM_12;
Helper_Quantize(EA, _inst.I, _inst.RS, _inst.W);
const u32 EA = rGPR[inst.RA] + inst.SIMM_12;
Helper_Quantize(EA, inst.I, inst.RS, inst.W);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{
return;
}
rGPR[_inst.RA] = EA;
rGPR[inst.RA] = EA;
}
void Interpreter::psq_lx(UGeckoInstruction _inst)
void Interpreter::psq_lx(UGeckoInstruction inst)
{
const u32 EA = _inst.RA ? (rGPR[_inst.RA] + rGPR[_inst.RB]) : rGPR[_inst.RB];
Helper_Dequantize(EA, _inst.Ix, _inst.RD, _inst.Wx);
const u32 EA = inst.RA ? (rGPR[inst.RA] + rGPR[inst.RB]) : rGPR[inst.RB];
Helper_Dequantize(EA, inst.Ix, inst.RD, inst.Wx);
}
void Interpreter::psq_stx(UGeckoInstruction _inst)
void Interpreter::psq_stx(UGeckoInstruction inst)
{
const u32 EA = _inst.RA ? (rGPR[_inst.RA] + rGPR[_inst.RB]) : rGPR[_inst.RB];
Helper_Quantize(EA, _inst.Ix, _inst.RS, _inst.Wx);
const u32 EA = inst.RA ? (rGPR[inst.RA] + rGPR[inst.RB]) : rGPR[inst.RB];
Helper_Quantize(EA, inst.Ix, inst.RS, inst.Wx);
}
void Interpreter::psq_lux(UGeckoInstruction _inst)
void Interpreter::psq_lux(UGeckoInstruction inst)
{
const u32 EA = rGPR[_inst.RA] + rGPR[_inst.RB];
Helper_Dequantize(EA, _inst.Ix, _inst.RD, _inst.Wx);
const u32 EA = rGPR[inst.RA] + rGPR[inst.RB];
Helper_Dequantize(EA, inst.Ix, inst.RD, inst.Wx);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{
return;
}
rGPR[_inst.RA] = EA;
rGPR[inst.RA] = EA;
}
void Interpreter::psq_stux(UGeckoInstruction _inst)
void Interpreter::psq_stux(UGeckoInstruction inst)
{
const u32 EA = rGPR[_inst.RA] + rGPR[_inst.RB];
Helper_Quantize(EA, _inst.Ix, _inst.RS, _inst.Wx);
const u32 EA = rGPR[inst.RA] + rGPR[inst.RB];
Helper_Quantize(EA, inst.Ix, inst.RS, inst.Wx);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{
return;
}
rGPR[_inst.RA] = EA;
rGPR[inst.RA] = EA;
}
File diff suppressed because it is too large Load Diff
@@ -45,54 +45,54 @@ static void FPSCRtoFPUSettings(UReg_FPSCR fp)
FPURoundMode::SetSIMDMode(fp.RN, fp.NI);
}
void Interpreter::mtfsb0x(UGeckoInstruction _inst)
void Interpreter::mtfsb0x(UGeckoInstruction inst)
{
u32 b = 0x80000000 >> _inst.CRBD;
u32 b = 0x80000000 >> inst.CRBD;
/*if (b & 0x9ff80700)
PanicAlert("mtfsb0 clears bit %d, PC=%x", _inst.CRBD, PC);*/
PanicAlert("mtfsb0 clears bit %d, PC=%x", inst.CRBD, PC);*/
FPSCR.Hex &= ~b;
FPSCRtoFPUSettings(FPSCR);
if (_inst.Rc)
PanicAlert("mtfsb0x: inst_.Rc");
if (inst.Rc)
PanicAlert("mtfsb0x: inst.Rc");
}
void Interpreter::mtfsb1x(UGeckoInstruction _inst)
void Interpreter::mtfsb1x(UGeckoInstruction inst)
{
// this instruction can affect FX
u32 b = 0x80000000 >> _inst.CRBD;
u32 b = 0x80000000 >> inst.CRBD;
if (b & FPSCR_ANY_X)
SetFPException(b);
else
FPSCR.Hex |= b;
FPSCRtoFPUSettings(FPSCR);
if (_inst.Rc)
PanicAlert("mtfsb1x: inst_.Rc");
if (inst.Rc)
PanicAlert("mtfsb1x: inst.Rc");
}
void Interpreter::mtfsfix(UGeckoInstruction _inst)
void Interpreter::mtfsfix(UGeckoInstruction inst)
{
u32 mask = (0xF0000000 >> (4 * _inst.CRFD));
u32 imm = (_inst.hex << 16) & 0xF0000000;
u32 mask = (0xF0000000 >> (4 * inst.CRFD));
u32 imm = (inst.hex << 16) & 0xF0000000;
/*u32 cleared = ~(imm >> (4 * _inst.CRFD)) & FPSCR.Hex & mask;
if (cleared & 0x9ff80700)
PanicAlert("mtfsfi clears %08x, PC=%x", cleared, PC);*/
FPSCR.Hex = (FPSCR.Hex & ~mask) | (imm >> (4 * _inst.CRFD));
FPSCR.Hex = (FPSCR.Hex & ~mask) | (imm >> (4 * inst.CRFD));
FPSCRtoFPUSettings(FPSCR);
if (_inst.Rc)
PanicAlert("mtfsfix: inst_.Rc");
if (inst.Rc)
PanicAlert("mtfsfix: inst.Rc");
}
void Interpreter::mtfsfx(UGeckoInstruction _inst)
void Interpreter::mtfsfx(UGeckoInstruction inst)
{
u32 fm = _inst.FM;
u32 fm = inst.FM;
u32 m = 0;
for (int i = 0; i < 8; i++)
{
@@ -104,31 +104,31 @@ void Interpreter::mtfsfx(UGeckoInstruction _inst)
if (cleared & 0x9ff80700)
PanicAlert("mtfsf clears %08x, PC=%x", cleared, PC);*/
FPSCR.Hex = (FPSCR.Hex & ~m) | ((u32)(riPS0(_inst.FB)) & m);
FPSCR.Hex = (FPSCR.Hex & ~m) | ((u32)(riPS0(inst.FB)) & m);
FPSCRtoFPUSettings(FPSCR);
if (_inst.Rc)
PanicAlert("mtfsfx: inst_.Rc");
if (inst.Rc)
PanicAlert("mtfsfx: inst.Rc");
}
void Interpreter::mcrxr(UGeckoInstruction _inst)
void Interpreter::mcrxr(UGeckoInstruction inst)
{
SetCRField(_inst.CRFD, GetXER().Hex >> 28);
SetCRField(inst.CRFD, GetXER().Hex >> 28);
PowerPC::ppcState.xer_ca = 0;
PowerPC::ppcState.xer_so_ov = 0;
}
void Interpreter::mfcr(UGeckoInstruction _inst)
void Interpreter::mfcr(UGeckoInstruction inst)
{
rGPR[_inst.RD] = GetCR();
rGPR[inst.RD] = GetCR();
}
void Interpreter::mtcrf(UGeckoInstruction _inst)
void Interpreter::mtcrf(UGeckoInstruction inst)
{
u32 crm = _inst.CRM;
u32 crm = inst.CRM;
if (crm == 0xFF)
{
SetCR(rGPR[_inst.RS]);
SetCR(rGPR[inst.RS]);
}
else
{
@@ -140,31 +140,31 @@ void Interpreter::mtcrf(UGeckoInstruction _inst)
mask |= 0xF << (i * 4);
}
SetCR((GetCR() & ~mask) | (rGPR[_inst.RS] & mask));
SetCR((GetCR() & ~mask) | (rGPR[inst.RS] & mask));
}
}
void Interpreter::mfmsr(UGeckoInstruction _inst)
void Interpreter::mfmsr(UGeckoInstruction inst)
{
// Privileged?
rGPR[_inst.RD] = MSR;
rGPR[inst.RD] = MSR;
}
void Interpreter::mfsr(UGeckoInstruction _inst)
void Interpreter::mfsr(UGeckoInstruction inst)
{
rGPR[_inst.RD] = PowerPC::ppcState.sr[_inst.SR];
rGPR[inst.RD] = PowerPC::ppcState.sr[inst.SR];
}
void Interpreter::mfsrin(UGeckoInstruction _inst)
void Interpreter::mfsrin(UGeckoInstruction inst)
{
int index = (rGPR[_inst.RB] >> 28) & 0xF;
rGPR[_inst.RD] = PowerPC::ppcState.sr[index];
int index = (rGPR[inst.RB] >> 28) & 0xF;
rGPR[inst.RD] = PowerPC::ppcState.sr[index];
}
void Interpreter::mtmsr(UGeckoInstruction _inst)
void Interpreter::mtmsr(UGeckoInstruction inst)
{
// Privileged?
MSR = rGPR[_inst.RS];
MSR = rGPR[inst.RS];
PowerPC::CheckExceptions();
m_end_block = true;
}
@@ -178,31 +178,31 @@ static void SetSR(int index, u32 value)
PowerPC::ppcState.sr[index] = value;
}
void Interpreter::mtsr(UGeckoInstruction _inst)
void Interpreter::mtsr(UGeckoInstruction inst)
{
int index = _inst.SR;
u32 value = rGPR[_inst.RS];
int index = inst.SR;
u32 value = rGPR[inst.RS];
SetSR(index, value);
}
void Interpreter::mtsrin(UGeckoInstruction _inst)
void Interpreter::mtsrin(UGeckoInstruction inst)
{
int index = (rGPR[_inst.RB] >> 28) & 0xF;
u32 value = rGPR[_inst.RS];
int index = (rGPR[inst.RB] >> 28) & 0xF;
u32 value = rGPR[inst.RS];
SetSR(index, value);
}
void Interpreter::mftb(UGeckoInstruction _inst)
void Interpreter::mftb(UGeckoInstruction inst)
{
int iIndex = (_inst.TBR >> 5) | ((_inst.TBR & 0x1F) << 5);
int iIndex = (inst.TBR >> 5) | ((inst.TBR & 0x1F) << 5);
_dbg_assert_msg_(POWERPC, (iIndex == SPR_TL) || (iIndex == SPR_TU), "Invalid mftb");
(void)iIndex;
mfspr(_inst);
mfspr(inst);
}
void Interpreter::mfspr(UGeckoInstruction _inst)
void Interpreter::mfspr(UGeckoInstruction inst)
{
u32 iIndex = ((_inst.SPR & 0x1F) << 5) + ((_inst.SPR >> 5) & 0x1F);
u32 iIndex = ((inst.SPR & 0x1F) << 5) + ((inst.SPR >> 5) & 0x1F);
// TODO - check processor privilege level - many of these require privilege
// XER LR CTR are the only ones available in user mode, time base can be read too.
@@ -241,14 +241,14 @@ void Interpreter::mfspr(UGeckoInstruction _inst)
rSPR(iIndex) = GetXER().Hex;
break;
}
rGPR[_inst.RD] = rSPR(iIndex);
rGPR[inst.RD] = rSPR(iIndex);
}
void Interpreter::mtspr(UGeckoInstruction _inst)
void Interpreter::mtspr(UGeckoInstruction inst)
{
u32 iIndex = (_inst.SPRU << 5) | (_inst.SPRL & 0x1F);
u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F);
u32 oldValue = rSPR(iIndex);
rSPR(iIndex) = rGPR[_inst.RD];
rSPR(iIndex) = rGPR[inst.RD];
// TODO - check processor privilege level - many of these require privilege
// XER LR CTR are the only ones available in user mode, time base can be read too.
@@ -265,12 +265,12 @@ void Interpreter::mtspr(UGeckoInstruction _inst)
break;
case SPR_TL_W:
TL = rGPR[_inst.RD];
TL = rGPR[inst.RD];
SystemTimers::TimeBaseSet();
break;
case SPR_TU_W:
TU = rGPR[_inst.RD];
TU = rGPR[inst.RD];
SystemTimers::TimeBaseSet();
break;
@@ -313,7 +313,7 @@ void Interpreter::mtspr(UGeckoInstruction _inst)
break;
case SPR_WPAR:
_assert_msg_(POWERPC, rGPR[_inst.RD] == 0x0C008000, "Gather pipe @ %08x", PC);
_assert_msg_(POWERPC, rGPR[inst.RD] == 0x0C008000, "Gather pipe @ %08x", PC);
GPFifo::ResetGatherPipe();
break;
@@ -353,7 +353,7 @@ void Interpreter::mtspr(UGeckoInstruction _inst)
break;
case SPR_DEC:
if (!(oldValue >> 31) && (rGPR[_inst.RD] >> 31)) // top bit from 0 to 1
if (!(oldValue >> 31) && (rGPR[inst.RD] >> 31)) // top bit from 0 to 1
{
PanicAlert("Interesting - Software triggered Decrementer exception");
PowerPC::ppcState.Exceptions |= EXCEPTION_DECREMENTER;
@@ -418,67 +418,67 @@ void Interpreter::mtspr(UGeckoInstruction _inst)
}
}
void Interpreter::crand(UGeckoInstruction _inst)
void Interpreter::crand(UGeckoInstruction inst)
{
SetCRBit(_inst.CRBD, GetCRBit(_inst.CRBA) & GetCRBit(_inst.CRBB));
SetCRBit(inst.CRBD, GetCRBit(inst.CRBA) & GetCRBit(inst.CRBB));
}
void Interpreter::crandc(UGeckoInstruction _inst)
void Interpreter::crandc(UGeckoInstruction inst)
{
SetCRBit(_inst.CRBD, GetCRBit(_inst.CRBA) & (1 ^ GetCRBit(_inst.CRBB)));
SetCRBit(inst.CRBD, GetCRBit(inst.CRBA) & (1 ^ GetCRBit(inst.CRBB)));
}
void Interpreter::creqv(UGeckoInstruction _inst)
void Interpreter::creqv(UGeckoInstruction inst)
{
SetCRBit(_inst.CRBD, 1 ^ (GetCRBit(_inst.CRBA) ^ GetCRBit(_inst.CRBB)));
SetCRBit(inst.CRBD, 1 ^ (GetCRBit(inst.CRBA) ^ GetCRBit(inst.CRBB)));
}
void Interpreter::crnand(UGeckoInstruction _inst)
void Interpreter::crnand(UGeckoInstruction inst)
{
SetCRBit(_inst.CRBD, 1 ^ (GetCRBit(_inst.CRBA) & GetCRBit(_inst.CRBB)));
SetCRBit(inst.CRBD, 1 ^ (GetCRBit(inst.CRBA) & GetCRBit(inst.CRBB)));
}
void Interpreter::crnor(UGeckoInstruction _inst)
void Interpreter::crnor(UGeckoInstruction inst)
{
SetCRBit(_inst.CRBD, 1 ^ (GetCRBit(_inst.CRBA) | GetCRBit(_inst.CRBB)));
SetCRBit(inst.CRBD, 1 ^ (GetCRBit(inst.CRBA) | GetCRBit(inst.CRBB)));
}
void Interpreter::cror(UGeckoInstruction _inst)
void Interpreter::cror(UGeckoInstruction inst)
{
SetCRBit(_inst.CRBD, (GetCRBit(_inst.CRBA) | GetCRBit(_inst.CRBB)));
SetCRBit(inst.CRBD, (GetCRBit(inst.CRBA) | GetCRBit(inst.CRBB)));
}
void Interpreter::crorc(UGeckoInstruction _inst)
void Interpreter::crorc(UGeckoInstruction inst)
{
SetCRBit(_inst.CRBD, (GetCRBit(_inst.CRBA) | (1 ^ GetCRBit(_inst.CRBB))));
SetCRBit(inst.CRBD, (GetCRBit(inst.CRBA) | (1 ^ GetCRBit(inst.CRBB))));
}
void Interpreter::crxor(UGeckoInstruction _inst)
void Interpreter::crxor(UGeckoInstruction inst)
{
SetCRBit(_inst.CRBD, (GetCRBit(_inst.CRBA) ^ GetCRBit(_inst.CRBB)));
SetCRBit(inst.CRBD, (GetCRBit(inst.CRBA) ^ GetCRBit(inst.CRBB)));
}
void Interpreter::mcrf(UGeckoInstruction _inst)
void Interpreter::mcrf(UGeckoInstruction inst)
{
int cr_f = GetCRField(_inst.CRFS);
SetCRField(_inst.CRFD, cr_f);
int cr_f = GetCRField(inst.CRFS);
SetCRField(inst.CRFD, cr_f);
}
void Interpreter::isync(UGeckoInstruction _inst)
void Interpreter::isync(UGeckoInstruction inst)
{
// shouldn't do anything
}
// the following commands read from FPSCR
void Interpreter::mcrfs(UGeckoInstruction _inst)
void Interpreter::mcrfs(UGeckoInstruction inst)
{
// if (_inst.CRFS != 3 && _inst.CRFS != 4)
// PanicAlert("msrfs at %x, CRFS = %d, CRFD = %d", PC, (int)_inst.CRFS, (int)_inst.CRFD);
UpdateFPSCR();
u32 fpflags = ((FPSCR.Hex >> (4 * (7 - _inst.CRFS))) & 0xF);
switch (_inst.CRFS)
u32 fpflags = ((FPSCR.Hex >> (4 * (7 - inst.CRFS))) & 0xF);
switch (inst.CRFS)
{
case 0:
FPSCR.FX = 0;
@@ -505,17 +505,17 @@ void Interpreter::mcrfs(UGeckoInstruction _inst)
FPSCR.VXCVI = 0;
break;
}
SetCRField(_inst.CRFD, fpflags);
SetCRField(inst.CRFD, fpflags);
}
void Interpreter::mffsx(UGeckoInstruction _inst)
void Interpreter::mffsx(UGeckoInstruction inst)
{
// load from FPSCR
// TODO(ector): grab all overflow flags etc and set them in FPSCR
UpdateFPSCR();
riPS0(_inst.FD) = 0xFFF8000000000000 | FPSCR.Hex;
riPS0(inst.FD) = 0xFFF8000000000000 | FPSCR.Hex;
if (_inst.Rc)
if (inst.Rc)
PanicAlert("mffsx: inst_.Rc");
}