vfpsf.S revision 1.3 1 /*-
2 * Copyright (c) 2013 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Matt Thomas of 3am Software Foundry.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <arm/asm.h>
31 #include <arm/vfpreg.h>
32
33 RCSID("$NetBSD: vfpsf.S,v 1.3 2018/07/17 15:03:48 joerg Exp $")
34
35 /*
36 * This file provides softfloat compatible routines which use VFP instructions
37 * to do the actual work. This should give near hard-float performance while
38 * being compatible with soft-float code.
39 *
40 * This file implements the single precision floating point routines.
41 */
42
43 .fpu vfp2
44
45 #ifdef __ARM_EABI__
46 #define __addsf3 __aeabi_fadd
47 #define __divsf3 __aeabi_fdiv
48 #define __mulsf3 __aeabi_fmul
49 #define __subsf3 __aeabi_fsub
50 #define __negsf2 __aeabi_fneg
51 #define __truncdfsf2 __aeabi_d2f
52 #define __fixsfsi __aeabi_f2iz
53 #define __fixunssfsi __aeabi_f2uiz
54 #define __floatsisf __aeabi_i2f
55 #define __floatunsisf __aeabi_ui2f
56 #endif
57
58 ENTRY(__addsf3)
59 vmov s0, s1, r0, r1
60 vadd.f32 s0, s0, s1
61 vmov r0, s0
62 RET
63 END(__addsf3)
64
65 ENTRY(__subsf3)
66 vmov s0, s1, r0, r1
67 vsub.f32 s0, s0, s1
68 vmov r0, s0
69 RET
70 END(__subsf3)
71
72 #ifdef __ARM_EABI__
73 ENTRY(__aeabi_frsub)
74 vmov s0, s1, r0, r1
75 vsub.f32 s0, s1, s0
76 vmov r0, s0
77 RET
78 END(__aeabi_frsub)
79 #endif
80
81 ENTRY(__mulsf3)
82 vmov s0, s1, r0, r1
83 vmul.f32 s0, s0, s1
84 vmov r0, s0
85 RET
86 END(__mulsf3)
87
88 ENTRY(__divsf3)
89 vmov s0, s1, r0, r1
90 vdiv.f32 s0, s0, s1
91 vmov r0, s0
92 RET
93 END(__divsf3)
94
95 ENTRY(__negsf2)
96 vmov s0, r0
97 vneg.f32 s0, s0
98 vmov r0, s0
99 RET
100 END(__negsf2)
101
102 ENTRY(__truncdfsf2)
103 #ifdef __ARMEL__
104 vmov d0, r0, r1
105 #else
106 vmov d0, r1, r0
107 #endif
108 vcvt.f32.f64 s0, d0
109 vmov r0, s0
110 RET
111 END(__truncdfsf2)
112
113 ENTRY(__fixsfsi)
114 vmov s0, r0
115 vcvt.s32.f32 s0, s0
116 vmov r0, s0
117 RET
118 END(__fixsfsi)
119
120 ENTRY(__fixunssfsi)
121 vmov s0, r0
122 vcvt.u32.f32 s0, s0
123 vmov r0, s0
124 RET
125 END(__fixunssfsi)
126
127 ENTRY(__floatsisf)
128 vmov s0, r0
129 vcvt.f32.s32 s0, s0
130 vmov r0, s0
131 RET
132 END(__floatsisf)
133
134 ENTRY(__floatunsisf)
135 vmov s0, r0
136 vcvt.f32.u32 s0, s0
137 vmov r0, s0
138 RET
139 END(__floatunsisf)
140
141 /*
142 * Effect of a floating point comparision on the condition flags.
143 * N Z C V
144 * EQ = 0 1 1 0
145 * LT = 1 0 0 0
146 * GT = 0 0 1 0
147 * UN = 0 0 1 1
148 */
149 #ifdef __ARM_EABI__
150 ENTRY(__aeabi_cfcmpeq)
151 vmov s0, s1, r0, r1
152 vcmp.f32 s0, s1
153 vmrs APSR_nzcv, fpscr
154 RET
155 END(__aeabi_cfcmpeq)
156
157 ENTRY(__aeabi_cfcmple)
158 vmov s0, s1, r0, r1
159 vcmpe.f32 s0, s1
160 vmrs APSR_nzcv, fpscr
161 RET
162 END(__aeabi_cfcmple)
163
164 ENTRY(__aeabi_cfrcmple)
165 vmov s0, s1, r0, r1
166 vcmpe.f32 s1, s0
167 vmrs APSR_nzcv, fpscr
168 RET
169 END(__aeabi_cfrcmple)
170
171 ENTRY(__aeabi_fcmpeq)
172 vmov s0, s1, r0, r1
173 vcmp.f32 s0, s1
174 vmrs APSR_nzcv, fpscr
175 moveq r0, #1 /* (a == b) */
176 movne r0, #0 /* (a != b) or unordered */
177 RET
178 END(__aeabi_fcmpeq)
179
180 ENTRY(__aeabi_fcmplt)
181 vmov s0, s1, r0, r1
182 vcmp.f32 s0, s1
183 vmrs APSR_nzcv, fpscr
184 movlt r0, #1 /* (a < b) */
185 movcs r0, #0 /* (a >= b) or unordered */
186 RET
187 END(__aeabi_fcmplt)
188
189 ENTRY(__aeabi_fcmple)
190 vmov s0, s1, r0, r1
191 vcmp.f32 s0, s1
192 vmrs APSR_nzcv, fpscr
193 movls r0, #1 /* (a <= b) */
194 movhi r0, #0 /* (a > b) or unordered */
195 RET
196 END(__aeabi_fcmple)
197
198 ENTRY(__aeabi_fcmpge)
199 vmov s0, s1, r0, r1
200 vcmp.f32 s0, s1
201 vmrs APSR_nzcv, fpscr
202 movge r0, #1 /* (a >= b) */
203 movlt r0, #0 /* (a < b) or unordered */
204 RET
205 END(__aeabi_fcmpge)
206
207 ENTRY(__aeabi_fcmpgt)
208 vmov s0, s1, r0, r1
209 vcmp.f32 s0, s1
210 vmrs APSR_nzcv, fpscr
211 movgt r0, #1 /* (a > b) */
212 movle r0, #0 /* (a <= b) or unordered */
213 RET
214 END(__aeabi_fcmpgt)
215
216 ENTRY(__aeabi_fcmpun)
217 vmov s0, s1, r0, r1
218 vcmp.f32 s0, s1
219 vmrs APSR_nzcv, fpscr
220 movvs r0, #1 /* (isnan(a) || isnan(b)) */
221 movvc r0, #0 /* !isnan(a) && !isnan(b) */
222 RET
223 END(__aeabi_fcmpun)
224
225 #else
226 /* N set if compare <= result */
227 /* Z set if compare = result */
228 /* C set if compare (=,>=,UNORD) result */
229 /* V set if compare UNORD result */
230
231 STRONG_ALIAS(__eqsf2, __nesf2)
232 ENTRY(__nesf2)
233 vmov s0, s1, r0, r1
234 vcmp.f32 s0, s1
235 vmrs APSR_nzcv, fpscr
236 moveq r0, #0 /* !(a == b) */
237 movne r0, #1 /* !(a == b) */
238 RET
239 END(__nesf2)
240
241 STRONG_ALIAS(__gesf2, __ltsf2)
242 ENTRY(__ltsf2)
243 vmov s0, s1, r0, r1
244 vcmp.f32 s0, s1
245 vmrs APSR_nzcv, fpscr
246 mvnmi r0, #0 /* -(a < b) */
247 movpl r0, #0 /* -(a < b) */
248 RET
249 END(__ltsf2)
250
251 STRONG_ALIAS(__gtsf2, __lesf2)
252 ENTRY(__lesf2)
253 vmov s0, s1, r0, r1
254 vcmp.f32 s0, s1
255 vmrs APSR_nzcv, fpscr
256 movgt r0, #1 /* (a > b) */
257 movle r0, #0 /* (a > b) */
258 RET
259 END(__lesf2)
260
261 ENTRY(__unordsf2)
262 vmov s0, s1, r0, r1
263 vcmp.f32 s0, s1
264 vmrs APSR_nzcv, fpscr
265 movvs r0, #1 /* isnan(a) || isnan(b) */
266 movvc r0, #0 /* isnan(a) || isnan(b) */
267 RET
268 END(__unordsf2)
269 #endif /* !__ARM_EABI__ */
270