xref: /openbsd-src/lib/libc/arch/arm/quad/fixsfdi.c (revision 7d412f24af4d115718e3f3ccc5e46e83cbd5ad03)
1*7d412f24Smbuhl /*	$OpenBSD: fixsfdi.c,v 1.1 2022/09/03 08:26:05 mbuhl Exp $	*/
2*7d412f24Smbuhl /*	$NetBSD: fixsfdi_ieee754.c,v 1.1 2013/08/24 00:51:48 matt Exp $	*/
3*7d412f24Smbuhl 
4*7d412f24Smbuhl /*-
5*7d412f24Smbuhl  * Copyright (c) 1992, 1993
6*7d412f24Smbuhl  *	The Regents of the University of California.  All rights reserved.
7*7d412f24Smbuhl  *
8*7d412f24Smbuhl  * This software was developed by the Computer Systems Engineering group
9*7d412f24Smbuhl  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
10*7d412f24Smbuhl  * contributed to Berkeley.
11*7d412f24Smbuhl  *
12*7d412f24Smbuhl  * Redistribution and use in source and binary forms, with or without
13*7d412f24Smbuhl  * modification, are permitted provided that the following conditions
14*7d412f24Smbuhl  * are met:
15*7d412f24Smbuhl  * 1. Redistributions of source code must retain the above copyright
16*7d412f24Smbuhl  *    notice, this list of conditions and the following disclaimer.
17*7d412f24Smbuhl  * 2. Redistributions in binary form must reproduce the above copyright
18*7d412f24Smbuhl  *    notice, this list of conditions and the following disclaimer in the
19*7d412f24Smbuhl  *    documentation and/or other materials provided with the distribution.
20*7d412f24Smbuhl  * 3. Neither the name of the University nor the names of its contributors
21*7d412f24Smbuhl  *    may be used to endorse or promote products derived from this software
22*7d412f24Smbuhl  *    without specific prior written permission.
23*7d412f24Smbuhl  *
24*7d412f24Smbuhl  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25*7d412f24Smbuhl  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26*7d412f24Smbuhl  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27*7d412f24Smbuhl  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28*7d412f24Smbuhl  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29*7d412f24Smbuhl  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30*7d412f24Smbuhl  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31*7d412f24Smbuhl  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32*7d412f24Smbuhl  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33*7d412f24Smbuhl  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34*7d412f24Smbuhl  * SUCH DAMAGE.
35*7d412f24Smbuhl  */
36*7d412f24Smbuhl 
37*7d412f24Smbuhl #include <sys/cdefs.h>
38*7d412f24Smbuhl #if defined(LIBC_SCCS) && !defined(lint)
39*7d412f24Smbuhl __RCSID("$NetBSD: fixsfdi_ieee754.c,v 1.1 2013/08/24 00:51:48 matt Exp $");
40*7d412f24Smbuhl #endif /* LIBC_SCCS and not lint */
41*7d412f24Smbuhl 
42*7d412f24Smbuhl #if defined(SOFTFLOAT) || defined(__ARM_EABI__)
43*7d412f24Smbuhl #include "softfloat/softfloat-for-gcc.h"
44*7d412f24Smbuhl #endif
45*7d412f24Smbuhl 
46*7d412f24Smbuhl #include "../../../quad/quad.h"
47*7d412f24Smbuhl #include <limits.h>
48*7d412f24Smbuhl #include <stdbool.h>
49*7d412f24Smbuhl #include <machine/ieee.h>
50*7d412f24Smbuhl 
51*7d412f24Smbuhl /*
52*7d412f24Smbuhl  * Convert float to signed quad.
53*7d412f24Smbuhl  */
54*7d412f24Smbuhl quad_t
__fixsfdi(float x)55*7d412f24Smbuhl __fixsfdi(float x)
56*7d412f24Smbuhl {
57*7d412f24Smbuhl 	struct ieee_single ux = *(struct ieee_single *)&x;
58*7d412f24Smbuhl 	signed int exp = ux.sng_exp - SNG_EXP_BIAS;
59*7d412f24Smbuhl 	const bool neg = ux.sng_sign;
60*7d412f24Smbuhl 	quad_t r;
61*7d412f24Smbuhl 
62*7d412f24Smbuhl 	if (exp < 0)
63*7d412f24Smbuhl 		return 0;
64*7d412f24Smbuhl 	if (exp > 62)
65*7d412f24Smbuhl 		return neg ? QUAD_MIN : QUAD_MAX;
66*7d412f24Smbuhl 
67*7d412f24Smbuhl 	r = 1 << SNG_FRACBITS;		/* implicit bit */
68*7d412f24Smbuhl 	r |= ux.sng_frac;
69*7d412f24Smbuhl 	exp -= SNG_FRACBITS;
70*7d412f24Smbuhl 	if (exp < 0) {
71*7d412f24Smbuhl 		r >>= -exp;
72*7d412f24Smbuhl 	} else if (exp > 0) {
73*7d412f24Smbuhl 		r <<= exp;
74*7d412f24Smbuhl 	}
75*7d412f24Smbuhl 	return neg ? -r : r;
76*7d412f24Smbuhl }
77