Commit 9951bf39f90519a2a2eb3809eb13a27471b9398d
1 parent
8948b5d6
fixed long double accesses when using soft MMU
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@428 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
150 additions
and
137 deletions
target-i386/exec.h
| ... | ... | @@ -171,6 +171,115 @@ void helper_wrmsr(void); |
| 171 | 171 | void helper_lsl(void); |
| 172 | 172 | void helper_lar(void); |
| 173 | 173 | |
| 174 | +/* XXX: move that to a generic header */ | |
| 175 | +#if !defined(CONFIG_USER_ONLY) | |
| 176 | + | |
| 177 | +#define ldul_user ldl_user | |
| 178 | +#define ldul_kernel ldl_kernel | |
| 179 | + | |
| 180 | +#define ACCESS_TYPE 0 | |
| 181 | +#define MEMSUFFIX _kernel | |
| 182 | +#define DATA_SIZE 1 | |
| 183 | +#include "softmmu_header.h" | |
| 184 | + | |
| 185 | +#define DATA_SIZE 2 | |
| 186 | +#include "softmmu_header.h" | |
| 187 | + | |
| 188 | +#define DATA_SIZE 4 | |
| 189 | +#include "softmmu_header.h" | |
| 190 | + | |
| 191 | +#define DATA_SIZE 8 | |
| 192 | +#include "softmmu_header.h" | |
| 193 | +#undef ACCESS_TYPE | |
| 194 | +#undef MEMSUFFIX | |
| 195 | + | |
| 196 | +#define ACCESS_TYPE 1 | |
| 197 | +#define MEMSUFFIX _user | |
| 198 | +#define DATA_SIZE 1 | |
| 199 | +#include "softmmu_header.h" | |
| 200 | + | |
| 201 | +#define DATA_SIZE 2 | |
| 202 | +#include "softmmu_header.h" | |
| 203 | + | |
| 204 | +#define DATA_SIZE 4 | |
| 205 | +#include "softmmu_header.h" | |
| 206 | + | |
| 207 | +#define DATA_SIZE 8 | |
| 208 | +#include "softmmu_header.h" | |
| 209 | +#undef ACCESS_TYPE | |
| 210 | +#undef MEMSUFFIX | |
| 211 | + | |
| 212 | +/* these access are slower, they must be as rare as possible */ | |
| 213 | +#define ACCESS_TYPE 2 | |
| 214 | +#define MEMSUFFIX _data | |
| 215 | +#define DATA_SIZE 1 | |
| 216 | +#include "softmmu_header.h" | |
| 217 | + | |
| 218 | +#define DATA_SIZE 2 | |
| 219 | +#include "softmmu_header.h" | |
| 220 | + | |
| 221 | +#define DATA_SIZE 4 | |
| 222 | +#include "softmmu_header.h" | |
| 223 | + | |
| 224 | +#define DATA_SIZE 8 | |
| 225 | +#include "softmmu_header.h" | |
| 226 | +#undef ACCESS_TYPE | |
| 227 | +#undef MEMSUFFIX | |
| 228 | + | |
| 229 | +#define ldub(p) ldub_data(p) | |
| 230 | +#define ldsb(p) ldsb_data(p) | |
| 231 | +#define lduw(p) lduw_data(p) | |
| 232 | +#define ldsw(p) ldsw_data(p) | |
| 233 | +#define ldl(p) ldl_data(p) | |
| 234 | +#define ldq(p) ldq_data(p) | |
| 235 | + | |
| 236 | +#define stb(p, v) stb_data(p, v) | |
| 237 | +#define stw(p, v) stw_data(p, v) | |
| 238 | +#define stl(p, v) stl_data(p, v) | |
| 239 | +#define stq(p, v) stq_data(p, v) | |
| 240 | + | |
| 241 | +static inline double ldfq(void *ptr) | |
| 242 | +{ | |
| 243 | + union { | |
| 244 | + double d; | |
| 245 | + uint64_t i; | |
| 246 | + } u; | |
| 247 | + u.i = ldq(ptr); | |
| 248 | + return u.d; | |
| 249 | +} | |
| 250 | + | |
| 251 | +static inline void stfq(void *ptr, double v) | |
| 252 | +{ | |
| 253 | + union { | |
| 254 | + double d; | |
| 255 | + uint64_t i; | |
| 256 | + } u; | |
| 257 | + u.d = v; | |
| 258 | + stq(ptr, u.i); | |
| 259 | +} | |
| 260 | + | |
| 261 | +static inline float ldfl(void *ptr) | |
| 262 | +{ | |
| 263 | + union { | |
| 264 | + float f; | |
| 265 | + uint32_t i; | |
| 266 | + } u; | |
| 267 | + u.i = ldl(ptr); | |
| 268 | + return u.f; | |
| 269 | +} | |
| 270 | + | |
| 271 | +static inline void stfl(void *ptr, float v) | |
| 272 | +{ | |
| 273 | + union { | |
| 274 | + float f; | |
| 275 | + uint32_t i; | |
| 276 | + } u; | |
| 277 | + u.f = v; | |
| 278 | + stl(ptr, u.i); | |
| 279 | +} | |
| 280 | + | |
| 281 | +#endif /* !defined(CONFIG_USER_ONLY) */ | |
| 282 | + | |
| 174 | 283 | #ifdef USE_X86LDOUBLE |
| 175 | 284 | /* use long double functions */ |
| 176 | 285 | #define lrint lrintl |
| ... | ... | @@ -317,7 +426,47 @@ static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) |
| 317 | 426 | e |= SIGND(temp) >> 16; |
| 318 | 427 | stw(ptr + 8, e); |
| 319 | 428 | } |
| 320 | -#endif | |
| 429 | +#else | |
| 430 | + | |
| 431 | +/* XXX: same endianness assumed */ | |
| 432 | + | |
| 433 | +#ifdef CONFIG_USER_ONLY | |
| 434 | + | |
| 435 | +static inline CPU86_LDouble helper_fldt(uint8_t *ptr) | |
| 436 | +{ | |
| 437 | + return *(CPU86_LDouble *)ptr; | |
| 438 | +} | |
| 439 | + | |
| 440 | +static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) | |
| 441 | +{ | |
| 442 | + *(CPU86_LDouble *)ptr = f; | |
| 443 | +} | |
| 444 | + | |
| 445 | +#else | |
| 446 | + | |
| 447 | +/* we use memory access macros */ | |
| 448 | + | |
| 449 | +static inline CPU86_LDouble helper_fldt(uint8_t *ptr) | |
| 450 | +{ | |
| 451 | + CPU86_LDoubleU temp; | |
| 452 | + | |
| 453 | + temp.l.lower = ldq(ptr); | |
| 454 | + temp.l.upper = lduw(ptr + 8); | |
| 455 | + return temp.d; | |
| 456 | +} | |
| 457 | + | |
| 458 | +static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) | |
| 459 | +{ | |
| 460 | + CPU86_LDoubleU temp; | |
| 461 | + | |
| 462 | + temp.d = f; | |
| 463 | + stq(ptr, temp.l.lower); | |
| 464 | + stw(ptr + 8, temp.l.upper); | |
| 465 | +} | |
| 466 | + | |
| 467 | +#endif /* !CONFIG_USER_ONLY */ | |
| 468 | + | |
| 469 | +#endif /* USE_X86LDOUBLE */ | |
| 321 | 470 | |
| 322 | 471 | const CPU86_LDouble f15rk[7]; |
| 323 | 472 | |
| ... | ... | @@ -368,111 +517,3 @@ static inline void load_eflags(int eflags, int update_mask) |
| 368 | 517 | (eflags & update_mask); |
| 369 | 518 | } |
| 370 | 519 | |
| 371 | -/* XXX: move that to a generic header */ | |
| 372 | -#if !defined(CONFIG_USER_ONLY) | |
| 373 | - | |
| 374 | -#define ldul_user ldl_user | |
| 375 | -#define ldul_kernel ldl_kernel | |
| 376 | - | |
| 377 | -#define ACCESS_TYPE 0 | |
| 378 | -#define MEMSUFFIX _kernel | |
| 379 | -#define DATA_SIZE 1 | |
| 380 | -#include "softmmu_header.h" | |
| 381 | - | |
| 382 | -#define DATA_SIZE 2 | |
| 383 | -#include "softmmu_header.h" | |
| 384 | - | |
| 385 | -#define DATA_SIZE 4 | |
| 386 | -#include "softmmu_header.h" | |
| 387 | - | |
| 388 | -#define DATA_SIZE 8 | |
| 389 | -#include "softmmu_header.h" | |
| 390 | -#undef ACCESS_TYPE | |
| 391 | -#undef MEMSUFFIX | |
| 392 | - | |
| 393 | -#define ACCESS_TYPE 1 | |
| 394 | -#define MEMSUFFIX _user | |
| 395 | -#define DATA_SIZE 1 | |
| 396 | -#include "softmmu_header.h" | |
| 397 | - | |
| 398 | -#define DATA_SIZE 2 | |
| 399 | -#include "softmmu_header.h" | |
| 400 | - | |
| 401 | -#define DATA_SIZE 4 | |
| 402 | -#include "softmmu_header.h" | |
| 403 | - | |
| 404 | -#define DATA_SIZE 8 | |
| 405 | -#include "softmmu_header.h" | |
| 406 | -#undef ACCESS_TYPE | |
| 407 | -#undef MEMSUFFIX | |
| 408 | - | |
| 409 | -/* these access are slower, they must be as rare as possible */ | |
| 410 | -#define ACCESS_TYPE 2 | |
| 411 | -#define MEMSUFFIX _data | |
| 412 | -#define DATA_SIZE 1 | |
| 413 | -#include "softmmu_header.h" | |
| 414 | - | |
| 415 | -#define DATA_SIZE 2 | |
| 416 | -#include "softmmu_header.h" | |
| 417 | - | |
| 418 | -#define DATA_SIZE 4 | |
| 419 | -#include "softmmu_header.h" | |
| 420 | - | |
| 421 | -#define DATA_SIZE 8 | |
| 422 | -#include "softmmu_header.h" | |
| 423 | -#undef ACCESS_TYPE | |
| 424 | -#undef MEMSUFFIX | |
| 425 | - | |
| 426 | -#define ldub(p) ldub_data(p) | |
| 427 | -#define ldsb(p) ldsb_data(p) | |
| 428 | -#define lduw(p) lduw_data(p) | |
| 429 | -#define ldsw(p) ldsw_data(p) | |
| 430 | -#define ldl(p) ldl_data(p) | |
| 431 | -#define ldq(p) ldq_data(p) | |
| 432 | - | |
| 433 | -#define stb(p, v) stb_data(p, v) | |
| 434 | -#define stw(p, v) stw_data(p, v) | |
| 435 | -#define stl(p, v) stl_data(p, v) | |
| 436 | -#define stq(p, v) stq_data(p, v) | |
| 437 | - | |
| 438 | -static inline double ldfq(void *ptr) | |
| 439 | -{ | |
| 440 | - union { | |
| 441 | - double d; | |
| 442 | - uint64_t i; | |
| 443 | - } u; | |
| 444 | - u.i = ldq(ptr); | |
| 445 | - return u.d; | |
| 446 | -} | |
| 447 | - | |
| 448 | -static inline void stfq(void *ptr, double v) | |
| 449 | -{ | |
| 450 | - union { | |
| 451 | - double d; | |
| 452 | - uint64_t i; | |
| 453 | - } u; | |
| 454 | - u.d = v; | |
| 455 | - stq(ptr, u.i); | |
| 456 | -} | |
| 457 | - | |
| 458 | -static inline float ldfl(void *ptr) | |
| 459 | -{ | |
| 460 | - union { | |
| 461 | - float f; | |
| 462 | - uint32_t i; | |
| 463 | - } u; | |
| 464 | - u.i = ldl(ptr); | |
| 465 | - return u.f; | |
| 466 | -} | |
| 467 | - | |
| 468 | -static inline void stfl(void *ptr, float v) | |
| 469 | -{ | |
| 470 | - union { | |
| 471 | - float f; | |
| 472 | - uint32_t i; | |
| 473 | - } u; | |
| 474 | - u.f = v; | |
| 475 | - stl(ptr, u.i); | |
| 476 | -} | |
| 477 | - | |
| 478 | -#endif /* !defined(CONFIG_USER_ONLY) */ | ... | ... |
target-i386/helper.c
| ... | ... | @@ -1318,7 +1318,6 @@ void helper_lar(void) |
| 1318 | 1318 | |
| 1319 | 1319 | /* FPU helpers */ |
| 1320 | 1320 | |
| 1321 | -#ifndef USE_X86LDOUBLE | |
| 1322 | 1321 | void helper_fldt_ST0_A0(void) |
| 1323 | 1322 | { |
| 1324 | 1323 | int new_fpstt; |
| ... | ... | @@ -1332,7 +1331,6 @@ void helper_fstt_ST0_A0(void) |
| 1332 | 1331 | { |
| 1333 | 1332 | helper_fstt(ST0, (uint8_t *)A0); |
| 1334 | 1333 | } |
| 1335 | -#endif | |
| 1336 | 1334 | |
| 1337 | 1335 | /* BCD ops */ |
| 1338 | 1336 | |
| ... | ... | @@ -1729,11 +1727,7 @@ void helper_fsave(uint8_t *ptr, int data32) |
| 1729 | 1727 | ptr += (14 << data32); |
| 1730 | 1728 | for(i = 0;i < 8; i++) { |
| 1731 | 1729 | tmp = ST(i); |
| 1732 | -#ifdef USE_X86LDOUBLE | |
| 1733 | - *(long double *)ptr = tmp; | |
| 1734 | -#else | |
| 1735 | 1730 | helper_fstt(tmp, ptr); |
| 1736 | -#endif | |
| 1737 | 1731 | ptr += 10; |
| 1738 | 1732 | } |
| 1739 | 1733 | |
| ... | ... | @@ -1760,11 +1754,7 @@ void helper_frstor(uint8_t *ptr, int data32) |
| 1760 | 1754 | ptr += (14 << data32); |
| 1761 | 1755 | |
| 1762 | 1756 | for(i = 0;i < 8; i++) { |
| 1763 | -#ifdef USE_X86LDOUBLE | |
| 1764 | - tmp = *(long double *)ptr; | |
| 1765 | -#else | |
| 1766 | 1757 | tmp = helper_fldt(ptr); |
| 1767 | -#endif | |
| 1768 | 1758 | ST(i) = tmp; |
| 1769 | 1759 | ptr += 10; |
| 1770 | 1760 | } | ... | ... |
target-i386/op.c
| ... | ... | @@ -1471,21 +1471,10 @@ void OPPROTO op_fldl_ST0_A0(void) |
| 1471 | 1471 | env->fptags[new_fpstt] = 0; /* validate stack entry */ |
| 1472 | 1472 | } |
| 1473 | 1473 | |
| 1474 | -#ifdef USE_X86LDOUBLE | |
| 1475 | -void OPPROTO op_fldt_ST0_A0(void) | |
| 1476 | -{ | |
| 1477 | - int new_fpstt; | |
| 1478 | - new_fpstt = (env->fpstt - 1) & 7; | |
| 1479 | - env->fpregs[new_fpstt] = *(long double *)A0; | |
| 1480 | - env->fpstt = new_fpstt; | |
| 1481 | - env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
| 1482 | -} | |
| 1483 | -#else | |
| 1484 | 1474 | void OPPROTO op_fldt_ST0_A0(void) |
| 1485 | 1475 | { |
| 1486 | 1476 | helper_fldt_ST0_A0(); |
| 1487 | 1477 | } |
| 1488 | -#endif | |
| 1489 | 1478 | |
| 1490 | 1479 | /* helpers are needed to avoid static constant reference. XXX: find a better way */ |
| 1491 | 1480 | #ifdef USE_INT_TO_FLOAT_HELPERS |
| ... | ... | @@ -1595,17 +1584,10 @@ void OPPROTO op_fstl_ST0_A0(void) |
| 1595 | 1584 | stfq((void *)A0, (double)ST0); |
| 1596 | 1585 | } |
| 1597 | 1586 | |
| 1598 | -#ifdef USE_X86LDOUBLE | |
| 1599 | -void OPPROTO op_fstt_ST0_A0(void) | |
| 1600 | -{ | |
| 1601 | - *(long double *)A0 = ST0; | |
| 1602 | -} | |
| 1603 | -#else | |
| 1604 | 1587 | void OPPROTO op_fstt_ST0_A0(void) |
| 1605 | 1588 | { |
| 1606 | 1589 | helper_fstt_ST0_A0(); |
| 1607 | 1590 | } |
| 1608 | -#endif | |
| 1609 | 1591 | |
| 1610 | 1592 | void OPPROTO op_fist_ST0_A0(void) |
| 1611 | 1593 | { | ... | ... |