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