2113 |
qemu_put_be16s(f, &fpregs_format); |
qemu_put_be16s(f, &fpregs_format); |
2114 |
|
|
2115 |
for(i = 0; i < 8; i++) { |
for(i = 0; i < 8; i++) { |
|
uint64_t mant; |
|
|
uint16_t exp; |
|
2116 |
#ifdef USE_X86LDOUBLE |
#ifdef USE_X86LDOUBLE |
2117 |
/* we save the real CPU data (in case of MMX usage only 'mant' |
{ |
2118 |
contains the MMX register */ |
uint64_t mant; |
2119 |
cpu_get_fp80(&mant, &exp, env->fpregs[i].d); |
uint16_t exp; |
2120 |
qemu_put_be64(f, mant); |
/* we save the real CPU data (in case of MMX usage only 'mant' |
2121 |
qemu_put_be16(f, exp); |
contains the MMX register */ |
2122 |
|
cpu_get_fp80(&mant, &exp, env->fpregs[i].d); |
2123 |
|
qemu_put_be64(f, mant); |
2124 |
|
qemu_put_be16(f, exp); |
2125 |
|
} |
2126 |
#else |
#else |
2127 |
/* if we use doubles for float emulation, we save the doubles to |
/* if we use doubles for float emulation, we save the doubles to |
2128 |
avoid losing information in case of MMX usage. It can give |
avoid losing information in case of MMX usage. It can give |
2129 |
problems if the image is restored on a CPU where long |
problems if the image is restored on a CPU where long |
2130 |
doubles are used instead. */ |
doubles are used instead. */ |
2131 |
qemu_put_be64(f, env->fpregs[i].xmm.MMX_Q(0)); |
qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0)); |
2132 |
#endif |
#endif |
2133 |
} |
} |
2134 |
|
|
2171 |
#endif |
#endif |
2172 |
} |
} |
2173 |
|
|
2174 |
|
#ifdef USE_X86LDOUBLE |
2175 |
/* XXX: add that in a FPU generic layer */ |
/* XXX: add that in a FPU generic layer */ |
2176 |
union x86_longdouble { |
union x86_longdouble { |
2177 |
uint64_t mant; |
uint64_t mant; |
2193 |
e |= SIGND1(temp) >> 16; |
e |= SIGND1(temp) >> 16; |
2194 |
p->exp = e; |
p->exp = e; |
2195 |
} |
} |
2196 |
|
#endif |
2197 |
|
|
2198 |
int cpu_load(QEMUFile *f, void *opaque, int version_id) |
int cpu_load(QEMUFile *f, void *opaque, int version_id) |
2199 |
{ |
{ |
2222 |
for(i = 0; i < 8; i++) { |
for(i = 0; i < 8; i++) { |
2223 |
uint64_t mant; |
uint64_t mant; |
2224 |
uint16_t exp; |
uint16_t exp; |
|
union x86_longdouble *p; |
|
2225 |
|
|
2226 |
switch(fpregs_format) { |
switch(fpregs_format) { |
2227 |
case 0: |
case 0: |
2232 |
#else |
#else |
2233 |
/* difficult case */ |
/* difficult case */ |
2234 |
if (guess_mmx) |
if (guess_mmx) |
2235 |
env->fpregs[i].xmm.MMX_Q(0) = mant; |
env->fpregs[i].mmx.MMX_Q(0) = mant; |
2236 |
else |
else |
2237 |
env->fpregs[i].d = cpu_set_fp80(mant, exp); |
env->fpregs[i].d = cpu_set_fp80(mant, exp); |
2238 |
#endif |
#endif |
2240 |
case 1: |
case 1: |
2241 |
mant = qemu_get_be64(f); |
mant = qemu_get_be64(f); |
2242 |
#ifdef USE_X86LDOUBLE |
#ifdef USE_X86LDOUBLE |
2243 |
/* difficult case */ |
{ |
2244 |
p = (void *)&env->fpregs[i]; |
union x86_longdouble *p; |
2245 |
if (guess_mmx) { |
/* difficult case */ |
2246 |
p->mant = mant; |
p = (void *)&env->fpregs[i]; |
2247 |
p->exp = 0xffff; |
if (guess_mmx) { |
2248 |
} else { |
p->mant = mant; |
2249 |
fp64_to_fp80(p, mant); |
p->exp = 0xffff; |
2250 |
|
} else { |
2251 |
|
fp64_to_fp80(p, mant); |
2252 |
|
} |
2253 |
} |
} |
2254 |
#else |
#else |
2255 |
env->fpregs[i].xmm.MMX_Q(0) = mant; |
env->fpregs[i].mmx.MMX_Q(0) = mant; |
2256 |
#endif |
#endif |
2257 |
break; |
break; |
2258 |
default: |
default: |