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 | { |