Commit 53cd6637924a83481038b2266c59dc1e1ff7bb11

Authored by bellard
1 parent 7a0e1f41

soft float support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1337 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
@@ -119,7 +119,7 @@ static inline void tswap64s(uint64_t *s) @@ -119,7 +119,7 @@ static inline void tswap64s(uint64_t *s)
119 /* NOTE: arm FPA is horrible as double 32 bit words are stored in big 119 /* NOTE: arm FPA is horrible as double 32 bit words are stored in big
120 endian ! */ 120 endian ! */
121 typedef union { 121 typedef union {
122 - double d; 122 + float64 d;
123 #if defined(WORDS_BIGENDIAN) || (defined(__arm__) && !defined(__VFP_FP__)) 123 #if defined(WORDS_BIGENDIAN) || (defined(__arm__) && !defined(__VFP_FP__))
124 struct { 124 struct {
125 uint32_t upper; 125 uint32_t upper;
@@ -268,27 +268,27 @@ static inline void stq_p(void *ptr, uint64_t v) @@ -268,27 +268,27 @@ static inline void stq_p(void *ptr, uint64_t v)
268 268
269 /* float access */ 269 /* float access */
270 270
271 -static inline float ldfl_p(void *ptr) 271 +static inline float32 ldfl_p(void *ptr)
272 { 272 {
273 union { 273 union {
274 - float f; 274 + float32 f;
275 uint32_t i; 275 uint32_t i;
276 } u; 276 } u;
277 u.i = ldl_p(ptr); 277 u.i = ldl_p(ptr);
278 return u.f; 278 return u.f;
279 } 279 }
280 280
281 -static inline void stfl_p(void *ptr, float v) 281 +static inline void stfl_p(void *ptr, float32 v)
282 { 282 {
283 union { 283 union {
284 - float f; 284 + float32 f;
285 uint32_t i; 285 uint32_t i;
286 } u; 286 } u;
287 u.f = v; 287 u.f = v;
288 stl_p(ptr, u.i); 288 stl_p(ptr, u.i);
289 } 289 }
290 290
291 -static inline double ldfq_p(void *ptr) 291 +static inline float64 ldfq_p(void *ptr)
292 { 292 {
293 CPU_DoubleU u; 293 CPU_DoubleU u;
294 u.l.lower = ldl_p(ptr); 294 u.l.lower = ldl_p(ptr);
@@ -296,7 +296,7 @@ static inline double ldfq_p(void *ptr) @@ -296,7 +296,7 @@ static inline double ldfq_p(void *ptr)
296 return u.d; 296 return u.d;
297 } 297 }
298 298
299 -static inline void stfq_p(void *ptr, double v) 299 +static inline void stfq_p(void *ptr, float64 v)
300 { 300 {
301 CPU_DoubleU u; 301 CPU_DoubleU u;
302 u.d = v; 302 u.d = v;
@@ -397,27 +397,27 @@ static inline void stq_p(void *ptr, uint64_t v) @@ -397,27 +397,27 @@ static inline void stq_p(void *ptr, uint64_t v)
397 397
398 /* float access */ 398 /* float access */
399 399
400 -static inline float ldfl_p(void *ptr) 400 +static inline float32 ldfl_p(void *ptr)
401 { 401 {
402 union { 402 union {
403 - float f; 403 + float32 f;
404 uint32_t i; 404 uint32_t i;
405 } u; 405 } u;
406 u.i = ldl_p(ptr); 406 u.i = ldl_p(ptr);
407 return u.f; 407 return u.f;
408 } 408 }
409 409
410 -static inline void stfl_p(void *ptr, float v) 410 +static inline void stfl_p(void *ptr, float32 v)
411 { 411 {
412 union { 412 union {
413 - float f; 413 + float32 f;
414 uint32_t i; 414 uint32_t i;
415 } u; 415 } u;
416 u.f = v; 416 u.f = v;
417 stl_p(ptr, u.i); 417 stl_p(ptr, u.i);
418 } 418 }
419 419
420 -static inline double ldfq_p(void *ptr) 420 +static inline float64 ldfq_p(void *ptr)
421 { 421 {
422 CPU_DoubleU u; 422 CPU_DoubleU u;
423 u.l.upper = ldl_p(ptr); 423 u.l.upper = ldl_p(ptr);
@@ -425,7 +425,7 @@ static inline double ldfq_p(void *ptr) @@ -425,7 +425,7 @@ static inline double ldfq_p(void *ptr)
425 return u.d; 425 return u.d;
426 } 426 }
427 427
428 -static inline void stfq_p(void *ptr, double v) 428 +static inline void stfq_p(void *ptr, float64 v)
429 { 429 {
430 CPU_DoubleU u; 430 CPU_DoubleU u;
431 u.d = v; 431 u.d = v;
@@ -472,24 +472,24 @@ static inline void stq_p(void *ptr, uint64_t v) @@ -472,24 +472,24 @@ static inline void stq_p(void *ptr, uint64_t v)
472 472
473 /* float access */ 473 /* float access */
474 474
475 -static inline float ldfl_p(void *ptr) 475 +static inline float32 ldfl_p(void *ptr)
476 { 476 {
477 - return *(float *)ptr; 477 + return *(float32 *)ptr;
478 } 478 }
479 479
480 -static inline double ldfq_p(void *ptr) 480 +static inline float64 ldfq_p(void *ptr)
481 { 481 {
482 - return *(double *)ptr; 482 + return *(float64 *)ptr;
483 } 483 }
484 484
485 -static inline void stfl_p(void *ptr, float v) 485 +static inline void stfl_p(void *ptr, float32 v)
486 { 486 {
487 - *(float *)ptr = v; 487 + *(float32 *)ptr = v;
488 } 488 }
489 489
490 -static inline void stfq_p(void *ptr, double v) 490 +static inline void stfq_p(void *ptr, float64 v)
491 { 491 {
492 - *(double *)ptr = v; 492 + *(float64 *)ptr = v;
493 } 493 }
494 #endif 494 #endif
495 495
target-arm/cpu.h
@@ -24,6 +24,8 @@ @@ -24,6 +24,8 @@
24 24
25 #include "cpu-defs.h" 25 #include "cpu-defs.h"
26 26
  27 +#include "softfloat.h"
  28 +
27 #define EXCP_UDEF 1 /* undefined instruction */ 29 #define EXCP_UDEF 1 /* undefined instruction */
28 #define EXCP_SWI 2 /* software interrupt */ 30 #define EXCP_SWI 2 /* software interrupt */
29 #define EXCP_PREFETCH_ABORT 3 31 #define EXCP_PREFETCH_ABORT 3
@@ -70,8 +72,8 @@ typedef struct CPUARMState { @@ -70,8 +72,8 @@ typedef struct CPUARMState {
70 /* VFP coprocessor state. */ 72 /* VFP coprocessor state. */
71 struct { 73 struct {
72 union { 74 union {
73 - float s[32];  
74 - double d[16]; 75 + float32 s[32];
  76 + float64 d[16];
75 } regs; 77 } regs;
76 78
77 /* We store these fpcsr fields separately for convenience. */ 79 /* We store these fpcsr fields separately for convenience. */
@@ -81,9 +83,10 @@ typedef struct CPUARMState { @@ -81,9 +83,10 @@ typedef struct CPUARMState {
81 uint32_t fpscr; 83 uint32_t fpscr;
82 84
83 /* Temporary variables if we don't have spare fp regs. */ 85 /* Temporary variables if we don't have spare fp regs. */
84 - float tmp0s, tmp1s;  
85 - double tmp0d, tmp1d;  
86 - 86 + float32 tmp0s, tmp1s;
  87 + float64 tmp0d, tmp1d;
  88 +
  89 + float_status fp_status;
87 } vfp; 90 } vfp;
88 91
89 /* user data */ 92 /* user data */
target-arm/op.c
@@ -864,19 +864,19 @@ void OPPROTO op_undef_insn(void) @@ -864,19 +864,19 @@ void OPPROTO op_undef_insn(void)
864 864
865 #define VFP_OP(name, p) void OPPROTO op_vfp_##name##p(void) 865 #define VFP_OP(name, p) void OPPROTO op_vfp_##name##p(void)
866 866
867 -#define VFP_BINOP(name, op) \ 867 +#define VFP_BINOP(name) \
868 VFP_OP(name, s) \ 868 VFP_OP(name, s) \
869 { \ 869 { \
870 - FT0s = FT0s op FT1s; \ 870 + FT0s = float32_ ## name (FT0s, FT1s, &env->vfp.fp_status); \
871 } \ 871 } \
872 VFP_OP(name, d) \ 872 VFP_OP(name, d) \
873 { \ 873 { \
874 - FT0d = FT0d op FT1d; \ 874 + FT0d = float64_ ## name (FT0d, FT1d, &env->vfp.fp_status); \
875 } 875 }
876 -VFP_BINOP(add, +)  
877 -VFP_BINOP(sub, -)  
878 -VFP_BINOP(mul, *)  
879 -VFP_BINOP(div, /) 876 +VFP_BINOP(add)
  877 +VFP_BINOP(sub)
  878 +VFP_BINOP(mul)
  879 +VFP_BINOP(div)
880 #undef VFP_BINOP 880 #undef VFP_BINOP
881 881
882 #define VFP_HELPER(name) \ 882 #define VFP_HELPER(name) \
@@ -898,41 +898,51 @@ VFP_HELPER(cmpe) @@ -898,41 +898,51 @@ VFP_HELPER(cmpe)
898 without looking at the rest of the value. */ 898 without looking at the rest of the value. */
899 VFP_OP(neg, s) 899 VFP_OP(neg, s)
900 { 900 {
901 - FT0s = -FT0s; 901 + FT0s = float32_chs(FT0s);
902 } 902 }
903 903
904 VFP_OP(neg, d) 904 VFP_OP(neg, d)
905 { 905 {
906 - FT0d = -FT0d; 906 + FT0d = float64_chs(FT0d);
907 } 907 }
908 908
909 VFP_OP(F1_ld0, s) 909 VFP_OP(F1_ld0, s)
910 { 910 {
911 - FT1s = 0.0f; 911 + union {
  912 + uint32_t i;
  913 + float32 s;
  914 + } v;
  915 + v.i = 0;
  916 + FT1s = v.s;
912 } 917 }
913 918
914 VFP_OP(F1_ld0, d) 919 VFP_OP(F1_ld0, d)
915 { 920 {
916 - FT1d = 0.0; 921 + union {
  922 + uint64_t i;
  923 + float64 d;
  924 + } v;
  925 + v.i = 0;
  926 + FT1d = v.d;
917 } 927 }
918 928
919 /* Helper routines to perform bitwise copies between float and int. */ 929 /* Helper routines to perform bitwise copies between float and int. */
920 -static inline float vfp_itos(uint32_t i) 930 +static inline float32 vfp_itos(uint32_t i)
921 { 931 {
922 union { 932 union {
923 uint32_t i; 933 uint32_t i;
924 - float s; 934 + float32 s;
925 } v; 935 } v;
926 936
927 v.i = i; 937 v.i = i;
928 return v.s; 938 return v.s;
929 } 939 }
930 940
931 -static inline uint32_t vfp_stoi(float s) 941 +static inline uint32_t vfp_stoi(float32 s)
932 { 942 {
933 union { 943 union {
934 uint32_t i; 944 uint32_t i;
935 - float s; 945 + float32 s;
936 } v; 946 } v;
937 947
938 v.s = s; 948 v.s = s;
@@ -942,111 +952,106 @@ static inline uint32_t vfp_stoi(float s) @@ -942,111 +952,106 @@ static inline uint32_t vfp_stoi(float s)
942 /* Integer to float conversion. */ 952 /* Integer to float conversion. */
943 VFP_OP(uito, s) 953 VFP_OP(uito, s)
944 { 954 {
945 - FT0s = (float)(uint32_t)vfp_stoi(FT0s); 955 + FT0s = uint32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
946 } 956 }
947 957
948 VFP_OP(uito, d) 958 VFP_OP(uito, d)
949 { 959 {
950 - FT0d = (double)(uint32_t)vfp_stoi(FT0s); 960 + FT0d = uint32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
951 } 961 }
952 962
953 VFP_OP(sito, s) 963 VFP_OP(sito, s)
954 { 964 {
955 - FT0s = (float)(int32_t)vfp_stoi(FT0s); 965 + FT0s = int32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
956 } 966 }
957 967
958 VFP_OP(sito, d) 968 VFP_OP(sito, d)
959 { 969 {
960 - FT0d = (double)(int32_t)vfp_stoi(FT0s); 970 + FT0d = int32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
961 } 971 }
962 972
963 /* Float to integer conversion. */ 973 /* Float to integer conversion. */
964 VFP_OP(toui, s) 974 VFP_OP(toui, s)
965 { 975 {
966 - FT0s = vfp_itos((uint32_t)FT0s); 976 + FT0s = vfp_itos(float32_to_uint32(FT0s, &env->vfp.fp_status));
967 } 977 }
968 978
969 VFP_OP(toui, d) 979 VFP_OP(toui, d)
970 { 980 {
971 - FT0s = vfp_itos((uint32_t)FT0d); 981 + FT0s = vfp_itos(float64_to_uint32(FT0d, &env->vfp.fp_status));
972 } 982 }
973 983
974 VFP_OP(tosi, s) 984 VFP_OP(tosi, s)
975 { 985 {
976 - FT0s = vfp_itos((int32_t)FT0s); 986 + FT0s = vfp_itos(float32_to_int32(FT0s, &env->vfp.fp_status));
977 } 987 }
978 988
979 VFP_OP(tosi, d) 989 VFP_OP(tosi, d)
980 { 990 {
981 - FT0s = vfp_itos((int32_t)FT0d); 991 + FT0s = vfp_itos(float64_to_int32(FT0d, &env->vfp.fp_status));
982 } 992 }
983 993
984 /* TODO: Set rounding mode properly. */ 994 /* TODO: Set rounding mode properly. */
985 VFP_OP(touiz, s) 995 VFP_OP(touiz, s)
986 { 996 {
987 - FT0s = vfp_itos((uint32_t)FT0s); 997 + FT0s = vfp_itos(float32_to_uint32_round_to_zero(FT0s, &env->vfp.fp_status));
988 } 998 }
989 999
990 VFP_OP(touiz, d) 1000 VFP_OP(touiz, d)
991 { 1001 {
992 - FT0s = vfp_itos((uint32_t)FT0d); 1002 + FT0s = vfp_itos(float64_to_uint32_round_to_zero(FT0d, &env->vfp.fp_status));
993 } 1003 }
994 1004
995 VFP_OP(tosiz, s) 1005 VFP_OP(tosiz, s)
996 { 1006 {
997 - FT0s = vfp_itos((int32_t)FT0s); 1007 + FT0s = vfp_itos(float32_to_int32_round_to_zero(FT0s, &env->vfp.fp_status));
998 } 1008 }
999 1009
1000 VFP_OP(tosiz, d) 1010 VFP_OP(tosiz, d)
1001 { 1011 {
1002 - FT0s = vfp_itos((int32_t)FT0d); 1012 + FT0s = vfp_itos(float64_to_int32_round_to_zero(FT0d, &env->vfp.fp_status));
1003 } 1013 }
1004 1014
1005 /* floating point conversion */ 1015 /* floating point conversion */
1006 VFP_OP(fcvtd, s) 1016 VFP_OP(fcvtd, s)
1007 { 1017 {
1008 - FT0d = (double)FT0s; 1018 + FT0d = float32_to_float64(FT0s, &env->vfp.fp_status);
1009 } 1019 }
1010 1020
1011 VFP_OP(fcvts, d) 1021 VFP_OP(fcvts, d)
1012 { 1022 {
1013 - FT0s = (float)FT0d; 1023 + FT0s = float64_to_float32(FT0d, &env->vfp.fp_status);
1014 } 1024 }
1015 1025
1016 /* Get and Put values from registers. */ 1026 /* Get and Put values from registers. */
1017 VFP_OP(getreg_F0, d) 1027 VFP_OP(getreg_F0, d)
1018 { 1028 {
1019 - FT0d = *(double *)((char *) env + PARAM1); 1029 + FT0d = *(float64 *)((char *) env + PARAM1);
1020 } 1030 }
1021 1031
1022 VFP_OP(getreg_F0, s) 1032 VFP_OP(getreg_F0, s)
1023 { 1033 {
1024 - FT0s = *(float *)((char *) env + PARAM1); 1034 + FT0s = *(float32 *)((char *) env + PARAM1);
1025 } 1035 }
1026 1036
1027 VFP_OP(getreg_F1, d) 1037 VFP_OP(getreg_F1, d)
1028 { 1038 {
1029 - FT1d = *(double *)((char *) env + PARAM1); 1039 + FT1d = *(float64 *)((char *) env + PARAM1);
1030 } 1040 }
1031 1041
1032 VFP_OP(getreg_F1, s) 1042 VFP_OP(getreg_F1, s)
1033 { 1043 {
1034 - FT1s = *(float *)((char *) env + PARAM1); 1044 + FT1s = *(float32 *)((char *) env + PARAM1);
1035 } 1045 }
1036 1046
1037 VFP_OP(setreg_F0, d) 1047 VFP_OP(setreg_F0, d)
1038 { 1048 {
1039 - *(double *)((char *) env + PARAM1) = FT0d; 1049 + *(float64 *)((char *) env + PARAM1) = FT0d;
1040 } 1050 }
1041 1051
1042 VFP_OP(setreg_F0, s) 1052 VFP_OP(setreg_F0, s)
1043 { 1053 {
1044 - *(float *)((char *) env + PARAM1) = FT0s;  
1045 -}  
1046 -  
1047 -VFP_OP(foobar, d)  
1048 -{  
1049 - FT0d = env->vfp.regs.s[3]; 1054 + *(float32 *)((char *) env + PARAM1) = FT0s;
1050 } 1055 }
1051 1056
1052 void OPPROTO op_vfp_movl_T0_fpscr(void) 1057 void OPPROTO op_vfp_movl_T0_fpscr(void)
target-arm/op_helper.c
@@ -17,24 +17,8 @@ @@ -17,24 +17,8 @@
17 * License along with this library; if not, write to the Free Software 17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 -  
21 -#include <math.h>  
22 -#include <fenv.h>  
23 #include "exec.h" 20 #include "exec.h"
24 21
25 -/* If the host doesn't define C99 math intrinsics then use the normal  
26 - operators. This may generate excess exceptions, but it's probably  
27 - near enough for most things. */  
28 -#ifndef isless  
29 -#define isless(x, y) (x < y)  
30 -#endif  
31 -#ifndef isgreater  
32 -#define isgreater(x, y) (x > y)  
33 -#endif  
34 -#ifndef isunordered  
35 -#define isunordered(x, y) (!((x < y) || (x >= y)))  
36 -#endif  
37 -  
38 void raise_exception(int tt) 22 void raise_exception(int tt)
39 { 23 {
40 env->exception_index = tt; 24 env->exception_index = tt;
@@ -59,119 +43,88 @@ void cpu_unlock(void) @@ -59,119 +43,88 @@ void cpu_unlock(void)
59 43
60 void do_vfp_abss(void) 44 void do_vfp_abss(void)
61 { 45 {
62 - FT0s = fabsf(FT0s); 46 + FT0s = float32_abs(FT0s);
63 } 47 }
64 48
65 void do_vfp_absd(void) 49 void do_vfp_absd(void)
66 { 50 {
67 - FT0d = fabs(FT0d); 51 + FT0d = float64_abs(FT0d);
68 } 52 }
69 53
70 void do_vfp_sqrts(void) 54 void do_vfp_sqrts(void)
71 { 55 {
72 - FT0s = sqrtf(FT0s); 56 + FT0s = float32_sqrt(FT0s, &env->vfp.fp_status);
73 } 57 }
74 58
75 void do_vfp_sqrtd(void) 59 void do_vfp_sqrtd(void)
76 { 60 {
77 - FT0d = sqrt(FT0d); 61 + FT0d = float64_sqrt(FT0d, &env->vfp.fp_status);
78 } 62 }
79 63
80 -/* We use an == operator first to generate teh correct floating point  
81 - exception. Subsequent comparisons use the exception-safe macros. */  
82 -#define DO_VFP_cmp(p) \ 64 +/* XXX: check quiet/signaling case */
  65 +#define DO_VFP_cmp(p, size) \
83 void do_vfp_cmp##p(void) \ 66 void do_vfp_cmp##p(void) \
84 { \ 67 { \
85 uint32_t flags; \ 68 uint32_t flags; \
86 - if (FT0##p == FT1##p) \  
87 - flags = 0xc; \  
88 - else if (isless (FT0##p, FT1##p)) \  
89 - flags = 0x8; \  
90 - else if (isgreater (FT0##p, FT1##p)) \  
91 - flags = 0x2; \  
92 - else /* unordered */ \  
93 - flags = 0x3; \ 69 + switch(float ## size ## _compare_quiet(FT0##p, FT1##p, &env->vfp.fp_status)) {\
  70 + case 0: flags = 0xc; break;\
  71 + case -1: flags = 0x8; break;\
  72 + case 1: flags = 0x2; break;\
  73 + default: case 2: flags = 0x3; break;\
  74 + }\
94 env->vfp.fpscr = (flags << 28) | (env->vfp.fpscr & 0x0fffffff); \ 75 env->vfp.fpscr = (flags << 28) | (env->vfp.fpscr & 0x0fffffff); \
95 FORCE_RET(); \ 76 FORCE_RET(); \
96 -}  
97 -DO_VFP_cmp(s)  
98 -DO_VFP_cmp(d)  
99 -#undef DO_VFP_cmp  
100 -  
101 -/* We use a > operator first to get FP exceptions right. */  
102 -#define DO_VFP_cmpe(p) \ 77 +}\
  78 +\
103 void do_vfp_cmpe##p(void) \ 79 void do_vfp_cmpe##p(void) \
104 { \ 80 { \
105 - uint32_t flags; \  
106 - if (FT0##p > FT1##p) \  
107 - flags = 0x2; \  
108 - else if (isless (FT0##p, FT1##p)) \  
109 - flags = 0x8; \  
110 - else if (isunordered (FT0##p, FT1##p)) \  
111 - flags = 0x3; \  
112 - else /* equal */ \  
113 - flags = 0xc; \ 81 + uint32_t flags; \
  82 + switch(float ## size ## _compare(FT0##p, FT1##p, &env->vfp.fp_status)) {\
  83 + case 0: flags = 0xc; break;\
  84 + case -1: flags = 0x8; break;\
  85 + case 1: flags = 0x2; break;\
  86 + default: case 2: flags = 0x3; break;\
  87 + }\
114 env->vfp.fpscr = (flags << 28) | (env->vfp.fpscr & 0x0fffffff); \ 88 env->vfp.fpscr = (flags << 28) | (env->vfp.fpscr & 0x0fffffff); \
115 - FORCE_RET(); \ 89 + FORCE_RET(); \
116 } 90 }
117 -DO_VFP_cmpe(s)  
118 -DO_VFP_cmpe(d)  
119 -#undef DO_VFP_cmpe 91 +DO_VFP_cmp(s, 32)
  92 +DO_VFP_cmp(d, 64)
  93 +#undef DO_VFP_cmp
120 94
121 /* Convert host exception flags to vfp form. */ 95 /* Convert host exception flags to vfp form. */
122 -int vfp_exceptbits_from_host(int host_bits) 96 +static inline int vfp_exceptbits_from_host(int host_bits)
123 { 97 {
124 int target_bits = 0; 98 int target_bits = 0;
125 99
126 -#ifdef FE_INVALID  
127 - if (host_bits & FE_INVALID) 100 + if (host_bits & float_flag_invalid)
128 target_bits |= 1; 101 target_bits |= 1;
129 -#endif  
130 -#ifdef FE_DIVBYZERO  
131 - if (host_bits & FE_DIVBYZERO) 102 + if (host_bits & float_flag_divbyzero)
132 target_bits |= 2; 103 target_bits |= 2;
133 -#endif  
134 -#ifdef FE_OVERFLOW  
135 - if (host_bits & FE_OVERFLOW) 104 + if (host_bits & float_flag_overflow)
136 target_bits |= 4; 105 target_bits |= 4;
137 -#endif  
138 -#ifdef FE_UNDERFLOW  
139 - if (host_bits & FE_UNDERFLOW) 106 + if (host_bits & float_flag_underflow)
140 target_bits |= 8; 107 target_bits |= 8;
141 -#endif  
142 -#ifdef FE_INEXACT  
143 - if (host_bits & FE_INEXACT) 108 + if (host_bits & float_flag_inexact)
144 target_bits |= 0x10; 109 target_bits |= 0x10;
145 -#endif  
146 - /* C doesn't define an inexact exception. */  
147 return target_bits; 110 return target_bits;
148 } 111 }
149 112
150 /* Convert vfp exception flags to target form. */ 113 /* Convert vfp exception flags to target form. */
151 -int vfp_host_exceptbits_to_host(int target_bits) 114 +static inline int vfp_exceptbits_to_host(int target_bits)
152 { 115 {
153 int host_bits = 0; 116 int host_bits = 0;
154 117
155 -#ifdef FE_INVALID  
156 if (target_bits & 1) 118 if (target_bits & 1)
157 - host_bits |= FE_INVALID;  
158 -#endif  
159 -#ifdef FE_DIVBYZERO 119 + host_bits |= float_flag_invalid;
160 if (target_bits & 2) 120 if (target_bits & 2)
161 - host_bits |= FE_DIVBYZERO;  
162 -#endif  
163 -#ifdef FE_OVERFLOW 121 + host_bits |= float_flag_divbyzero;
164 if (target_bits & 4) 122 if (target_bits & 4)
165 - host_bits |= FE_OVERFLOW;  
166 -#endif  
167 -#ifdef FE_UNDERFLOW 123 + host_bits |= float_flag_overflow;
168 if (target_bits & 8) 124 if (target_bits & 8)
169 - host_bits |= FE_UNDERFLOW;  
170 -#endif  
171 -#ifdef FE_INEXACT 125 + host_bits |= float_flag_underflow;
172 if (target_bits & 0x10) 126 if (target_bits & 0x10)
173 - host_bits |= FE_INEXACT;  
174 -#endif 127 + host_bits |= float_flag_inexact;
175 return host_bits; 128 return host_bits;
176 } 129 }
177 130
@@ -190,31 +143,23 @@ void do_vfp_set_fpscr(void) @@ -190,31 +143,23 @@ void do_vfp_set_fpscr(void)
190 i = (T0 >> 22) & 3; 143 i = (T0 >> 22) & 3;
191 switch (i) { 144 switch (i) {
192 case 0: 145 case 0:
193 - i = FE_TONEAREST; 146 + i = float_round_nearest_even;
194 break; 147 break;
195 case 1: 148 case 1:
196 - i = FE_UPWARD; 149 + i = float_round_up;
197 break; 150 break;
198 case 2: 151 case 2:
199 - i = FE_DOWNWARD; 152 + i = float_round_down;
200 break; 153 break;
201 case 3: 154 case 3:
202 - i = FE_TOWARDZERO; 155 + i = float_round_to_zero;
203 break; 156 break;
204 } 157 }
205 - fesetround (i); 158 + set_float_rounding_mode(i, &env->vfp.fp_status);
206 } 159 }
207 160
208 - /* Clear host exception flags. */  
209 - feclearexcept(FE_ALL_EXCEPT);  
210 -  
211 -#ifdef feenableexcept  
212 - if (changed & 0x1f00) {  
213 - i = vfp_exceptbits_to_host((T0 >> 8) & 0x1f);  
214 - feenableexcept (i);  
215 - fedisableexcept (FE_ALL_EXCEPT & ~i);  
216 - }  
217 -#endif 161 + i = vfp_exceptbits_to_host((T0 >> 8) & 0x1f);
  162 + set_float_exception_flags(i, &env->vfp.fp_status);
218 /* XXX: FZ and DN are not implemented. */ 163 /* XXX: FZ and DN are not implemented. */
219 } 164 }
220 165
@@ -224,6 +169,6 @@ void do_vfp_get_fpscr(void) @@ -224,6 +169,6 @@ void do_vfp_get_fpscr(void)
224 169
225 T0 = (env->vfp.fpscr & 0xffc8ffff) | (env->vfp.vec_len << 16) 170 T0 = (env->vfp.fpscr & 0xffc8ffff) | (env->vfp.vec_len << 16)
226 | (env->vfp.vec_stride << 20); 171 | (env->vfp.vec_stride << 20);
227 - i = fetestexcept(FE_ALL_EXCEPT); 172 + i = get_float_exception_flags(&env->vfp.fp_status);
228 T0 |= vfp_exceptbits_from_host(i); 173 T0 |= vfp_exceptbits_from_host(i);
229 } 174 }