diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-03-31 12:23:35 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-03-31 12:23:35 +0200 |
| commit | 4431ef7736587e490c6c122038f4203bb729b8e6 (patch) | |
| tree | 5d075f11d2f028c983e9aef2855ef0c13f2b7e1e /src | |
| parent | 4c86c8c2647fc9d88e2c7b847d62fb30f765b597 (diff) | |
| download | box64-4431ef7736587e490c6c122038f4203bb729b8e6.tar.gz box64-4431ef7736587e490c6c122038f4203bb729b8e6.zip | |
Added 66 0F 3A 08/09 opcodes ([ARM64_DYNAREC] too)
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64/arm64_emitter.h | 4 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_660f.c | 34 | ||||
| -rw-r--r-- | src/emu/x64run660f.c | 56 |
3 files changed, 94 insertions, 0 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h index 0cd9888e..7d6b76cd 100755 --- a/src/dynarec/arm64/arm64_emitter.h +++ b/src/dynarec/arm64/arm64_emitter.h @@ -1301,6 +1301,10 @@ #define VFRINTIS(Vd,Vn) EMIT(FRINT_vector(0, 1, 1, 0, 1, Vn, Vd)) #define VFRINTISQ(Vd,Vn) EMIT(FRINT_vector(1, 1, 1, 0, 1, Vn, Vd)) #define VFRINTIDQ(Vd,Vn) EMIT(FRINT_vector(1, 1, 1, 1, 1, Vn, Vd)) +// round with mode, mode is 0 = TieEven, 1=+inf, 2=-inf, 3=zero +#define VFRINTRDQ(Vd,Vn, mode) EMIT(FRINT_vector(1, 0, ((mode)>>1)&1, 1, (mode)&1, Vn, Vd)) +// round with mode, mode is 0 = TieEven, 1=+inf, 2=-inf, 3=zero +#define VFRINTRSQ(Vd,Vn, mode) EMIT(FRINT_vector(1, 0, ((mode)>>1)&1, 0, (mode)&1, Vn, Vd)) #define FRINTI_scalar(type, Rn, Rd) (0b11110<<24 | (type)<<22 | 1<<21 | 0b001<<18 | 0b111<<15 | 0b10000<<10 | (Rn)<<5 | (Rd)) #define FRINTIS(Sd, Sn) EMIT(FRINTI_scalar(0b00, Sn, Sd)) diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c index f703ac09..71ee97f2 100755 --- a/src/dynarec/arm64/dynarec_arm64_660f.c +++ b/src/dynarec/arm64/dynarec_arm64_660f.c @@ -670,6 +670,40 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n case 0x3A: // these are some more SSSE3+ opcodes opcode = F8; switch(opcode) { + case 0x08: + INST_NAME("ROUNDPS Gx, Ex, Ib"); + nextop = F8; + GETEX(q1, 0, 1); + GETGX_empty(q0); + u8 = F8; + v1 = fpu_get_scratch(dyn); + if(u8&4) { + u8 = sse_setround(dyn, ninst, x1, x2, x3); + VFRINTISQ(q0, q1); + x87_restoreround(dyn, ninst, u8); + } else { + const uint8_t rounds[] = {0, 2, 1, 3}; + MAYUSE(rounds); + VFRINTRSQ(q0, q1, rounds[u8&3]); + } + break; + case 0x09: + INST_NAME("ROUNDPD Gx, Ex, Ib"); + nextop = F8; + GETEX(q1, 0, 1); + GETGX_empty(q0); + u8 = F8; + v1 = fpu_get_scratch(dyn); + if(u8&4) { + u8 = sse_setround(dyn, ninst, x1, x2, x3); + VFRINTIDQ(q0, q1); + x87_restoreround(dyn, ninst, u8); + } else { + const uint8_t rounds[] = {0, 2, 1, 3}; + MAYUSE(rounds); + VFRINTRDQ(q0, q1, rounds[u8&3]); + } + break; case 0x0A: INST_NAME("ROUNDSS Gx, Ex, Ib"); nextop = F8; diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c index 178cd107..4db88fbc 100644 --- a/src/emu/x64run660f.c +++ b/src/emu/x64run660f.c @@ -703,6 +703,62 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr) case 0x3A: // these are some SSE3 & SSE4.x opcodes opcode = F8; switch(opcode) { + case 0x08: // ROUNDPS Gx, Ex, u8 + nextop = F8; + GETEX(1); + GETGX; + tmp8u = F8; // ignoring bit 3 interupt thingy + if(tmp8u&4) + tmp8u = emu->mxcsr.f.MXCSR_RC; + else + tmp8u &= 3; + switch(tmp8u) { + case ROUND_Nearest: + for(int i=0; i<4; ++i) + GX->f[i] = nearbyintf(EX->f[i]); + break; + case ROUND_Down: + for(int i=0; i<4; ++i) + GX->f[i] = floorf(EX->f[i]); + break; + case ROUND_Up: + for(int i=0; i<4; ++i) + GX->f[i] = ceilf(EX->f[i]); + break; + case ROUND_Chop: + for(int i=0; i<4; ++i) + GX->f[i] = EX->f[i]; + break; + } + break; + case 0x09: // ROUNDPD Gx, Ex, u8 + nextop = F8; + GETEX(1); + GETGX; + tmp8u = F8; // ignoring bit 3 interupt thingy + if(tmp8u&4) + tmp8u = emu->mxcsr.f.MXCSR_RC; + else + tmp8u &= 3; + switch(tmp8u) { + case ROUND_Nearest: + GX->d[0] = nearbyint(EX->d[0]); + GX->d[1] = nearbyint(EX->d[1]); + break; + case ROUND_Down: + GX->d[0] = floor(EX->d[0]); + GX->d[1] = floor(EX->d[1]); + break; + case ROUND_Up: + GX->d[0] = ceil(EX->d[0]); + GX->d[1] = ceil(EX->d[1]); + break; + case ROUND_Chop: + GX->d[0] = EX->d[0]; + GX->d[1] = EX->d[1]; + break; + } + break; case 0x0A: // ROUNDSS Gx, Ex, u8 nextop = F8; GETEX(1); |