Cemu/src/Cafe/HW/Espresso/Interpreter/PPCInterpreterInternal.h
2022-08-22 22:21:23 +02:00

300 lines
12 KiB
C

#pragma once
#include "Cafe/HW/Espresso/PPCState.h"
// SPR constants
#define SPR_XER 1
#define SPR_LR 8
#define SPR_CTR 9
#define SPR_DEC 22
#define SPR_SRR0 26
#define SPR_SRR1 27
#define SPR_HID0 1008
#define SPR_HID1 1009
#define SPR_HID2 920
#define SPR_TBL 268
#define SPR_TBU 269
#define SPR_DMAU 922
#define SPR_DMAL 923
// graphics quantization registers
#define SPR_GQR0 912
#define SPR_GQR1 913
#define SPR_GQR2 914
#define SPR_GQR3 915
#define SPR_GQR4 916
#define SPR_GQR5 917
#define SPR_GQR6 918
#define SPR_GQR7 919
// user graphics quantization registers
#define SPR_UGQR0 896
#define SPR_UGQR1 897
#define SPR_UGQR2 898
#define SPR_UGQR3 899
#define SPR_UGQR4 900
#define SPR_UGQR5 901
#define SPR_UGQR6 902
#define SPR_UGQR7 903
#define SPR_FPECR 1022 // used by the OS to store values
#define SPR_PVR 287 // processor version, for Wii U this must be 0x7001xxxx - this register is only readable
#define SPR_UPIR 1007 // core index
#define SPR_SCR 947 // core control
#define SPR_SDR1 25
// reversed CR bit indices
#define CR_BIT_LT 0
#define CR_BIT_GT 1
#define CR_BIT_EQ 2
#define CR_BIT_SO 3
#define XER_SO (1<<31) // summary overflow bit
#define XER_OV (1<<30) // overflow bit
#define XER_BIT_CA (29) // carry bit index. To accelerate frequent access, this bit is stored as a separate uint8
// FPSCR
#define FPSCR_VXSNAN (1<<24)
#define FPSCR_VXVC (1<<19)
#define MSR_SF (1<<31)
#define MSR_UNKNOWN (1<<30)
#define MSR_UNKNOWN2 (1<<27)
#define MSR_VEC (1<<25)
#define MSR_POW (1<<18)
#define MSR_TGPR (1<<15)
#define MSR_ILE (1<<16)
#define MSR_EE (1<<15)
#define MSR_PR (1<<14)
#define MSR_FP (1<<13)
#define MSR_ME (1<<12)
#define MSR_FE0 (1<<11)
#define MSR_SE (1<<10)
#define MSR_BE (1<<9)
#define MSR_FE1 (1<<8)
#define MSR_IP (1<<6)
#define MSR_IR (1<<5)
#define MSR_DR (1<<4)
#define MSR_PM (1<<2)
#define MSR_RI (1<<1)
#define MSR_LE (1)
// helpers
#define GET_MSR_BIT(__bit) ((hCPU->sprExtended.msr&(__bit))!=0)
#define opHasRC() ((opcode & PPC_OPC_RC) != 0)
// assume fixed values for PSE/LSQE. This optimization is possible because Wii U applications run only in user mode (todo - handle this correctly in LLE mode)
//#define PPC_LSQE (hCPU->LSQE)
//#define PPC_PSE (hCPU->PSE)
#define PPC_LSQE (1)
#define PPC_PSE (1)
#define PPC_ASSERT(v)
#define PPC_OPC_RC 1
#define PPC_OPC_OE (1<<10)
#define PPC_OPC_LK 1
#define PPC_OPC_AA (1<<1)
#define PPC_OPC_TEMPL_A(opc, rD, rA, rB, rC) {rD=((opc)>>21)&0x1f;rA=((opc)>>16)&0x1f;rB=((opc)>>11)&0x1f;rC=((opc)>>6)&0x1f;}
#define PPC_OPC_TEMPL_B(opc, BO, BI, BD) {BO=((opc)>>21)&0x1f;BI=((opc)>>16)&0x1f;BD=(uint32)(sint32)(sint16)((opc)&0xfffc);}
#define PPC_OPC_TEMPL_D_SImm(opc, rD, rA, imm) {rD=((opc)>>21)&0x1f;rA=((opc)>>16)&0x1f;imm=(uint32)(sint32)(sint16)((opc)&0xffff);}
#define PPC_OPC_TEMPL_D_UImm(opc, rD, rA, imm) {rD=((opc)>>21)&0x1f;rA=((opc)>>16)&0x1f;imm=(opc)&0xffff;}
#define PPC_OPC_TEMPL_D_Shift16(opc, rD, rA, imm) {rD=((opc)>>21)&0x1f;rA=((opc)>>16)&0x1f;imm=(opc)<<16;}
#define PPC_OPC_TEMPL_I(opc, LI) {LI=(opc)&0x3fffffc;if (LI&0x02000000) LI |= 0xfc000000;}
#define PPC_OPC_TEMPL_M(opc, rS, rA, SH, MB, ME) {rS=((opc)>>21)&0x1f;rA=((opc)>>16)&0x1f;SH=((opc)>>11)&0x1f;MB=((opc)>>6)&0x1f;ME=((opc)>>1)&0x1f;}
#define PPC_OPC_TEMPL_X(opc, rS, rA, rB) {rS=((opc)>>21)&0x1f;rA=((opc)>>16)&0x1f;rB=((opc)>>11)&0x1f;}
#define PPC_OPC_TEMPL_XFX(opc, rS, CRM) {rS=((opc)>>21)&0x1f;CRM=((opc)>>12)&0xff;}
#define PPC_OPC_TEMPL_XO(opc, rS, rA, rB) {rS=((opc)>>21)&0x1f;rA=((opc)>>16)&0x1f;rB=((opc)>>11)&0x1f;}
#define PPC_OPC_TEMPL_XL(opc, BO, BI, BD) {BO=((opc)>>21)&0x1f;BI=((opc)>>16)&0x1f;BD=((opc)>>11)&0x1f;}
#define PPC_OPC_TEMPL_XFL(opc, rB, FM) {rB=((opc)>>11)&0x1f;FM=((opc)>>17)&0xff;}
#define PPC_OPC_TEMPL3_XO() sint32 rD, rA, rB; rD=((opcode)>>21)&0x1f;rA=((opcode)>>16)&0x1f;rB=((opcode)>>11)&0x1f
#define PPC_OPC_TEMPL_X_CR() sint32 crD, crA, crB; crD=((opcode)>>21)&0x1f;crA=((opcode)>>16)&0x1f;crB=((opcode)>>11)&0x1f
static inline void ppc_update_cr0(PPCInterpreter_t* hCPU, uint32 r)
{
hCPU->cr[CR_BIT_SO] = (hCPU->spr.XER&XER_SO) ? 1 : 0;
hCPU->cr[CR_BIT_LT] = ((r != 0) ? 1 : 0) & ((r & 0x80000000) ? 1 : 0);
hCPU->cr[CR_BIT_EQ] = (r == 0);
hCPU->cr[CR_BIT_GT] = hCPU->cr[CR_BIT_EQ] ^ hCPU->cr[CR_BIT_LT] ^ 1; // this works because EQ and LT can never be set at the same time. So the only case where GT becomes 1 is when LT=0 and EQ=0
}
static inline uint8 ppc_getCRBit(PPCInterpreter_t* hCPU, uint32 r)
{
return hCPU->cr[r];
}
static inline bool ppc_MTCRFMaskHasCRFieldSet(const uint32 mtcrfMask, const uint32 crIndex)
{
// 1000 0000 (0x80) -> cr0
// 0000 0001 (0x01) -> cr7
return (mtcrfMask & (1 << (7 - crIndex))) != 0;
}
// returns CR mask with CR0.LT in LSB
static inline uint32 ppc_MTCRFMaskToCRBitMask(const uint32 mtcrfMask)
{
uint32 crMask = 0;
for (uint32 crF = 0; crF < 8; crF++)
{
if (ppc_MTCRFMaskHasCRFieldSet(mtcrfMask, crF))
crMask |= (0xF << (crF * 4));
}
return crMask;
}
static inline void ppc_setCRBit(PPCInterpreter_t* hCPU, uint32 r, uint8 v)
{
hCPU->cr[r] = v;
}
static inline void ppc_setCR(PPCInterpreter_t* hCPU, uint32 cr)
{
uint32 tempCr = cr;
for (sint32 i = 31; i >= 0; i--)
{
ppc_setCRBit(hCPU, i, tempCr & 1);
tempCr >>= 1;
}
}
static inline uint32 ppc_getCR(PPCInterpreter_t* hCPU)
{
uint32 cr = 0;
for (sint32 i = 0; i < 32; i++)
{
cr <<= 1;
if (ppc_getCRBit(hCPU, i))
cr |= 1;
}
return cr;
}
// FPU helper
#define IS_NAN(X) ((((X) & 0x000fffffffffffffULL) != 0) && (((X) & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL))
#define IS_QNAN(X) ((((X) & 0x000fffffffffffffULL) != 0) && (((X) & 0x7ff8000000000000ULL) == 0x7ff8000000000000ULL))
#define IS_SNAN(X) ((((X) & 0x000fffffffffffffULL) != 0) && (((X) & 0x7ff8000000000000ULL) == 0x7ff0000000000000ULL))
#define FPSCR_VE (1 << 7)
inline double roundTo25BitAccuracy(double d)
{
uint64 v = *(uint64*)&d;
v = (v & 0xFFFFFFFFF8000000ULL) + (v & 0x8000000ULL);
return *(double*)&v;
}
double fres_espresso(double input);
double frsqrte_espresso(double input);
void fcmpu_espresso(PPCInterpreter_t* hCPU, int crfD, double a, double b);
// OPC
void PPCInterpreter_virtualHLE(PPCInterpreter_t* hCPU, unsigned int opcode);
void PPCInterpreter_MFMSR(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_MTMSR(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_MFTB(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_MTFSB1X(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_MFCR(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_MCRF(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_MTCRF(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_MCRXR(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_TLBIE(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_TLBSYNC(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_DCBT(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_DCBST(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_DCBZL(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_DCBF(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_DCBI(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_DCBZ(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_ICBI(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_EIEIO(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_SC(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_SYNC(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_ISYNC(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_RFI(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_BX(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_BCX(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_BCLRX(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_BCCTR(PPCInterpreter_t* hCPU, uint32 Opcode);
// FPU
void PPCInterpreter_FCMPO(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FCMPU(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FMR(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FSEL(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FCTIWZ(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FCTIW(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FNEG(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FRSP(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FRSQRTE(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FRES(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FABS(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FNABS(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FADD(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FMUL(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FDIV(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FSUB(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FMADD(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FMSUB(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FMSUBS(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FNMADD(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FNMSUB(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_MFFS(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_MTFSF(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FDIVS(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FMULS(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FADDS(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FSUBS(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FMADDS(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FNMADDS(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_FNMSUBS(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_MERGE00(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_MERGE01(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_MERGE10(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_MERGE11(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_MR(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_NEG(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_ABS(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_NABS(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_RES(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_RSQRTE(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_ADD(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_SUB(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_MUL(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_DIV(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_MADD(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_NMADD(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_MADDS0(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_MADDS1(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_MSUB(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_NMSUB(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_SEL(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_SUM0(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_SUM1(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_MULS0(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_MULS1(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_CMPO0(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_CMPU0(PPCInterpreter_t* hCPU, uint32 Opcode);
void PPCInterpreter_PS_CMPU1(PPCInterpreter_t* hCPU, uint32 Opcode);