📄 ppc_vec.c
字号:
uint32 res; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); int i; for (i=0; i<4; i++) { res = gCPU.vr[vrA].w[i]; if (res > gCPU.vr[vrB].w[i]) res = gCPU.vr[vrB].w[i]; gCPU.vr[vrD].w[i] = res; }}/* vminsb Vector Minimum Signed Byte * v.188 */void ppc_opc_vminsb(){ VECTOR_DEBUG; int vrD, vrA, vrB; sint8 res; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); int i; for (i=0; i<16; i++) { res = gCPU.vr[vrA].sb[i]; if (res > gCPU.vr[vrB].sb[i]) res = gCPU.vr[vrB].sb[i]; gCPU.vr[vrD].sb[i] = res; }}/* vminsh Vector Minimum Signed Half Word * v.189 */void ppc_opc_vminsh(){ VECTOR_DEBUG; int vrD, vrA, vrB; sint16 res; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); int i; for (i=0; i<8; i++) { res = gCPU.vr[vrA].sh[i]; if (res > gCPU.vr[vrB].sh[i]) res = gCPU.vr[vrB].sh[i]; gCPU.vr[vrD].sh[i] = res; }}/* vminsw Vector Minimum Signed Word * v.190 */void ppc_opc_vminsw(){ VECTOR_DEBUG; int vrD, vrA, vrB; sint32 res; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); int i; for (i=0; i<4; i++) { res = gCPU.vr[vrA].sw[i]; if (res > gCPU.vr[vrB].sw[i]) res = gCPU.vr[vrB].sw[i]; gCPU.vr[vrD].sw[i] = res; }}/* vminfp Vector Minimum Floating Point * v.187 */void ppc_opc_vminfp(){ VECTOR_DEBUG; int vrD, vrA, vrB; float res; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP res = gCPU.vr[vrA].f[i]; if (res > gCPU.vr[vrB].f[i]) res = gCPU.vr[vrB].f[i]; gCPU.vr[vrD].f[i] = res; }}/* vrfin Vector Round to Floating-Point Integer Nearest * v.231 */void ppc_opc_vrfin(){ VECTOR_DEBUG; int vrD, vrA, vrB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); PPC_OPC_ASSERT(vrA==0); /* Documentation doesn't dictate how this instruction should * round from a middle point. With a test on a real G4, it was * found to be round to nearest, with bias to even if equidistant. * * This is covered by the function rint() */ int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP gCPU.vr[vrD].f[i] = rintf(gCPU.vr[vrB].f[i]); }}/* vrfip Vector Round to Floating-Point Integer toward Plus Infinity * v.232 */void ppc_opc_vrfip(){ VECTOR_DEBUG; int vrD, vrA, vrB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); PPC_OPC_ASSERT(vrA==0); int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP gCPU.vr[vrD].f[i] = ceilf(gCPU.vr[vrB].f[i]); }}/* vrfim Vector Round to Floating-Point Integer toward Minus Infinity * v.230 */void ppc_opc_vrfim(){ VECTOR_DEBUG; int vrD, vrA, vrB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); PPC_OPC_ASSERT(vrA==0); int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP gCPU.vr[vrD].f[i] = floorf(gCPU.vr[vrB].f[i]); }}/* vrfiz Vector Round to Floating-Point Integer toward Zero * v.233 */void ppc_opc_vrfiz(){ VECTOR_DEBUG; int vrD, vrA, vrB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); PPC_OPC_ASSERT(vrA==0); int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP gCPU.vr[vrD].f[i] = truncf(gCPU.vr[vrD].f[i]); }}/* vrefp Vector Reciprocal Estimate Floating Point * v.228 */void ppc_opc_vrefp(){ VECTOR_DEBUG; int vrD, vrA, vrB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); PPC_OPC_ASSERT(vrA==0); /* This emulation generates an exact value, instead of an estimate. * This is technically within specs, but some test-suites expect the * exact estimate value returned by G4s. These anomolous failures * should be ignored. */ int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP gCPU.vr[vrD].f[i] = 1 / gCPU.vr[vrB].f[i]; }}/* vrsqrtefp Vector Reciprocal Square Root Estimate Floating Point * v.237 */void ppc_opc_vrsqrtefp(){ VECTOR_DEBUG; int vrD, vrA, vrB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); PPC_OPC_ASSERT(vrA==0); /* This emulation generates an exact value, instead of an estimate. * This is technically within specs, but some test-suites expect the * exact estimate value returned by G4s. These anomolous failures * should be ignored. */ int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP gCPU.vr[vrD].f[i] = 1 / sqrt(gCPU.vr[vrB].f[i]); }}/* vlogefp Vector Log2 Estimate Floating Point * v.175 */void ppc_opc_vlogefp(){ VECTOR_DEBUG; int vrD, vrA, vrB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); PPC_OPC_ASSERT(vrA==0); /* This emulation generates an exact value, instead of an estimate. * This is technically within specs, but some test-suites expect the * exact estimate value returned by G4s. These anomolous failures * should be ignored. */ int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP gCPU.vr[vrD].f[i] = log2(gCPU.vr[vrB].f[i]); }}/* vexptefp Vector 2 Raised to the Exponent Estimate Floating Point * v.173 */void ppc_opc_vexptefp(){ VECTOR_DEBUG; int vrD, vrA, vrB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); PPC_OPC_ASSERT(vrA==0); /* This emulation generates an exact value, instead of an estimate. * This is technically within specs, but some test-suites expect the * exact estimate value returned by G4s. These anomolous failures * should be ignored. */ int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP gCPU.vr[vrD].f[i] = exp2(gCPU.vr[vrB].f[i]); }}/* vcfux Vector Convert from Unsigned Fixed-Point Word * v.156 */void ppc_opc_vcfux(){ VECTOR_DEBUG; int vrD, vrB; uint32 uimm; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, uimm, vrB); int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP gCPU.vr[vrD].f[i] = ((float)gCPU.vr[vrB].w[i]) / (1 << uimm); }}/* vcfsx Vector Convert from Signed Fixed-Point Word * v.155 */void ppc_opc_vcfsx(){ VECTOR_DEBUG; int vrD, vrB; uint32 uimm; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, uimm, vrB); int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP gCPU.vr[vrD].f[i] = ((float)gCPU.vr[vrB].sw[i]) / (1 << uimm); }}/* vctsxs Vector Convert To Signed Fixed-Point Word Saturate * v.171 */void ppc_opc_vctsxs(){ VECTOR_DEBUG; int vrD, vrB; uint32 uimm; float ftmp; sint32 tmp; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, uimm, vrB); int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP ftmp = gCPU.vr[vrB].f[i] * (float)(1 << uimm); ftmp = truncf(ftmp); tmp = (sint32)ftmp; if (ftmp > 2147483647.0) { tmp = 2147483647; // 0x7fffffff gCPU.vscr |= VSCR_SAT; } else if (ftmp < -2147483648.0) { tmp = -2147483648LL; // 0x80000000 gCPU.vscr |= VSCR_SAT; } gCPU.vr[vrD].sw[i] = tmp; }}/* vctuxs Vector Convert to Unsigned Fixed-Point Word Saturate * v.172 */void ppc_opc_vctuxs(){ VECTOR_DEBUG; int vrD, vrB; uint32 tmp, uimm; float ftmp; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, uimm, vrB); int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP ftmp = gCPU.vr[vrB].f[i] * (float)(1 << uimm); ftmp = truncf(ftmp); tmp = (uint32)ftmp; if (ftmp > 4294967295.0) { tmp = 0xffffffff; gCPU.vscr |= VSCR_SAT; } else if (ftmp < 0) { tmp = 0; gCPU.vscr |= VSCR_SAT; } gCPU.vr[vrD].w[i] = tmp; }}/* vand Vector Logical AND * v.147 */void ppc_opc_vand(){ VECTOR_DEBUG; int vrD, vrA, vrB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); gCPU.vr[vrD].d[0] = gCPU.vr[vrA].d[0] & gCPU.vr[vrB].d[0]; gCPU.vr[vrD].d[1] = gCPU.vr[vrA].d[1] & gCPU.vr[vrB].d[1];}/* vandc Vector Logical AND with Complement * v.148 */void ppc_opc_vandc(){ VECTOR_DEBUG; int vrD, vrA, vrB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); gCPU.vr[vrD].d[0] = gCPU.vr[vrA].d[0] & ~gCPU.vr[vrB].d[0]; gCPU.vr[vrD].d[1] = gCPU.vr[vrA].d[1] & ~gCPU.vr[vrB].d[1];}/* vor Vector Logical OR * v.217 */void ppc_opc_vor(){ VECTOR_DEBUG_COMMON; int vrD, vrA, vrB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); gCPU.vr[vrD].d[0] = gCPU.vr[vrA].d[0] | gCPU.vr[vrB].d[0]; gCPU.vr[vrD].d[1] = gCPU.vr[vrA].d[1] | gCPU.vr[vrB].d[1];}/* vnor Vector Logical NOR * v.216 */void ppc_opc_vnor(){ VECTOR_DEBUG; int vrD, vrA, vrB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); gCPU.vr[vrD].d[0] = ~(gCPU.vr[vrA].d[0] | gCPU.vr[vrB].d[0]); gCPU.vr[vrD].d[1] = ~(gCPU.vr[vrA].d[1] | gCPU.vr[vrB].d[1]);}/* vxor Vector Logical XOR * v.282 */void ppc_opc_vxor(){ VECTOR_DEBUG_COMMON; int vrD, vrA, vrB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); gCPU.vr[vrD].d[0] = gCPU.vr[vrA].d[0] ^ gCPU.vr[vrB].d[0]; gCPU.vr[vrD].d[1] = gCPU.vr[vrA].d[1] ^ gCPU.vr[vrB].d[1];}#define CR_CR6 (0x00f0)#define CR_CR6_EQ (1<<7)#define CR_CR6_NE (1<<5)/* vcmpequbx Vector Compare Equal-to Unsigned Byte * v.160 */void ppc_opc_vcmpequbx(){ VECTOR_DEBUG; int vrD, vrA, vrB; int tf=CR_CR6_EQ | CR_CR6_NE; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); int i; for (i=0; i<16; i++) { if (gCPU.vr[vrA].b[i] == gCPU.vr[vrB].b[i]) { gCPU.vr[vrD].b[i] = 0xff; tf &= ~CR_CR6_NE; } else { gCPU.vr[vrD].b[i] = 0; tf &= ~CR_CR6_EQ; } } if (PPC_OPC_VRc & gCPU.current_opc) { gCPU.cr &= ~CR_CR6; gCPU.cr |= tf; }}/* vcmpequhx Vector Compare Equal-to Unsigned Half Word * v.161 */void ppc_opc_vcmpequhx(){ VECTOR_DEBUG; int vrD, vrA, vrB; int tf=CR_CR6_EQ | CR_CR6_NE; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); int i; for (i=0; i<8; i++) { if (gCPU.vr[vrA].h[i] == gCPU.vr[vrB].h[i]) { gCPU.vr[vrD].h[i] = 0xffff; tf &= ~CR_CR6_NE; } else { gCPU.vr[vrD].h[i] = 0; tf &= ~CR_CR6_EQ; } } if (PPC_OPC_VRc & gCPU.current_opc) { gCPU.cr &= ~CR_CR6; gCPU.cr |= tf; }}/* vcmpequwx Vector Compare Equal-to Unsigned Word * v.162 */void ppc_opc_vcmpequwx(){ VECTOR_DEBUG; int vrD, vrA, vrB; int tf=CR_CR6_EQ | CR_CR6_NE; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); int i; for (i=0; i<4; i++) { if (gCPU.vr[vrA].w[i] == gCPU.vr[vrB].w[i]) { gCPU.vr[vrD].w[i] = 0xffffffff; tf &= ~CR_CR6_NE; } else { gCPU.vr[vrD].w[i] = 0; tf &= ~CR_CR6_EQ; } } if (PPC_OPC_VRc & gCPU.current_opc) { gCPU.cr &= ~CR_CR6; gCPU.cr |= tf; }}/* vcmpeqfpx Vector Compare Equal-to-Floating Point * v.159 */void ppc_opc_vcmpeqfpx(){ VECTOR_DEBUG; int vrD, vrA, vrB; int tf=CR_CR6_EQ | CR_CR6_NE; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); int i; for (i=0; i<4; i++) { //FIXME: This might not comply with Java FP if (gCPU.vr[vrA].f[i] == gCPU.vr[vrB].f[i]) { gCPU.vr[vrD].w[i] = 0xffffffff; tf &= ~CR_CR6_NE; } else { gCPU.vr[vrD].w[i] = 0; tf &= ~CR_CR6_EQ; } } if (PPC_OPC_VRc & gCPU.current_opc) { gCPU.cr &= ~CR_CR6; gCPU.cr |= tf; }}/* vcmpgtubx Vector Compare Greater-Than Unsigned Byte * v.168 */void ppc_opc_vcmpgtubx(){ VECTOR_DEBUG; int vrD, vrA, vrB; int tf=CR_CR6_EQ | CR_CR6_NE; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); int i; for (i=0; i<16; i++) { if (gCPU.vr[vrA].b[i] > gCPU.vr[vrB].b[i]) { gCPU.vr[vrD].b[i] = 0xff; tf &= ~CR_CR6_NE; } else { gCPU.vr[vrD].b[i] = 0; tf &= ~CR_CR6_EQ; } } if (PPC_OPC_VRc & gCPU.current_opc) { gCPU.cr &= ~CR_CR6; gCPU.cr |= tf; }}/* vcmpgtsbx Vector Compare Greater-Than Signed Byte * v.165 */void ppc_opc_vcmpgtsbx(){ VECTOR_DEBUG; int vrD, vrA, vrB; int tf=CR_CR6_EQ | CR_CR6_NE; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); int i; for (i=0; i<16; i++) { if (gCPU.vr[vrA].sb[i] > gCPU.vr[vrB].sb[i]) { gCPU.vr[vrD].b[i] = 0xff; tf &= ~CR_CR6_NE; } else { gCPU.vr[vrD].b[i] = 0; tf &= ~CR_CR6_EQ; } } if (PPC_OPC_VRc & gCPU.current_opc) { gCPU.cr &= ~CR_CR6; gCPU.cr |= tf; }}/* vcmpgtuhx Vector Compare Greater-Than Unsigned Half Word * v.169 */void ppc_opc_vcmpgtuhx(){ VECTOR_DEBUG; int vrD, vrA, vrB; int tf=CR_CR6_EQ | CR_CR6_NE; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); int i; for (i=0; i<8; i++) { if (gCPU.vr[vrA].h[i] > gCPU.vr[vrB].h[i]) { gCPU.vr[vrD].h[i] = 0xffff; tf &= ~CR_CR6_NE; } else { gCPU.vr[vrD].h[i] = 0; tf &= ~CR_CR6_EQ; } } if (PPC_OPC_VRc & gCPU.current_opc) { gCPU.cr &= ~CR_CR6; gCPU.cr |= tf; }}/* vcmpgtshx Vector Compare Greater-Than Signed Half Word * v.166 */void ppc_opc_vcmpgtshx(){ VECTOR_DEBUG; int vrD, vrA, vrB; int tf=CR_CR6_EQ | CR_CR6_NE; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, vrA, vrB); int i; for (i=0; i<8; i++) { if (gCPU.vr[vrA].sh[i] > gCPU.vr[vrB].sh[i]) { gCPU.vr[vrD].h[i] = 0xffff; tf &= ~CR_CR6_NE; } else { gCPU.vr[vrD].h[i] = 0; tf &= ~CR_CR6_EQ; } } if (PPC_OPC_VRc & gCPU.current_opc) { gCPU.cr &= ~CR_CR6; gCPU.cr |= tf; }}/* vcmpgtuwx Vecto
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -