about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-03-31 12:23:35 +0200
committerptitSeb <sebastien.chev@gmail.com>2023-03-31 12:23:35 +0200
commit4431ef7736587e490c6c122038f4203bb729b8e6 (patch)
tree5d075f11d2f028c983e9aef2855ef0c13f2b7e1e /src
parent4c86c8c2647fc9d88e2c7b847d62fb30f765b597 (diff)
downloadbox64-4431ef7736587e490c6c122038f4203bb729b8e6.tar.gz
box64-4431ef7736587e490c6c122038f4203bb729b8e6.zip
Added 66 0F 3A 08/09 opcodes ([ARM64_DYNAREC] too)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64/arm64_emitter.h4
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_660f.c34
-rw-r--r--src/emu/x64run660f.c56
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);