diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-25 15:06:48 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-25 15:06:48 +0100 |
| commit | 3c07dd58eb9974e6c2fb70cb1f51b5116451a9d7 (patch) | |
| tree | 553edf79c66a1b62577be19c372d65bd051ee699 /src | |
| parent | fcdd8fc383cace94ce970bd8af2385ab77d24def (diff) | |
| download | box64-3c07dd58eb9974e6c2fb70cb1f51b5116451a9d7.tar.gz box64-3c07dd58eb9974e6c2fb70cb1f51b5116451a9d7.zip | |
Added F3 0F BC opcode ([DYNAREC] too)
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/dynarec_arm64_f30f.c | 18 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 4 | ||||
| -rw-r--r-- | src/emu/x64runf30f.c | 38 |
3 files changed, 60 insertions, 0 deletions
diff --git a/src/dynarec/dynarec_arm64_f30f.c b/src/dynarec/dynarec_arm64_f30f.c index 3caf0f64..c4b698b6 100755 --- a/src/dynarec/dynarec_arm64_f30f.c +++ b/src/dynarec/dynarec_arm64_f30f.c @@ -50,6 +50,7 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n int q0, q1; int d0, d1; int fixedaddress; + int j32; MAYUSE(d0); MAYUSE(d1); @@ -57,6 +58,7 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n MAYUSE(q1); MAYUSE(v0); MAYUSE(v1); + MAYUSE(j32); switch(opcode) { @@ -257,6 +259,22 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } break; + case 0xBC: + INST_NAME("TZCNT Gd, Ed"); + SETFLAGS(X_CF|X_ZF, SF_SET); + nextop = F8; + GETED(0); + GETGD; + SET_DFNONE(x1); + TSTxw_REG(ed, ed); + BFIw(xFlags, x1, F_CF, 1); // CF = is source 0? + RBITxw(x1, ed); // reverse + CLZxw(gd, x1); // x2 gets leading 0 == TZCNT + TSTxw_REG(gd, gd); + CSETw(x1, cEQ); + BFIw(xFlags, x1, F_ZF, 1); // ZF = is dest 0? + break; + case 0xC2: INST_NAME("CMPSS Gx, Ex, Ib"); nextop = F8; diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index a06d54ea..2b588fef 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -264,6 +264,10 @@ #define B_MARK_nocond \ j32 = GETMARK-(dyn->arm_size); \ B(j32) +// Branch to MARK if reg is 0 (use j32) +#define CBZxw_MARK(reg) \ + j32 = GETMARK-(dyn->arm_size); \ + CBZxw(reg, j32) // Branch to MARK if reg is not 0 (use j32) #define CBNZx_MARK(reg) \ j32 = GETMARK-(dyn->arm_size); \ diff --git a/src/emu/x64runf30f.c b/src/emu/x64runf30f.c index f18aa951..aa3c9d76 100644 --- a/src/emu/x64runf30f.c +++ b/src/emu/x64runf30f.c @@ -28,6 +28,8 @@ int RunF30F(x64emu_t *emu, rex_t rex) uint8_t nextop; int8_t tmp8s; uint8_t tmp8u; + uint32_t tmp32u; + uint64_t tmp64u; reg64_t *oped, *opgd; sse_regs_t *opex, *opgx, eax1; mmx87_regs_t *opem; @@ -236,6 +238,42 @@ int RunF30F(x64emu_t *emu, rex_t rex) memcpy(EX, GX, 16); // unaligned... break; + case 0xBC: /* TZCNT Ed,Gd */ + CHECK_FLAGS(emu); + nextop = F8; + GETED(0); + GETGD; + if(rex.w) { + tmp64u = ED->q[0]; + if(tmp64u) { + CLEAR_FLAG(F_ZF); + tmp8u = 0; + while(!(tmp64u&(1LL<<tmp8u))) ++tmp8u; + GD->q[0] = tmp8u; + CONDITIONAL_SET_FLAG(tmp8u==0, F_ZF); + CLEAR_FLAG(F_CF); + } else { + CLEAR_FLAG(F_ZF); + SET_FLAG(F_CF); + GD->q[0] = 64; + } + } else { + tmp32u = ED->dword[0]; + if(tmp32u) { + CLEAR_FLAG(F_ZF); + tmp8u = 0; + while(!(tmp32u&(1<<tmp8u))) ++tmp8u; + GD->dword[0] = tmp8u; + CONDITIONAL_SET_FLAG(tmp8u==0, F_ZF); + CLEAR_FLAG(F_CF); + } else { + CLEAR_FLAG(F_ZF); + SET_FLAG(F_CF); + GD->dword[0] = 32; + } + } + break; + case 0xC2: /* CMPSS Gx, Ex, Ib */ nextop = F8; GETEX(1); |