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