1263239Sandrew/*
2263239Sandrew * Copyright (C) 2013 Andrew Turner
3263239Sandrew * All rights reserved.
4263239Sandrew *
5263239Sandrew * Redistribution and use in source and binary forms, with or without
6263239Sandrew * modification, are permitted provided that the following conditions
7263239Sandrew * are met:
8263239Sandrew * 1. Redistributions of source code must retain the above copyright
9263239Sandrew *    notice, this list of conditions and the following disclaimer.
10263239Sandrew * 2. Redistributions in binary form must reproduce the above copyright
11263239Sandrew *    notice, this list of conditions and the following disclaimer in the
12263239Sandrew *    documentation and/or other materials provided with the distribution.
13263239Sandrew *
14263239Sandrew * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15263239Sandrew * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16263239Sandrew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17263239Sandrew * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18263239Sandrew * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19263239Sandrew * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20263239Sandrew * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21263239Sandrew * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22263239Sandrew * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23263239Sandrew * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24263239Sandrew * SUCH DAMAGE.
25263239Sandrew *
26263239Sandrew */
27263239Sandrew
28263239Sandrew#include <machine/asm.h>
29263239Sandrew__FBSDID("$FreeBSD$");
30263239Sandrew
31263239Sandrew#include "aeabi_vfp.h"
32263239Sandrew
33263239Sandrew.fpu	vfp
34263239Sandrew.syntax	unified
35263239Sandrew
36273088Sandrew/* void __aeabi_cfcmpeq(float, float) */
37273088SandrewAEABI_ENTRY(cfcmpeq)
38273088Sandrew	LOAD_SREGS(s0, s1, r0, r1)
39273088Sandrew	vcmp.f32	s0, s1
40273088Sandrew	vmrs     	APSR_nzcv, fpscr
41273088Sandrew	RET
42273088SandrewAEABI_END(cfcmpeq)
43273088Sandrew
44273088Sandrew/* void __aeabi_cfcmple(float, float) */
45273088SandrewAEABI_ENTRY(cfcmple)
46273088Sandrew	LOAD_SREGS(s0, s1, r0, r1)
47273088Sandrew	vcmpe.f32	s0, s1
48273088Sandrew	vmrs     	APSR_nzcv, fpscr
49273088Sandrew	RET
50273088SandrewAEABI_END(cfcmple)
51273088Sandrew
52273088Sandrew/* void __aeabi_cfrcmple(float, float) */
53273088SandrewAEABI_ENTRY(cfrcmple)
54273088Sandrew	LOAD_SREGS(s0, s1, r0, r1)
55273088Sandrew	vcmpe.f32	s1, s0
56273088Sandrew	vmrs     	APSR_nzcv, fpscr
57273088Sandrew	RET
58273088SandrewAEABI_END(cfrcmple)
59273088Sandrew
60263239Sandrew/* int __aeabi_fcmpeq(float, float) */
61263239SandrewAEABI_ENTRY(fcmpeq)
62263239Sandrew	LOAD_SREGS(s0, s1, r0, r1)
63263239Sandrew	vcmp.f32 s0, s1
64263239Sandrew	vmrs     APSR_nzcv, fpscr
65282816Sandrew	ite      ne
66263239Sandrew	movne    r0, #0
67263239Sandrew	moveq    r0, #1
68263239Sandrew	RET
69263239SandrewAEABI_END(fcmpeq)
70263239Sandrew
71263239Sandrew/* int __aeabi_fcmplt(float, float) */
72263239SandrewAEABI_ENTRY(fcmplt)
73263239Sandrew	LOAD_SREGS(s0, s1, r0, r1)
74263239Sandrew	vcmp.f32 s0, s1
75263239Sandrew	vmrs     APSR_nzcv, fpscr
76282816Sandrew	ite      cs
77263239Sandrew	movcs    r0, #0
78282816Sandrew	movcc    r0, #1
79263239Sandrew	RET
80263239SandrewAEABI_END(fcmplt)
81263239Sandrew
82263239Sandrew/* int __aeabi_fcmple(float, float) */
83263239SandrewAEABI_ENTRY(fcmple)
84263239Sandrew	LOAD_SREGS(s0, s1, r0, r1)
85263239Sandrew	vcmp.f32 s0, s1
86263239Sandrew	vmrs     APSR_nzcv, fpscr
87282816Sandrew	ite      hi
88263239Sandrew	movhi    r0, #0
89263239Sandrew	movls    r0, #1
90263239Sandrew	RET
91263239SandrewAEABI_END(fcmple)
92263239Sandrew
93263239Sandrew/* int __aeabi_fcmpge(float, float) */
94263239SandrewAEABI_ENTRY(fcmpge)
95263239Sandrew	LOAD_SREGS(s0, s1, r0, r1)
96263239Sandrew	vcmp.f32 s0, s1
97263239Sandrew	vmrs     APSR_nzcv, fpscr
98282816Sandrew	ite      lt
99263239Sandrew	movlt    r0, #0
100263239Sandrew	movge    r0, #1
101263239Sandrew	RET
102263239SandrewAEABI_END(fcmpge)
103263239Sandrew
104263239Sandrew/* int __aeabi_fcmpgt(float, float) */
105263239SandrewAEABI_ENTRY(fcmpgt)
106263239Sandrew	LOAD_SREGS(s0, s1, r0, r1)
107263239Sandrew	vcmp.f32 s0, s1
108263239Sandrew	vmrs     APSR_nzcv, fpscr
109282816Sandrew	ite      le
110263239Sandrew	movle    r0, #0
111263239Sandrew	movgt    r0, #1
112263239Sandrew	RET
113263239SandrewAEABI_END(fcmpgt)
114263239Sandrew
115263239Sandrew/* int __aeabi_fcmpun(float, float) */
116263239SandrewAEABI_ENTRY(fcmpun)
117263239Sandrew	LOAD_SREGS(s0, s1, r0, r1)
118263239Sandrew	vcmp.f32 s0, s1
119263239Sandrew	vmrs     APSR_nzcv, fpscr
120282816Sandrew	ite      vc
121263239Sandrew	movvc    r0, #0
122263239Sandrew	movvs    r0, #1
123263239Sandrew	RET
124263239SandrewAEABI_END(fcmpun)
125263239Sandrew
126263239Sandrew/* int __aeabi_f2iz(float) */
127263239SandrewAEABI_ENTRY(f2iz)
128263239Sandrew	LOAD_SREG(s0, r0)
129263239Sandrew#if 0
130263239Sandrew	/*
131263239Sandrew	 * This should be the correct instruction, but binutils incorrectly
132263239Sandrew	 * encodes it as the version that used FPSCR to determine the rounding.
133263239Sandrew	 * When binutils is fixed we can use this again.
134263239Sandrew	 */
135263239Sandrew	vcvt.s32.f32 s0, s0
136263239Sandrew#else
137263239Sandrew	ftosizs      s0, s0
138263239Sandrew#endif
139263239Sandrew	vmov         r0, s0
140263239Sandrew	RET
141263239SandrewAEABI_END(f2iz)
142263239Sandrew
143263239Sandrew/* double __aeabi_f2d(float) */
144263239SandrewAEABI_ENTRY(f2d)
145263239Sandrew	LOAD_SREG(s0, r0)
146263239Sandrew	vcvt.f64.f32 d0, s0
147263239Sandrew	UNLOAD_DREG(r0, r1, d0)
148263239Sandrew	RET
149263239SandrewAEABI_END(f2d)
150263239Sandrew
151263239Sandrew/* float __aeabi_i2f(int) */
152263239SandrewAEABI_ENTRY(i2f)
153263239Sandrew	vmov         s0, r0
154263239Sandrew	vcvt.f32.s32 s0, s0
155263239Sandrew	UNLOAD_SREG(r0, s0)
156263239Sandrew	RET
157263239SandrewAEABI_END(i2f)
158263239Sandrew
159263239Sandrew/* float __aeabi_fadd(float, float) */
160263239SandrewAEABI_ENTRY(fadd)
161263239Sandrew	LOAD_SREGS(s0, s1, r0, r1)
162263239Sandrew	vadd.f32 s0, s0, s1
163263239Sandrew	UNLOAD_SREG(r0, s0)
164263239Sandrew	RET
165263239SandrewAEABI_END(fadd)
166263239Sandrew
167263239Sandrew/* float __aeabi_fmul(float, float) */
168263239SandrewAEABI_ENTRY(fdiv)
169263239Sandrew	LOAD_SREGS(s0, s1, r0, r1)
170263239Sandrew	vdiv.f32 s0, s0, s1
171263239Sandrew	UNLOAD_SREG(r0, s0)
172263239Sandrew	RET
173263239SandrewAEABI_END(fdiv)
174263239Sandrew
175263239Sandrew/* float __aeabi_fmul(float, float) */
176263239SandrewAEABI_ENTRY(fmul)
177263239Sandrew	LOAD_SREGS(s0, s1, r0, r1)
178263239Sandrew	vmul.f32 s0, s0, s1
179263239Sandrew	UNLOAD_SREG(r0, s0)
180263239Sandrew	RET
181263239SandrewAEABI_END(fmul)
182263239Sandrew
183263239Sandrew/* float __aeabi_fsub(float, float) */
184263239SandrewAEABI_ENTRY(fsub)
185263239Sandrew	LOAD_SREGS(s0, s1, r0, r1)
186263239Sandrew	vsub.f32 s0, s0, s1
187263239Sandrew	UNLOAD_SREG(r0, s0)
188263239Sandrew	RET
189263239SandrewAEABI_END(fsub)
190263239Sandrew
191288373Skib	.section .note.GNU-stack,"",%progbits
192