about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-07-02 17:30:52 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-07-02 17:30:52 +0200
commit3b19a7fe1d6ec6f721107795c4411cf5f6d78e89 (patch)
tree9aa1b9f8917d40d476f3a59fad08738d84119e56 /src
parentccf9775658d99f613fc1532a6ef2e1cdf5faafe1 (diff)
downloadbox64-3b19a7fe1d6ec6f721107795c4411cf5f6d78e89.tar.gz
box64-3b19a7fe1d6ec6f721107795c4411cf5f6d78e89.zip
Added 64 D1/D3 opcodes ([DYNAREC] too)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/dynarec_arm64_64.c204
-rw-r--r--src/emu/x64run64.c42
2 files changed, 246 insertions, 0 deletions
diff --git a/src/dynarec/dynarec_arm64_64.c b/src/dynarec/dynarec_arm64_64.c
index e735784d..9adfbbb8 100644
--- a/src/dynarec/dynarec_arm64_64.c
+++ b/src/dynarec/dynarec_arm64_64.c
@@ -421,6 +421,210 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
 
+        case 0xD1:
+            nextop = F8;
+            grab_segdata(dyn, addr, ninst, x6, seg);
+            switch((nextop>>3)&7) {
+                case 0:
+                    INST_NAME("ROL Ed, 1");
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET);
+                    GETEDO(x6, 0);
+                    emit_rol32c(dyn, ninst, rex, ed, 1, x3, x4);
+                    WBACKO(x6);
+                    break;
+                case 1:
+                    INST_NAME("ROR Ed, 1");
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET);
+                    GETEDO(x6, 0);
+                    emit_ror32c(dyn, ninst, rex, ed, 1, x3, x4);
+                    WBACKO(x6);
+                    break;
+                case 2:
+                    INST_NAME("RCL Ed, 1");
+                    MESSAGE(LOG_DUMP, "Need Optimization\n");
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    MOV32w(x2, 1);
+                    GETEDO(x6, 0);
+                    if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
+                    if(ed!=x1) {MOVxw_REG(x1, ed);}
+                    CALL_(rcl32, ed, x6);
+                    WBACK;
+                    break;
+                case 3:
+                    INST_NAME("RCR Ed, 1");
+                    MESSAGE(LOG_DUMP, "Need Optimization\n");
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    MOV32w(x2, 1);
+                    GETEDO(x6, 0);
+                    if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
+                    if(ed!=x1) {MOVxw_REG(x1, ed);}
+                    CALL_(rcr32, ed, x6);
+                    WBACK;
+                    break;
+                case 4:
+                case 6:
+                    INST_NAME("SHL Ed, 1");
+                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
+                    GETEDO(x6, 0);
+                    emit_shl32c(dyn, ninst, rex, ed, 1, x3, x4);
+                    WBACKO(x6);
+                    break;
+                case 5:
+                    INST_NAME("SHR Ed, 1");
+                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
+                    GETEDO(x6, 0);
+                    emit_shr32c(dyn, ninst, rex, ed, 1, x3, x4);
+                    WBACKO(x6);
+                    break;
+                case 7:
+                    INST_NAME("SAR Ed, 1");
+                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
+                    GETEDO(x6, 0);
+                    emit_sar32c(dyn, ninst, rex, ed, 1, x3, x4);
+                    WBACKO(x6);
+                    break;
+            }
+            break;
+        case 0xD3:
+            nextop = F8;
+            grab_segdata(dyn, addr, ninst, x6, seg);
+            switch((nextop>>3)&7) {
+                case 0:
+                    INST_NAME("ROL Ed, CL");
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET);
+                    if(rex.w) {
+                        ANDSx_mask(x3, xRCX, 1, 0, 0b00101);  //mask=0x000000000000003f
+                    } else {
+                        ANDSw_mask(x3, xRCX, 0, 0b00100);  //mask=0x00000001f
+                    }
+                    MOV64xw(x4, (rex.w?64:32));
+                    SUBx_REG(x3, x4, x3);
+                    GETEDO(x6, 0);
+                    if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
+                    B_NEXT(cEQ);
+                    RORxw_REG(ed, ed, x3);
+                    WBACKO(x6);
+                    UFLAG_IF {  // calculate flags directly
+                        CMPSw_U12(x3, rex.w?63:31);
+                        B_MARK(cNE);
+                            LSRxw(x4, ed, rex.w?63:31);
+                            ADDxw_REG(x4, x4, ed);
+                            BFIw(xFlags, x4, F_OF, 1);
+                        MARK;
+                        BFIw(xFlags, ed, F_CF, 1);
+                        UFLAG_DF(x2, d_none);
+                    }
+                    break;
+                case 1:
+                    INST_NAME("ROR Ed, CL");
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET);
+                    if(rex.w) {
+                        ANDSx_mask(x3, xRCX, 1, 0, 0b00101);  //mask=0x000000000000003f
+                    } else {
+                        ANDSw_mask(x3, xRCX, 0, 0b00100);  //mask=0x00000001f
+                    }
+                    GETEDO(x6, 0);
+                    if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
+                    B_NEXT(cEQ);
+                    RORxw_REG(ed, ed, x3);
+                    WBACKO(x6);
+                    UFLAG_IF {  // calculate flags directly
+                        CMPSw_U12(x3, 1);
+                        B_MARK(cNE);
+                            LSRxw(x2, ed, rex.w?62:30); // x2 = d>>30
+                            EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>30) ^ ((d>>30)>>1))
+                            BFIw(xFlags, x2, F_OF, 1);
+                        MARK;
+                        LSRxw(x2, ed, rex.w?63:31);
+                        BFIw(xFlags, x2, F_CF, 1);
+                        UFLAG_DF(x2, d_none);
+                    }
+                    break;
+                case 2:
+                    INST_NAME("RCL Ed, CL");
+                    MESSAGE(LOG_DUMP, "Need Optimization\n");
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    if(rex.w) {
+                        ANDSx_mask(x2, xRCX, 1, 0, 0b00101);  //mask=0x000000000000003f
+                    } else {
+                        ANDSw_mask(x2, xRCX, 0, 0b00100);  //mask=0x00000001f
+                    }
+                    GETEDO(x6, 0);
+                    if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
+                    if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
+                    B_NEXT(cEQ);
+                    CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x6);
+                    WBACK;
+                    break;
+                case 3:
+                    INST_NAME("RCR Ed, CL");
+                    MESSAGE(LOG_DUMP, "Need Optimization\n");
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    if(rex.w) {
+                        ANDSx_mask(x2, xRCX, 1, 0, 0b00101);  //mask=0x000000000000003f
+                    } else {
+                        ANDSw_mask(x2, xRCX, 0, 0b00100);  //mask=0x00000001f
+                    }
+                    GETEDO(x6, 0);
+                    if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
+                    if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
+                    B_NEXT(cEQ);
+                    CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x6);
+                    WBACK;
+                    break;
+                case 4:
+                case 6:
+                    INST_NAME("SHL Ed, CL");
+                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
+                    if(rex.w) {
+                        ANDSx_mask(x3, xRCX, 1, 0, 0b00101);  //mask=0x000000000000003f
+                    } else {
+                        ANDSw_mask(x3, xRCX, 0, 0b00100);  //mask=0x00000001f
+                    }
+                    GETEDO(x6, 0);
+                    if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
+                    B_NEXT(cEQ);
+                    emit_shl32(dyn, ninst, rex, ed, x3, x5, x4);
+                    WBACKO(x6);
+                    break;
+                case 5:
+                    INST_NAME("SHR Ed, CL");
+                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
+                    if(rex.w) {
+                        ANDSx_mask(x3, xRCX, 1, 0, 0b00101);  //mask=0x000000000000003f
+                    } else {
+                        ANDSw_mask(x3, xRCX, 0, 0b00100);  //mask=0x00000001f
+                    }
+                    GETEDO(x6, 0);
+                    if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
+                    B_NEXT(cEQ);
+                    emit_shr32(dyn, ninst, rex, ed, x3, x5, x4);
+                    WBACKO(x6);
+                    break;
+                case 7:
+                    INST_NAME("SAR Ed, CL");
+                    SETFLAGS(X_ALL, SF_PENDING);
+                    if(rex.w) {
+                        ANDSx_mask(x3, xRCX, 1, 0, 0b00101);  //mask=0x000000000000003f
+                    } else {
+                        ANDSw_mask(x3, xRCX, 0, 0b00100);  //mask=0x00000001f
+                    }
+                    GETEDO(x6, 0);
+                    if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
+                    B_NEXT(cEQ);
+                    UFLAG_OP12(ed, x3);
+                    ASRxw_REG(ed, ed, x3);
+                    WBACKO(x6);
+                    UFLAG_RES(ed);
+                    UFLAG_DF(x3, rex.w?d_sar64:d_sar32);
+                    break;
+            }
+            break;
+            
         default:
             DEFAULT;
     }
diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c
index 63b95199..9e789b0f 100644
--- a/src/emu/x64run64.c
+++ b/src/emu/x64run64.c
@@ -364,6 +364,48 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
                     ED->dword[0] = F32;

             break;

 

+        case 0xD1:                      /* GRP2 Ed,1 */

+        case 0xD3:                      /* GRP2 Ed,CL */

+            nextop = F8;

+            GETED_OFFS(0, tlsdata);

+            tmp8u = (opcode==0xD1)?1:R_CL;

+            if(rex.w) {

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

+                    case 0: ED->q[0] = rol64(emu, ED->q[0], tmp8u); break;

+                    case 1: ED->q[0] = ror64(emu, ED->q[0], tmp8u); break;

+                    case 2: ED->q[0] = rcl64(emu, ED->q[0], tmp8u); break;

+                    case 3: ED->q[0] = rcr64(emu, ED->q[0], tmp8u); break;

+                    case 4: 

+                    case 6: ED->q[0] = shl64(emu, ED->q[0], tmp8u); break;

+                    case 5: ED->q[0] = shr64(emu, ED->q[0], tmp8u); break;

+                    case 7: ED->q[0] = sar64(emu, ED->q[0], tmp8u); break;

+                }

+            } else {

+                if(MODREG)

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

+                        case 0: ED->q[0] = rol32(emu, ED->dword[0], tmp8u); break;

+                        case 1: ED->q[0] = ror32(emu, ED->dword[0], tmp8u); break;

+                        case 2: ED->q[0] = rcl32(emu, ED->dword[0], tmp8u); break;

+                        case 3: ED->q[0] = rcr32(emu, ED->dword[0], tmp8u); break;

+                        case 4: 

+                        case 6: ED->q[0] = shl32(emu, ED->dword[0], tmp8u); break;

+                        case 5: ED->q[0] = shr32(emu, ED->dword[0], tmp8u); break;

+                        case 7: ED->q[0] = sar32(emu, ED->dword[0], tmp8u); break;

+                    }

+                else

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

+                        case 0: ED->dword[0] = rol32(emu, ED->dword[0], tmp8u); break;

+                        case 1: ED->dword[0] = ror32(emu, ED->dword[0], tmp8u); break;

+                        case 2: ED->dword[0] = rcl32(emu, ED->dword[0], tmp8u); break;

+                        case 3: ED->dword[0] = rcr32(emu, ED->dword[0], tmp8u); break;

+                        case 4: 

+                        case 6: ED->dword[0] = shl32(emu, ED->dword[0], tmp8u); break;

+                        case 5: ED->dword[0] = shr32(emu, ED->dword[0], tmp8u); break;

+                        case 7: ED->dword[0] = sar32(emu, ED->dword[0], tmp8u); break;

+                    }

+            }

+            break;

+

        default:

             return 1;

     }