about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-20 10:34:00 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-20 10:34:00 +0100
commitcc2016bbc9b6a68c730db2982e1060df250c7a97 (patch)
treeb056981f637b20749047a9bc82e958d5b69e4e50
parenta68be9117b1d8cc78e9e6ceea5f8236f074983c9 (diff)
downloadbox64-cc2016bbc9b6a68c730db2982e1060df250c7a97.tar.gz
box64-cc2016bbc9b6a68c730db2982e1060df250c7a97.zip
[DYNAREC] Added 66 D1/D3 opcodes
-rwxr-xr-xsrc/dynarec/arm64_emitter.h7
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_66.c103
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h2
4 files changed, 107 insertions, 7 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h
index 4d8c6ff3..5e72e4d8 100755
--- a/src/dynarec/arm64_emitter.h
+++ b/src/dynarec/arm64_emitter.h
@@ -210,9 +210,10 @@
 #define LDRB_REG(Rt, Rn, Rm)            EMIT(LDR_REG_gen(0b00, Rm, 0b011, 0, Rn, Rt))
 #define LDRH_REG(Rt, Rn, Rm)            EMIT(LDR_REG_gen(0b01, Rm, 0b011, 0, Rn, Rt))
 
-#define LDRSH_gen(size, op1, opc, imm9, op2, Rn, Rt)    ((size)<<30 | 0b111<<27 | (op1)<<24 | (opc)<<22 | (imm9)<<12 | (op2)<<10 | (Rn)<<5 | (Rt))
-#define LDRSHx_U12(Rt, Rn, imm12)           EMIT(LD_gen(0b01, 0b00, 0b10, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt))
-#define LDRSHw_U12(Rt, Rn, imm12)           EMIT(LD_gen(0b01, 0b00, 0b11, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt))
+#define LDRSH_gen(size, op1, opc, imm12, Rn, Rt)    ((size)<<30 | 0b111<<27 | (op1)<<24 | (opc)<<22 | (imm12)<<10 | (Rn)<<5 | (Rt))
+#define LDRSHx_U12(Rt, Rn, imm12)           EMIT(LDRSH_gen(0b01, 0b01, 0b10, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt))
+#define LDRSHw_U12(Rt, Rn, imm12)           EMIT(LDRSH_gen(0b01, 0b01, 0b11, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt))
+#define LDRSHxw_U12(Rt, Rn, imm12)          EMIT(LDRSH_gen(0b01, 0b01, rex.w?0b10:0b11, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt))
 
 #define LDR_PC_gen(opc, imm19, Rt)      ((opc)<<30 | 0b011<<27 | (imm19)<<5 | (Rt))
 #define LDRx_literal(Rt, imm19)         EMIT(LDR_PC_gen(0b01, ((imm19)>>2)&0x7FFFF, Rt))
diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c
index d0bb204c..fb1424de 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -283,7 +283,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;
 
         case 0x66:
-            addr = dynarec64_66(dyn, addr, ip, ninst, rex, ok, need_epilog);
+            addr = dynarec64_66(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
             break;
 
         case 0x68:
diff --git a/src/dynarec/dynarec_arm64_66.c b/src/dynarec/dynarec_arm64_66.c
index 3242b169..e2ad11e6 100755
--- a/src/dynarec/dynarec_arm64_66.c
+++ b/src/dynarec/dynarec_arm64_66.c
@@ -23,7 +23,7 @@
 #include "dynarec_arm64_functions.h"

 

 

-uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)

+uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)

 {

     uint8_t opcode = F8;

     uint8_t nextop, u8;

@@ -34,7 +34,6 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
     uint8_t gd, ed;

     uint8_t wback, wb1;

     int fixedaddress;

-    int rep;

     MAYUSE(u16);

     MAYUSE(u8);

     MAYUSE(j32);

@@ -61,6 +60,106 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             addr = dynarec64_660F(dyn, addr, ip, ninst, rex, ok, need_epilog);

             break;

 

+        case 0xD1:

+        case 0xD3:

+            nextop = F8;

+            switch((nextop>>3)&7) {

+                case 0:

+                    if(opcode==0xD1) {

+                        INST_NAME("ROL Ew, 1");

+                        MOV32w(x2, 1);

+                    } else {

+                        INST_NAME("ROL Ew, CL");

+                        ANDSw_mask(x2, xRCX, 0, 0b00100);

+                    }

+                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    GETEW(x1, 0);

+                    CALL_(rol16, x1, x3);

+                    EWBACK;

+                    break;

+                case 1:

+                    if(opcode==0xD1) {

+                        INST_NAME("ROR Ew, 1");

+                        MOV32w(x2, 1);

+                    } else {

+                        INST_NAME("ROR Ew, CL");

+                        ANDSw_mask(x2, xRCX, 0, 0b00100);

+                    }

+                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    GETEW(x1, 0);

+                    CALL_(ror16, x1, x3);

+                    EWBACK;

+                    break;

+                case 2:

+                    if(opcode==0xD1) {INST_NAME("RCL Ew, 1"); } else { INST_NAME("RCL Ew, CL");}

+                    READFLAGS(X_CF);

+                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);}

+                    GETEW(x1, 0);

+                    CALL_(rcl16, x1, x3);

+                    EWBACK;

+                    break;

+                case 3:

+                    if(opcode==0xD1) {INST_NAME("RCR Ew, 1");} else {INST_NAME("RCR Ew, CL");}

+                    READFLAGS(X_CF);

+                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);}

+                    GETEW(x1, 0);

+                    CALL_(rcr16, x1, x3);

+                    EWBACK;

+                    break;

+                case 4:

+                case 6:

+                    if(opcode==0xD1) {

+                        INST_NAME("SHL Ew, 1");

+                        MOV32w(x4, 1);

+                    } else {

+                        INST_NAME("SHL Ew, CL");

+                        ANDSw_mask(x4, xRCX, 0, 0b00100);

+                    }

+                    SETFLAGS(X_ALL, SF_PENDING);

+                    GETEW(x1, 0);

+                    UFLAG_OP12(ed, x4)

+                    LSLw_REG(ed, ed, x4);

+                    EWBACK;

+                    UFLAG_RES(ed);

+                    UFLAG_DF(x3, d_shl16);

+                    break;

+                case 5:

+                    if(opcode==0xD1) {

+                        INST_NAME("SHR Ew, 1");

+                        MOV32w(x4, 1);

+                    } else {

+                        INST_NAME("SHR Ew, CL");

+                        ANDSw_mask(x4, xRCX, 0, 0b00100);

+                    }

+                    SETFLAGS(X_ALL, SF_PENDING);

+                    GETEW(x1, 0);

+                    UFLAG_OP12(ed, x4)

+                    LSRw_REG(ed, ed, x4);

+                    EWBACK;

+                    UFLAG_RES(ed);

+                    UFLAG_DF(x3, d_shr16);

+                    break;

+                case 7:

+                    if(opcode==0xD1) {

+                        INST_NAME("SAR Ew, 1");

+                        MOV32w(x4, 1);

+                    } else {

+                        INST_NAME("SAR Ew, CL");

+                        ANDSw_mask(x4, xRCX, 0, 0b00100);

+                    }

+                    SETFLAGS(X_ALL, SF_PENDING);

+                    GETSEW(x1, 0);

+                    UFLAG_OP12(ed, x4)

+                    ASRw_REG(ed, ed, x4);

+                    EWBACK;

+                    UFLAG_RES(ed);

+                    UFLAG_DF(x3, d_sar16);

+                    break;

+            }

+            break;

+            

         default:

             DEFAULT;

     }

diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h
index 0c08e5c4..6615598f 100755
--- a/src/dynarec/dynarec_arm64_helper.h
+++ b/src/dynarec/dynarec_arm64_helper.h
@@ -761,7 +761,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
 //uintptr_t dynarec64_FS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
 //uintptr_t dynarec64_GS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
-uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
+uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
 //uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
 //uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
 //uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);