4 * Copyright (c) 2005 CodeSourcery, LLC
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
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
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. */
29 #define isless(x, y) (x < y)
32 #define isgreater(x, y) (x > y)
35 #define isunordered(x, y) (!((x < y) || (x >= y)))
38 void raise_exception(int tt
)
40 env
->exception_index
= tt
;
46 spinlock_t global_cpu_lock
= SPIN_LOCK_UNLOCKED
;
50 spin_lock(&global_cpu_lock
);
55 spin_unlock(&global_cpu_lock
);
60 void do_vfp_abss(void)
65 void do_vfp_absd(void)
70 void do_vfp_sqrts(void)
75 void do_vfp_sqrtd(void)
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) \
83 void do_vfp_cmp##p(void) \
86 if (FT0##p == FT1##p) \
88 else if (isless (FT0##p, FT1##p)) \
90 else if (isgreater (FT0##p, FT1##p)) \
92 else /* unordered */ \
94 env->vfp.fpscr = (flags << 28) | (env->vfp.fpscr & 0x0fffffff); \
101 /* We use a > operator first to get FP exceptions right. */
102 #define DO_VFP_cmpe(p) \
103 void do_vfp_cmpe##p(void) \
106 if (FT0##p > FT1##p) \
108 else if (isless (FT0##p, FT1##p)) \
110 else if (isunordered (FT0##p, FT1##p)) \
114 env->vfp.fpscr = (flags << 28) | (env->vfp.fpscr & 0x0fffffff); \
121 /* Convert host exception flags to vfp form. */
122 int vfp_exceptbits_from_host(int host_bits
)
127 if (host_bits
& FE_INVALID
)
131 if (host_bits
& FE_DIVBYZERO
)
135 if (host_bits
& FE_OVERFLOW
)
139 if (host_bits
& FE_UNDERFLOW
)
143 if (host_bits
& FE_INEXACT
)
146 /* C doesn't define an inexact exception. */
150 /* Convert vfp exception flags to target form. */
151 int vfp_host_exceptbits_to_host(int target_bits
)
157 host_bits
|= FE_INVALID
;
161 host_bits
|= FE_DIVBYZERO
;
165 host_bits
|= FE_OVERFLOW
;
169 host_bits
|= FE_UNDERFLOW
;
172 if (target_bits
& 0x10)
173 host_bits
|= FE_INEXACT
;
178 void do_vfp_set_fpscr(void)
183 changed
= env
->vfp
.fpscr
;
184 env
->vfp
.fpscr
= (T0
& 0xffc8ffff);
185 env
->vfp
.vec_len
= (T0
>> 16) & 7;
186 env
->vfp
.vec_stride
= (T0
>> 20) & 3;
189 if (changed
& (3 << 22)) {
208 /* Clear host exception flags. */
209 feclearexcept(FE_ALL_EXCEPT
);
211 #ifdef feenableexcept
212 if (changed
& 0x1f00) {
213 i
= vfp_exceptbits_to_host((T0
>> 8) & 0x1f);
215 fedisableexcept (FE_ALL_EXCEPT
& ~i
);
218 /* XXX: FZ and DN are not implemented. */
221 void do_vfp_get_fpscr(void)
225 T0
= (env
->vfp
.fpscr
& 0xffc8ffff) | (env
->vfp
.vec_len
<< 16)
226 | (env
->vfp
.vec_stride
<< 20);
227 i
= fetestexcept(FE_ALL_EXCEPT
);
228 T0
|= vfp_exceptbits_from_host(i
);