mirror of
https://github.com/izzy2lost/PCSX2_ARM64.git
synced 2026-06-19 10:16:23 -07:00
Android project - Add mVU_SSE4 structure to VUDef.h header
This commit is contained in:
@@ -58,6 +58,10 @@ uptr g_argPtrs[kMaxArgs];
|
||||
|
||||
void cpuReset()
|
||||
{
|
||||
//// cpuRegistersPack -> VIFregisters
|
||||
g_cpuRegistersPack.vifRegs[0] = vif0Regs;
|
||||
g_cpuRegistersPack.vifRegs[1] = vif1Regs;
|
||||
////
|
||||
std::memset(&cpuRegs, 0, sizeof(cpuRegs));
|
||||
std::memset(&fpuRegs, 0, sizeof(fpuRegs));
|
||||
std::memset(&tlb, 0, sizeof(tlb));
|
||||
|
||||
@@ -208,4 +208,76 @@ struct mVU_Globals
|
||||
#undef __four
|
||||
};
|
||||
|
||||
#define SINGLE(sign, exp, mant) (((u32)(sign) << 31) | ((u32)(exp) << 23) | (u32)(mant))
|
||||
#define DOUBLE(sign, exp, mant) (((sign##ULL) << 63) | ((exp##ULL) << 52) | (mant##ULL))
|
||||
|
||||
struct FPUd_Globals
|
||||
{
|
||||
u32 neg[4], pos[4];
|
||||
|
||||
u32 pos_inf[4], neg_inf[4],
|
||||
one_exp[4];
|
||||
|
||||
u64 dbl_one_exp[2];
|
||||
|
||||
u64 dbl_cvt_overflow, // needs special code if above or equal
|
||||
dbl_ps2_overflow, // overflow & clamp if above or equal
|
||||
dbl_underflow; // underflow if below
|
||||
|
||||
u64 padding;
|
||||
|
||||
u64 dbl_s_pos[2];
|
||||
//u64 dlb_s_neg[2];
|
||||
};
|
||||
|
||||
struct mVU_SSE4
|
||||
{
|
||||
u32 sse4_minvals[2][4] = {
|
||||
{0xff7fffff, 0xffffffff, 0xffffffff, 0xffffffff}, //1000
|
||||
{0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}, //1111
|
||||
};
|
||||
u32 sse4_maxvals[2][4] = {
|
||||
{0x7f7fffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1000
|
||||
{0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111
|
||||
};
|
||||
////
|
||||
u32 sse4_compvals[2][4] = {
|
||||
{0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111
|
||||
{0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1111
|
||||
};
|
||||
////
|
||||
u32 s_neg[4] = {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff};
|
||||
u32 s_pos[4] = {0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff};
|
||||
////
|
||||
u32 g_minvals[4] = {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff};
|
||||
u32 g_maxvals[4] = {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff};
|
||||
////
|
||||
FPUd_Globals s_const =
|
||||
{
|
||||
{0x80000000, 0xffffffff, 0xffffffff, 0xffffffff},
|
||||
{0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff},
|
||||
|
||||
{SINGLE(0, 0xff, 0), 0, 0, 0},
|
||||
{SINGLE(1, 0xff, 0), 0, 0, 0},
|
||||
{SINGLE(0, 1, 0), 0, 0, 0},
|
||||
|
||||
{DOUBLE(0, 1, 0), 0},
|
||||
|
||||
DOUBLE(0, 1151, 0), // cvt_overflow
|
||||
DOUBLE(0, 1152, 0), // ps2_overflow
|
||||
DOUBLE(0, 897, 0), // underflow
|
||||
|
||||
0, // Padding!!
|
||||
|
||||
{0x7fffffffffffffffULL, 0},
|
||||
//{0x8000000000000000ULL, 0},
|
||||
};
|
||||
////
|
||||
u32 minmax_mask[8] =
|
||||
{
|
||||
0xffffffff, 0x80000000, 0, 0,
|
||||
0, 0x40000000, 0, 0,
|
||||
};
|
||||
};
|
||||
|
||||
#endif //PCSX2_VUDEF_H
|
||||
|
||||
@@ -15,6 +15,8 @@ struct cpuRegistersPack
|
||||
alignas(16) fpuRegisters fpuRegs{};
|
||||
alignas(16) psxRegisters psxRegs{};
|
||||
alignas(16) VURegs vuRegs[2];
|
||||
alignas(16) VIFregisters vifRegs[2];
|
||||
alignas(16) mVU_SSE4 mVUss4;
|
||||
alignas(32) mVU_Globals mVUglob;
|
||||
};
|
||||
alignas(32) extern cpuRegistersPack g_cpuRegistersPack;
|
||||
@@ -24,6 +26,7 @@ static fpuRegisters& fpuRegs = g_cpuRegistersPack.fpuRegs;
|
||||
static psxRegisters& psxRegs = g_cpuRegistersPack.psxRegs;
|
||||
static VURegs& VU0 = g_cpuRegistersPack.vuRegs[0];
|
||||
static VURegs& VU1 = g_cpuRegistersPack.vuRegs[1];
|
||||
static mVU_SSE4& mVUClamp = g_cpuRegistersPack.mVUss4;
|
||||
static mVU_Globals& mVUglob = g_cpuRegistersPack.mVUglob;
|
||||
|
||||
#endif //PCSX2_CPUREGISTERSPACK_H
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
using namespace x86Emitter;
|
||||
#endif
|
||||
|
||||
alignas(16) const u32 g_minvals[4] = {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff};
|
||||
alignas(16) const u32 g_maxvals[4] = {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff};
|
||||
//alignas(16) const u32 g_minvals[4] = {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff};
|
||||
//alignas(16) const u32 g_maxvals[4] = {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff};
|
||||
|
||||
//------------------------------------------------------------------
|
||||
namespace R5900 {
|
||||
@@ -67,8 +67,8 @@ namespace DOUBLE
|
||||
// Add/Sub opcodes produce the same results as the ps2
|
||||
#define FPU_CORRECT_ADD_SUB 1
|
||||
|
||||
alignas(16) static const u32 s_neg[4] = {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff};
|
||||
alignas(16) static const u32 s_pos[4] = {0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff};
|
||||
//alignas(16) static const u32 s_neg[4] = {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff};
|
||||
//alignas(16) static const u32 s_pos[4] = {0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff};
|
||||
|
||||
#define REC_FPUBRANCH(f) \
|
||||
void f(); \
|
||||
@@ -382,9 +382,9 @@ __fi void fpuFloat3(int regd) // +NaN -> +fMax, -NaN -> -fMax, +Inf -> +fMax, -I
|
||||
auto regQ = a64::QRegister(regd);
|
||||
|
||||
// xPMIN.SD(xRegisterSSE(regd), ptr128[&g_maxvals[0]]);
|
||||
armAsm->Smin(regQ.V4S(), regQ.V4S(), armLoadPtrV(&g_maxvals[0]).V4S());
|
||||
armAsm->Smin(regQ.V4S(), regQ.V4S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).V4S());
|
||||
// xPMIN.UD(xRegisterSSE(regd), ptr128[&g_minvals[0]]);
|
||||
armAsm->Umin(regQ.V4S(), regQ.V4S(), armLoadPtrV(&g_minvals[0]).V4S());
|
||||
armAsm->Umin(regQ.V4S(), regQ.V4S(), armLoadPtrV(PTR_CPU(mVUss4.g_minvals[0])).V4S());
|
||||
}
|
||||
|
||||
__fi void fpuFloat(int regd) // +/-NaN -> +fMax, +Inf -> +fMax, -Inf -> -fMax
|
||||
@@ -394,9 +394,9 @@ __fi void fpuFloat(int regd) // +/-NaN -> +fMax, +Inf -> +fMax, -Inf -> -fMax
|
||||
auto regQ = a64::QRegister(regd);
|
||||
|
||||
// xMIN.SS(xRegisterSSE(regd), ptr[&g_maxvals[0]]); // MIN() must be before MAX()! So that NaN's become +Maximum
|
||||
armAsm->Fminnm(regQ.S(), regQ.S(), armLoadPtrV(&g_maxvals[0]).S());
|
||||
armAsm->Fminnm(regQ.S(), regQ.S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).S());
|
||||
// xMAX.SS(xRegisterSSE(regd), ptr[&g_minvals[0]]);
|
||||
armAsm->Fmaxnm(regQ.S(), regQ.S(), armLoadPtrV(&g_minvals[0]).S());
|
||||
armAsm->Fmaxnm(regQ.S(), regQ.S(), armLoadPtrV(PTR_CPU(mVUss4.g_minvals[0])).S());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,12 +434,12 @@ void recABS_S_xmm(int info)
|
||||
}
|
||||
|
||||
// xAND.PS(xRegisterSSE(EEREC_D), ptr[&s_pos[0]]);
|
||||
armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(&s_pos[0]).V16B());
|
||||
armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_pos[0])).V16B());
|
||||
//xAND(ptr32[&fpuRegs.fprc[31]], ~(FPUflagO|FPUflagU)); // Clear O and U flags
|
||||
|
||||
if (CHECK_FPU_OVERFLOW) { // Only need to do positive clamp, since EEREC_D is positive
|
||||
// xMIN.SS(xRegisterSSE(EEREC_D), ptr[&g_maxvals[0]]);
|
||||
armAsm->Fminnm(regED.S(), regED.S(), armLoadPtrV(&g_maxvals[0]).S());
|
||||
armAsm->Fminnm(regED.S(), regED.S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).S());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,7 +529,7 @@ void FPU_ADD_SUB(int regd, int regt, int issub)
|
||||
// xMOVAPS(xRegisterSSE(xmmtemp), xRegisterSSE(regt));
|
||||
armAsm->Mov(regQTemp, regT);
|
||||
// xAND.PS(xRegisterSSE(xmmtemp), ptr[s_neg]);
|
||||
armAsm->And(regQTemp.V16B(), regQTemp.V16B(), armLoadPtrV(s_neg).V16B());
|
||||
armAsm->And(regQTemp.V16B(), regQTemp.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_neg)).V16B());
|
||||
if (issub) {
|
||||
// xSUB.SS(xRegisterSSE(regd), xRegisterSSE(xmmtemp));
|
||||
armAsm->Fsub(regD.S(), regD.S(), regQTemp.S());
|
||||
@@ -569,7 +569,7 @@ void FPU_ADD_SUB(int regd, int regt, int issub)
|
||||
armBind(&j8Ptr3);
|
||||
//diff = -255 .. -25, expd < expt
|
||||
// xAND.PS(xRegisterSSE(regd), ptr[s_neg]);
|
||||
armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(s_neg).V16B());
|
||||
armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_neg)).V16B());
|
||||
if (issub) {
|
||||
// xSUB.SS(xRegisterSSE(regd), xRegisterSSE(regt));
|
||||
armAsm->Fsub(regD.S(), regD.S(), regT.S());
|
||||
@@ -1340,9 +1340,9 @@ void recDIVhelper1(int regd, int regt) // Sets flags
|
||||
// xMOVMSKPS(eax, xRegisterSSE(t1reg));
|
||||
armMOVMSKPS(EAX, regT1);
|
||||
// xAND(eax, 1); //Check sign (if regt == zero, sign will be set)
|
||||
armAsm->Ands(EAX, EAX, 1);
|
||||
armAsm->And(EAX, EAX, 1);
|
||||
// ajmp32 = JZ32(0); //Skip if not set
|
||||
armAsm->B(&ajmp32, a64::Condition::eq);
|
||||
armAsm->Cbz(EAX, &ajmp32);
|
||||
|
||||
/*--- Check for 0/0 ---*/
|
||||
// xXOR.PS(xRegisterSSE(t1reg), xRegisterSSE(t1reg));
|
||||
@@ -1352,9 +1352,9 @@ void recDIVhelper1(int regd, int regt) // Sets flags
|
||||
// xMOVMSKPS(eax, xRegisterSSE(t1reg));
|
||||
armMOVMSKPS(EAX, regT1);
|
||||
// xAND(eax, 1); //Check sign (if regd == zero, sign will be set)
|
||||
armAsm->Ands(EAX, EAX, 1);
|
||||
armAsm->And(EAX, EAX, 1);
|
||||
// pjmp1 = JZ8(0); //Skip if not set
|
||||
armAsm->B(&pjmp1, a64::Condition::eq);
|
||||
armAsm->Cbz(EAX, &pjmp1);
|
||||
// xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags ( 0/0 )
|
||||
armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI);
|
||||
// pjmp2 = JMP8(0);
|
||||
@@ -1370,9 +1370,9 @@ void recDIVhelper1(int regd, int regt) // Sets flags
|
||||
// xXOR.PS(xRegisterSSE(regd), xRegisterSSE(regt)); // Make regd Positive or Negative
|
||||
armAsm->Eor(regD.V16B(), regD.V16B(), regT.V16B());
|
||||
// xAND.PS(xRegisterSSE(regd), ptr[&s_neg[0]]); // Get the sign bit
|
||||
armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(&s_neg[0]).V16B());
|
||||
armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_neg[0])).V16B());
|
||||
// xOR.PS(xRegisterSSE(regd), ptr[&g_maxvals[0]]); // regd = +/- Maximum
|
||||
armAsm->Orr(regD.V16B(), regD.V16B(), armLoadPtrV(&g_maxvals[0]).V16B());
|
||||
armAsm->Orr(regD.V16B(), regD.V16B(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).V16B());
|
||||
//xMOVSSZX(xRegisterSSE(regd), ptr[&g_maxvals[0]]);
|
||||
// bjmp32 = JMP32(0);
|
||||
armAsm->B(&bjmp32);
|
||||
@@ -2087,7 +2087,7 @@ void recNEG_S_xmm(int info)
|
||||
|
||||
//xAND(ptr32[&fpuRegs.fprc[31]], ~(FPUflagO|FPUflagU)); // Clear O and U flags
|
||||
// xXOR.PS(xRegisterSSE(EEREC_D), ptr[&s_neg[0]]);
|
||||
armAsm->Eor(regED.V16B(), regED.V16B(), armLoadPtrV(&s_neg[0]).V16B());
|
||||
armAsm->Eor(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_neg[0])).V16B());
|
||||
|
||||
// Always preserve sign. Using float clamping here would result in
|
||||
// +inf to become +fMax instead of -fMax, which is definitely wrong.
|
||||
@@ -2235,25 +2235,25 @@ void recSQRT_S_xmm(int info)
|
||||
// xMOVMSKPS(eax, xRegisterSSE(EEREC_D));
|
||||
armMOVMSKPS(EAX, regED);
|
||||
// xAND(eax, 1); //Check sign
|
||||
armAsm->Ands(EAX, EAX, 1);
|
||||
armAsm->And(EAX, EAX, 1);
|
||||
// u8* pjmp = JZ8(0); //Skip if none are
|
||||
a64::Label pjmp;
|
||||
armAsm->B(&pjmp, a64::Condition::eq);
|
||||
armAsm->Cbz(EAX, &pjmp);
|
||||
// xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags
|
||||
armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI);
|
||||
// xAND.PS(xRegisterSSE(EEREC_D), ptr[&s_pos[0]]); // Make EEREC_D Positive
|
||||
armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(&s_pos[0]).V16B());
|
||||
armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_pos[0])).V16B());
|
||||
// x86SetJ8(pjmp);
|
||||
armBind(&pjmp);
|
||||
}
|
||||
else {
|
||||
// xAND.PS(xRegisterSSE(EEREC_D), ptr[&s_pos[0]]); // Make EEREC_D Positive
|
||||
armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(&s_pos[0]).V16B());
|
||||
armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_pos[0])).V16B());
|
||||
}
|
||||
|
||||
if (CHECK_FPU_OVERFLOW) { // Only need to do positive clamp, since EEREC_D is positive
|
||||
// xMIN.SS(xRegisterSSE(EEREC_D), ptr[&g_maxvals[0]]);
|
||||
armAsm->Fminnm(regED.S(), regED.S(), armLoadPtrV(&g_maxvals[0]).S());
|
||||
armAsm->Fminnm(regED.S(), regED.S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).S());
|
||||
}
|
||||
// xSQRT.SS(xRegisterSSE(EEREC_D), xRegisterSSE(EEREC_D));
|
||||
armAsm->Fsqrt(regED.S(), regED.S());
|
||||
@@ -2294,13 +2294,13 @@ void recRSQRThelper1(int regd, int t0reg) // Preforms the RSQRT function when re
|
||||
// xMOVMSKPS(eax, xRegisterSSE(t0reg));
|
||||
armMOVMSKPS(EAX, regT0);
|
||||
// xAND(eax, 1); //Check sign
|
||||
armAsm->Ands(EAX, EAX, 1);
|
||||
armAsm->And(EAX, EAX, 1);
|
||||
// pjmp2 = JZ8(0); //Skip if not set
|
||||
armAsm->B(&pjmp2, a64::Condition::eq);
|
||||
armAsm->Cbz(EAX, &pjmp2);
|
||||
// xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags
|
||||
armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI);
|
||||
// xAND.PS(xRegisterSSE(t0reg), ptr[&s_pos[0]]); // Make t0reg Positive
|
||||
armAsm->And(regT0.V16B(), regT0.V16B(), armLoadPtrV(&s_pos[0]).V16B()); // Make t0reg Positive
|
||||
armAsm->And(regT0.V16B(), regT0.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_pos[0])).V16B()); // Make t0reg Positive
|
||||
// x86SetJ8(pjmp2);
|
||||
armBind(&pjmp2);
|
||||
|
||||
@@ -2312,9 +2312,9 @@ void recRSQRThelper1(int regd, int t0reg) // Preforms the RSQRT function when re
|
||||
// xMOVMSKPS(eax, xRegisterSSE(t1reg));
|
||||
armMOVMSKPS(EAX, a64::QRegister(t1reg));
|
||||
// xAND(eax, 1); //Check sign (if t0reg == zero, sign will be set)
|
||||
armAsm->Ands(EAX, EAX, 1);
|
||||
armAsm->And(EAX, EAX, 1);
|
||||
// pjmp1 = JZ8(0); //Skip if not set
|
||||
armAsm->B(&pjmp1, a64::Condition::eq);
|
||||
armAsm->Cbz(EAX, &pjmp1);
|
||||
/*--- Check for 0/0 ---*/
|
||||
// xXOR.PS(xRegisterSSE(t1reg), xRegisterSSE(t1reg));
|
||||
armAsm->Eor(a64::QRegister(t1reg).V16B(), a64::QRegister(t1reg).V16B(), a64::QRegister(t1reg).V16B());
|
||||
@@ -2323,9 +2323,9 @@ void recRSQRThelper1(int regd, int t0reg) // Preforms the RSQRT function when re
|
||||
// xMOVMSKPS(eax, xRegisterSSE(t1reg));
|
||||
armMOVMSKPS(EAX, a64::QRegister(t1reg));
|
||||
// xAND(eax, 1); //Check sign (if regd == zero, sign will be set)
|
||||
armAsm->Ands(EAX, EAX, 1);
|
||||
armAsm->And(EAX, EAX, 1);
|
||||
// qjmp1 = JZ8(0); //Skip if not set
|
||||
armAsm->B(&qjmp1, a64::Condition::eq);
|
||||
armAsm->Cbz(EAX, &qjmp1);
|
||||
// xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags ( 0/0 )
|
||||
armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI);
|
||||
// qjmp2 = JMP8(0);
|
||||
@@ -2339,9 +2339,9 @@ void recRSQRThelper1(int regd, int t0reg) // Preforms the RSQRT function when re
|
||||
|
||||
/*--- Make regd +/- Maximum ---*/
|
||||
// xAND.PS(xRegisterSSE(regd), ptr[&s_neg[0]]); // Get the sign bit
|
||||
armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(&s_neg[0]).V16B());
|
||||
armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_neg[0])).V16B());
|
||||
// xOR.PS(xRegisterSSE(regd), ptr[&g_maxvals[0]]); // regd = +/- Maximum
|
||||
armAsm->Orr(regD.V16B(), regD.V16B(), armLoadPtrV(&g_maxvals[0]).V16B());
|
||||
armAsm->Orr(regD.V16B(), regD.V16B(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).V16B());
|
||||
// pjmp32 = JMP32(0);
|
||||
armAsm->B(&pjmp32);
|
||||
// x86SetJ8(pjmp1);
|
||||
@@ -2350,7 +2350,7 @@ void recRSQRThelper1(int regd, int t0reg) // Preforms the RSQRT function when re
|
||||
if (CHECK_FPU_EXTRA_OVERFLOW)
|
||||
{
|
||||
// xMIN.SS(xRegisterSSE(t0reg), ptr[&g_maxvals[0]]); // Only need to do positive clamp, since t0reg is positive
|
||||
armAsm->Fminnm(regT0.S(), regT0.S(), armLoadPtrV(&g_maxvals[0]).S());
|
||||
armAsm->Fminnm(regT0.S(), regT0.S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).S());
|
||||
fpuFloat2(regd);
|
||||
}
|
||||
|
||||
@@ -2372,11 +2372,11 @@ void recRSQRThelper2(int regd, int t0reg) // Preforms the RSQRT function when re
|
||||
auto regT0 = a64::QRegister(t0reg);
|
||||
|
||||
// xAND.PS(xRegisterSSE(t0reg), ptr[&s_pos[0]]); // Make t0reg Positive
|
||||
armAsm->And(regT0.V16B(), regT0.V16B(), armLoadPtrV(&s_pos[0]).V16B());
|
||||
armAsm->And(regT0.V16B(), regT0.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_pos[0])).V16B());
|
||||
if (CHECK_FPU_EXTRA_OVERFLOW)
|
||||
{
|
||||
// xMIN.SS(xRegisterSSE(t0reg), ptr[&g_maxvals[0]]); // Only need to do positive clamp, since t0reg is positive
|
||||
armAsm->Fminnm(regT0.S(), regT0.S(), armLoadPtrV(&g_maxvals[0]).S());
|
||||
armAsm->Fminnm(regT0.S(), regT0.S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).S());
|
||||
fpuFloat2(regd);
|
||||
}
|
||||
// xSQRT.SS(xRegisterSSE(t0reg), xRegisterSSE(t0reg));
|
||||
|
||||
@@ -80,48 +80,48 @@ namespace DOUBLE {
|
||||
// PS2 -> DOUBLE
|
||||
//------------------------------------------------------------------
|
||||
|
||||
#define SINGLE(sign, exp, mant) (((u32)(sign) << 31) | ((u32)(exp) << 23) | (u32)(mant))
|
||||
#define DOUBLE(sign, exp, mant) (((sign##ULL) << 63) | ((exp##ULL) << 52) | (mant##ULL))
|
||||
//#define SINGLE(sign, exp, mant) (((u32)(sign) << 31) | ((u32)(exp) << 23) | (u32)(mant))
|
||||
//#define DOUBLE(sign, exp, mant) (((sign##ULL) << 63) | ((exp##ULL) << 52) | (mant##ULL))
|
||||
|
||||
struct FPUd_Globals
|
||||
{
|
||||
u32 neg[4], pos[4];
|
||||
//struct FPUd_Globals
|
||||
//{
|
||||
// u32 neg[4], pos[4];
|
||||
//
|
||||
// u32 pos_inf[4], neg_inf[4],
|
||||
// one_exp[4];
|
||||
//
|
||||
// u64 dbl_one_exp[2];
|
||||
//
|
||||
// u64 dbl_cvt_overflow, // needs special code if above or equal
|
||||
// dbl_ps2_overflow, // overflow & clamp if above or equal
|
||||
// dbl_underflow; // underflow if below
|
||||
//
|
||||
// u64 padding;
|
||||
//
|
||||
// u64 dbl_s_pos[2];
|
||||
// //u64 dlb_s_neg[2];
|
||||
//};
|
||||
|
||||
u32 pos_inf[4], neg_inf[4],
|
||||
one_exp[4];
|
||||
|
||||
u64 dbl_one_exp[2];
|
||||
|
||||
u64 dbl_cvt_overflow, // needs special code if above or equal
|
||||
dbl_ps2_overflow, // overflow & clamp if above or equal
|
||||
dbl_underflow; // underflow if below
|
||||
|
||||
u64 padding;
|
||||
|
||||
u64 dbl_s_pos[2];
|
||||
//u64 dlb_s_neg[2];
|
||||
};
|
||||
|
||||
alignas(32) static const FPUd_Globals s_const =
|
||||
{
|
||||
{0x80000000, 0xffffffff, 0xffffffff, 0xffffffff},
|
||||
{0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff},
|
||||
|
||||
{SINGLE(0, 0xff, 0), 0, 0, 0},
|
||||
{SINGLE(1, 0xff, 0), 0, 0, 0},
|
||||
{SINGLE(0, 1, 0), 0, 0, 0},
|
||||
|
||||
{DOUBLE(0, 1, 0), 0},
|
||||
|
||||
DOUBLE(0, 1151, 0), // cvt_overflow
|
||||
DOUBLE(0, 1152, 0), // ps2_overflow
|
||||
DOUBLE(0, 897, 0), // underflow
|
||||
|
||||
0, // Padding!!
|
||||
|
||||
{0x7fffffffffffffffULL, 0},
|
||||
//{0x8000000000000000ULL, 0},
|
||||
};
|
||||
//alignas(32) static const FPUd_Globals s_const =
|
||||
//{
|
||||
// {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff},
|
||||
// {0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff},
|
||||
//
|
||||
// {SINGLE(0, 0xff, 0), 0, 0, 0},
|
||||
// {SINGLE(1, 0xff, 0), 0, 0, 0},
|
||||
// {SINGLE(0, 1, 0), 0, 0, 0},
|
||||
//
|
||||
// {DOUBLE(0, 1, 0), 0},
|
||||
//
|
||||
// DOUBLE(0, 1151, 0), // cvt_overflow
|
||||
// DOUBLE(0, 1152, 0), // ps2_overflow
|
||||
// DOUBLE(0, 897, 0), // underflow
|
||||
//
|
||||
// 0, // Padding!!
|
||||
//
|
||||
// {0x7fffffffffffffffULL, 0},
|
||||
// //{0x8000000000000000ULL, 0},
|
||||
//};
|
||||
|
||||
|
||||
// ToDouble : converts single-precision PS2 float to double-precision IEEE float
|
||||
@@ -131,12 +131,12 @@ void ToDouble(int reg)
|
||||
auto regQ = a64::QRegister(reg);
|
||||
|
||||
// xUCOMI.SS(xRegisterSSE(reg), ptr[s_const.pos_inf]); // Sets ZF if reg is equal or incomparable to pos_inf
|
||||
armAsm->Fcmp(regQ.S(), armLoadPtrV(s_const.pos_inf).S());
|
||||
armAsm->Fcmp(regQ.S(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos_inf)).S());
|
||||
// u8* to_complex = JE8(0); // Complex conversion if positive infinity or NaN
|
||||
a64::Label to_complex;
|
||||
armAsm->B(&to_complex, a64::Condition::eq);
|
||||
// xUCOMI.SS(xRegisterSSE(reg), ptr[s_const.neg_inf]);
|
||||
armAsm->Fcmp(regQ.S(), armLoadPtrV(s_const.neg_inf).S());
|
||||
armAsm->Fcmp(regQ.S(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg_inf)).S());
|
||||
// u8* to_complex2 = JE8(0); // Complex conversion if negative infinity
|
||||
a64::Label to_complex2;
|
||||
armAsm->B(&to_complex2, a64::Condition::eq);
|
||||
@@ -154,11 +154,11 @@ void ToDouble(int reg)
|
||||
|
||||
// Special conversion for when IEEE sees the value in reg as an INF/NaN
|
||||
// xPSUB.D(xRegisterSSE(reg), ptr[s_const.one_exp]); // Lower exponent by one
|
||||
armAsm->Sub(regQ.V4S(), regQ.V4S(), armLoadPtrV(s_const.one_exp).V4S());
|
||||
armAsm->Sub(regQ.V4S(), regQ.V4S(), armLoadPtrV(PTR_CPU(mVUss4.s_const.one_exp)).V4S());
|
||||
// xCVTSS2SD(xRegisterSSE(reg), xRegisterSSE(reg));
|
||||
armAsm->Fcvt(regQ.V1D(), regQ.S());
|
||||
// xPADD.Q(xRegisterSSE(reg), ptr[s_const.dbl_one_exp]); // Raise exponent by one
|
||||
armAsm->Fadd(regQ.V2D(), regQ.V2D(), armLoadPtrV(s_const.dbl_one_exp).V2D());
|
||||
armAsm->Fadd(regQ.V2D(), regQ.V2D(), armLoadPtrV(PTR_CPU(mVUss4.s_const.dbl_one_exp)).V2D());
|
||||
|
||||
// x86SetJ8(end);
|
||||
armBind(&end);
|
||||
@@ -198,16 +198,16 @@ void ToPS2FPU_Full(int reg, bool flags, int absreg, bool acc, bool addsub)
|
||||
// xMOVAPS(xRegisterSSE(absreg), xRegisterSSE(reg));
|
||||
armAsm->Mov(regAbs, a64::QRegister(reg));
|
||||
// xAND.PD(xRegisterSSE(absreg), ptr[&s_const.dbl_s_pos]);
|
||||
armAsm->And(regAbs.V16B(), regAbs.V16B(), armLoadPtrV(&s_const.dbl_s_pos).V16B());
|
||||
armAsm->And(regAbs.V16B(), regAbs.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.dbl_s_pos)).V16B());
|
||||
|
||||
// xUCOMI.SD(xRegisterSSE(absreg), ptr[&s_const.dbl_cvt_overflow]);
|
||||
armAsm->Fcmp(regAbs.V1D(), armLoadPtrV(&s_const.dbl_cvt_overflow).V1D());
|
||||
armAsm->Fcmp(regAbs.V1D(), armLoadPtrV(PTR_CPU(mVUss4.s_const.dbl_cvt_overflow)).V1D());
|
||||
// u8* to_complex = JAE8(0);
|
||||
a64::Label to_complex;
|
||||
armAsm->B(&to_complex, a64::Condition::cs);
|
||||
|
||||
// xUCOMI.SD(xRegisterSSE(absreg), ptr[&s_const.dbl_underflow]);
|
||||
armAsm->Fcmp(regAbs.V1D(), armLoadPtrV(&s_const.dbl_underflow).V1D());
|
||||
armAsm->Fcmp(regAbs.V1D(), armLoadPtrV(PTR_CPU(mVUss4.s_const.dbl_underflow)).V1D());
|
||||
// u8* to_underflow = JB8(0);
|
||||
a64::Label to_underflow;
|
||||
armAsm->B(&to_underflow, a64::Condition::cc);
|
||||
@@ -222,17 +222,17 @@ void ToPS2FPU_Full(int reg, bool flags, int absreg, bool acc, bool addsub)
|
||||
// x86SetJ8(to_complex);
|
||||
armBind(&to_complex);
|
||||
// xUCOMI.SD(xRegisterSSE(absreg), ptr[&s_const.dbl_ps2_overflow]);
|
||||
armAsm->Fcmp(regAbs.V1D(), armLoadPtrV(&s_const.dbl_ps2_overflow).V1D());
|
||||
armAsm->Fcmp(regAbs.V1D(), armLoadPtrV(PTR_CPU(mVUss4.s_const.dbl_ps2_overflow)).V1D());
|
||||
// u8* to_overflow = JAE8(0);
|
||||
a64::Label to_overflow;
|
||||
armAsm->B(&to_overflow, a64::Condition::cs);
|
||||
|
||||
// xPSUB.Q(xRegisterSSE(reg), ptr[&s_const.dbl_one_exp]); //lower exponent
|
||||
armAsm->Sub(regQ.V2D(), regQ.V2D(), armLoadPtrV(&s_const.dbl_one_exp).V2D());
|
||||
armAsm->Sub(regQ.V2D(), regQ.V2D(), armLoadPtrV(PTR_CPU(mVUss4.s_const.dbl_one_exp)).V2D());
|
||||
// xCVTSD2SS(xRegisterSSE(reg), xRegisterSSE(reg)); //convert
|
||||
armAsm->Fcvt(regQ.S(), regQ.V1D());
|
||||
// xPADD.D(xRegisterSSE(reg), ptr[s_const.one_exp]); //raise exponent
|
||||
armAsm->Add(regQ.V4S(), regQ.V4S(), armLoadPtrV(s_const.one_exp).V4S());
|
||||
armAsm->Add(regQ.V4S(), regQ.V4S(), armLoadPtrV(PTR_CPU(mVUss4.s_const.one_exp)).V4S());
|
||||
|
||||
// u32* end2 = JMP32(0);
|
||||
a64::Label end2;
|
||||
@@ -243,7 +243,7 @@ void ToPS2FPU_Full(int reg, bool flags, int absreg, bool acc, bool addsub)
|
||||
// xCVTSD2SS(xRegisterSSE(reg), xRegisterSSE(reg));
|
||||
armAsm->Fcvt(regQ.S(), regQ.V1D());
|
||||
// xOR.PS(xRegisterSSE(reg), ptr[&s_const.pos]); //clamp
|
||||
armAsm->Orr(regQ.V16B(), regQ.V16B(), armLoadPtrV(&s_const.pos).V16B());
|
||||
armAsm->Orr(regQ.V16B(), regQ.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos)).V16B());
|
||||
if (flags && FPU_FLAGS_OVERFLOW) {
|
||||
// xOR(ptr32[&fpuRegs.fprc[31]], (FPUflagO | FPUflagSO));
|
||||
armOrr(PTR_CPU(fpuRegs.fprc[31]), (FPUflagO | FPUflagSO));
|
||||
@@ -299,7 +299,7 @@ void ToPS2FPU_Full(int reg, bool flags, int absreg, bool acc, bool addsub)
|
||||
// xCVTSD2SS(xRegisterSSE(reg), xRegisterSSE(reg));
|
||||
armAsm->Fcvt(regQ.S(), regQ.V1D());
|
||||
// xAND.PS(xRegisterSSE(reg), ptr[s_const.neg]); //flush to zero
|
||||
armAsm->And(regQ.V16B(), regQ.V16B(), armLoadPtrV(s_const.neg).V16B());
|
||||
armAsm->And(regQ.V16B(), regQ.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg)).V16B());
|
||||
|
||||
// x86SetJ32(end);
|
||||
armBind(&end);
|
||||
@@ -326,9 +326,9 @@ void ToPS2FPU(int reg, bool flags, int absreg, bool acc, bool addsub = false)
|
||||
// xCVTSD2SS(xRegisterSSE(reg), xRegisterSSE(reg)); //clamp
|
||||
armAsm->Fcvt(regQ.S(), regQ.V1D());
|
||||
// xMIN.SS(xRegisterSSE(reg), ptr[&g_maxvals[0]]);
|
||||
armAsm->Fminnm(regQ.S(), regQ.S(), armLoadPtrV(&g_maxvals[0]).S());
|
||||
armAsm->Fminnm(regQ.S(), regQ.S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).S());
|
||||
// xMAX.SS(xRegisterSSE(reg), ptr[&g_minvals[0]]);
|
||||
armAsm->Fmaxnm(regQ.S(), regQ.S(), armLoadPtrV(&g_minvals[0]).S());
|
||||
armAsm->Fmaxnm(regQ.S(), regQ.S(), armLoadPtrV(PTR_CPU(mVUss4.g_minvals[0])).S());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,14 +339,14 @@ void SetMaxValue(int regd)
|
||||
|
||||
if (FPU_RESULT) {
|
||||
// xOR.PS(xRegisterSSE(regd), ptr[&s_const.pos[0]]); // set regd to maximum
|
||||
armAsm->Orr(regQ.V16B(), regQ.V16B(), armLoadPtrV(&s_const.pos[0]).V16B());
|
||||
armAsm->Orr(regQ.V16B(), regQ.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos[0])).V16B());
|
||||
}
|
||||
else
|
||||
{
|
||||
// xAND.PS(xRegisterSSE(regd), ptr[&s_const.neg[0]]); // Get the sign bit
|
||||
armAsm->And(regQ.V16B(), regQ.V16B(), armLoadPtrV(&s_const.neg[0]).V16B());
|
||||
armAsm->And(regQ.V16B(), regQ.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg[0])).V16B());
|
||||
// xOR.PS(xRegisterSSE(regd), ptr[&g_maxvals[0]]); // regd = +/- Maximum (CLAMP)!
|
||||
armAsm->Orr(regQ.V16B(), regQ.V16B(), armLoadPtrV(&g_maxvals[0]).V16B());
|
||||
armAsm->Orr(regQ.V16B(), regQ.V16B(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).V16B());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,7 +410,7 @@ void recABS_S_xmm(int info)
|
||||
|
||||
// xAND.PS(xRegisterSSE(EEREC_D), ptr[s_const.pos]);
|
||||
auto regED = a64::QRegister(EEREC_D);
|
||||
armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(s_const.pos).V16B());
|
||||
armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos)).V16B());
|
||||
}
|
||||
|
||||
FPURECOMPILE_CONSTCODE(ABS_S, XMMINFO_WRITED | XMMINFO_READS);
|
||||
@@ -489,7 +489,7 @@ void FPU_ADD_SUB(int tempd, int tempt) //tempd and tempt are overwritten, they a
|
||||
armBind(&j8Ptr0);
|
||||
//diff = 25 .. 255 , expt < expd
|
||||
// xAND.PS(xRegisterSSE(tempt), ptr[s_const.neg]);
|
||||
armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(s_const.neg).V16B());
|
||||
armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg)).V16B());
|
||||
// j8Ptr[5] = JMP8(0);
|
||||
armAsm->B(&j8Ptr5);
|
||||
|
||||
@@ -513,7 +513,7 @@ void FPU_ADD_SUB(int tempd, int tempt) //tempd and tempt are overwritten, they a
|
||||
armBind(&j8Ptr3);
|
||||
//diff = -255 .. -25, expd < expt
|
||||
// xAND.PS(xRegisterSSE(tempd), ptr[s_const.neg]);
|
||||
armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(s_const.neg).V16B());
|
||||
armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg)).V16B());
|
||||
|
||||
// x86SetJ8(j8Ptr[2]);
|
||||
armBind(&j8Ptr2);
|
||||
@@ -765,9 +765,9 @@ void recDIVhelper1(int regd, int regt) // Sets flags
|
||||
// xMOVMSKPS(eax, xRegisterSSE(t1reg));
|
||||
armMOVMSKPS(EAX, regT1);
|
||||
// xAND(eax, 1); //Check sign (if regt == zero, sign will be set)
|
||||
armAsm->Ands(EAX, EAX, 1);
|
||||
armAsm->And(EAX, EAX, 1);
|
||||
// ajmp32 = JZ32(0); //Skip if not set
|
||||
armAsm->B(&ajmp32, a64::Condition::eq);
|
||||
armAsm->Cbz(EAX, &ajmp32);
|
||||
|
||||
//--- Check for 0/0 ---
|
||||
// xXOR.PS(xRegisterSSE(t1reg), xRegisterSSE(t1reg));
|
||||
@@ -777,9 +777,9 @@ void recDIVhelper1(int regd, int regt) // Sets flags
|
||||
// xMOVMSKPS(eax, xRegisterSSE(t1reg));
|
||||
armMOVMSKPS(EAX, regT1);
|
||||
// xAND(eax, 1); //Check sign (if regd == zero, sign will be set)
|
||||
armAsm->Ands(EAX, EAX, 1);
|
||||
armAsm->And(EAX, EAX, 1);
|
||||
// pjmp1 = JZ8(0); //Skip if not set
|
||||
armAsm->B(&pjmp1, a64::Condition::eq);
|
||||
armAsm->Cbz(EAX, &pjmp1);
|
||||
// xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags ( 0/0 )
|
||||
armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI);
|
||||
// pjmp2 = JMP8(0);
|
||||
@@ -912,7 +912,7 @@ void recMaddsub(int info, int regd, int op, bool acc)
|
||||
armBind(&mulovf);
|
||||
if (op == 1) { //sub
|
||||
// xXOR.PS(xRegisterSSE(sreg), ptr[s_const.neg]);
|
||||
armAsm->Eor(regS.V16B(), regS.V16B(), armLoadPtrV(s_const.neg).V16B());
|
||||
armAsm->Eor(regS.V16B(), regS.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg)).V16B());
|
||||
}
|
||||
// xMOVAPS(xRegisterSSE(treg), xRegisterSSE(sreg)); //fall through below
|
||||
armAsm->Mov(regT, regS);
|
||||
@@ -978,11 +978,11 @@ FPURECOMPILE_CONSTCODE(MADDA_S, XMMINFO_WRITEACC | XMMINFO_READACC | XMMINFO_REA
|
||||
// MAX / MIN XMM
|
||||
//------------------------------------------------------------------
|
||||
|
||||
alignas(16) static const u32 minmax_mask[8] =
|
||||
{
|
||||
0xffffffff, 0x80000000, 0, 0,
|
||||
0, 0x40000000, 0, 0,
|
||||
};
|
||||
//alignas(16) static const u32 minmax_mask[8] =
|
||||
//{
|
||||
// 0xffffffff, 0x80000000, 0, 0,
|
||||
// 0, 0x40000000, 0, 0,
|
||||
//};
|
||||
// FPU's MAX/MIN work with all numbers (including "denormals"). Check VU's logical min max for more info.
|
||||
void recMINMAX(int info, bool ismin)
|
||||
{
|
||||
@@ -997,15 +997,15 @@ void recMINMAX(int info, bool ismin)
|
||||
// xPSHUF.D(xRegisterSSE(sreg), xRegisterSSE(sreg), 0x00);
|
||||
armPSHUFD(regS, regS, 0x00);
|
||||
// xPAND(xRegisterSSE(sreg), ptr[minmax_mask]);
|
||||
armAsm->And(regS.V16B(), regS.V16B(), armLoadPtrV(minmax_mask).V16B());
|
||||
armAsm->And(regS.V16B(), regS.V16B(), armLoadPtrV(PTR_CPU(mVUss4.minmax_mask)).V16B());
|
||||
// xPOR(xRegisterSSE(sreg), ptr[&minmax_mask[4]]);
|
||||
armAsm->Orr(regS.V16B(), regS.V16B(), armLoadPtrV(&minmax_mask[4]).V16B());
|
||||
armAsm->Orr(regS.V16B(), regS.V16B(), armLoadPtrV(PTR_CPU(mVUss4.minmax_mask[4])).V16B());
|
||||
// xPSHUF.D(xRegisterSSE(treg), xRegisterSSE(treg), 0x00);
|
||||
armPSHUFD(regT, regT, 0x00);
|
||||
// xPAND(xRegisterSSE(treg), ptr[minmax_mask]);
|
||||
armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(minmax_mask).V16B());
|
||||
armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(PTR_CPU(mVUss4.minmax_mask)).V16B());
|
||||
// xPOR(xRegisterSSE(treg), ptr[&minmax_mask[4]]);
|
||||
armAsm->Orr(regT.V16B(), regT.V16B(), armLoadPtrV(&minmax_mask[4]).V16B());
|
||||
armAsm->Orr(regT.V16B(), regT.V16B(), armLoadPtrV(PTR_CPU(mVUss4.minmax_mask[4])).V16B());
|
||||
if (ismin) {
|
||||
// xMIN.SD(xRegisterSSE(sreg), xRegisterSSE(treg));
|
||||
armAsm->Fminnm(regS.V1D(), regS.V1D(), regT.V1D());
|
||||
@@ -1113,7 +1113,7 @@ void recNEG_S_xmm(int info)
|
||||
CLEAR_OU_FLAGS;
|
||||
|
||||
// xXOR.PS(xRegisterSSE(EEREC_D), ptr[&s_const.neg[0]]);
|
||||
armAsm->Eor(a64::QRegister(EEREC_D).V16B(), a64::QRegister(EEREC_D).V16B(), armLoadPtrV(&s_const.neg[0]).V16B());
|
||||
armAsm->Eor(a64::QRegister(EEREC_D).V16B(), a64::QRegister(EEREC_D).V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg[0])).V16B());
|
||||
}
|
||||
|
||||
FPURECOMPILE_CONSTCODE(NEG_S, XMMINFO_WRITED | XMMINFO_READS);
|
||||
@@ -1177,21 +1177,21 @@ void recSQRT_S_xmm(int info)
|
||||
// xMOVMSKPS(eax, xRegisterSSE(EEREC_D));
|
||||
armMOVMSKPS(EAX, regED);
|
||||
// xAND(eax, 1); //Check sign
|
||||
armAsm->Ands(EAX, EAX, 1);
|
||||
armAsm->And(EAX, EAX, 1);
|
||||
// u8* pjmp = JZ8(0); //Skip if none are
|
||||
a64::Label pjmp;
|
||||
armAsm->B(&pjmp, a64::Condition::eq);
|
||||
armAsm->Cbz(EAX, &pjmp);
|
||||
// xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags
|
||||
armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI);
|
||||
// xAND.PS(xRegisterSSE(EEREC_D), ptr[&s_const.pos[0]]); // Make EEREC_D Positive
|
||||
armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(&s_const.pos[0]).V16B());
|
||||
armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos[0])).V16B());
|
||||
// x86SetJ8(pjmp);
|
||||
armBind(&pjmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// xAND.PS(xRegisterSSE(EEREC_D), ptr[&s_const.pos[0]]); // Make EEREC_D Positive
|
||||
armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(&s_const.pos[0]).V16B());
|
||||
armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos[0])).V16B());
|
||||
}
|
||||
|
||||
|
||||
@@ -1239,13 +1239,13 @@ void recRSQRThelper1(int regd, int regt) // Preforms the RSQRT function when reg
|
||||
// xMOVMSKPS(eax, xRegisterSSE(regt));
|
||||
armMOVMSKPS(EAX, regT);
|
||||
// xAND(eax, 1); //Check sign
|
||||
armAsm->Ands(EAX, EAX, 1);
|
||||
armAsm->And(EAX, EAX, 1);
|
||||
// pjmp2 = JZ8(0); //Skip if not set
|
||||
armAsm->B(&pjmp2, a64::Condition::eq);
|
||||
armAsm->Cbz(EAX, &pjmp2);
|
||||
// xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags
|
||||
armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI);
|
||||
// xAND.PS(xRegisterSSE(regt), ptr[&s_const.pos[0]]); // Make regt Positive
|
||||
armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(&s_const.pos[0]).V16B());
|
||||
armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos[0])).V16B());
|
||||
// x86SetJ8(pjmp2);
|
||||
armBind(&pjmp2);
|
||||
|
||||
@@ -1257,9 +1257,9 @@ void recRSQRThelper1(int regd, int regt) // Preforms the RSQRT function when reg
|
||||
// xMOVMSKPS(eax, xRegisterSSE(t1reg));
|
||||
armMOVMSKPS(EAX, regT1);
|
||||
// xAND(eax, 1); //Check sign (if regt == zero, sign will be set)
|
||||
armAsm->Ands(EAX, EAX, 1);
|
||||
armAsm->And(EAX, EAX, 1);
|
||||
// pjmp1 = JZ8(0); //Skip if not set
|
||||
armAsm->B(&pjmp1, a64::Condition::eq);
|
||||
armAsm->Cbz(EAX, &pjmp1);
|
||||
|
||||
//--- Check for 0/0 ---
|
||||
// xXOR.PS(xRegisterSSE(t1reg), xRegisterSSE(t1reg));
|
||||
@@ -1269,9 +1269,9 @@ void recRSQRThelper1(int regd, int regt) // Preforms the RSQRT function when reg
|
||||
// xMOVMSKPS(eax, xRegisterSSE(t1reg));
|
||||
armMOVMSKPS(EAX, regT1);
|
||||
// xAND(eax, 1); //Check sign (if regd == zero, sign will be set)
|
||||
armAsm->Ands(EAX, EAX, 1);
|
||||
armAsm->And(EAX, EAX, 1);
|
||||
// qjmp1 = JZ8(0); //Skip if not set
|
||||
armAsm->B(&qjmp1, a64::Condition::eq);
|
||||
armAsm->Cbz(EAX, &qjmp1);
|
||||
// xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags ( 0/0 )
|
||||
armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI);
|
||||
// qjmp2 = JMP8(0);
|
||||
@@ -1309,7 +1309,7 @@ void recRSQRThelper2(int regd, int regt) // Preforms the RSQRT function when reg
|
||||
auto regT = a64::QRegister(regt);
|
||||
|
||||
// xAND.PS(xRegisterSSE(regt), ptr[&s_const.pos[0]]); // Make regt Positive
|
||||
armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(&s_const.pos[0]).V16B());
|
||||
armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos[0])).V16B());
|
||||
|
||||
ToDouble(regt); ToDouble(regd);
|
||||
|
||||
|
||||
@@ -389,11 +389,11 @@ void recLWR()
|
||||
auto reg32 = a64::WRegister(treg);
|
||||
|
||||
// xAND(temp, 3);
|
||||
armAsm->Ands(temp, temp, 3);
|
||||
armAsm->And(temp, temp, 3);
|
||||
|
||||
// xForwardJE8 nomask;
|
||||
a64::Label nomask;
|
||||
armAsm->B(&nomask, a64::Condition::eq);
|
||||
armAsm->Cbz(temp, &nomask);
|
||||
// xSHL(temp, 3);
|
||||
armAsm->Lsl(temp, temp, 3);
|
||||
// mask off bytes loaded
|
||||
@@ -576,7 +576,7 @@ void recSWR()
|
||||
// xMOV(temp, arg1regd);
|
||||
armAsm->Mov(temp, ECX);
|
||||
// xAND(arg1regd, ~3);
|
||||
armAsm->And(ECX, ECX, ~3);
|
||||
armAsm->Ands(ECX, ECX, ~3);
|
||||
// xAND(temp, 3);
|
||||
armAsm->Ands(temp, temp, 3);
|
||||
|
||||
@@ -1239,7 +1239,7 @@ void recSDR()
|
||||
// xMOV(temp2, arg2reg);
|
||||
armAsm->Mov(temp2, RDX);
|
||||
// xAND(arg1regd, ~0x07);
|
||||
armAsm->And(ECX, ECX, ~0x07);
|
||||
armAsm->Ands(ECX, ECX, ~0x07);
|
||||
// xAND(temp1, 0x7);
|
||||
armAsm->Ands(temp1, temp1, 0x7);
|
||||
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
// Micro VU - Clamp Functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
alignas(16) const u32 sse4_minvals[2][4] = {
|
||||
{0xff7fffff, 0xffffffff, 0xffffffff, 0xffffffff}, //1000
|
||||
{0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}, //1111
|
||||
};
|
||||
alignas(16) const u32 sse4_maxvals[2][4] = {
|
||||
{0x7f7fffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1000
|
||||
{0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111
|
||||
};
|
||||
//alignas(16) const u32 sse4_minvals[2][4] = {
|
||||
// {0xff7fffff, 0xffffffff, 0xffffffff, 0xffffffff}, //1000
|
||||
// {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}, //1111
|
||||
//};
|
||||
//alignas(16) const u32 sse4_maxvals[2][4] = {
|
||||
// {0x7f7fffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1000
|
||||
// {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111
|
||||
//};
|
||||
|
||||
// Used for Result Clamping
|
||||
// Note: This function will not preserve NaN values' sign.
|
||||
@@ -55,9 +55,9 @@ void mVUclamp2(microVU& mVU, const xmm& reg, const xmm& regT1in, int xyzw, bool
|
||||
{
|
||||
int i = (xyzw == 1 || xyzw == 2 || xyzw == 4 || xyzw == 8) ? 0 : 1;
|
||||
// xPMIN.SD(reg, ptr128[&sse4_maxvals[i][0]]);
|
||||
armAsm->Smin(reg.V4S(), reg.V4S(), armLoadPtrV(&sse4_maxvals[i][0]).V4S());
|
||||
armAsm->Smin(reg.V4S(), reg.V4S(), armLoadPtrV(PTR_CPU(mVUss4.sse4_maxvals[i][0])).V4S());
|
||||
// xPMIN.UD(reg, ptr128[&sse4_minvals[i][0]]);
|
||||
armAsm->Umin(reg.V4S(), reg.V4S(), armLoadPtrV(&sse4_minvals[i][0]).V4S());
|
||||
armAsm->Umin(reg.V4S(), reg.V4S(), armLoadPtrV(PTR_CPU(mVUss4.sse4_minvals[i][0])).V4S());
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -2071,7 +2071,7 @@ mVUop(mVU_XTOP)
|
||||
if (mVU.index && THREAD_VU1) {
|
||||
armAsm->Ldrh(regT, PTR_VU1(vifRegs.top));
|
||||
} else {
|
||||
armAsm->Ldrh(regT, armMemOperandPtr(&mVU.getVifRegs().top));
|
||||
armAsm->Ldrh(regT, PTR_CPU(vifRegs[mVU.index].top));
|
||||
}
|
||||
mVU.regAlloc->clearNeeded(regT);
|
||||
mVU.profiler.EmitOp(opXTOP);
|
||||
@@ -2095,7 +2095,7 @@ mVUop(mVU_XITOP)
|
||||
if (mVU.index && THREAD_VU1) {
|
||||
armAsm->Ldrh(regT, PTR_VU1(vifRegs.itop));
|
||||
} else {
|
||||
armAsm->Ldrh(regT, armMemOperandPtr(&mVU.getVifRegs().itop));
|
||||
armAsm->Ldrh(regT, PTR_CPU(vifRegs[mVU.index].itop));
|
||||
}
|
||||
// xAND(regT, isVU1 ? 0x3ff : 0xff);
|
||||
armAsm->And(regT, regT, isVU1 ? 0x3ff : 0xff);
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
} while (0)
|
||||
|
||||
|
||||
alignas(16) const u32 sse4_compvals[2][4] = {
|
||||
{0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111
|
||||
{0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1111
|
||||
};
|
||||
//alignas(16) const u32 sse4_compvals[2][4] = {
|
||||
// {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111
|
||||
// {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1111
|
||||
//};
|
||||
|
||||
const std::array<u16, 16> flipMask{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
|
||||
|
||||
@@ -96,16 +96,16 @@ static void mVUupdateFlags(mV, const xmm& reg, const xmm& regT1in = a64::NoVReg,
|
||||
// xMOVAPS(regT1, regT2);
|
||||
armAsm->Mov(regT1.Q(), regT2.Q());
|
||||
// xAND.PS(regT1, ptr128[&sse4_compvals[1][0]]); // Remove sign flags (we don't care)
|
||||
armAsm->And(regT1.V16B(), regT1.V16B(), armLoadPtrV(&sse4_compvals[1][0]).V16B());
|
||||
armAsm->And(regT1.V16B(), regT1.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sse4_compvals[1][0])).V16B());
|
||||
// xCMPNLT.PS(regT1, ptr128[&sse4_compvals[0][0]]); // Compare if T1 == FLT_MAX
|
||||
armAsm->Fcmge(regT1.V4S(), regT1.V4S(), armLoadPtrV(&sse4_compvals[0][0]).V4S());
|
||||
armAsm->Fcmeq(regT1.V4S(), regT1.V4S(), armLoadPtrV(PTR_CPU(mVUss4.sse4_compvals[0][0])).V4S());
|
||||
// xMOVMSKPS(gprT2, regT1); // Grab sign bits for equal results
|
||||
armMOVMSKPS(gprT2, regT1);
|
||||
// xAND(gprT2, AND_XYZW); // Grab "Is FLT_MAX" bits from the previous calculation
|
||||
armAsm->Ands(gprT2, gprT2, AND_XYZW);
|
||||
armAsm->And(gprT2, gprT2, AND_XYZW);
|
||||
// xForwardJump32 oJMP(Jcc_Zero);
|
||||
a64::Label oJMP;
|
||||
armAsm->B(&oJMP, a64::Condition::eq);
|
||||
armAsm->Cbz(gprT2, &oJMP);
|
||||
|
||||
// xOR(sReg, 0x820000);
|
||||
armAsm->Orr(sReg, sReg, 0x820000);
|
||||
|
||||
Reference in New Issue
Block a user