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