mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-18 17:37:15 +00:00
FPU control word and tags
This commit is contained in:
parent
a5f2a64de5
commit
0a3799eada
|
@ -248,7 +248,9 @@ UC_X86_REG_IDTR = 242
|
||||||
UC_X86_REG_GDTR = 243
|
UC_X86_REG_GDTR = 243
|
||||||
UC_X86_REG_LDTR = 244
|
UC_X86_REG_LDTR = 244
|
||||||
UC_X86_REG_TR = 245
|
UC_X86_REG_TR = 245
|
||||||
UC_X86_REG_ENDING = 246
|
UC_X86_REG_FPTAGS = 246
|
||||||
|
UC_X86_REG_FPCW = 247
|
||||||
|
UC_X86_REG_ENDING = 248
|
||||||
|
|
||||||
# X86 instructions
|
# X86 instructions
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,8 @@ typedef enum uc_x86_reg {
|
||||||
UC_X86_REG_R9D, UC_X86_REG_R10D, UC_X86_REG_R11D, UC_X86_REG_R12D, UC_X86_REG_R13D,
|
UC_X86_REG_R9D, UC_X86_REG_R10D, UC_X86_REG_R11D, UC_X86_REG_R12D, UC_X86_REG_R13D,
|
||||||
UC_X86_REG_R14D, UC_X86_REG_R15D, UC_X86_REG_R8W, UC_X86_REG_R9W, UC_X86_REG_R10W,
|
UC_X86_REG_R14D, UC_X86_REG_R15D, UC_X86_REG_R8W, UC_X86_REG_R9W, UC_X86_REG_R10W,
|
||||||
UC_X86_REG_R11W, UC_X86_REG_R12W, UC_X86_REG_R13W, UC_X86_REG_R14W, UC_X86_REG_R15W,
|
UC_X86_REG_R11W, UC_X86_REG_R12W, UC_X86_REG_R13W, UC_X86_REG_R14W, UC_X86_REG_R15W,
|
||||||
UC_X86_REG_IDTR, UC_X86_REG_GDTR, UC_X86_REG_LDTR, UC_X86_REG_TR,
|
UC_X86_REG_IDTR, UC_X86_REG_GDTR, UC_X86_REG_LDTR, UC_X86_REG_TR, UC_X86_REG_FPCW,
|
||||||
|
UC_X86_REG_FPTAG,
|
||||||
|
|
||||||
UC_X86_REG_ENDING // <-- mark the end of the list of registers
|
UC_X86_REG_ENDING // <-- mark the end of the list of registers
|
||||||
} uc_x86_reg;
|
} uc_x86_reg;
|
||||||
|
|
|
@ -152,10 +152,42 @@ int x86_reg_read(struct uc_struct *uc, unsigned int regid, void *value)
|
||||||
case UC_X86_REG_FPSW:
|
case UC_X86_REG_FPSW:
|
||||||
{
|
{
|
||||||
uint16_t fpus = X86_CPU(uc, mycpu)->env.fpus;
|
uint16_t fpus = X86_CPU(uc, mycpu)->env.fpus;
|
||||||
fpus = fpus & ~(7<<11);
|
fpus = fpus & ~0x3800;
|
||||||
fpus |= (X86_CPU(uc, mycpu)->env.fpstt&7)<<11;
|
fpus |= ( X86_CPU(uc, mycpu)->env.fpstt & 0x7 ) << 11;
|
||||||
*(uint16_t*) value = fpus;
|
*(uint16_t*) value = fpus;
|
||||||
}
|
}
|
||||||
|
case UC_X86_REG_FPCW:
|
||||||
|
*(uint16_t*) value = X86_CPU(uc, mycpu)->env.fpuc;
|
||||||
|
break;
|
||||||
|
case UC_X86_REG_FPTAG:
|
||||||
|
{
|
||||||
|
#define EXPD(fp) (fp.l.upper & 0x7fff)
|
||||||
|
#define MANTD(fp) (fp.l.lower)
|
||||||
|
#define MAXEXPD 0x7fff
|
||||||
|
int fptag, exp, i;
|
||||||
|
uint64_t mant;
|
||||||
|
CPU_LDoubleU tmp;
|
||||||
|
fptag = 0;
|
||||||
|
for (i = 7; i >= 0; i--) {
|
||||||
|
fptag <<= 2;
|
||||||
|
if (X86_CPU(uc, mycpu)->env.fptags[i]) {
|
||||||
|
fptag |= 3;
|
||||||
|
} else {
|
||||||
|
tmp.d = X86_CPU(uc, mycpu)->env.fpregs[i].d;
|
||||||
|
exp = EXPD(tmp);
|
||||||
|
mant = MANTD(tmp);
|
||||||
|
if (exp == 0 && mant == 0) {
|
||||||
|
/* zero */
|
||||||
|
fptag |= 1;
|
||||||
|
} else if (exp == 0 || exp == MAXEXPD
|
||||||
|
|| (mant & (1LL << 63)) == 0) {
|
||||||
|
/* NaNs, infinity, denormal */
|
||||||
|
fptag |= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*(uint16_t*) value = fptag;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,10 +638,22 @@ int x86_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
|
||||||
case UC_X86_REG_FPSW:
|
case UC_X86_REG_FPSW:
|
||||||
{
|
{
|
||||||
uint16_t fpus = *(uint16_t*) value;
|
uint16_t fpus = *(uint16_t*) value;
|
||||||
X86_CPU(uc, mycpu)->env.fpus = fpus;
|
X86_CPU(uc, mycpu)->env.fpus = fpus & ~0x3800;
|
||||||
X86_CPU(uc, mycpu)->env.fpstt = (fpus>>11)&7;
|
X86_CPU(uc, mycpu)->env.fpstt = (fpus >> 11) & 0x7;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case UC_X86_REG_FPCW:
|
||||||
|
*(uint16_t*) value = X86_CPU(uc, mycpu)->env.fpuc;
|
||||||
|
break;
|
||||||
|
case UC_X86_REG_FPTAG:
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint16_t fptag = *(uint16_t*) value;
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
X86_CPU(uc, mycpu)->env.fptags[i] = ((fptag & 3) == 3);
|
||||||
|
fptag >>= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(uc->mode) {
|
switch(uc->mode) {
|
||||||
|
|
Loading…
Reference in a new issue