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 33RCSID("$NetBSD: vfpsf.S,v 1.4 2018/07/19 19:35:02 joerg 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 58ENTRY(__addsf3) 59 vmov s0, s1, r0, r1 60 vadd.f32 s0, s0, s1 61 vmov r0, s0 62 RET 63END(__addsf3) 64 65ENTRY(__subsf3) 66 vmov s0, s1, r0, r1 67 vsub.f32 s0, s0, s1 68 vmov r0, s0 69 RET 70END(__subsf3) 71 72#ifdef __ARM_EABI__ 73ENTRY(__aeabi_frsub) 74 vmov s0, s1, r0, r1 75 vsub.f32 s0, s1, s0 76 vmov r0, s0 77 RET 78END(__aeabi_frsub) 79#endif 80 81ENTRY(__mulsf3) 82 vmov s0, s1, r0, r1 83 vmul.f32 s0, s0, s1 84 vmov r0, s0 85 RET 86END(__mulsf3) 87 88ENTRY(__divsf3) 89 vmov s0, s1, r0, r1 90 vdiv.f32 s0, s0, s1 91 vmov r0, s0 92 RET 93END(__divsf3) 94 95ENTRY(__negsf2) 96 vmov s0, r0 97 vneg.f32 s0, s0 98 vmov r0, s0 99 RET 100END(__negsf2) 101 102ENTRY(__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 111END(__truncdfsf2) 112 113ENTRY(__fixsfsi) 114 vmov s0, r0 115 vcvt.s32.f32 s0, s0 116 vmov r0, s0 117 RET 118END(__fixsfsi) 119 120ENTRY(__fixunssfsi) 121 vmov s0, r0 122 vcvt.u32.f32 s0, s0 123 vmov r0, s0 124 RET 125END(__fixunssfsi) 126 127ENTRY(__floatsisf) 128 vmov s0, r0 129 vcvt.f32.s32 s0, s0 130 vmov r0, s0 131 RET 132END(__floatsisf) 133 134ENTRY(__floatunsisf) 135 vmov s0, r0 136 vcvt.f32.u32 s0, s0 137 vmov r0, s0 138 RET 139END(__floatunsisf) 140 141/* 142 * Effect of a floating point comparision 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__ 150ENTRY(__aeabi_cfcmpeq) 151 vmov s0, s1, r0, r1 152 vcmp.f32 s0, s1 153 vmrs APSR_nzcv, fpscr 154 RET 155END(__aeabi_cfcmpeq) 156 157ENTRY(__aeabi_cfcmple) 158 vmov s0, s1, r0, r1 159 vcmpe.f32 s0, s1 160 vmrs APSR_nzcv, fpscr 161 RET 162END(__aeabi_cfcmple) 163 164ENTRY(__aeabi_cfrcmple) 165 vmov s0, s1, r0, r1 166 vcmpe.f32 s1, s0 167 vmrs APSR_nzcv, fpscr 168 RET 169END(__aeabi_cfrcmple) 170 171ENTRY(__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 178END(__aeabi_fcmpeq) 179 180ENTRY(__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 187END(__aeabi_fcmplt) 188 189ENTRY(__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 196END(__aeabi_fcmple) 197 198ENTRY(__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 205END(__aeabi_fcmpge) 206 207ENTRY(__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 214END(__aeabi_fcmpgt) 215 216ENTRY(__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 223END(__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 231STRONG_ALIAS(__eqsf2, __nesf2) 232ENTRY(__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 239END(__nesf2) 240 241STRONG_ALIAS(__gesf2, __ltsf2) 242ENTRY(__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 249END(__ltsf2) 250 251STRONG_ALIAS(__gtsf2, __lesf2) 252ENTRY(__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 259END(__lesf2) 260 261ENTRY(__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 268END(__unordsf2) 269#endif /* !__ARM_EABI__ */ 270