target-i386: Fix exceptions for fxsave/fxrstor
This patch corrects the following aspects of exception generation in fxsave/fxrstor: * Generate #GP if the operand is not aligned to a 16 byte boundary * Generate #UD if the LOCK prefix is used * For CR0.EM = 1 #NM is generated, not #UD Signed-off-by: Kevin Wolf <mail@kevin-wolf.de> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
94f4af02a1
commit
09d85fb843
@ -4350,6 +4350,11 @@ void helper_fxsave(target_ulong ptr, int data64)
|
||||
CPU86_LDouble tmp;
|
||||
target_ulong addr;
|
||||
|
||||
/* The operand must be 16 byte aligned */
|
||||
if (ptr & 0xf) {
|
||||
raise_exception(EXCP0D_GPF);
|
||||
}
|
||||
|
||||
fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
|
||||
fptag = 0;
|
||||
for(i = 0; i < 8; i++) {
|
||||
@ -4406,6 +4411,11 @@ void helper_fxrstor(target_ulong ptr, int data64)
|
||||
CPU86_LDouble tmp;
|
||||
target_ulong addr;
|
||||
|
||||
/* The operand must be 16 byte aligned */
|
||||
if (ptr & 0xf) {
|
||||
raise_exception(EXCP0D_GPF);
|
||||
}
|
||||
|
||||
env->fpuc = lduw(ptr);
|
||||
fpus = lduw(ptr + 2);
|
||||
fptag = lduw(ptr + 4);
|
||||
|
@ -7502,9 +7502,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
|
||||
switch(op) {
|
||||
case 0: /* fxsave */
|
||||
if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
|
||||
(s->flags & HF_EM_MASK))
|
||||
(s->prefix & PREFIX_LOCK))
|
||||
goto illegal_op;
|
||||
if (s->flags & HF_TS_MASK) {
|
||||
if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
|
||||
gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
|
||||
break;
|
||||
}
|
||||
@ -7516,9 +7516,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
|
||||
break;
|
||||
case 1: /* fxrstor */
|
||||
if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
|
||||
(s->flags & HF_EM_MASK))
|
||||
(s->prefix & PREFIX_LOCK))
|
||||
goto illegal_op;
|
||||
if (s->flags & HF_TS_MASK) {
|
||||
if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
|
||||
gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user