diff options
| author | CorteX <30485844+Seas0@users.noreply.github.com> | 2022-01-07 16:52:54 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-07 16:52:54 +0800 |
| commit | f5d06338c73429f945881cf4e89920c5f2ca56c2 (patch) | |
| tree | 77e7a3c57bda249e0a28fc2325bfe8240a3117f5 /src | |
| parent | 42ab23a8332aaeee4e4a47e2608fba09833b46be (diff) | |
| parent | e249a33d3e038f0e3c17f2f6c3eb5b8d7a21a2c3 (diff) | |
| download | box64-f5d06338c73429f945881cf4e89920c5f2ca56c2.tar.gz box64-f5d06338c73429f945881cf4e89920c5f2ca56c2.zip | |
Merge branch 'ptitSeb:main' into main
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64_emitter.h | 9 | ||||
| -rwxr-xr-x | src/dynarec/arm64_printer.c | 15 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 14 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_660f.c | 39 | ||||
| -rw-r--r-- | src/emu/x64run0f.c | 54 | ||||
| -rw-r--r-- | src/emu/x64runf0.c | 114 |
6 files changed, 160 insertions, 85 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h index a063c958..b06aa319 100755 --- a/src/dynarec/arm64_emitter.h +++ b/src/dynarec/arm64_emitter.h @@ -1315,6 +1315,15 @@ #define VUZP1Q_64(Rt, Rn, Rm) EMIT(UZP_gen(1, 0b11, Rm, 0, Rn, Rt)) #define VUZP2Q_64(Rt, Rn, Rm) EMIT(UZP_gen(1, 0b11, Rm, 1, Rn, Rt)) +#define DUP_gen(Q, imm5, Rn, Rd) ((Q)<<30 | 0b01110000<<21 | (imm5)<<16 | 1<<10 | (Rn)<<5 | (Rd)) +#define VDUP_8(Vd, Vn, idx) EMIT(DUP_gen(0, ((idx)<<1|1), Vn, Vd)) +#define VDUPQ_8(Vd, Vn, idx) EMIT(DUP_gen(1, ((idx)<<1|1), Vn, Vd)) +#define VDUP_16(Vd, Vn, idx) EMIT(DUP_gen(0, ((idx)<<2|0b10), Vn, Vd)) +#define VDUPQ_16(Vd, Vn, idx) EMIT(DUP_gen(1, ((idx)<<2|0b10), Vn, Vd)) +#define VDUP_32(Vd, Vn, idx) EMIT(DUP_gen(0, ((idx)<<3|0b100), Vn, Vd)) +#define VDUPQ_32(Vd, Vn, idx) EMIT(DUP_gen(1, ((idx)<<3|0b100), Vn, Vd)) +#define VDUPQ_64(Vd, Vn, idx) EMIT(DUP_gen(1, ((idx)<<4|0b1000), Vn, Vd)) + // TBL #define TBL_gen(Q, Rm, len, op, Rn, Rd) ((Q)<<30 | 0b001110<<24 | (Rm)<<16 | (len)<<13 | (op)<<12 | (Rn)<<5 | (Rd)) //Use Rm[] to pick from Rn element and store in Rd. Out-of-range element gets 0 diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c index c19b48ea..7849db23 100755 --- a/src/dynarec/arm64_printer.c +++ b/src/dynarec/arm64_printer.c @@ -1311,6 +1311,21 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) snprintf(buff, sizeof(buff), "%cSHLL%s V%d.%s, V%d.%s, #%d", a.U?'U':'S', a.Q?"2":"", Rd, Va, Rn, Vd, sh); return buff; } + + // DUP + if(isMask(opcode, "0Q001110000iiiii000001nnnnnddddd", &a)) { + const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "2D", "??"}; + const char* Z[] = {"B", "H", "S", "D"}; + int sz = 3; + if((imm&0b0001)==0b0001) sz=0; + else if((imm&0b0011)==0b0010) sz=1; + else if((imm&0b0111)==0b0100) sz=2; + int sh=imm - (1<<sz); + const char* Vd = Y[(sz<<1)|a.Q]; + const char* Vn = Z[sz]; + snprintf(buff, sizeof(buff), "DUP V%d.%s, V%d.%s[%d]", Rd, Vd, Rn, Vn, sh); + return buff; + } // AES if(isMask(opcode, "0100111000101000010f10nnnnnddddd", &a)) { diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index 77451bb1..fa6a58a1 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -1011,7 +1011,19 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } } break; - + case 0x8E: + INST_NAME("MOV Seg,Ew"); + nextop = F8; + if((nextop&0xC0)==0xC0) { + ed = xRAX+(nextop&7)+(rex.b<<3); + } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<2, 0, rex, 0, 0); + LDRH_U12(x1, ed, fixedaddress); + ed = x1; + } + STRw_U12(ed, xEmu, offsetof(x64emu_t, segs[(nextop&0x38)>>3])); + STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[(nextop&0x38)>>3])); + break; case 0x8F: INST_NAME("POP Ed"); nextop = F8; diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c index 39467aa5..b1640609 100755 --- a/src/dynarec/dynarec_arm64_660f.c +++ b/src/dynarec/dynarec_arm64_660f.c @@ -236,6 +236,20 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n VANDQ(d0, d0, q1); // mask the index VTBLQ1_8(q0, q0, d0); break; + case 0x01: + INST_NAME("PHADDW Gx, Ex"); + nextop = F8; + GETGX(q0); + GETEX(q1, 0); + VADDPQ_16(q0, q0, q1); + break; + case 0x02: + INST_NAME("PHADDD Gx, Ex"); + nextop = F8; + GETGX(q0); + GETEX(q1, 0); + VADDPQ_32(q0, q0, q1); + break; case 0x04: INST_NAME("PMADDUBSW Gx,Ex"); @@ -1507,17 +1521,24 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } break; - + case 0xD1: + INST_NAME("PSRLW Gx,Ex"); + nextop = F8; + GETGX(q0); + GETEX(q1, 0); + v0 = fpu_get_scratch(dyn); + VDUPQ_16(v0, q1, 0); + NEGQ_16(v0, v0); // neg, because SHR + USHLQ_16(q0, q0, v0); // SHR x8 + break; case 0xD2: INST_NAME("PSRLD Gx,Ex"); nextop = F8; GETGX(q0); GETEX(q1, 0); v0 = fpu_get_scratch(dyn); - SQSHRN_32(v0, q1, 0); // S64x1->S32x1 - VMOVeS(v0, 1, v0, 0); // S32x1->S32x2 - NEG_32(v0, v0); // neg, because SHR - VMOVeD(v0, 1, v0, 0); // S32x2->S32x4 + VDUPQ_32(v0, q1, 0); + NEGQ_32(v0, v0); // neg, because SHR USHLQ_32(q0, q0, v0); // SHR x4 break; case 0xD3: @@ -1673,7 +1694,13 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n VMOVeD(v0, 1, v0, 0); SSHLQ_32(q0, q0, v0); break; - + case 0xE3: + INST_NAME("PAVGW Gx,Ex"); + nextop = F8; + GETGX(v0); + GETEX(q0, 0); + URHADDQ_16(v0, v0, q0); + break; case 0xE4: INST_NAME("PMULHUW Gx,Ex"); nextop = F8; diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c index 977e6c73..e934c6c2 100644 --- a/src/emu/x64run0f.c +++ b/src/emu/x64run0f.c @@ -1221,30 +1221,36 @@ int Run0F(x64emu_t *emu, rex_t rex) CHECK_FLAGS(emu); nextop = F8; GETED(0); - if(rex.w) { - tmp64u = ED->q[0]; - tmp64u2= ED->q[1]; - if(R_RAX == tmp64u && R_RDX == tmp64u2) { - SET_FLAG(F_ZF); - ED->q[0] = R_EBX; - ED->q[1] = R_ECX; - } else { - CLEAR_FLAG(F_ZF); - R_RAX = tmp64u; - R_RDX = tmp64u2; - } - } else { - tmp32u = ED->dword[0]; - tmp32u2= ED->dword[1]; - if(R_EAX == tmp32u && R_EDX == tmp32u2) { - SET_FLAG(F_ZF); - ED->dword[0] = R_EBX; - ED->dword[1] = R_ECX; - } else { - CLEAR_FLAG(F_ZF); - R_RAX = tmp32u; - R_RDX = tmp32u2; - } + switch((nextop>>3)&7) { + case 1: + if(rex.w) { + tmp64u = ED->q[0]; + tmp64u2= ED->q[1]; + if(R_RAX == tmp64u && R_RDX == tmp64u2) { + SET_FLAG(F_ZF); + ED->q[0] = R_EBX; + ED->q[1] = R_ECX; + } else { + CLEAR_FLAG(F_ZF); + R_RAX = tmp64u; + R_RDX = tmp64u2; + } + } else { + tmp32u = ED->dword[0]; + tmp32u2= ED->dword[1]; + if(R_EAX == tmp32u && R_EDX == tmp32u2) { + SET_FLAG(F_ZF); + ED->dword[0] = R_EBX; + ED->dword[1] = R_ECX; + } else { + CLEAR_FLAG(F_ZF); + R_RAX = tmp32u; + R_RDX = tmp32u2; + } + } + break; + default: + return 1; } break; case 0xC8: diff --git a/src/emu/x64runf0.c b/src/emu/x64runf0.c index f3c0fb10..041c147a 100644 --- a/src/emu/x64runf0.c +++ b/src/emu/x64runf0.c @@ -634,66 +634,72 @@ int RunF0(x64emu_t *emu, rex_t rex) break; case 0xC7: /* CMPXCHG8B Gq */ - CHECK_FLAGS(emu); nextop = F8; GETED(0); - GETGD; + switch((nextop>>3)&7) { + case 1: + CHECK_FLAGS(emu); + GETGD; #ifdef DYNAREC - if(rex.w) - do { - arm64_lock_read_dq(&tmp64u, &tmp64u2, ED); - if(R_RAX == tmp64u && R_RDX == tmp64u2) { - SET_FLAG(F_ZF); - tmp32s = arm64_lock_write_dq(R_RBX, R_RCX, ED); - } else { - CLEAR_FLAG(F_ZF); - R_RAX = tmp64u; - R_RDX = tmp64u2; - tmp32s = 0; - } - } while(tmp32s); - else - do { - tmp64u = arm64_lock_read_dd(ED); - if((R_EAX == (tmp64u&0xffffffff)) && (R_EDX == ((tmp64u>>32)&0xffffffff))) { - SET_FLAG(F_ZF); - tmp32s = arm64_lock_write_dd(ED, R_EBX|(((uint64_t)R_ECX)<<32)); + if(rex.w) + do { + arm64_lock_read_dq(&tmp64u, &tmp64u2, ED); + if(R_RAX == tmp64u && R_RDX == tmp64u2) { + SET_FLAG(F_ZF); + tmp32s = arm64_lock_write_dq(R_RBX, R_RCX, ED); + } else { + CLEAR_FLAG(F_ZF); + R_RAX = tmp64u; + R_RDX = tmp64u2; + tmp32s = 0; + } + } while(tmp32s); + else + do { + tmp64u = arm64_lock_read_dd(ED); + if((R_EAX == (tmp64u&0xffffffff)) && (R_EDX == ((tmp64u>>32)&0xffffffff))) { + SET_FLAG(F_ZF); + tmp32s = arm64_lock_write_dd(ED, R_EBX|(((uint64_t)R_ECX)<<32)); + } else { + CLEAR_FLAG(F_ZF); + R_RAX = tmp64u&0xffffffff; + R_RDX = (tmp64u>>32)&0xffffffff; + tmp32s = 0; + } + } while(tmp32s); +#else + pthread_mutex_lock(&emu->context->mutex_lock); + if(rex.w) { + tmp64u = ED->q[0]; + tmp64u2= ED->q[1]; + if(R_RAX == tmp64u && R_RDX == tmp64u2) { + SET_FLAG(F_ZF); + ED->q[0] = R_RBX; + ED->q[1] = R_RCX; + } else { + CLEAR_FLAG(F_ZF); + R_RAX = tmp64u; + R_RDX = tmp64u2; + } } else { - CLEAR_FLAG(F_ZF); - R_RAX = tmp64u&0xffffffff; - R_RDX = (tmp64u>>32)&0xffffffff; - tmp32s = 0; + tmp32u = ED->dword[0]; + tmp32u2= ED->dword[1]; + if(R_EAX == tmp32u && R_EDX == tmp32u2) { + SET_FLAG(F_ZF); + ED->dword[0] = R_EBX; + ED->dword[1] = R_ECX; + } else { + CLEAR_FLAG(F_ZF); + R_RAX = tmp32u; + R_RDX = tmp32u2; + } } - } while(tmp32s); -#else - pthread_mutex_lock(&emu->context->mutex_lock); - if(rex.w) { - tmp64u = ED->q[0]; - tmp64u2= ED->q[1]; - if(R_RAX == tmp64u && R_RDX == tmp64u2) { - SET_FLAG(F_ZF); - ED->q[0] = R_RBX; - ED->q[1] = R_RCX; - } else { - CLEAR_FLAG(F_ZF); - R_RAX = tmp64u; - R_RDX = tmp64u2; - } - } else { - tmp32u = ED->dword[0]; - tmp32u2= ED->dword[1]; - if(R_EAX == tmp32u && R_EDX == tmp32u2) { - SET_FLAG(F_ZF); - ED->dword[0] = R_EBX; - ED->dword[1] = R_ECX; - } else { - CLEAR_FLAG(F_ZF); - R_RAX = tmp32u; - R_RDX = tmp32u2; - } - } - pthread_mutex_unlock(&emu->context->mutex_lock); + pthread_mutex_unlock(&emu->context->mutex_lock); #endif + break; + default: + return 1; + } break; default: |