Added REX F7 opcodes

This commit is contained in:
ptitSeb 2021-03-05 14:38:55 +01:00
parent b13273be05
commit cafbaa1e23
3 changed files with 123 additions and 3 deletions

View File

@ -1371,10 +1371,10 @@ void idiv32(x64emu_t *emu, uint32_t s)
INTR_RAISE_DIV0(emu);
return;
}
lldiv_t p = lldiv(dvd, (int32_t)s);
ldiv_t p = ldiv(dvd, (int32_t)s);
quot = p.quot;
mod = p.rem;
if (llabs(quot) > 0x7fffffff) {
if (labs(quot) > 0x7fffffff) {
INTR_RAISE_DIV0(emu);
return;
}
@ -1388,6 +1388,32 @@ void idiv32(x64emu_t *emu, uint32_t s)
R_EDX = (uint32_t)mod;
}
void idiv64(x64emu_t *emu, uint64_t s)
{
__int128 dvd, quot, mod;
RESET_FLAGS(emu);
dvd = (((__int128)R_RDX) << 64) | R_RAX;
if (s == 0) {
INTR_RAISE_DIV0(emu);
return;
}
quot = dvd/(int64_t)s;
mod = dvd%(int64_t)s;
if (llabs(quot) > 0x7fffffffffffffffL) {
INTR_RAISE_DIV0(emu);
return;
}
CLEAR_FLAG(F_CF);
CLEAR_FLAG(F_AF);
CLEAR_FLAG(F_SF);
SET_FLAG(F_ZF);
CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
R_RAX = (uint64_t)quot;
R_RDX = (uint64_t)mod;
}
/****************************************************************************
REMARKS:
Implements the DIV instruction and side effects.
@ -1462,3 +1488,29 @@ void div32(x64emu_t *emu, uint32_t s)
R_EAX = (uint32_t)div;
R_EDX = (uint32_t)mod;
}
void div64(x64emu_t *emu, uint64_t s)
{
__int128 dvd, div, mod;
RESET_FLAGS(emu);
dvd = (((__int128)R_RDX) << 64) | R_RAX;
if (s == 0) {
INTR_RAISE_DIV0(emu);
return;
}
div = dvd / (unsigned __int128)s;
mod = dvd % (unsigned __int128)s;
if (div > 0xffffffffffffffffL) {
INTR_RAISE_DIV0(emu);
return;
}
CLEAR_FLAG(F_CF);
CLEAR_FLAG(F_AF);
CLEAR_FLAG(F_SF);
SET_FLAG(F_ZF);
CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
R_RAX = (uint64_t)div;
R_RDX = (uint64_t)mod;
}

View File

@ -559,7 +559,7 @@ static inline uint64_t imul64(x64emu_t *emu, uint64_t op1, uint64_t op2)
return emu->res;
}
static inline void imul64_eax(x64emu_t *emu, uint64_t s)
static inline void imul64_rax(x64emu_t *emu, uint64_t s)
{
emu->df = d_imul64;
imul64_direct(&R_RAX,&R_RDX,R_RAX,s);
@ -589,11 +589,21 @@ static inline void mul32_eax(x64emu_t *emu, uint32_t s)
emu->op1 = R_EDX = (uint32_t)(res >> 32);
}
static inline void mul64_rax(x64emu_t *emu, uint64_t s)
{
emu->df = d_mul64;
__int128 res = (__int128)R_RAX * s;
emu->res = R_RAX = (uint64_t)res;
emu->op1 = R_RDX = (uint64_t)(res >> 64);
}
void idiv8 (x64emu_t *emu, uint8_t s);
void idiv16 (x64emu_t *emu, uint16_t s);
void idiv32 (x64emu_t *emu, uint32_t s);
void idiv64 (x64emu_t *emu, uint64_t s);
void div8 (x64emu_t *emu, uint8_t s);
void div16 (x64emu_t *emu, uint16_t s);
void div32 (x64emu_t *emu, uint32_t s);
void div64 (x64emu_t *emu, uint64_t s);
#endif //__X64PRIMOP_H_

View File

@ -473,6 +473,64 @@ x64emurun:
STEP
break;
case 0xF7: /* GRP3 Ed(,Id) */
nextop = F8;
GETED;
if(rex.w) {
switch((nextop>>3)&7) {
case 0:
case 1: /* TEST Ed,Id */
tmp64u = F32S64;
test64(emu, ED->q[0], tmp64u);
break;
case 2: /* NOT Ed */
ED->q[0] = not64(emu, ED->q[0]);
break;
case 3: /* NEG Ed */
ED->q[0] = neg64(emu, ED->q[0]);
break;
case 4: /* MUL RAX,Ed */
mul64_rax(emu, ED->q[0]);
break;
case 5: /* IMUL RAX,Ed */
imul64_rax(emu, ED->q[0]);
break;
case 6: /* DIV Ed */
div64(emu, ED->q[0]);
break;
case 7: /* IDIV Ed */
idiv64(emu, ED->q[0]);
break;
}
} else {
switch((nextop>>3)&7) {
case 0:
case 1: /* TEST Ed,Id */
tmp32u = F32;
test32(emu, ED->dword[0], tmp32u);
break;
case 2: /* NOT Ed */
ED->dword[0] = not32(emu, ED->dword[0]);
break;
case 3: /* NEG Ed */
ED->dword[0] = neg32(emu, ED->dword[0]);
break;
case 4: /* MUL EAX,Ed */
mul32_eax(emu, ED->dword[0]);
break;
case 5: /* IMUL EAX,Ed */
imul32_eax(emu, ED->dword[0]);
break;
case 6: /* DIV Ed */
div32(emu, ED->dword[0]);
break;
case 7: /* IDIV Ed */
idiv32(emu, ED->dword[0]);
break;
}
}
break;
case 0xFF: /* GRP 5 Ed */
nextop = F8;
GETED;