about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_emitter.h3
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c100
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h4
3 files changed, 104 insertions, 3 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h
index 5e72e4d8..091544df 100755
--- a/src/dynarec/arm64_emitter.h
+++ b/src/dynarec/arm64_emitter.h
@@ -214,6 +214,9 @@
 #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 LDRSBx_U12(Rt, Rn, imm12)           EMIT(LDRSH_gen(0b00, 0b01, 0b10, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt))
+#define LDRSBw_U12(Rt, Rn, imm12)           EMIT(LDRSH_gen(0b00, 0b01, 0b11, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt))
+#define LDRSBxw_U12(Rt, Rn, imm12)          EMIT(LDRSH_gen(0b00, 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 fb1424de..ac3e470c 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -706,7 +706,105 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 #endif
             }
             break;
-
+        case 0xD0:
+        case 0xD2:  // TODO: Jump if CL is 0
+            nextop = F8;
+            switch((nextop>>3)&7) {
+                case 0:
+                    if(opcode==0xD0) {
+                        INST_NAME("ROL Eb, 1");
+                        MOV32w(x2, 1);
+                    } else {
+                        INST_NAME("ROL Eb, CL");
+                        ANDSw_mask(x2, xRCX, 0, 0b00100);
+                    }
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET);
+                    GETEB(x1, 0);
+                    CALL_(rol8, x1, x3);
+                    EBBACK;
+                    break;
+                case 1:
+                    if(opcode==0xD0) {
+                        INST_NAME("ROR Eb, 1");
+                        MOV32w(x2, 1);
+                    } else {
+                        INST_NAME("ROR Eb, CL");
+                        ANDSw_mask(x2, xRCX, 0, 0b00100);
+                    }
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET);
+                    GETEB(x1, 0);
+                    CALL_(ror8, x1, x3);
+                    EBBACK;
+                    break;
+                case 2:
+                    if(opcode==0xD0) {INST_NAME("RCL Eb, 1");} else {INST_NAME("RCL Eb, CL");}
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    if(opcode==0xD0) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);}
+                    GETEB(x1, 0);
+                    CALL_(rcl8, x1, x3);
+                    EBBACK;
+                    break;
+                case 3:
+                    if(opcode==0xD0) {INST_NAME("RCR Eb, 1");} else {INST_NAME("RCR Eb, CL");}
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    if(opcode==0xD0) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);}
+                    GETEB(x1, 0);
+                    CALL_(rcr8, x1, x3);
+                    EBBACK;
+                    break;
+                case 4:
+                case 6:
+                    if(opcode==0xD0) {
+                        INST_NAME("SHL Eb, 1");
+                        MOV32w(x2, 1);
+                    } else {
+                        INST_NAME("SHL Eb, CL");
+                        ANDSw_mask(x2, xRCX, 0, 0b00100);
+                    }
+                    SETFLAGS(X_ALL, SF_PENDING);
+                    GETEB(x1, 0);
+                    UFLAG_OP12(ed, x2)
+                    LSLw_REG(ed, ed, x2);
+                    EBBACK;
+                    UFLAG_RES(ed);
+                    UFLAG_DF(x3, d_shl8);
+                    break;
+                case 5:
+                    if(opcode==0xD0) {
+                        INST_NAME("SHR Eb, 1");
+                        MOV32w(x2, 1);
+                    } else {
+                        INST_NAME("SHR Eb, CL");
+                        ANDSw_mask(x2, xRCX, 0, 0b00100);
+                    }
+                    SETFLAGS(X_ALL, SF_PENDING);
+                    GETEB(x1, 0);
+                    UFLAG_OP12(ed, x2);
+                    LSRw_REG(ed, ed, x2);
+                    EBBACK;
+                    UFLAG_RES(ed);
+                    UFLAG_DF(x3, d_shr8);
+                    break;
+                case 7:
+                    if(opcode==0xD0) {
+                        INST_NAME("SAR Eb, 1");
+                        MOV32w(x2, 1);
+                    } else {
+                        INST_NAME("SAR Eb, CL");
+                        ANDSw_mask(x2, xRCX, 0, 0b00100);
+                    }
+                    SETFLAGS(X_ALL, SF_PENDING);
+                    GETSEB(x1, 0);
+                    UFLAG_OP12(ed, x2)
+                    ASRw_REG(ed, ed, x2);
+                    EBBACK;
+                    UFLAG_RES(ed);
+                    UFLAG_DF(x3, d_sar8);
+                    break;
+            }
+            break;
         case 0xD1:
             nextop = F8;
             switch((nextop>>3)&7) {
diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h
index 6615598f..b3e08d7d 100755
--- a/src/dynarec/dynarec_arm64_helper.h
+++ b/src/dynarec/dynarec_arm64_helper.h
@@ -176,7 +176,7 @@
                     ed = i;                 \
                 }
 //GETSEB sign extend EB, will use i for ed, and can use r3 for wback.
-#define GETSEB(i) if(MODREG) {                \
+#define GETSEB(i, D) if(MODREG) {                \
                     if(rex.rex) {               \
                         wback = xRAX+(nextop&7)+(rex.b<<3);     \
                         wb2 = 0;                \
@@ -190,7 +190,7 @@
                     ed = i;                     \
                 } else {                        \
                     addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff, 0, rex, 0, D); \
-                    LDRSB_U12(i, wback, fixedaddress); \
+                    LDRSBx_U12(i, wback, fixedaddress); \
                     wb1 = 1;                    \
                     ed = i;                     \
                 }