Revision 7a0e1f41

b/dyngen-exec.h
62 62
extern int printf(const char *, ...);
63 63
#undef NULL
64 64
#define NULL 0
65
#if defined(_BSD) && !defined(__APPLE__)
66
#include <ieeefp.h>
67

  
68
#define FE_TONEAREST   FP_RN
69
#define FE_DOWNWARD    FP_RM
70
#define FE_UPWARD      FP_RP
71
#define FE_TOWARDZERO  FP_RZ
72
#define fesetround(x)  fpsetround(x)
73
#else
74
#include <fenv.h>
75
#endif
76 65

  
77 66
#ifdef __i386__
78 67
#define AREG0 "ebp"
b/target-i386/cpu.h
36 36

  
37 37
#include "cpu-defs.h"
38 38

  
39
#include "softfloat.h"
40

  
39 41
#if defined(__i386__) && !defined(CONFIG_SOFTMMU)
40 42
#define USE_CODE_COPY
41 43
#endif
......
332 334
    CC_OP_NB,
333 335
};
334 336

  
335
#if (defined(__i386__) || defined(__x86_64__)) && !defined(_BSD)
337
#ifdef FLOATX80
336 338
#define USE_X86LDOUBLE
337 339
#endif
338 340

  
339 341
#ifdef USE_X86LDOUBLE
340
typedef long double CPU86_LDouble;
342
typedef floatx80 CPU86_LDouble;
341 343
#else
342
typedef double CPU86_LDouble;
344
typedef float64 CPU86_LDouble;
343 345
#endif
344 346

  
345 347
typedef struct SegmentCache {
......
354 356
    uint16_t _w[8];
355 357
    uint32_t _l[4];
356 358
    uint64_t _q[2];
357
    float _s[4];
358
    double _d[2];
359
    float32 _s[4];
360
    float64 _d[2];
359 361
} XMMReg;
360 362

  
361 363
typedef union {
......
441 443
    } fpregs[8];
442 444

  
443 445
    /* emulator internal variables */
446
    float_status fp_status;
444 447
    CPU86_LDouble ft0;
445 448
    union {
446 449
	float f;
......
449 452
        int64_t i64;
450 453
    } fp_convert;
451 454
    
455
    float_status sse_status;
452 456
    uint32_t mxcsr;
453 457
    XMMReg xmm_regs[CPU_NB_REGS];
454 458
    XMMReg xmm_t0;
b/target-i386/exec.h
139 139
#include "cpu.h"
140 140
#include "exec-all.h"
141 141

  
142
/* XXX: add a generic FPU library */
143

  
144
static inline double float32_to_float64(float a)
145
{
146
    return a;
147
}
148

  
149
static inline float float64_to_float32(double a)
150
{
151
    return a;
152
}
153

  
154
#if defined(__powerpc__)
155
/* better to call an helper on ppc */
156
float int32_to_float32(int32_t a);
157
double int32_to_float64(int32_t a);
158
#else
159
static inline float int32_to_float32(int32_t a)
160
{
161
    return (float)a;
162
}
163

  
164
static inline double int32_to_float64(int32_t a)
165
{
166
    return (double)a;
167
}
168
#endif
169

  
170
static inline float int64_to_float32(int64_t a)
171
{
172
    return (float)a;
173
}
174

  
175
static inline double int64_to_float64(int64_t a)
176
{
177
    return (double)a;
178
}
179

  
180 142
typedef struct CCTable {
181 143
    int (*compute_all)(void); /* return all the flags */
182 144
    int (*compute_c)(void);  /* return the C flag */
......
358 320

  
359 321
#ifdef USE_X86LDOUBLE
360 322
/* use long double functions */
361
#define lrint lrintl
362
#define llrint llrintl
363
#define fabs fabsl
323
#define floatx_to_int32 floatx80_to_int32
324
#define floatx_to_int64 floatx80_to_int64
325
#define floatx_abs floatx80_abs
326
#define floatx_chs floatx80_chs
327
#define floatx_round_to_int floatx80_round_to_int
364 328
#define sin sinl
365 329
#define cos cosl
366 330
#define sqrt sqrtl
......
370 334
#define atan2 atan2l
371 335
#define floor floorl
372 336
#define ceil ceill
373
#define rint rintl
374
#endif
375

  
376
#if !defined(_BSD)
377
extern int lrint(CPU86_LDouble x);
378
extern int64_t llrint(CPU86_LDouble x);
379 337
#else
380
#define lrint(d)		((int)rint(d))
381
#define llrint(d)		((int)rint(d))
338
#define floatx_to_int32 float64_to_int32
339
#define floatx_to_int64 float64_to_int64
340
#define floatx_abs float64_abs
341
#define floatx_chs float64_chs
342
#define floatx_round_to_int float64_round_to_int
382 343
#endif
383
extern CPU86_LDouble fabs(CPU86_LDouble x);
344

  
384 345
extern CPU86_LDouble sin(CPU86_LDouble x);
385 346
extern CPU86_LDouble cos(CPU86_LDouble x);
386 347
extern CPU86_LDouble sqrt(CPU86_LDouble x);
......
390 351
extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble);
391 352
extern CPU86_LDouble floor(CPU86_LDouble x);
392 353
extern CPU86_LDouble ceil(CPU86_LDouble x);
393
extern CPU86_LDouble rint(CPU86_LDouble x);
394 354

  
395 355
#define RC_MASK         0xc00
396 356
#define RC_NEAR		0x000
......
400 360

  
401 361
#define MAXTAN 9223372036854775808.0
402 362

  
403
#ifdef __arm__
404
/* we have no way to do correct rounding - a FPU emulator is needed */
405
#define FE_DOWNWARD   FE_TONEAREST
406
#define FE_UPWARD     FE_TONEAREST
407
#define FE_TOWARDZERO FE_TONEAREST
408
#endif
409

  
410 363
#ifdef USE_X86LDOUBLE
411 364

  
412 365
/* only for x86 */
......
596 549
float approx_rcp(float a);
597 550
double helper_sqrt(double a);
598 551
int fpu_isnan(double a);
552
void update_fp_status(void);
599 553

  
600 554
extern const uint8_t parity_table[256];
601 555
extern const uint8_t rclw_table[32];
b/target-i386/helper.c
2541 2541

  
2542 2542
void helper_fbst_ST0_A0(void)
2543 2543
{
2544
    CPU86_LDouble tmp;
2545 2544
    int v;
2546 2545
    target_ulong mem_ref, mem_end;
2547 2546
    int64_t val;
2548 2547

  
2549
    tmp = rint(ST0);
2550
    val = (int64_t)tmp;
2548
    val = floatx_to_int64(ST0, &env->fp_status);
2551 2549
    mem_ref = A0;
2552 2550
    mem_end = mem_ref + 9;
2553 2551
    if (val < 0) {
......
2740 2738

  
2741 2739
void helper_frndint(void)
2742 2740
{
2743
    CPU86_LDouble a;
2744

  
2745
    a = ST0;
2746
#ifdef __arm__
2747
    switch(env->fpuc & RC_MASK) {
2748
    default:
2749
    case RC_NEAR:
2750
        asm("rndd %0, %1" : "=f" (a) : "f"(a));
2751
        break;
2752
    case RC_DOWN:
2753
        asm("rnddm %0, %1" : "=f" (a) : "f"(a));
2754
        break;
2755
    case RC_UP:
2756
        asm("rnddp %0, %1" : "=f" (a) : "f"(a));
2757
        break;
2758
    case RC_CHOP:
2759
        asm("rnddz %0, %1" : "=f" (a) : "f"(a));
2760
        break;
2761
    }
2762
#else
2763
    a = rint(a);
2764
#endif
2765
    ST0 = a;
2741
    ST0 = floatx_round_to_int(ST0, &env->fp_status);
2766 2742
}
2767 2743

  
2768 2744
void helper_fscale(void)
......
3263 3239
    return 1.0 / a;
3264 3240
}
3265 3241

  
3266
/* XXX: find a better solution */
3267
double helper_sqrt(double a)
3242
void update_fp_status(void)
3268 3243
{
3269
    return sqrt(a);
3270
}
3244
    int rnd_type;
3271 3245

  
3272
/* XXX: move that to another file */
3273
#if defined(__powerpc__)
3274
/* better to call an helper on ppc */
3275
float int32_to_float32(int32_t a)
3276
{
3277
    return (float)a;
3278
}
3279

  
3280
double int32_to_float64(int32_t a)
3281
{
3282
    return (double)a;
3283
}
3246
    /* set rounding mode */
3247
    switch(env->fpuc & RC_MASK) {
3248
    default:
3249
    case RC_NEAR:
3250
        rnd_type = float_round_nearest_even;
3251
        break;
3252
    case RC_DOWN:
3253
        rnd_type = float_round_down;
3254
        break;
3255
    case RC_UP:
3256
        rnd_type = float_round_up;
3257
        break;
3258
    case RC_CHOP:
3259
        rnd_type = float_round_to_zero;
3260
        break;
3261
    }
3262
    set_float_rounding_mode(rnd_type, &env->fp_status);
3263
#ifdef FLOATX80
3264
    switch((env->fpuc >> 8) & 3) {
3265
    case 0:
3266
        rnd_type = 32;
3267
        break;
3268
    case 2:
3269
        rnd_type = 64;
3270
        break;
3271
    case 3:
3272
    default:
3273
        rnd_type = 80;
3274
        break;
3275
    }
3276
    set_floatx80_rounding_precision(rnd_type, &env->fp_status);
3284 3277
#endif
3278
}
3285 3279

  
3286 3280
#if !defined(CONFIG_USER_ONLY) 
3287 3281

  
b/target-i386/op.c
1598 1598
   functions comes from the LGPL'ed x86 emulator found in the Willows
1599 1599
   TWIN windows emulator. */
1600 1600

  
1601
#if defined(__powerpc__)
1602
extern CPU86_LDouble copysign(CPU86_LDouble, CPU86_LDouble);
1603

  
1604
/* correct (but slow) PowerPC rint() (glibc version is incorrect) */
1605
double qemu_rint(double x)
1606
{
1607
    double y = 4503599627370496.0;
1608
    if (fabs(x) >= y)
1609
        return x;
1610
    if (x < 0) 
1611
        y = -y;
1612
    y = (x + y) - y;
1613
    if (y == 0.0)
1614
        y = copysign(y, x);
1615
    return y;
1616
}
1617

  
1618
#define rint qemu_rint
1619
#endif
1620

  
1621 1601
/* fp load FT0 */
1622 1602

  
1623 1603
void OPPROTO op_flds_FT0_A0(void)
......
1866 1846
    int val;
1867 1847

  
1868 1848
    d = ST0;
1869
    val = lrint(d);
1849
    val = floatx_to_int32(d, &env->fp_status);
1870 1850
    if (val != (int16_t)val)
1871 1851
        val = -32768;
1872 1852
    stw(A0, val);
......
1883 1863
    int val;
1884 1864

  
1885 1865
    d = ST0;
1886
    val = lrint(d);
1866
    val = floatx_to_int32(d, &env->fp_status);
1887 1867
    stl(A0, val);
1888 1868
    FORCE_RET();
1889 1869
}
......
1898 1878
    int64_t val;
1899 1879

  
1900 1880
    d = ST0;
1901
    val = llrint(d);
1881
    val = floatx_to_int64(d, &env->fp_status);
1902 1882
    stq(A0, val);
1903 1883
    FORCE_RET();
1904 1884
}
......
2101 2081
/* misc FPU operations */
2102 2082
void OPPROTO op_fchs_ST0(void)
2103 2083
{
2104
    ST0 = -ST0;
2084
    ST0 = floatx_chs(ST0);
2105 2085
}
2106 2086

  
2107 2087
void OPPROTO op_fabs_ST0(void)
2108 2088
{
2109
    ST0 = fabs(ST0);
2089
    ST0 = floatx_abs(ST0);
2110 2090
}
2111 2091

  
2112 2092
void OPPROTO op_fxam_ST0(void)
......
2251 2231

  
2252 2232
void OPPROTO op_fldcw_A0(void)
2253 2233
{
2254
    int rnd_type;
2255 2234
    env->fpuc = lduw(A0);
2256
    /* set rounding mode */
2257
    switch(env->fpuc & RC_MASK) {
2258
    default:
2259
    case RC_NEAR:
2260
        rnd_type = FE_TONEAREST;
2261
        break;
2262
    case RC_DOWN:
2263
        rnd_type = FE_DOWNWARD;
2264
        break;
2265
    case RC_UP:
2266
        rnd_type = FE_UPWARD;
2267
        break;
2268
    case RC_CHOP:
2269
        rnd_type = FE_TOWARDZERO;
2270
        break;
2271
    }
2272
    fesetround(rnd_type);
2235
    update_fp_status();
2273 2236
}
2274 2237

  
2275 2238
void OPPROTO op_fclex(void)
b/target-i386/ops_sse.h
654 654
    Reg *d, *s;\
655 655
    d = (Reg *)((char *)env + PARAM1);\
656 656
    s = (Reg *)((char *)env + PARAM2);\
657
    d->XMM_S(0) = F(d->XMM_S(0), s->XMM_S(0));\
658
    d->XMM_S(1) = F(d->XMM_S(1), s->XMM_S(1));\
659
    d->XMM_S(2) = F(d->XMM_S(2), s->XMM_S(2));\
660
    d->XMM_S(3) = F(d->XMM_S(3), s->XMM_S(3));\
657
    d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
658
    d->XMM_S(1) = F(32, d->XMM_S(1), s->XMM_S(1));\
659
    d->XMM_S(2) = F(32, d->XMM_S(2), s->XMM_S(2));\
660
    d->XMM_S(3) = F(32, d->XMM_S(3), s->XMM_S(3));\
661 661
}\
662 662
\
663 663
void OPPROTO op_ ## name ## ss (void)\
......
665 665
    Reg *d, *s;\
666 666
    d = (Reg *)((char *)env + PARAM1);\
667 667
    s = (Reg *)((char *)env + PARAM2);\
668
    d->XMM_S(0) = F(d->XMM_S(0), s->XMM_S(0));\
668
    d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
669 669
}\
670 670
void OPPROTO op_ ## name ## pd (void)\
671 671
{\
672 672
    Reg *d, *s;\
673 673
    d = (Reg *)((char *)env + PARAM1);\
674 674
    s = (Reg *)((char *)env + PARAM2);\
675
    d->XMM_D(0) = F(d->XMM_D(0), s->XMM_D(0));\
676
    d->XMM_D(1) = F(d->XMM_D(1), s->XMM_D(1));\
675
    d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
676
    d->XMM_D(1) = F(64, d->XMM_D(1), s->XMM_D(1));\
677 677
}\
678 678
\
679 679
void OPPROTO op_ ## name ## sd (void)\
......
681 681
    Reg *d, *s;\
682 682
    d = (Reg *)((char *)env + PARAM1);\
683 683
    s = (Reg *)((char *)env + PARAM2);\
684
    d->XMM_D(0) = F(d->XMM_D(0), s->XMM_D(0));\
684
    d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
685 685
}
686 686

  
687
#define FPU_ADD(a, b) (a) + (b)
688
#define FPU_SUB(a, b) (a) - (b)
689
#define FPU_MUL(a, b) (a) * (b)
690
#define FPU_DIV(a, b) (a) / (b)
691
#define FPU_MIN(a, b) (a) < (b) ? (a) : (b)
692
#define FPU_MAX(a, b) (a) > (b) ? (a) : (b)
693
#define FPU_SQRT(a, b) helper_sqrt(b)
687
#define FPU_ADD(size, a, b) float ## size ## _add(a, b, &env->sse_status)
688
#define FPU_SUB(size, a, b) float ## size ## _sub(a, b, &env->sse_status)
689
#define FPU_MUL(size, a, b) float ## size ## _mul(a, b, &env->sse_status)
690
#define FPU_DIV(size, a, b) float ## size ## _div(a, b, &env->sse_status)
691
#define FPU_MIN(size, a, b) (a) < (b) ? (a) : (b)
692
#define FPU_MAX(size, a, b) (a) > (b) ? (a) : (b)
693
#define FPU_SQRT(size, a, b) float ## size ## _sqrt(b, &env->sse_status)
694 694

  
695 695
SSE_OP_S(add, FPU_ADD)
696 696
SSE_OP_S(sub, FPU_SUB)
......
710 710
    s = (Reg *)((char *)env + PARAM2);
711 711
    s0 = s->XMM_S(0);
712 712
    s1 = s->XMM_S(1);
713
    d->XMM_D(0) = float32_to_float64(s0);
714
    d->XMM_D(1) = float32_to_float64(s1);
713
    d->XMM_D(0) = float32_to_float64(s0, &env->sse_status);
714
    d->XMM_D(1) = float32_to_float64(s1, &env->sse_status);
715 715
}
716 716

  
717 717
void OPPROTO op_cvtpd2ps(void)
......
719 719
    Reg *d, *s;
720 720
    d = (Reg *)((char *)env + PARAM1);
721 721
    s = (Reg *)((char *)env + PARAM2);
722
    d->XMM_S(0) = float64_to_float32(s->XMM_D(0));
723
    d->XMM_S(1) = float64_to_float32(s->XMM_D(1));
722
    d->XMM_S(0) = float64_to_float32(s->XMM_D(0), &env->sse_status);
723
    d->XMM_S(1) = float64_to_float32(s->XMM_D(1), &env->sse_status);
724 724
    d->Q(1) = 0;
725 725
}
726 726

  
......
729 729
    Reg *d, *s;
730 730
    d = (Reg *)((char *)env + PARAM1);
731 731
    s = (Reg *)((char *)env + PARAM2);
732
    d->XMM_D(0) = float32_to_float64(s->XMM_S(0));
732
    d->XMM_D(0) = float32_to_float64(s->XMM_S(0), &env->sse_status);
733 733
}
734 734

  
735 735
void OPPROTO op_cvtsd2ss(void)
......
737 737
    Reg *d, *s;
738 738
    d = (Reg *)((char *)env + PARAM1);
739 739
    s = (Reg *)((char *)env + PARAM2);
740
    d->XMM_S(0) = float64_to_float32(s->XMM_D(0));
740
    d->XMM_S(0) = float64_to_float32(s->XMM_D(0), &env->sse_status);
741 741
}
742 742

  
743 743
/* integer to float */
......
745 745
{
746 746
    XMMReg *d = (XMMReg *)((char *)env + PARAM1);
747 747
    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
748
    d->XMM_S(0) = int32_to_float32(s->XMM_L(0));
749
    d->XMM_S(1) = int32_to_float32(s->XMM_L(1));
750
    d->XMM_S(2) = int32_to_float32(s->XMM_L(2));
751
    d->XMM_S(3) = int32_to_float32(s->XMM_L(3));
748
    d->XMM_S(0) = int32_to_float32(s->XMM_L(0), &env->sse_status);
749
    d->XMM_S(1) = int32_to_float32(s->XMM_L(1), &env->sse_status);
750
    d->XMM_S(2) = int32_to_float32(s->XMM_L(2), &env->sse_status);
751
    d->XMM_S(3) = int32_to_float32(s->XMM_L(3), &env->sse_status);
752 752
}
753 753

  
754 754
void OPPROTO op_cvtdq2pd(void)
......
758 758
    int32_t l0, l1;
759 759
    l0 = (int32_t)s->XMM_L(0);
760 760
    l1 = (int32_t)s->XMM_L(1);
761
    d->XMM_D(0) = int32_to_float64(l0);
762
    d->XMM_D(1) = int32_to_float64(l1);
761
    d->XMM_D(0) = int32_to_float64(l0, &env->sse_status);
762
    d->XMM_D(1) = int32_to_float64(l1, &env->sse_status);
763 763
}
764 764

  
765 765
void OPPROTO op_cvtpi2ps(void)
766 766
{
767 767
    XMMReg *d = (Reg *)((char *)env + PARAM1);
768 768
    MMXReg *s = (MMXReg *)((char *)env + PARAM2);
769
    d->XMM_S(0) = int32_to_float32(s->MMX_L(0));
770
    d->XMM_S(1) = int32_to_float32(s->MMX_L(1));
769
    d->XMM_S(0) = int32_to_float32(s->MMX_L(0), &env->sse_status);
770
    d->XMM_S(1) = int32_to_float32(s->MMX_L(1), &env->sse_status);
771 771
}
772 772

  
773 773
void OPPROTO op_cvtpi2pd(void)
774 774
{
775 775
    XMMReg *d = (Reg *)((char *)env + PARAM1);
776 776
    MMXReg *s = (MMXReg *)((char *)env + PARAM2);
777
    d->XMM_D(0) = int32_to_float64(s->MMX_L(0));
778
    d->XMM_D(1) = int32_to_float64(s->MMX_L(1));
777
    d->XMM_D(0) = int32_to_float64(s->MMX_L(0), &env->sse_status);
778
    d->XMM_D(1) = int32_to_float64(s->MMX_L(1), &env->sse_status);
779 779
}
780 780

  
781 781
void OPPROTO op_cvtsi2ss(void)
782 782
{
783 783
    XMMReg *d = (Reg *)((char *)env + PARAM1);
784
    d->XMM_S(0) = int32_to_float32(T0);
784
    d->XMM_S(0) = int32_to_float32(T0, &env->sse_status);
785 785
}
786 786

  
787 787
void OPPROTO op_cvtsi2sd(void)
788 788
{
789 789
    XMMReg *d = (Reg *)((char *)env + PARAM1);
790
    d->XMM_D(0) = int32_to_float64(T0);
790
    d->XMM_D(0) = int32_to_float64(T0, &env->sse_status);
791 791
}
792 792

  
793 793
#ifdef TARGET_X86_64
794 794
void OPPROTO op_cvtsq2ss(void)
795 795
{
796 796
    XMMReg *d = (Reg *)((char *)env + PARAM1);
797
    d->XMM_S(0) = int64_to_float32(T0);
797
    d->XMM_S(0) = int64_to_float32(T0, &env->sse_status);
798 798
}
799 799

  
800 800
void OPPROTO op_cvtsq2sd(void)
801 801
{
802 802
    XMMReg *d = (Reg *)((char *)env + PARAM1);
803
    d->XMM_D(0) = int64_to_float64(T0);
803
    d->XMM_D(0) = int64_to_float64(T0, &env->sse_status);
804 804
}
805 805
#endif
806 806

  
......
809 809
{
810 810
    XMMReg *d = (XMMReg *)((char *)env + PARAM1);
811 811
    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
812
    d->XMM_L(0) = lrint(s->XMM_S(0));
813
    d->XMM_L(1) = lrint(s->XMM_S(1));
814
    d->XMM_L(2) = lrint(s->XMM_S(2));
815
    d->XMM_L(3) = lrint(s->XMM_S(3));
812
    d->XMM_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status);
813
    d->XMM_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status);
814
    d->XMM_L(2) = float32_to_int32(s->XMM_S(2), &env->sse_status);
815
    d->XMM_L(3) = float32_to_int32(s->XMM_S(3), &env->sse_status);
816 816
}
817 817

  
818 818
void OPPROTO op_cvtpd2dq(void)
819 819
{
820 820
    XMMReg *d = (XMMReg *)((char *)env + PARAM1);
821 821
    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
822
    d->XMM_L(0) = lrint(s->XMM_D(0));
823
    d->XMM_L(1) = lrint(s->XMM_D(1));
822
    d->XMM_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status);
823
    d->XMM_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status);
824 824
    d->XMM_Q(1) = 0;
825 825
}
826 826

  
......
828 828
{
829 829
    MMXReg *d = (MMXReg *)((char *)env + PARAM1);
830 830
    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
831
    d->MMX_L(0) = lrint(s->XMM_S(0));
832
    d->MMX_L(1) = lrint(s->XMM_S(1));
831
    d->MMX_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status);
832
    d->MMX_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status);
833 833
}
834 834

  
835 835
void OPPROTO op_cvtpd2pi(void)
836 836
{
837 837
    MMXReg *d = (MMXReg *)((char *)env + PARAM1);
838 838
    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
839
    d->MMX_L(0) = lrint(s->XMM_D(0));
840
    d->MMX_L(1) = lrint(s->XMM_D(1));
839
    d->MMX_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status);
840
    d->MMX_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status);
841 841
}
842 842

  
843 843
void OPPROTO op_cvtss2si(void)
844 844
{
845 845
    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
846
    T0 = (int32_t)lrint(s->XMM_S(0));
846
    T0 = float32_to_int32(s->XMM_S(0), &env->sse_status);
847 847
}
848 848

  
849 849
void OPPROTO op_cvtsd2si(void)
850 850
{
851 851
    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
852
    T0 = (int32_t)lrint(s->XMM_D(0));
852
    T0 = float64_to_int32(s->XMM_D(0), &env->sse_status);
853 853
}
854 854

  
855 855
#ifdef TARGET_X86_64
856 856
void OPPROTO op_cvtss2sq(void)
857 857
{
858 858
    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
859
    T0 = llrint(s->XMM_S(0));
859
    T0 = float32_to_int64(s->XMM_S(0), &env->sse_status);
860 860
}
861 861

  
862 862
void OPPROTO op_cvtsd2sq(void)
863 863
{
864 864
    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
865
    T0 = llrint(s->XMM_D(0));
865
    T0 = float64_to_int64(s->XMM_D(0), &env->sse_status);
866 866
}
867 867
#endif
868 868

  
......
871 871
{
872 872
    XMMReg *d = (XMMReg *)((char *)env + PARAM1);
873 873
    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
874
    d->XMM_L(0) = (int32_t)s->XMM_S(0);
875
    d->XMM_L(1) = (int32_t)s->XMM_S(1);
876
    d->XMM_L(2) = (int32_t)s->XMM_S(2);
877
    d->XMM_L(3) = (int32_t)s->XMM_S(3);
874
    d->XMM_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
875
    d->XMM_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status);
876
    d->XMM_L(2) = float32_to_int32_round_to_zero(s->XMM_S(2), &env->sse_status);
877
    d->XMM_L(3) = float32_to_int32_round_to_zero(s->XMM_S(3), &env->sse_status);
878 878
}
879 879

  
880 880
void OPPROTO op_cvttpd2dq(void)
881 881
{
882 882
    XMMReg *d = (XMMReg *)((char *)env + PARAM1);
883 883
    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
884
    d->XMM_L(0) = (int32_t)s->XMM_D(0);
885
    d->XMM_L(1) = (int32_t)s->XMM_D(1);
884
    d->XMM_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
885
    d->XMM_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status);
886 886
    d->XMM_Q(1) = 0;
887 887
}
888 888

  
......
890 890
{
891 891
    MMXReg *d = (MMXReg *)((char *)env + PARAM1);
892 892
    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
893
    d->MMX_L(0) = (int32_t)(s->XMM_S(0));
894
    d->MMX_L(1) = (int32_t)(s->XMM_S(1));
893
    d->MMX_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
894
    d->MMX_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status);
895 895
}
896 896

  
897 897
void OPPROTO op_cvttpd2pi(void)
898 898
{
899 899
    MMXReg *d = (MMXReg *)((char *)env + PARAM1);
900 900
    XMMReg *s = (XMMReg *)((char *)env + PARAM2);
901
    d->MMX_L(0) = (int32_t)(s->XMM_D(0));
902
    d->MMX_L(1) = (int32_t)(s->XMM_D(1));
901
    d->MMX_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
902
    d->MMX_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status);
903 903
}
904 904

  
905 905
void OPPROTO op_cvttss2si(void)
906 906
{
907 907
    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
908
    T0 = (int32_t)(s->XMM_S(0));
908
    T0 = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
909 909
}
910 910

  
911 911
void OPPROTO op_cvttsd2si(void)
912 912
{
913 913
    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
914
    T0 = (int32_t)(s->XMM_D(0));
914
    T0 = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
915 915
}
916 916

  
917 917
#ifdef TARGET_X86_64
918 918
void OPPROTO op_cvttss2sq(void)
919 919
{
920 920
    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
921
    T0 = (int64_t)(s->XMM_S(0));
921
    T0 = float32_to_int64_round_to_zero(s->XMM_S(0), &env->sse_status);
922 922
}
923 923

  
924 924
void OPPROTO op_cvttsd2sq(void)
925 925
{
926 926
    XMMReg *s = (XMMReg *)((char *)env + PARAM1);
927
    T0 = (int64_t)(s->XMM_D(0));
927
    T0 = float64_to_int64_round_to_zero(s->XMM_D(0), &env->sse_status);
928 928
}
929 929
#endif
930 930

  
b/target-sparc/cpu.h
15 15

  
16 16
#include "cpu-defs.h"
17 17

  
18
#include "softfloat.h"
19

  
18 20
/*#define EXCP_INTERRUPT 0x100*/
19 21

  
20 22
/* trap definitions */
......
150 152
    /* temporary float registers */
151 153
    float ft0, ft1, ft2;
152 154
    double dt0, dt1, dt2;
155
    float_status fp_status;
153 156
#if defined(TARGET_SPARC64)
154 157
    target_ulong t0, t1, t2;
155 158
#endif
b/target-sparc/op_helper.c
1
#include <math.h>
2
#include <fenv.h>
3 1
#include "exec.h"
4 2

  
5 3
//#define DEBUG_MMU
......
24 22

  
25 23
void do_fabss(void)
26 24
{
27
    FT0 = fabsf(FT1);
25
    FT0 = float32_abs(FT1);
28 26
}
29 27

  
30 28
void do_fsqrts(void)
31 29
{
32
    FT0 = sqrtf(FT1);
30
    FT0 = float32_sqrt(FT1, &env->fp_status);
33 31
}
34 32

  
35 33
void do_fsqrtd(void)
36 34
{
37
    DT0 = sqrt(DT1);
35
    DT0 = float64_sqrt(DT1, &env->fp_status);
38 36
}
39 37

  
40 38
void do_fcmps (void)
......
252 250

  
253 251
void helper_ldfsr(void)
254 252
{
253
    int rnd_mode;
255 254
    switch (env->fsr & FSR_RD_MASK) {
256 255
    case FSR_RD_NEAREST:
257
	fesetround(FE_TONEAREST);
256
        rnd_mode = float_round_nearest_even;
258 257
	break;
259 258
    case FSR_RD_ZERO:
260
	fesetround(FE_TOWARDZERO);
259
        rnd_mode = float_round_to_zero;
261 260
	break;
262 261
    case FSR_RD_POS:
263
	fesetround(FE_UPWARD);
262
        rnd_mode = float_round_up;
264 263
	break;
265 264
    case FSR_RD_NEG:
266
	fesetround(FE_DOWNWARD);
265
        rnd_mode = float_round_down;
267 266
	break;
268 267
    }
268
    set_float_rounding_mode(rnd_mode, &env->fp_status);
269 269
}
270 270

  
271 271
void cpu_get_fp64(uint64_t *pmant, uint16_t *pexp, double f)
b/vl.c
2271 2271
    }
2272 2272

  
2273 2273
    env->fpuc = fpuc;
2274
    /* XXX: restore FPU round state */
2274 2275
    env->fpstt = (fpus >> 11) & 7;
2275 2276
    env->fpus = fpus & ~0x3800;
2276 2277
    fptag ^= 0xff;

Also available in: Unified diff