about summary refs log tree commit diff stats
path: root/src/dynarec
diff options
context:
space:
mode:
authorkaixindeken <ra.zhang@hl-it.cn>2024-04-12 14:06:45 +0800
committerGitHub <noreply@github.com>2024-04-12 08:06:45 +0200
commitf94ab1be6f23d4aeb6d1584b267d7620247a4953 (patch)
tree16b8f56b6233a10031db535efff501b8089a0fb7 /src/dynarec
parent05c7596acb15fefe1b5010ddd07cc154aa8a0b78 (diff)
downloadbox64-f94ab1be6f23d4aeb6d1584b267d7620247a4953.tar.gz
box64-f94ab1be6f23d4aeb6d1584b267d7620247a4953.zip
[RV64_DYNAREC] Implementation of some CRC32 instructions (#1435)
* [RV64_Dynarec] Implementation of some CRC32 instructions

* Use BEXTI to detect the lowest bit

* Prefer ANDI for lowest bit checking
Diffstat (limited to 'src/dynarec')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66f20f.c25
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f20f.c34
2 files changed, 58 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_66f20f.c b/src/dynarec/rv64/dynarec_rv64_66f20f.c
index cf377f46..949270b3 100644
--- a/src/dynarec/rv64/dynarec_rv64_66f20f.c
+++ b/src/dynarec/rv64/dynarec_rv64_66f20f.c
@@ -51,6 +51,31 @@ uintptr_t dynarec64_66F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, in
     static const int8_t round_round[] = { RD_RNE, RD_RDN, RD_RUP, RD_RTZ };
 
     switch (opcode) {
+        case 0x38:  // these are some more SSSE4.2+ opcodes
+            opcode = F8;
+            switch(opcode) {
+                case 0xF1:  // CRC32 Gd, Ew
+                    INST_NAME("CRC32 Gd, Ew");
+                    nextop = F8;
+                    GETGD;
+                    GETEW(x1, 0);
+                    MOV32w(x2, 0x82f63b78);
+                    for(int j=0; j<2; ++j) {
+                        SRLI(x5, ed, 8*j);
+                        ANDI(x3, x5, 0xFF);
+                        XOR(gd, gd, x3);
+                        for (int i = 0; i < 8; i++) {
+                            SRLI((i&1)?gd:x4, (i&1)?x4:gd, 1);
+                            ANDI(x6, (i&1)?x4:gd, 1);
+                            BEQZ(x6, 4+4);
+                            XOR((i&1)?gd:x4, (i&1)?gd:x4, x2);
+                        }
+                    }
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
         default:
             DEFAULT;
     }
diff --git a/src/dynarec/rv64/dynarec_rv64_f20f.c b/src/dynarec/rv64/dynarec_rv64_f20f.c
index 2d063aba..dfa4adc5 100644
--- a/src/dynarec/rv64/dynarec_rv64_f20f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f20f.c
@@ -28,7 +28,7 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
     uint8_t opcode = F8;
     uint8_t nextop;
     uint8_t gd, ed;
-    uint8_t wback, gback;
+    uint8_t wb1, wback, wb2, gback;
     uint8_t u8;
     uint64_t u64, j64;
     int v0, v1;
@@ -147,6 +147,38 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             opcode = F8;
             switch(opcode) {
 
+                case 0xF0:  // CRC32 Gd, Eb
+                    INST_NAME("CRC32 Gd, Eb");
+                    nextop = F8;
+                    GETEB(x1, 0);
+                    GETGD;
+                    XOR(gd, gd, ed);
+                    MOV32w(x2, 0x82f63b78);
+                    for (int i = 0; i < 8; i++) {
+                        SRLI((i&1)?gd:x4, (i&1)?x4:gd, 1);
+                        ANDI(x6, (i&1)?x4:gd, 1);
+                        BEQZ(x6, 4+4);
+                        XOR((i&1)?gd:x4, (i&1)?gd:x4, x2);
+                    }
+                    break;
+                case 0xF1:  // CRC32 Gd, Ed
+                    INST_NAME("CRC32 Gd, Ed");
+                    nextop = F8;
+                    GETGD;
+                    GETED(0);
+                    MOV32w(x2, 0x82f63b78);
+                    for(int j=0; j<4*(rex.w+1); ++j) {
+                        SRLI(x5, ed, 8*j);
+                        ANDI(x3, x5, 0xFF);
+                        XOR(gd, gd, x3);
+                        for (int i = 0; i < 8; i++) {
+                            SRLI((i&1)?gd:x4, (i&1)?x4:gd, 1);
+                            ANDI(x6, (i&1)?x4:gd, 1);
+                            BEQZ(x6, 4+4);
+                            XOR((i&1)?gd:x4, (i&1)?gd:x4, x2);
+                        }
+                    }
+                    break;
                 default:
                     DEFAULT;
             }