vfpdf.S revision 1.4 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
32 RCSID("$NetBSD: vfpdf.S,v 1.4 2018/07/19 19:35:02 joerg Exp $")
33
34 /*
35 * This file provides softfloat compatible routines which use VFP instructions
36 * to do the actual work. This should give near hard-float performance while
37 * being compatible with soft-float code.
38 *
39 * This file implements the double precision floating point routines.
40 */
41
42 .fpu vfp
43
44 #ifdef __ARMEL__
45 #define vmov_arg0 vmov d0, r0, r1
46 #define vmov_arg1 vmov d1, r2, r3
47 #define vmov_ret vmov r0, r1, d0
48 #else
49 #define vmov_arg0 vmov d0, r1, r0
50 #define vmov_arg1 vmov d1, r3, r2
51 #define vmov_ret vmov r1, r0, d0
52 #endif
53 #define vmov_args vmov_arg0; vmov_arg1
54
55 #ifdef __ARM_EABI__
56 #define __adddf3 __aeabi_dadd
57 #define __divdf3 __aeabi_ddiv
58 #define __muldf3 __aeabi_dmul
59 #define __subdf3 __aeabi_dsub
60 #define __negdf2 __aeabi_dneg
61 #define __extendsfdf2 __aeabi_f2d
62 #define __fixdfsi __aeabi_d2iz
63 #define __fixunsdfsi __aeabi_d2uiz
64 #define __floatsidf __aeabi_i2d
65 #define __floatunsidf __aeabi_ui2d
66 #endif
67
68 ENTRY(__adddf3)
69 vmov_args
70 vadd.f64 d0, d0, d1
71 vmov_ret
72 RET
73 END(__adddf3)
74
75 ENTRY(__subdf3)
76 vmov_args
77 vsub.f64 d0, d0, d1
78 vmov_ret
79 RET
80 END(__subdf3)
81
82 #ifdef __ARM_EABI__
83 ENTRY(__aeabi_drsub)
84 vmov_args
85 vsub.f64 d0, d1, d0
86 vmov_ret
87 RET
88 END(__aeabi_drsub)
89 #endif
90
91 ENTRY(__muldf3)
92 vmov_args
93 vmul.f64 d0, d0, d1
94 vmov_ret
95 RET
96 END(__muldf3)
97
98 ENTRY(__divdf3)
99 vmov_args
100 vdiv.f64 d0, d0, d1
101 vmov_ret
102 RET
103 END(__divdf3)
104
105 ENTRY(__negdf2)
106 vmov_arg0
107 vneg.f64 d0, d0
108 vmov_ret
109 RET
110 END(__negdf2)
111
112 ENTRY(__extendsfdf2)
113 vmov s0, r0
114 vcvt.f64.f32 d0, s0
115 vmov_ret
116 RET
117 END(__extendsfdf2)
118
119 ENTRY(__fixdfsi)
120 vmov_arg0
121 vcvt.s32.f64 s0, d0
122 vmov r0, s0
123 RET
124 END(__fixdfsi)
125
126 ENTRY(__fixunsdfsi)
127 vmov_arg0
128 vcvt.u32.f64 s0, d0
129 vmov r0, s0
130 RET
131 END(__fixunsdfsi)
132
133 ENTRY(__floatsidf)
134 vmov s0, r0
135 vcvt.f64.s32 d0, s0
136 vmov_ret
137 RET
138 END(__floatsidf)
139
140 ENTRY(__floatunsidf)
141 vmov s0, r0
142 vcvt.f64.u32 d0, s0
143 vmov_ret
144 RET
145 END(__floatunsidf)
146
147 /*
148 * Effect of a floating point comparision on the condition flags.
149 * N Z C V
150 * EQ = 0 1 1 0
151 * LT = 1 0 0 0
152 * GT = 0 0 1 0
153 * UN = 0 0 1 1
154 */
155 #ifdef __ARM_EABI__
156 ENTRY(__aeabi_cdcmpeq)
157 vmov_args
158 vcmp.f64 d0, d1
159 vmrs APSR_nzcv, fpscr
160 RET
161 END(__aeabi_cdcmpeq)
162
163 ENTRY(__aeabi_cdcmple)
164 vmov_args
165 vcmpe.f64 d0, d1
166 vmrs APSR_nzcv, fpscr
167 RET
168 END(__aeabi_cdcmple)
169
170 ENTRY(__aeabi_cdrcmple)
171 vmov_args
172 vcmpe.f64 d1, d0
173 vmrs APSR_nzcv, fpscr
174 RET
175 END(__aeabi_cdrcmple)
176
177 ENTRY(__aeabi_dcmpeq)
178 vmov_args
179 vcmp.f64 d0, d1
180 vmrs APSR_nzcv, fpscr
181 moveq r0, #1 /* (a == b) */
182 movne r0, #0 /* (a != b) or unordered */
183 RET
184 END(__aeabi_dcmpeq)
185
186 ENTRY(__aeabi_dcmplt)
187 vmov_args
188 vcmp.f64 d0, d1
189 vmrs APSR_nzcv, fpscr
190 movlt r0, #1 /* (a < b) */
191 movcs r0, #0 /* (a >= b) or unordered */
192 RET
193 END(__aeabi_dcmplt)
194
195 ENTRY(__aeabi_dcmple)
196 vmov_args
197 vcmp.f64 d0, d1
198 vmrs APSR_nzcv, fpscr
199 movls r0, #1 /* (a <= b) */
200 movhi r0, #0 /* (a > b) or unordered */
201 RET
202 END(__aeabi_dcmple)
203
204 ENTRY(__aeabi_dcmpge)
205 vmov_args
206 vcmp.f64 d0, d1
207 vmrs APSR_nzcv, fpscr
208 movge r0, #1 /* (a >= b) */
209 movlt r0, #0 /* (a < b) or unordered */
210 RET
211 END(__aeabi_dcmpge)
212
213 ENTRY(__aeabi_dcmpgt)
214 vmov_args
215 vcmp.f64 d0, d1
216 vmrs APSR_nzcv, fpscr
217 movgt r0, #1 /* (a > b) */
218 movle r0, #0 /* (a <= b) or unordered */
219 RET
220 END(__aeabi_dcmpgt)
221
222 ENTRY(__aeabi_dcmpun)
223 vmov_args
224 vcmp.f64 d0, d1
225 vmrs APSR_nzcv, fpscr
226 movvs r0, #1 /* (isnan(a) || isnan(b)) */
227 movvc r0, #0 /* !isnan(a) && !isnan(b) */
228 RET
229 END(__aeabi_dcmpun)
230
231 #else
232 /* N set if compare <= result */
233 /* Z set if compare = result */
234 /* C set if compare (=,>=,UNORD) result */
235 /* V set if compare UNORD result */
236
237 STRONG_ALIAS(__eqdf2, __nedf2)
238 ENTRY(__nedf2)
239 vmov_args
240 vcmp.f64 d0, d1
241 vmrs APSR_nzcv, fpscr
242 moveq r0, #0 /* !(a == b) */
243 movne r0, #1 /* !(a == b) */
244 RET
245 END(__nedf2)
246
247 STRONG_ALIAS(__gedf2, __ltdf2)
248 ENTRY(__ltdf2)
249 vmov_args
250 vcmp.f64 d0, d1
251 vmrs APSR_nzcv, fpscr
252 mvnmi r0, #0 /* -(a < b) */
253 movpl r0, #0 /* -(a < b) */
254 RET
255 END(__ltdf2)
256
257 STRONG_ALIAS(__gtdf2, __ledf2)
258 ENTRY(__ledf2)
259 vmov_args
260 vcmp.f64 d0, d1
261 vmrs APSR_nzcv, fpscr
262 movgt r0, #1 /* (a > b) */
263 movle r0, #0 /* (a > b) */
264 RET
265 END(__ledf2)
266
267 ENTRY(__unorddf2)
268 vmov_args
269 vcmp.f64 d0, d1
270 vmrs APSR_nzcv, fpscr
271 movvs r0, #1 /* isnan(a) || isnan(b) */
272 movvc r0, #0 /* isnan(a) || isnan(b) */
273 RET
274 END(__unorddf2)
275 #endif /* !__ARM_EABI__ */
276