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