about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_emit_shift.c4
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h58
-rw-r--r--src/dynarec/rv64/rv64_emitter.h63
3 files changed, 103 insertions, 22 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_emit_shift.c b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
index 7030c674..80dea7a9 100644
--- a/src/dynarec/rv64/dynarec_rv64_emit_shift.c
+++ b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
@@ -421,6 +421,8 @@ void emit_rol32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
     }
     if(rv64_zbb) {
         RORIxw(s1, s1, (rex.w?64:32)-c);
+    } else if (rv64_xtheadbb) {
+        TH_SRRIxw(s1, s1, (rex.w?64:32)-c);
     } else {
         SLLIxw(s3, s1, c);
         SRLIxw(s1, s1, (rex.w?64:32)-c);
@@ -466,6 +468,8 @@ void emit_ror32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
     }
     if(rv64_zbb) {
         RORIxw(s1, s1, c);
+    } else if (rv64_xtheadbb) {
+        TH_SRRIxw(s1, s1, c);
     } else {
         SRLIxw(s3, s1, c);
         SLLIxw(s1, s1, (rex.w?64:32)-c);
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 51d7817f..04a20308 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -210,7 +210,15 @@
                         wb2 = (wback>>2)*8;     \
                         wback = xRAX+(wback&3); \
                     }                           \
-                    if (wb2) {MV(i, wback); SRLI(i, i, wb2); ANDI(i, i, 0xff);} else {ANDI(i, wback, 0xff);}   \
+                    if (wb2) {                  \
+                        if (rv64_xtheadbb) {    \
+                            TH_EXTU(i, wback, 15, 8);   \
+                        } else {                \
+                            MV(i, wback);       \
+                            SRLI(i, i, wb2);    \
+                            ANDI(i, i, 0xff);   \
+                        }                       \
+                    } else ANDI(i, wback, 0xff);\
                     wb1 = 0;                    \
                     ed = i;                     \
                 } else {                        \
@@ -230,7 +238,15 @@
                         wb2 = (wback>>2)*8;     \
                         wback = xRAX+(wback&3); \
                     }                           \
-                    if (wb2) {MV(i, wback); SRLI(i, i, wb2); ANDI(i, i, 0xff);} else {ANDI(i, wback, 0xff);}   \
+                    if (wb2) {                  \
+                        if (rv64_xtheadbb) {    \
+                            TH_EXTU(i, wback, 15, 8);   \
+                        } else {                \
+                            MV(i, wback);       \
+                            SRLI(i, i, wb2);    \
+                            ANDI(i, i, 0xff);   \
+                        }                       \
+                    } else ANDI(i, wback, 0xff);\
                     wb1 = 0;                    \
                     ed = i;                     \
                 } else {                        \
@@ -274,7 +290,15 @@
                         wb2 = (wback>>2)*8;     \
                         wback = xRAX+(wback&3); \
                     }                           \
-                    if (wb2) {MV(i, wback); SRLI(i, i, wb2); ANDI(i, i, 0xff);} else {ANDI(i, wback, 0xff);}   \
+                    if (wb2) {                  \
+                        if (rv64_xtheadbb) {    \
+                            TH_EXTU(i, wback, 15, 8);   \
+                        } else {                \
+                            MV(i, wback);       \
+                            SRLI(i, i, wb2);    \
+                            ANDI(i, i, 0xff);   \
+                        }                       \
+                    } else ANDI(i, wback, 0xff);\
                     wb1 = 0;                    \
                     ed = i;                     \
                 } else {                        \
@@ -286,16 +310,24 @@
                 }
 
 //GETGB will use i for gd
-#define GETGB(i) if(rex.rex) {                                \
-                    gb1 = xRAX+((nextop&0x38)>>3)+(rex.r<<3); \
-                    gb2 = 0;                                  \
-                } else {                                      \
-                    gd = (nextop&0x38)>>3;                    \
-                    gb2 = ((gd&4)>>2);                        \
-                    gb1 = xRAX+(gd&3);                        \
-                }                                             \
-                gd = i;                                       \
-                if (gb2) {MV(gd, gb1); SRLI(gd, gd, 8); ANDI(gd, gd, 0xff);} else {ANDI(gd, gb1, 0xff);}
+#define GETGB(i) if(rex.rex) {  \
+                    gb1 = xRAX+((nextop&0x38)>>3)+(rex.r<<3);   \
+                    gb2 = 0;                    \
+                } else {                        \
+                    gd = (nextop&0x38)>>3;      \
+                    gb2 = ((gd&4)>>2);          \
+                    gb1 = xRAX+(gd&3);          \
+                }                               \
+                gd = i;                         \
+                if (gb2) {                      \
+                    if (rv64_xtheadbb) {        \
+                        TH_EXTU(gd, gb1, 15, 8);\
+                    } else {                    \
+                        MV(gd, gb1);            \
+                        SRLI(gd, gd, 8);        \
+                        ANDI(gd, gd, 0xff);     \
+                    }                           \
+                } else ANDI(gd, gb1, 0xff);
 
 // Write gb (gd) back to original register / memory, using s1 as scratch
 #define GBBACK(s1) if(gb2) {                            \
diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h
index 4eebb353..1caebc90 100644
--- a/src/dynarec/rv64/rv64_emitter.h
+++ b/src/dynarec/rv64/rv64_emitter.h
@@ -673,19 +673,64 @@ f28–31  ft8–11  FP temporaries                  Caller
 
 // XTheadBb - Basic bit-manipulation
 
+#define TH_SRRIxw(rd, rs1, imm) if(rex.w) { \
+        TH_SRRI(rd, rs1, imm);  \
+    } else {                    \
+        TH_SRRIW(rd, rs1, imm); \
+    }
+
 // Perform a cyclic right shift.
 // reg[rd] := (reg[rs1] >> imm6) | (reg[rs1] << (xlen - imm6))
 #define TH_SRRI(rd, rs1, imm6) EMIT(I_type(0b000100000000|(imm6&0x3f), rs1, 0b001, rd, 0b0001011))
 
-// TODO
-// th.srriw rd, rs1, imm5 Cyclic right shift on word operand
-// th.ext rd, rs1, imm1, imm2 Extract and sign-extend bits
-// th.extu rd, rs1, imm1, imm2 Extract and zero-extend bits
-// th.ff0 rd, rs1 Find first '0'-bit
-// th.ff1 rd, rs1 Find first '1'-bit
-// th.rev rd, rs1 Reverse byte order
-// th.revw rd, rs1 Reverse byte order of word operand
-// th.tstnbz rd, rs1 Test for NUL bytes
+// Perform a cyclic right shift on word operand.
+// data := zext.w(reg[rs1])
+// reg[rd] := (data >> imm5) | (data << (32 - imm5))
+#define TH_SRRIW(rd, rs1, imm5) EMIT(I_type(0b000101000000|(imm5&0x1f), rs1, 0b001, rd, 0b0001011))
+
+// Extract and sign-extend bits.
+// reg[rd] := sign_extend(reg[rs1][imm1:imm2])
+#define TH_EXT(rd, rs1, imm1, imm2) EMIT(I_type(((imm1&0x1f)<<6)|(imm2&0x1f), rs1, 0b010, rd, 0b0001011))
+
+// Extract and zero-extend bits.
+// reg[rd] := zero_extend(reg[rs1][imm1:imm2])
+#define TH_EXTU(rd, rs1, imm1, imm2) EMIT(I_type(((imm1&0x1f)<<6)|(imm2&0x1f), rs1, 0b011, rd, 0b0001011))
+
+// Find first '0'-bit
+// for i=xlen..0:
+//   if reg[rs1][i] == 0:
+//     break;
+// reg[rd] = (xlen - 1) - i
+#define TH_FF0(rd, rs1) EMIT(I_type(0b100001000000, rs1, 0b001, rd, 0b0001011))
+
+// Find first '1'-bit
+// for i=xlen..0:
+//   if reg[rs1][i] == 1:
+//     break;
+// reg[rd] = (xlen - 1) - i
+#define TH_FF1(rd, rs1) EMIT(I_type(0b100001100000, rs1, 0b001, rd, 0b0001011))
+
+// Reverse the byte order.
+// for i=0..(xlen/8-1):
+//   j := xlen/8 - 1 - i
+//   tmp[i] := reg[rs1][j]
+// reg[rd] := tmp
+#define TH_REV(rd, rs1) EMIT(I_type(0b100000100000, rs1, 0b001, rd, 0b0001011))
+
+// Reverse the byte order of a word operand.
+// for i=0..3:
+//   j := 3 - i
+//   tmp[i] := reg[rs1][j]
+// reg[rd] := tmp
+#define TH_REVW(rd, rs1) EMIT(I_type(0b100100000000, rs1, 0b001, rd, 0b0001011))
+
+// Test for NUL bytes.
+// for i=0..(xlen/8-1):
+//   if reg[rs1][i] == 0:
+//     reg[rd][i] := 0xff
+//   else
+//     reg[rd][i] := 0
+#define TH_TSTNBZ(rd, rs1) EMIT(I_type(0b1000000000000, rs1, 0b001, rd, 0b0001011))
 
 // XTheadBs - Single-bit instructions