Home | History | Annotate | Line # | Download | only in libc_vfp
      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 #include <arm/vfpreg.h>
     32 
     33 RCSID("$NetBSD: vfpsf.S,v 1.5 2020/12/02 14:20:20 wiz Exp $")
     34 
     35 /*
     36  * This file provides softfloat compatible routines which use VFP instructions
     37  * to do the actual work.  This should give near hard-float performance while
     38  * being compatible with soft-float code.
     39  *
     40  * This file implements the single precision floating point routines.
     41  */
     42 
     43 .fpu vfp
     44 
     45 #ifdef __ARM_EABI__
     46 #define	__addsf3	__aeabi_fadd
     47 #define	__divsf3	__aeabi_fdiv
     48 #define	__mulsf3	__aeabi_fmul
     49 #define	__subsf3	__aeabi_fsub
     50 #define	__negsf2	__aeabi_fneg
     51 #define	__truncdfsf2	__aeabi_d2f
     52 #define	__fixsfsi	__aeabi_f2iz
     53 #define	__fixunssfsi	__aeabi_f2uiz
     54 #define	__floatsisf	__aeabi_i2f
     55 #define	__floatunsisf	__aeabi_ui2f
     56 #endif
     57 
     58 ENTRY(__addsf3)
     59 	vmov		s0, s1, r0, r1
     60 	vadd.f32	s0, s0, s1
     61 	vmov		r0, s0
     62 	RET
     63 END(__addsf3)
     64 
     65 ENTRY(__subsf3)
     66 	vmov		s0, s1, r0, r1
     67 	vsub.f32	s0, s0, s1
     68 	vmov		r0, s0
     69 	RET
     70 END(__subsf3)
     71 
     72 #ifdef __ARM_EABI__
     73 ENTRY(__aeabi_frsub)
     74 	vmov		s0, s1, r0, r1
     75 	vsub.f32	s0, s1, s0
     76 	vmov		r0, s0
     77 	RET
     78 END(__aeabi_frsub)
     79 #endif
     80 
     81 ENTRY(__mulsf3)
     82 	vmov		s0, s1, r0, r1
     83 	vmul.f32	s0, s0, s1
     84 	vmov		r0, s0
     85 	RET
     86 END(__mulsf3)
     87 
     88 ENTRY(__divsf3)
     89 	vmov		s0, s1, r0, r1
     90 	vdiv.f32	s0, s0, s1
     91 	vmov		r0, s0
     92 	RET
     93 END(__divsf3)
     94 
     95 ENTRY(__negsf2)
     96 	vmov		s0, r0
     97 	vneg.f32	s0, s0
     98 	vmov		r0, s0
     99 	RET
    100 END(__negsf2)
    101 
    102 ENTRY(__truncdfsf2)
    103 #ifdef __ARMEL__
    104 	vmov		d0, r0, r1
    105 #else
    106 	vmov		d0, r1, r0
    107 #endif
    108 	vcvt.f32.f64	s0, d0
    109 	vmov		r0, s0
    110 	RET
    111 END(__truncdfsf2)
    112 
    113 ENTRY(__fixsfsi)
    114 	vmov		s0, r0
    115 	vcvt.s32.f32	s0, s0
    116 	vmov		r0, s0
    117 	RET
    118 END(__fixsfsi)
    119 
    120 ENTRY(__fixunssfsi)
    121 	vmov		s0, r0
    122 	vcvt.u32.f32	s0, s0
    123 	vmov		r0, s0
    124 	RET
    125 END(__fixunssfsi)
    126 
    127 ENTRY(__floatsisf)
    128 	vmov		s0, r0
    129 	vcvt.f32.s32	s0, s0
    130 	vmov		r0, s0
    131 	RET
    132 END(__floatsisf)
    133 
    134 ENTRY(__floatunsisf)
    135 	vmov		s0, r0
    136 	vcvt.f32.u32	s0, s0
    137 	vmov		r0, s0
    138 	RET
    139 END(__floatunsisf)
    140 
    141 /*
    142  * Effect of a floating point comparison on the condition flags.
    143  *      N Z C V
    144  * EQ = 0 1 1 0
    145  * LT = 1 0 0 0
    146  * GT = 0 0 1 0
    147  * UN = 0 0 1 1
    148  */
    149 #ifdef __ARM_EABI__
    150 ENTRY(__aeabi_cfcmpeq)
    151 	vmov		s0, s1, r0, r1
    152 	vcmp.f32	s0, s1
    153 	vmrs		APSR_nzcv, fpscr
    154 	RET
    155 END(__aeabi_cfcmpeq)
    156 
    157 ENTRY(__aeabi_cfcmple)
    158 	vmov		s0, s1, r0, r1
    159 	vcmpe.f32	s0, s1
    160 	vmrs		APSR_nzcv, fpscr
    161 	RET
    162 END(__aeabi_cfcmple)
    163 
    164 ENTRY(__aeabi_cfrcmple)
    165 	vmov		s0, s1, r0, r1
    166 	vcmpe.f32	s1, s0
    167 	vmrs		APSR_nzcv, fpscr
    168 	RET
    169 END(__aeabi_cfrcmple)
    170 
    171 ENTRY(__aeabi_fcmpeq)
    172 	vmov		s0, s1, r0, r1
    173 	vcmp.f32	s0, s1
    174 	vmrs		APSR_nzcv, fpscr
    175 	moveq		r0, #1		/* (a == b) */
    176 	movne		r0, #0		/* (a != b) or unordered */
    177 	RET
    178 END(__aeabi_fcmpeq)
    179 
    180 ENTRY(__aeabi_fcmplt)
    181 	vmov		s0, s1, r0, r1
    182 	vcmp.f32	s0, s1
    183 	vmrs		APSR_nzcv, fpscr
    184 	movlt		r0, #1		/* (a < b) */
    185 	movcs		r0, #0		/* (a >= b) or unordered */
    186 	RET
    187 END(__aeabi_fcmplt)
    188 
    189 ENTRY(__aeabi_fcmple)
    190 	vmov		s0, s1, r0, r1
    191 	vcmp.f32	s0, s1
    192 	vmrs		APSR_nzcv, fpscr
    193 	movls		r0, #1		/* (a <= b) */
    194 	movhi		r0, #0		/* (a > b) or unordered */
    195 	RET
    196 END(__aeabi_fcmple)
    197 
    198 ENTRY(__aeabi_fcmpge)
    199 	vmov		s0, s1, r0, r1
    200 	vcmp.f32	s0, s1
    201 	vmrs		APSR_nzcv, fpscr
    202 	movge		r0, #1		/* (a >= b) */
    203 	movlt		r0, #0		/* (a < b) or unordered */
    204 	RET
    205 END(__aeabi_fcmpge)
    206 
    207 ENTRY(__aeabi_fcmpgt)
    208 	vmov		s0, s1, r0, r1
    209 	vcmp.f32	s0, s1
    210 	vmrs		APSR_nzcv, fpscr
    211 	movgt		r0, #1		/* (a > b) */
    212 	movle		r0, #0		/* (a <= b) or unordered */
    213 	RET
    214 END(__aeabi_fcmpgt)
    215 
    216 ENTRY(__aeabi_fcmpun)
    217 	vmov		s0, s1, r0, r1
    218 	vcmp.f32	s0, s1
    219 	vmrs		APSR_nzcv, fpscr
    220 	movvs		r0, #1		/* (isnan(a) || isnan(b)) */
    221 	movvc		r0, #0		/* !isnan(a) && !isnan(b) */
    222 	RET
    223 END(__aeabi_fcmpun)
    224 
    225 #else
    226 /* N set if compare <= result */
    227 /* Z set if compare = result */
    228 /* C set if compare (=,>=,UNORD) result */
    229 /* V set if compare UNORD result */
    230 
    231 STRONG_ALIAS(__eqsf2, __nesf2)
    232 ENTRY(__nesf2)
    233 	vmov		s0, s1, r0, r1
    234 	vcmp.f32	s0, s1
    235 	vmrs		APSR_nzcv, fpscr
    236 	moveq		r0, #0		/* !(a == b) */
    237 	movne		r0, #1		/* !(a == b) */
    238 	RET
    239 END(__nesf2)
    240 
    241 STRONG_ALIAS(__gesf2, __ltsf2)
    242 ENTRY(__ltsf2)
    243 	vmov		s0, s1, r0, r1
    244 	vcmp.f32	s0, s1
    245 	vmrs		APSR_nzcv, fpscr
    246 	mvnmi		r0, #0		/* -(a < b) */
    247 	movpl		r0, #0		/* -(a < b) */
    248 	RET
    249 END(__ltsf2)
    250 
    251 STRONG_ALIAS(__gtsf2, __lesf2)
    252 ENTRY(__lesf2)
    253 	vmov		s0, s1, r0, r1
    254 	vcmp.f32	s0, s1
    255 	vmrs		APSR_nzcv, fpscr
    256 	movgt		r0, #1		/* (a > b) */
    257 	movle		r0, #0		/* (a > b) */
    258 	RET
    259 END(__lesf2)
    260 
    261 ENTRY(__unordsf2)
    262 	vmov		s0, s1, r0, r1
    263 	vcmp.f32	s0, s1
    264 	vmrs		APSR_nzcv, fpscr
    265 	movvs		r0, #1		/* isnan(a) || isnan(b) */
    266 	movvc		r0, #0		/* isnan(a) || isnan(b) */
    267 	RET
    268 END(__unordsf2)
    269 #endif /* !__ARM_EABI__ */
    270