xref: /freebsd/lib/libc/arm/aeabi/aeabi_vfp_double.S (revision 1d386b48)
1a06918a3SAndrew Turner/*
2a06918a3SAndrew Turner * Copyright (C) 2013 Andrew Turner
3a06918a3SAndrew Turner * All rights reserved.
4a06918a3SAndrew Turner *
5a06918a3SAndrew Turner * Redistribution and use in source and binary forms, with or without
6a06918a3SAndrew Turner * modification, are permitted provided that the following conditions
7a06918a3SAndrew Turner * are met:
8a06918a3SAndrew Turner * 1. Redistributions of source code must retain the above copyright
9a06918a3SAndrew Turner *    notice, this list of conditions and the following disclaimer.
10a06918a3SAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright
11a06918a3SAndrew Turner *    notice, this list of conditions and the following disclaimer in the
12a06918a3SAndrew Turner *    documentation and/or other materials provided with the distribution.
13a06918a3SAndrew Turner *
14a06918a3SAndrew Turner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15a06918a3SAndrew Turner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16a06918a3SAndrew Turner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17a06918a3SAndrew Turner * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18a06918a3SAndrew Turner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19a06918a3SAndrew Turner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20a06918a3SAndrew Turner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21a06918a3SAndrew Turner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22a06918a3SAndrew Turner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23a06918a3SAndrew Turner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24a06918a3SAndrew Turner * SUCH DAMAGE.
25a06918a3SAndrew Turner *
26a06918a3SAndrew Turner */
27a06918a3SAndrew Turner
28a06918a3SAndrew Turner#include <machine/asm.h>
29a06918a3SAndrew Turner#include "aeabi_vfp.h"
30a06918a3SAndrew Turner
31a06918a3SAndrew Turner.fpu	vfp
32a06918a3SAndrew Turner.syntax	unified
33a06918a3SAndrew Turner
34cb8bcafaSAndrew Turner/* void __aeabi_cdcmpeq(double, double) */
35cb8bcafaSAndrew TurnerAEABI_ENTRY(cdcmpeq)
36cb8bcafaSAndrew Turner	LOAD_DREG(d0, r0, r1)
37cb8bcafaSAndrew Turner	LOAD_DREG(d1, r2, r3)
38cb8bcafaSAndrew Turner	vcmp.f64	d0, d1
39cb8bcafaSAndrew Turner	vmrs		APSR_nzcv, fpscr
40cb8bcafaSAndrew Turner	RET
41cb8bcafaSAndrew TurnerAEABI_END(cdcmpeq)
42cb8bcafaSAndrew Turner
43cb8bcafaSAndrew Turner/* void __aeabi_cdcmple(double, double) */
44cb8bcafaSAndrew TurnerAEABI_ENTRY(cdcmple)
45cb8bcafaSAndrew Turner	LOAD_DREG(d0, r0, r1)
46cb8bcafaSAndrew Turner	LOAD_DREG(d1, r2, r3)
47cb8bcafaSAndrew Turner	vcmpe.f64	d0, d1
48cb8bcafaSAndrew Turner	vmrs		APSR_nzcv, fpscr
49cb8bcafaSAndrew Turner	RET
50cb8bcafaSAndrew TurnerAEABI_END(cdcmple)
51cb8bcafaSAndrew Turner
52cb8bcafaSAndrew Turner/* void __aeabi_cdrcmple(double, double) */
53cb8bcafaSAndrew TurnerAEABI_ENTRY(cdrcmple)
54cb8bcafaSAndrew Turner	LOAD_DREG(d0, r0, r1)
55cb8bcafaSAndrew Turner	LOAD_DREG(d1, r2, r3)
56cb8bcafaSAndrew Turner	vcmpe.f64	d1, d0
57cb8bcafaSAndrew Turner	vmrs		APSR_nzcv, fpscr
58cb8bcafaSAndrew Turner	RET
59cb8bcafaSAndrew TurnerAEABI_END(cdrcmple)
60cb8bcafaSAndrew Turner
61a06918a3SAndrew Turner/* int __aeabi_dcmpeq(double, double) */
62a06918a3SAndrew TurnerAEABI_ENTRY(dcmpeq)
63a06918a3SAndrew Turner	LOAD_DREG(d0, r0, r1)
64a06918a3SAndrew Turner	LOAD_DREG(d1, r2, r3)
65a06918a3SAndrew Turner	vcmp.f64 d0, d1
66a06918a3SAndrew Turner	vmrs     APSR_nzcv, fpscr
672b6a6357SAndrew Turner	ite      ne
68a06918a3SAndrew Turner	movne    r0, #0
69a06918a3SAndrew Turner	moveq    r0, #1
70a06918a3SAndrew Turner	RET
71a06918a3SAndrew TurnerAEABI_END(dcmpeq)
72a06918a3SAndrew Turner
73a06918a3SAndrew Turner/* int __aeabi_dcmplt(double, double) */
74a06918a3SAndrew TurnerAEABI_ENTRY(dcmplt)
75a06918a3SAndrew Turner	LOAD_DREG(d0, r0, r1)
76a06918a3SAndrew Turner	LOAD_DREG(d1, r2, r3)
77a06918a3SAndrew Turner	vcmp.f64 d0, d1
78a06918a3SAndrew Turner	vmrs     APSR_nzcv, fpscr
792b6a6357SAndrew Turner	ite      cs
80a06918a3SAndrew Turner	movcs    r0, #0
812b6a6357SAndrew Turner	movcc    r0, #1
82a06918a3SAndrew Turner	RET
83a06918a3SAndrew TurnerAEABI_END(dcmplt)
84a06918a3SAndrew Turner
85a06918a3SAndrew Turner/* int __aeabi_dcmple(double, double) */
86a06918a3SAndrew TurnerAEABI_ENTRY(dcmple)
87a06918a3SAndrew Turner	LOAD_DREG(d0, r0, r1)
88a06918a3SAndrew Turner	LOAD_DREG(d1, r2, r3)
89a06918a3SAndrew Turner	vcmp.f64 d0, d1
90a06918a3SAndrew Turner	vmrs     APSR_nzcv, fpscr
912b6a6357SAndrew Turner	ite      hi
92a06918a3SAndrew Turner	movhi    r0, #0
93a06918a3SAndrew Turner	movls    r0, #1
94a06918a3SAndrew Turner	RET
95a06918a3SAndrew TurnerAEABI_END(dcmple)
96a06918a3SAndrew Turner
97a06918a3SAndrew Turner/* int __aeabi_dcmpge(double, double) */
98a06918a3SAndrew TurnerAEABI_ENTRY(dcmpge)
99a06918a3SAndrew Turner	LOAD_DREG(d0, r0, r1)
100a06918a3SAndrew Turner	LOAD_DREG(d1, r2, r3)
101a06918a3SAndrew Turner	vcmp.f64 d0, d1
102a06918a3SAndrew Turner	vmrs     APSR_nzcv, fpscr
1032b6a6357SAndrew Turner	ite      lt
104a06918a3SAndrew Turner	movlt    r0, #0
105a06918a3SAndrew Turner	movge    r0, #1
106a06918a3SAndrew Turner	RET
107a06918a3SAndrew TurnerAEABI_END(dcmpge)
108a06918a3SAndrew Turner
109a06918a3SAndrew Turner/* int __aeabi_dcmpgt(double, double) */
110a06918a3SAndrew TurnerAEABI_ENTRY(dcmpgt)
111a06918a3SAndrew Turner	LOAD_DREG(d0, r0, r1)
112a06918a3SAndrew Turner	LOAD_DREG(d1, r2, r3)
113a06918a3SAndrew Turner	vcmp.f64 d0, d1
114a06918a3SAndrew Turner	vmrs     APSR_nzcv, fpscr
1152b6a6357SAndrew Turner	ite      le
116a06918a3SAndrew Turner	movle    r0, #0
117a06918a3SAndrew Turner	movgt    r0, #1
118a06918a3SAndrew Turner	RET
119a06918a3SAndrew TurnerAEABI_END(dcmpgt)
120a06918a3SAndrew Turner
121a06918a3SAndrew Turner/* int __aeabi_dcmpun(double, double) */
122a06918a3SAndrew TurnerAEABI_ENTRY(dcmpun)
123a06918a3SAndrew Turner	LOAD_DREG(d0, r0, r1)
124a06918a3SAndrew Turner	LOAD_DREG(d1, r2, r3)
125a06918a3SAndrew Turner	vcmp.f64 d0, d1
126a06918a3SAndrew Turner	vmrs     APSR_nzcv, fpscr
1272b6a6357SAndrew Turner	ite      vc
128a06918a3SAndrew Turner	movvc    r0, #0
129a06918a3SAndrew Turner	movvs    r0, #1
130a06918a3SAndrew Turner	RET
131a06918a3SAndrew TurnerAEABI_END(dcmpun)
132a06918a3SAndrew Turner
133a06918a3SAndrew Turner/* int __aeabi_d2iz(double) */
134a06918a3SAndrew TurnerAEABI_ENTRY(d2iz)
135a06918a3SAndrew Turner	LOAD_DREG(d0, r0, r1)
136a06918a3SAndrew Turner#if 0
137a06918a3SAndrew Turner	/*
138a06918a3SAndrew Turner	 * This should be the correct instruction, but binutils incorrectly
139a06918a3SAndrew Turner	 * encodes it as the version that used FPSCR to determine the rounding.
140a06918a3SAndrew Turner	 * When binutils is fixed we can use this again.
141a06918a3SAndrew Turner	 */
142a06918a3SAndrew Turner	vcvt.s32.f64 s0, d0
143a06918a3SAndrew Turner#else
144a06918a3SAndrew Turner	ftosizd s0, d0
145a06918a3SAndrew Turner#endif
146a06918a3SAndrew Turner	vmov         r0, s0
147a06918a3SAndrew Turner	RET
148a06918a3SAndrew TurnerAEABI_END(d2iz)
149a06918a3SAndrew Turner
150a06918a3SAndrew Turner/* float __aeabi_d2f(double) */
151a06918a3SAndrew TurnerAEABI_ENTRY(d2f)
152a06918a3SAndrew Turner	LOAD_DREG(d0, r0, r1)
153a06918a3SAndrew Turner	vcvt.f32.f64 s0, d0
154a06918a3SAndrew Turner	UNLOAD_SREG(r0, s0)
155a06918a3SAndrew Turner	RET
156a06918a3SAndrew TurnerAEABI_END(d2f)
157a06918a3SAndrew Turner
158a06918a3SAndrew Turner/* double __aeabi_i2d(int) */
159a06918a3SAndrew TurnerAEABI_ENTRY(i2d)
160a06918a3SAndrew Turner	vmov         s0, r0
161a06918a3SAndrew Turner	vcvt.f64.s32 d0, s0
162a06918a3SAndrew Turner	UNLOAD_DREG(r0, r1, d0)
163a06918a3SAndrew Turner	RET
164a06918a3SAndrew TurnerAEABI_END(i2d)
165a06918a3SAndrew Turner
166a06918a3SAndrew Turner/* double __aeabi_dadd(double, double) */
167a06918a3SAndrew TurnerAEABI_ENTRY(dadd)
168a06918a3SAndrew Turner	LOAD_DREG(d0, r0, r1)
169a06918a3SAndrew Turner	LOAD_DREG(d1, r2, r3)
170a06918a3SAndrew Turner	vadd.f64 d0, d0, d1
171a06918a3SAndrew Turner	UNLOAD_DREG(r0, r1, d0)
172a06918a3SAndrew Turner	RET
173a06918a3SAndrew TurnerAEABI_END(dadd)
174a06918a3SAndrew Turner
175a06918a3SAndrew Turner/* double __aeabi_ddiv(double, double) */
176a06918a3SAndrew TurnerAEABI_ENTRY(ddiv)
177a06918a3SAndrew Turner	LOAD_DREG(d0, r0, r1)
178a06918a3SAndrew Turner	LOAD_DREG(d1, r2, r3)
179a06918a3SAndrew Turner	vdiv.f64 d0, d0, d1
180a06918a3SAndrew Turner	UNLOAD_DREG(r0, r1, d0)
181a06918a3SAndrew Turner	RET
182a06918a3SAndrew TurnerAEABI_END(ddiv)
183a06918a3SAndrew Turner
184a06918a3SAndrew Turner/* double __aeabi_dmul(double, double) */
185a06918a3SAndrew TurnerAEABI_ENTRY(dmul)
186a06918a3SAndrew Turner	LOAD_DREG(d0, r0, r1)
187a06918a3SAndrew Turner	LOAD_DREG(d1, r2, r3)
188a06918a3SAndrew Turner	vmul.f64 d0, d0, d1
189a06918a3SAndrew Turner	UNLOAD_DREG(r0, r1, d0)
190a06918a3SAndrew Turner	RET
191a06918a3SAndrew TurnerAEABI_END(dmul)
192a06918a3SAndrew Turner
193a06918a3SAndrew Turner/* double __aeabi_dsub(double, double) */
194a06918a3SAndrew TurnerAEABI_ENTRY(dsub)
195a06918a3SAndrew Turner	LOAD_DREG(d0, r0, r1)
196a06918a3SAndrew Turner	LOAD_DREG(d1, r2, r3)
197a06918a3SAndrew Turner	vsub.f64 d0, d0, d1
198a06918a3SAndrew Turner	UNLOAD_DREG(r0, r1, d0)
199a06918a3SAndrew Turner	RET
200a06918a3SAndrew TurnerAEABI_END(dsub)
201a06918a3SAndrew Turner
20296cdb0abSKonstantin Belousov	.section .note.GNU-stack,"",%progbits
203