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,6 +171,115 @@ void helper_wrmsr(void); | ||
| 171 | void helper_lsl(void); | 171 | void helper_lsl(void); |
| 172 | void helper_lar(void); | 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 | #ifdef USE_X86LDOUBLE | 283 | #ifdef USE_X86LDOUBLE |
| 175 | /* use long double functions */ | 284 | /* use long double functions */ |
| 176 | #define lrint lrintl | 285 | #define lrint lrintl |
| @@ -317,7 +426,47 @@ static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) | @@ -317,7 +426,47 @@ static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) | ||
| 317 | e |= SIGND(temp) >> 16; | 426 | e |= SIGND(temp) >> 16; |
| 318 | stw(ptr + 8, e); | 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 | const CPU86_LDouble f15rk[7]; | 471 | const CPU86_LDouble f15rk[7]; |
| 323 | 472 | ||
| @@ -368,111 +517,3 @@ static inline void load_eflags(int eflags, int update_mask) | @@ -368,111 +517,3 @@ static inline void load_eflags(int eflags, int update_mask) | ||
| 368 | (eflags & update_mask); | 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,7 +1318,6 @@ void helper_lar(void) | ||
| 1318 | 1318 | ||
| 1319 | /* FPU helpers */ | 1319 | /* FPU helpers */ |
| 1320 | 1320 | ||
| 1321 | -#ifndef USE_X86LDOUBLE | ||
| 1322 | void helper_fldt_ST0_A0(void) | 1321 | void helper_fldt_ST0_A0(void) |
| 1323 | { | 1322 | { |
| 1324 | int new_fpstt; | 1323 | int new_fpstt; |
| @@ -1332,7 +1331,6 @@ void helper_fstt_ST0_A0(void) | @@ -1332,7 +1331,6 @@ void helper_fstt_ST0_A0(void) | ||
| 1332 | { | 1331 | { |
| 1333 | helper_fstt(ST0, (uint8_t *)A0); | 1332 | helper_fstt(ST0, (uint8_t *)A0); |
| 1334 | } | 1333 | } |
| 1335 | -#endif | ||
| 1336 | 1334 | ||
| 1337 | /* BCD ops */ | 1335 | /* BCD ops */ |
| 1338 | 1336 | ||
| @@ -1729,11 +1727,7 @@ void helper_fsave(uint8_t *ptr, int data32) | @@ -1729,11 +1727,7 @@ void helper_fsave(uint8_t *ptr, int data32) | ||
| 1729 | ptr += (14 << data32); | 1727 | ptr += (14 << data32); |
| 1730 | for(i = 0;i < 8; i++) { | 1728 | for(i = 0;i < 8; i++) { |
| 1731 | tmp = ST(i); | 1729 | tmp = ST(i); |
| 1732 | -#ifdef USE_X86LDOUBLE | ||
| 1733 | - *(long double *)ptr = tmp; | ||
| 1734 | -#else | ||
| 1735 | helper_fstt(tmp, ptr); | 1730 | helper_fstt(tmp, ptr); |
| 1736 | -#endif | ||
| 1737 | ptr += 10; | 1731 | ptr += 10; |
| 1738 | } | 1732 | } |
| 1739 | 1733 | ||
| @@ -1760,11 +1754,7 @@ void helper_frstor(uint8_t *ptr, int data32) | @@ -1760,11 +1754,7 @@ void helper_frstor(uint8_t *ptr, int data32) | ||
| 1760 | ptr += (14 << data32); | 1754 | ptr += (14 << data32); |
| 1761 | 1755 | ||
| 1762 | for(i = 0;i < 8; i++) { | 1756 | for(i = 0;i < 8; i++) { |
| 1763 | -#ifdef USE_X86LDOUBLE | ||
| 1764 | - tmp = *(long double *)ptr; | ||
| 1765 | -#else | ||
| 1766 | tmp = helper_fldt(ptr); | 1757 | tmp = helper_fldt(ptr); |
| 1767 | -#endif | ||
| 1768 | ST(i) = tmp; | 1758 | ST(i) = tmp; |
| 1769 | ptr += 10; | 1759 | ptr += 10; |
| 1770 | } | 1760 | } |
target-i386/op.c
| @@ -1471,21 +1471,10 @@ void OPPROTO op_fldl_ST0_A0(void) | @@ -1471,21 +1471,10 @@ void OPPROTO op_fldl_ST0_A0(void) | ||
| 1471 | env->fptags[new_fpstt] = 0; /* validate stack entry */ | 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 | void OPPROTO op_fldt_ST0_A0(void) | 1474 | void OPPROTO op_fldt_ST0_A0(void) |
| 1485 | { | 1475 | { |
| 1486 | helper_fldt_ST0_A0(); | 1476 | helper_fldt_ST0_A0(); |
| 1487 | } | 1477 | } |
| 1488 | -#endif | ||
| 1489 | 1478 | ||
| 1490 | /* helpers are needed to avoid static constant reference. XXX: find a better way */ | 1479 | /* helpers are needed to avoid static constant reference. XXX: find a better way */ |
| 1491 | #ifdef USE_INT_TO_FLOAT_HELPERS | 1480 | #ifdef USE_INT_TO_FLOAT_HELPERS |
| @@ -1595,17 +1584,10 @@ void OPPROTO op_fstl_ST0_A0(void) | @@ -1595,17 +1584,10 @@ void OPPROTO op_fstl_ST0_A0(void) | ||
| 1595 | stfq((void *)A0, (double)ST0); | 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 | void OPPROTO op_fstt_ST0_A0(void) | 1587 | void OPPROTO op_fstt_ST0_A0(void) |
| 1605 | { | 1588 | { |
| 1606 | helper_fstt_ST0_A0(); | 1589 | helper_fstt_ST0_A0(); |
| 1607 | } | 1590 | } |
| 1608 | -#endif | ||
| 1609 | 1591 | ||
| 1610 | void OPPROTO op_fist_ST0_A0(void) | 1592 | void OPPROTO op_fist_ST0_A0(void) |
| 1611 | { | 1593 | { |