diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-05-28 16:50:51 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-05-28 16:50:51 +0200 |
| commit | 4e0889469af7784edff2d102e4bfcb1165f81898 (patch) | |
| tree | b5a081996e063e79b0c6e2ee54847ef3f9884acb | |
| parent | 7c5bf62fc0747bdda15d58798d6a5f59a18f2a41 (diff) | |
| download | box64-4e0889469af7784edff2d102e4bfcb1165f81898.tar.gz box64-4e0889469af7784edff2d102e4bfcb1165f81898.zip | |
[INTERPRETER] Even more avx/avx2 opcodes, and a fix for android builds
| -rw-r--r-- | src/emu/x64emu.c | 5 | ||||
| -rw-r--r-- | src/emu/x64runavx660f.c | 135 | ||||
| -rw-r--r-- | src/emu/x64runavx660f38.c | 36 | ||||
| -rw-r--r-- | src/emu/x64runavx660f3a.c | 18 | ||||
| -rw-r--r-- | src/emu/x64runavxf20f.c | 90 | ||||
| -rw-r--r-- | src/emu/x64runavxf30f.c | 5 |
6 files changed, 285 insertions, 4 deletions
diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index f19b6e73..10507768 100644 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -428,7 +428,10 @@ const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip, int is32bits) } strcat(buff, tmp); } - if ((i&3)==3) strcat(buff, "\n"); else strcat(buff, " "); + if(box64_avx) + if ((i&1)==1) strcat(buff, "\n"); else strcat(buff, " "); + else + if ((i&3)==3) strcat(buff, "\n"); else strcat(buff, " "); } } #endif diff --git a/src/emu/x64runavx660f.c b/src/emu/x64runavx660f.c index c8f23596..b851fde4 100644 --- a/src/emu/x64runavx660f.c +++ b/src/emu/x64runavx660f.c @@ -545,6 +545,126 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) } break; + case 0x7C: /* VHADDPD Gx, Vx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + GETEY; + if(GX==EX) { + eax1 = *EX; + EX = &eax1; + } + #ifndef NOALIGN + is_nan = isnan(VX->d[0]) || isnan(VX->d[1]); + #endif + GX->d[0] = VX->d[0] + VX->d[1]; + #ifndef NOALIGN + if(!is_nan && isnan(GX->d[0])) + GX->d[0] = -NAN; + #endif + if(EX==VX) { + GX->d[1] = GX->d[0]; + } else { + #ifndef NOALIGN + is_nan = isnan(EX->d[0]) || isnan(EX->d[1]); + #endif + GX->d[1] = EX->d[0] + EX->d[1]; + #ifndef NOALIGN + if(!is_nan && isnan(GX->d[1])) + GX->d[1] = -NAN; + #endif + } + if(vex.l) { + if(GY==EY) { + eay1 = *EY; + EY = &eay1; + } + GETVY; + #ifndef NOALIGN + is_nan = isnan(VY->d[0]) || isnan(VY->d[1]); + #endif + GY->d[0] = VY->d[0] + VY->d[1]; + #ifndef NOALIGN + if(!is_nan && isnan(GY->d[0])) + GY->d[0] = -NAN; + #endif + if(EY==VY) { + GY->d[1] = GY->d[0]; + } else { + #ifndef NOALIGN + is_nan = isnan(EY->d[0]) || isnan(EY->d[1]); + #endif + GY->d[1] = EY->d[0] + EY->d[1]; + #ifndef NOALIGN + if(!is_nan && isnan(GY->d[1])) + GY->d[1] = -NAN; + #endif + } + } else + GY->u128 = 0; + break; + case 0x7D: /* VHSUBPD Gx, Vx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + GETEY; + if(GX==EX) { + eax1 = *EX; + EX = &eax1; + } + #ifndef NOALIGN + is_nan = isnan(VX->d[0]) || isnan(VX->d[1]); + #endif + GX->d[0] = VX->d[0] - VX->d[1]; + #ifndef NOALIGN + if(!is_nan && isnan(GX->d[0])) + GX->d[0] = -NAN; + #endif + if(EX==VX) { + GX->d[1] = GX->d[0]; + } else { + #ifndef NOALIGN + is_nan = isnan(EX->d[0]) || isnan(EX->d[1]); + #endif + GX->d[1] = EX->d[0] - EX->d[1]; + #ifndef NOALIGN + if(!is_nan && isnan(GX->d[1])) + GX->d[1] = -NAN; + #endif + } + if(vex.l) { + if(GY==EY) { + eay1 = *EY; + EY = &eay1; + } + GETVY; + #ifndef NOALIGN + is_nan = isnan(VY->d[0]) || isnan(VY->d[1]); + #endif + GY->d[0] = VY->d[0] - VY->d[1]; + #ifndef NOALIGN + if(!is_nan && isnan(GY->d[0])) + GY->d[0] = -NAN; + #endif + if(EY==VY) { + GY->d[1] = GY->d[0]; + } else { + #ifndef NOALIGN + is_nan = isnan(EY->d[0]) || isnan(EY->d[1]); + #endif + GY->d[1] = EY->d[0] - EY->d[1]; + #ifndef NOALIGN + if(!is_nan && isnan(GY->d[1])) + GY->d[1] = -NAN; + #endif + } + } else + GY->u128 = 0; + break; case 0x7E: /* VMOVD Ed, Gx */ nextop = F8; GETED(0); @@ -714,6 +834,21 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) break; + case 0xF7: /* VMASKMOVDQU Gx, Ex */ + nextop = F8; + if(vex.l) { + emit_signal(emu, SIGILL, (void*)R_RIP, 0); + } + GETEX(0); + GETGX; + VX = (sse_regs_t *)(R_RDI); + for (int i=0; i<16; ++i) { + if(EX->ub[i]&0x80) + VX->ub[i] = GX->ub[i]; + } + // no raz of upper ymm + break; + default: return 0; } diff --git a/src/emu/x64runavx660f38.c b/src/emu/x64runavx660f38.c index ae6d1cbf..b6074146 100644 --- a/src/emu/x64runavx660f38.c +++ b/src/emu/x64runavx660f38.c @@ -207,20 +207,50 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) } else GY->u128 = 0; break; - + case 0x2D: /*VMASKMOVPD Gx, Vx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + for(int i=0; i<2; ++i) + GX->q[i] = (VX->q[i]>>63)?EX->q[i]:0; + if(vex.l) { + GETEY; + GETVY; + for(int i=0; i<2; ++i) + GY->q[i] = (VY->q[i]>>63)?EY->q[i]:0; + } else + GY->u128 = 0; + break; case 0x2E: /*VMASKMOVPS Ex, Vx, Gx */ nextop = F8; GETEX(0); GETGX; GETVX; for(int i=0; i<4; ++i) - EX->ud[i] = (VX->ud[i]>>31)?GX->ud[i]:0; + if(VX->ud[i]>>31) EX->ud[i] = GX->ud[i]; if(vex.l) { GETGY; GETEY; GETVY; for(int i=0; i<4; ++i) - EY->ud[i] = (VY->ud[i]>>31)?GY->ud[i]:0; + if(VY->ud[i]>>31) EY->ud[i] = GY->ud[i]; + } + break; + case 0x2F: /*VMASKMOVPD Ex, Vx, Gx */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + for(int i=0; i<2; ++i) + if(VX->q[i]>>63) EX->q[i] = GX->q[i]; + if(vex.l) { + GETGY; + GETEY; + GETVY; + for(int i=0; i<2; ++i) + if(VY->q[i]>>63) EY->q[i] = GY->q[i]; } break; diff --git a/src/emu/x64runavx660f3a.c b/src/emu/x64runavx660f3a.c index e09de6bf..63125974 100644 --- a/src/emu/x64runavx660f3a.c +++ b/src/emu/x64runavx660f3a.c @@ -226,6 +226,24 @@ uintptr_t RunAVX_660F3A(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GY->u128 = 0; break; + case 0x38: /* VINSERTI128 Gx, Ex, imm8 */ + nextop = F8; + GETEX(1); + GETGX; + GETVX; + GETGY; + GETVY; + tmp8u = F8; + if(tmp8u&1) { + GY->u128 = EX->u128; + if(GX!=VX); + GX->u128 = VX->u128; + } else { + GX->u128 = EX->u128; + if(GY!=VY) + GY->u128 = VY->u128; + } + break; case 0x39: /* VEXTRACTI128 Ex, Gx, Ib */ nextop = F8; GETGX; diff --git a/src/emu/x64runavxf20f.c b/src/emu/x64runavxf20f.c index fc51a3a4..1b0e6291 100644 --- a/src/emu/x64runavxf20f.c +++ b/src/emu/x64runavxf20f.c @@ -214,6 +214,83 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GY->u128 = 0; break; + case 0x7C: /* VHADDPS Gx, Vx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + GETEY; + if(GX==EX) { + eax1 = *EX; + EX = &eax1; + } + GX->f[0] = VX->f[0] + VX->f[1]; + GX->f[1] = VX->f[2] + VX->f[3]; + if(EX==VX) { + GX->f[2] = GX->f[0]; + GX->f[3] = GX->f[1]; + } else { + GX->f[2] = EX->f[0] + EX->f[1]; + GX->f[3] = EX->f[2] + EX->f[3]; + } + if(vex.l) { + if(GY==EY) { + eay1 = *EY; + EY = &eay1; + } + GETVY; + GY->f[0] = VY->f[0] + VY->f[1]; + GY->f[1] = VY->f[2] + VY->f[3]; + if(EY==VY) { + GY->f[2] = GY->f[0]; + GY->f[3] = GY->f[1]; + } else { + GY->f[2] = EY->f[0] + EY->f[1]; + GY->f[3] = EY->f[2] + EY->f[3]; + } + } else + GY->u128 = 0; + break; + case 0x7D: /* VHSUBPS Gx, Vx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + GETEY; + if(GX==EX) { + eax1 = *EX; + EX = &eax1; + } + GX->f[0] = VX->f[0] - VX->f[1]; + GX->f[1] = VX->f[2] - VX->f[3]; + if(EX==VX) { + GX->f[2] = GX->f[0]; + GX->f[3] = GX->f[1]; + } else { + GX->f[2] = EX->f[0] - EX->f[1]; + GX->f[3] = EX->f[2] - EX->f[3]; + } + if(vex.l) { + if(GY==EY) { + eay1 = *EY; + EY = &eay1; + } + GETVY; + GY->f[0] = VY->f[0] - VY->f[1]; + GY->f[1] = VY->f[2] - VY->f[3]; + if(EY==VY) { + GY->f[2] = GY->f[0]; + GY->f[3] = GY->f[1]; + } else { + GY->f[2] = EY->f[0] - EY->f[1]; + GY->f[3] = EY->f[2] - EY->f[3]; + } + } else + GY->u128 = 0; + break; + case 0xC2: /* VCMPSD Gx, Vx, Ex, Ib */ nextop = F8; GETEX(1); @@ -334,6 +411,19 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GY->u128 = 0; break; + case 0xF0: /* VLDDQU Gx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETGY; + memcpy(GX, EX, 16); + if(vex.l) { + GETEY; + memcpy(GY, EY, 16); + } else + GY->u128 = 0; + break; + default: return 0; } diff --git a/src/emu/x64runavxf30f.c b/src/emu/x64runavxf30f.c index 9afb1c10..9afef5a8 100644 --- a/src/emu/x64runavxf30f.c +++ b/src/emu/x64runavxf30f.c @@ -30,6 +30,11 @@ #include "modrm.h" +#ifdef __clang__ +extern int isinff(float); +extern int isnanf(float); +#endif + #ifdef TEST_INTERPRETER uintptr_t TestAVX_F30F(x64test_t *test, vex_t vex, uintptr_t addr, int *step) #else |