1245655Sandrew/*
2245655Sandrew * Copyright (C) 2012 Andrew Turner
3245655Sandrew * All rights reserved.
4245655Sandrew *
5245655Sandrew * Redistribution and use in source and binary forms, with or without
6245655Sandrew * modification, are permitted provided that the following conditions
7245655Sandrew * are met:
8245655Sandrew * 1. Redistributions of source code must retain the above copyright
9245655Sandrew *    notice, this list of conditions and the following disclaimer.
10245655Sandrew * 2. Redistributions in binary form must reproduce the above copyright
11245655Sandrew *    notice, this list of conditions and the following disclaimer in the
12245655Sandrew *    documentation and/or other materials provided with the distribution.
13245655Sandrew *
14245655Sandrew * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15245655Sandrew * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16245655Sandrew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17245655Sandrew * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18245655Sandrew * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19245655Sandrew * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20245655Sandrew * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21245655Sandrew * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22245655Sandrew * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23245655Sandrew * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24245655Sandrew * SUCH DAMAGE.
25245655Sandrew *
26245655Sandrew */
27245655Sandrew
28245655Sandrew#include <sys/cdefs.h>
29245655Sandrew__FBSDID("$FreeBSD$");
30245655Sandrew
31245655Sandrew#include "softfloat-for-gcc.h"
32245655Sandrew#include "milieu.h"
33245655Sandrew#include "softfloat.h"
34245655Sandrew
35266314Sian#include "aeabi_vfp.h"
36245655Sandrew
37266314Sianextern int _libc_arm_fpu_present;
38245655Sandrew
39266314Sianflag __unordsf2(float32, float32);
40245655Sandrew
41266314Sian/* These are written in asm and are only called from this file */
42266314Sianint __aeabi_fcmpeq_vfp(float32, float32);
43266314Sianint __aeabi_fcmplt_vfp(float32, float32);
44266314Sianint __aeabi_fcmple_vfp(float32, float32);
45266314Sianint __aeabi_fcmpgt_vfp(float32, float32);
46266314Sianint __aeabi_fcmpge_vfp(float32, float32);
47266314Sianint __aeabi_fcmpun_vfp(float32, float32);
48266314Sianint __aeabi_f2iz_vfp(float32);
49266314Sianfloat64 __aeabi_f2d_vfp(float32);
50266314Sianfloat32 __aeabi_i2f_vfp(int);
51266314Sianfloat32 __aeabi_fadd_vfp(float32, float32);
52266314Sianfloat32 __aeabi_fdiv_vfp(float32, float32);
53266314Sianfloat32 __aeabi_fmul_vfp(float32, float32);
54266314Sianfloat32 __aeabi_fsub_vfp(float32, float32);
55245655Sandrew
56266314Sian/*
57266314Sian * Depending on the target these will:
58266314Sian *  On armv6 with a vfp call the above function, or
59266314Sian *  Call the softfloat function in the 3rd argument.
60266314Sian */
61266314Sianint AEABI_FUNC2(fcmpeq, float32, float32_eq)
62266314Sianint AEABI_FUNC2(fcmplt, float32, float32_lt)
63266314Sianint AEABI_FUNC2(fcmple, float32, float32_le)
64266314Sianint AEABI_FUNC2_REV(fcmpge, float32, float32_le)
65266314Sianint AEABI_FUNC2_REV(fcmpgt, float32, float32_lt)
66266314Sianint AEABI_FUNC2(fcmpun, float32, __unordsf2)
67245655Sandrew
68266314Sianint AEABI_FUNC(f2iz, float32, float32_to_int32_round_to_zero)
69266314Sianfloat64 AEABI_FUNC(f2d, float32, float32_to_float64)
70266314Sianfloat32 AEABI_FUNC(i2f, int, int32_to_float32)
71245655Sandrew
72266314Sianfloat32 AEABI_FUNC2(fadd, float32, float32_add)
73266314Sianfloat32 AEABI_FUNC2(fdiv, float32, float32_div)
74266314Sianfloat32 AEABI_FUNC2(fmul, float32, float32_mul)
75266314Sianfloat32 AEABI_FUNC2(fsub, float32, float32_sub)
76245655Sandrew
77273471Sandrewint
78273471Sandrew__aeabi_cfcmpeq_helper(float32 a, float32 b)
79273471Sandrew{
80273471Sandrew	int quiet = 0;
81273471Sandrew
82273471Sandrew	/* Check if a is a NaN */
83273471Sandrew	if ((a << 1) > 0xff000000u) {
84273471Sandrew		/* If it's a signalling NaN we will always signal */
85273471Sandrew		if ((a & 0x00400000u) == 0)
86273471Sandrew			return (0);
87273471Sandrew
88273471Sandrew		quiet = 1;
89273471Sandrew	}
90273471Sandrew
91273471Sandrew	/* Check if b is a NaN */
92273471Sandrew	if ((b << 1) > 0xff000000u) {
93273471Sandrew		/* If it's a signalling NaN we will always signal */
94273471Sandrew		if ((b & 0x00400000u) == 0)
95273471Sandrew			return (0);
96273471Sandrew
97273471Sandrew		quiet = 1;
98273471Sandrew	}
99273471Sandrew
100273471Sandrew	return (quiet);
101273471Sandrew}
102