about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorwannacu <wannacu2049@gmail.com>2023-08-07 16:51:16 +0800
committerwannacu <wannacu2049@gmail.com>2023-08-07 17:07:31 +0800
commit3308cc60e9ef645a6675ae993c82d4aa68dbcebf (patch)
treed62ce13dac4ace30c5788b2ac8a02f7ac6bcf324 /src
parente4b235378be84f434928fd5fbaa634e1da0b7edd (diff)
downloadbox64-3308cc60e9ef645a6675ae993c82d4aa68dbcebf.tar.gz
box64-3308cc60e9ef645a6675ae993c82d4aa68dbcebf.zip
[RV64_DYNAREC] Added movbe opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_660f.c32
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c127
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c38
-rw-r--r--src/dynarec/rv64/rv64_emitter.h2
-rw-r--r--src/emu/x64run660f.c13
5 files changed, 210 insertions, 2 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c
index b4aa13fa..9f30df50 100644
--- a/src/dynarec/arm64/dynarec_arm64_660f.c
+++ b/src/dynarec/arm64/dynarec_arm64_660f.c
@@ -747,7 +747,37 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                         VEORQ(q0, q0, q1);

                     }

                     break;

-

+                case 0xF0:

+                    INST_NAME("MOVBE Gw, Ew");

+                    nextop=F8;

+                    gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3);

+                    if(MODREG) {

+                        ed = xRAX+(nextop&7)+(rex.b<<3);

+                        REV16x(x1, ed);

+                        BFIx(gd, x1, 0, 16);

+                    } else {

+                        SMREAD();

+                        addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0);

+                        LDH(x1, ed, fixedaddress);

+                        REV16x(x1, x1);

+                        BFIx(gd, x1, 0, 16);

+                    }

+                    break;

+                case 0xF1:

+                    INST_NAME("MOVBE Ew, Gw");

+                    nextop=F8;

+                    gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3);

+                    if(MODREG) {

+                        ed = xRAX+(nextop&7)+(rex.b<<3);

+                        REV16x(x1, gd);

+                        BFIx(ed, x1, 0, 16);

+                    } else {

+                        SMREAD();

+                        addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0);

+                        REV16x(x1, gd);

+                        STH(x1, ed, fixedaddress);

+                    }

+                    break;

                 default:

                     DEFAULT;

             }

diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 5c8d7b81..10c3e63d 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -316,7 +316,134 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             SRLI(xRDX, x3, 32);
             AND(xRAX, x3, 32);   // wipe upper part
             break;
+        case 0x38:
+            //SSE3
+            nextop=F8;
+            switch(nextop) {
+                case 0xF0:
+                    INST_NAME("MOVBE Gd, Ed");
+                    nextop=F8;
+                    GETGD;
+                    SMREAD();
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                    LDxw(gd, ed, fixedaddress);
+                    if (rv64_zbb) {
+                        REV8(gd, gd);
+                        if (!rex.w) {
+                            SRLI(gd, gd, 32);
+                        }
+                    } else {
+                        if (rex.w) {
+                            LI(x2, 0xff);
+                            SLLI(x1, gd, 56);
+                            SRLI(x3, gd, 56);
+                            SRLI(x4, gd, 40);
+                            SLLI(x2, x2, 8);
+                            AND(x4, x4, x2);
+                            OR(x1, x1, x3);
+                            OR(x1, x1, x4);
+                            SLLI(x3, gd, 40);
+                            SLLI(x4, x2, 40);
+                            AND(x3, x3, x4);
+                            OR(x1, x1, x3);
+
+                            SRLI(x3, gd, 24);
+                            SLLI(x4, x2, 8);
+                            AND(x3, x3, x4);
+                            OR(x1, x1, x3);
+                            SLLI(x3, gd, 24);
+                            SLLI(x4, x2, 32);
+                            AND(x3, x3, x4);
+                            OR(x1, x1, x3);
+
+                            SRLI(x3, gd, 8);
+                            SLLI(x4, x2, 16);
+                            AND(x3, x3, x4);
+                            OR(x1, x1, x3);                     
+                            SLLI(x3, gd, 8);
+                            SLLI(x4, x2, 24);
+                            AND(x3, x3, x4);
+                            OR(gd, x1, x3);
+                        } else {
+                            LI(x2, 0xff);
+                            SLLIW(x2, x2, 8);
+                            SLLIW(x1, gd, 24);
+                            SRLIW(x3, gd, 24);
+                            SRLIW(x4, gd, 8);
+                            AND(x4, x4, x2);
+                            OR(x1, x1, x3);
+                            OR(x1, x1, x4);
+                            SLLIW(gd, gd, 8);
+                            LUI(x2, 0xff0);
+                            AND(gd, gd, x2);
+                            OR(gd, gd, x1);
+                        }                        
+                    }
+                    break;
+                case 0xF1:
+                    INST_NAME("MOVBE Ed, Gd");
+                    nextop=F8;
+                    GETGD;
+                    SMREAD();
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                    if (rv64_zbb) {
+                        REV8(x1, gd);
+                        if (!rex.w) {
+                            SRLI(x1, x1, 32);
+                        }
+                    } else {
+                        if (rex.w) {
+                            LI(x2, 0xff);
+                            SLLI(x1, gd, 56);
+                            SRLI(x3, gd, 56);
+                            SRLI(x4, gd, 40);
+                            SLLI(x2, x2, 8);
+                            AND(x4, x4, x2);
+                            OR(x1, x1, x3);
+                            OR(x1, x1, x4);
+                            SLLI(x3, gd, 40);
+                            SLLI(x4, x2, 40);
+                            AND(x3, x3, x4);
+                            OR(x1, x1, x3);
 
+                            SRLI(x3, gd, 24);
+                            SLLI(x4, x2, 8);
+                            AND(x3, x3, x4);
+                            OR(x1, x1, x3);
+                            SLLI(x3, gd, 24);
+                            SLLI(x4, x2, 32);
+                            AND(x3, x3, x4);
+                            OR(x1, x1, x3);
+
+                            SRLI(x3, gd, 8);
+                            SLLI(x4, x2, 16);
+                            AND(x3, x3, x4);
+                            OR(x1, x1, x3);                     
+                            SLLI(x3, gd, 8);
+                            SLLI(x4, x2, 24);
+                            AND(x3, x3, x4);
+                            OR(x1, x1, x3);
+                        } else {
+                            LI(x2, 0xff);
+                            SLLIW(x2, x2, 8);
+                            SLLIW(x1, gd, 24);
+                            SRLIW(x3, gd, 24);
+                            SRLIW(x4, gd, 8);
+                            AND(x4, x4, x2);
+                            OR(x1, x1, x3);
+                            OR(x1, x1, x4);
+                            SLLIW(x3, gd, 8);
+                            LUI(x2, 0xff0);
+                            AND(x3, x3, x2);
+                            OR(x1, x1, x3);
+                        }
+                    }
+                    SDxw(x1, wback, fixedaddress);
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
 
         #define GO(GETFLAGS, NO, YES, F)            \
             READFLAGS(F);                           \
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index 86bf0dbe..c60d214d 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -715,6 +715,44 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     GETEX(x2, 0);
                     SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4));
                     break;
+                case 0xF0:
+                    INST_NAME("MOVBE Gw, Ew");
+                    nextop=F8;
+                    GETGD;
+                    SMREAD();
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 1);
+                    LHU(x1, ed, fixedaddress);
+                    if (rv64_zbb) {
+                        REV8(x1, x1);
+                        SRLI(x1, x1, 48);
+                    } else {
+                        ANDI(x2, x1, 0xff);
+                        SLLI(x2, x2, 8);
+                        SRLI(x1, x1, 8);
+                        OR(x1, x1, x2);
+                    }
+                    LUI(x2, 0xffff0);
+                    AND(gd, gd, x2);
+                    OR(gd, gd, x1);                    
+                    break;
+                case 0xF1:
+                    INST_NAME("MOVBE Ew, Gw");
+                    nextop=F8;
+                    GETGD;
+                    SMREAD();
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 0, 1);  
+                    if (rv64_zbb) {
+                        REV8(x1, gd);
+                        SRLI(x1, x1, 48);
+                    } else {
+                        ANDI(x1, gd, 0xff);
+                        SLLI(x1, x1, 8);
+                        SRLI(x2, gd, 8);
+                        ANDI(x2, x2, 0xff);
+                        OR(x1, x1, x2);
+                    }
+                    SH(x1, wback, fixedaddress);
+                    break;
                 default:
                     DEFAULT;
             }
diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h
index e9fa2f6d..6a5dd4bd 100644
--- a/src/dynarec/rv64/rv64_emitter.h
+++ b/src/dynarec/rv64/rv64_emitter.h
@@ -128,6 +128,8 @@ f28–31  ft8–11  FP temporaries                  Caller
 // RV32I
 // put imm20 in the [31:12] bits of rd, zero [11:0] and sign extend bits31
 #define LUI(rd, imm20)                 EMIT(U_type((imm20)<<12, rd, 0b0110111))
+
+#define LI(rd, imm12)                  if (imm12 < 0x800) { ADDI(rd, xZR, imm12);} else {LUI(rd, 1); ADDIW(rd, rd, -(0x1000 - imm12));}
 // put PC+imm20 in rd
 #define AUIPC(rd, imm20)               EMIT(U_type((imm20)<<12, rd, 0b0010111))
 
diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c
index 3083b7b0..902772e5 100644
--- a/src/emu/x64run660f.c
+++ b/src/emu/x64run660f.c
@@ -788,7 +788,18 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
                 GX->q[0] ^= EX->q[0];

                 GX->q[1] ^= EX->q[1];

                 break;

-

+            case 0xF0: /* MOVBE Gw, Ew */

+                nextop = F8;

+                GETEX(0);

+                GETGX;

+                GX->uw[0] = __builtin_bswap16(EX->uw[0]);

+                break;

+            case 0xF1: /* MOVBE Ew, Gw */

+                nextop = F8;

+                GETEX(0);

+                GETGX;

+                EX->uw[0] = __builtin_bswap16(GX->uw[0]);

+                break;

             default:

                 return 0;

         }