diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-07-02 17:30:52 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-07-02 17:30:52 +0200 |
| commit | 3b19a7fe1d6ec6f721107795c4411cf5f6d78e89 (patch) | |
| tree | 9aa1b9f8917d40d476f3a59fad08738d84119e56 /src | |
| parent | ccf9775658d99f613fc1532a6ef2e1cdf5faafe1 (diff) | |
| download | box64-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.c | 204 | ||||
| -rw-r--r-- | src/emu/x64run64.c | 42 |
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; } |