summaryrefslogtreecommitdiffstats
path: root/lib/libc/arm/aeabi/aeabi_vfp.h
blob: 927652f193cad3d3dccba157573f2edf84a1258f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * Copyright (C) 2013 Andrew Turner
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD$
 *
 */

#ifndef AEABI_VFP_H
#define	AEABI_VFP_H

#include <machine/acle-compat.h>

/*
 * ASM helper macros. These allow the functions to be changed depending on
 * the endian-ness we are building for.
 */

/* Allow the name of the function to be changed depending on the ABI */
#ifndef __ARM_PCS_VFP
#define	AEABI_ENTRY(x)	ENTRY(__aeabi_ ## x ## _vfp)
#define	AEABI_END(x)	END(__aeabi_ ## x ## _vfp)
#else
#define	AEABI_ENTRY(x)	ENTRY(__aeabi_ ## x)
#define	AEABI_END(x)	END(__aeabi_ ## x)
#endif

/*
 * These should be used when a function either takes, or returns a floating
 * point falue. They will load the data from an ARM to a VFP register(s),
 * or from a VFP to an ARM register
 */
#ifdef __ARM_BIG_ENDIAN
#define	LOAD_DREG(vreg, reg0, reg1)   vmov vreg, reg1, reg0
#define	UNLOAD_DREG(reg0, reg1, vreg) vmov reg1, reg0, vreg
#else
#define	LOAD_DREG(vreg, reg0, reg1)   vmov vreg, reg0, reg1
#define	UNLOAD_DREG(reg0, reg1, vreg) vmov reg0, reg1, vreg
#endif

#define	LOAD_SREGS(vreg0, vreg1, reg0, reg1) vmov vreg0, vreg1, reg0, reg1
#define	LOAD_SREG(vreg, reg)                 vmov vreg, reg
#define	UNLOAD_SREG(reg, vreg)               vmov reg, vreg

/*
 * C Helper macros
 */

#if __ARM_ARCH >= 6
/*
 * Generate a function that will either call into the VFP implementation,
 * or the soft float version for a given __aeabi_* helper. The function
 * will take a single argument of the type given by in_type.
 */
#define	AEABI_FUNC(name, in_type, soft_func)			\
__aeabi_ ## name(in_type a)					\
{								\
	if (_libc_arm_fpu_present)				\
		return __aeabi_ ## name ## _vfp(a);		\
	else							\
		return soft_func (a);				\
}

/* As above, but takes two arguments of the same type */
#define	AEABI_FUNC2(name, in_type, soft_func)			\
__aeabi_ ## name(in_type a, in_type b)				\
{								\
	if (_libc_arm_fpu_present)				\
		return __aeabi_ ## name ## _vfp(a, b);	\
	else							\
		return soft_func (a, b);			\
}

/* As above, but with the soft float arguments reversed */
#define	AEABI_FUNC2_REV(name, in_type, soft_func)		\
__aeabi_ ## name(in_type a, in_type b)				\
{								\
	if (_libc_arm_fpu_present)				\
		return __aeabi_ ## name ## _vfp(a, b);	\
	else							\
		return soft_func (b, a);			\
}
#else
/*
 * Helper macros for when we are only able to use the softfloat
 * version of these functions, i.e. on arm before armv6.
 */
#define	AEABI_FUNC(name, in_type, soft_func)			\
__aeabi_ ## name(in_type a)					\
{								\
	return soft_func (a);					\
}

/* As above, but takes two arguments of the same type */
#define	AEABI_FUNC2(name, in_type, soft_func)			\
__aeabi_ ## name(in_type a, in_type b)				\
{								\
	return soft_func (a, b);				\
}

/* As above, but with the soft float arguments reversed */
#define	AEABI_FUNC2_REV(name, in_type, soft_func)		\
__aeabi_ ## name(in_type a, in_type b)				\
{								\
	return soft_func (b, a);				\
}
#endif

#endif

OpenPOWER on IntegriCloud