Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* Machine-dependent software floating-point definitions.  PPC version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)    Copyright (C) 1997 Free Software Foundation, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)    This file is part of the GNU C Library.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)    The GNU C Library is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)    modify it under the terms of the GNU Library General Public License as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)    published by the Free Software Foundation; either version 2 of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)    License, or (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)    The GNU C Library is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)    but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)    Library General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)    You should have received a copy of the GNU Library General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)    License along with the GNU C Library; see the file COPYING.LIB.  If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)    not, write to the Free Software Foundation, Inc.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)    Actually, this is a PPC (32bit) version, written based on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)    i386, sparc, and sparc64 versions, by me,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)    Peter Maydell (pmaydell@chiark.greenend.org.uk).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)    Comments are by and large also mine, although they may be inaccurate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)    In picking out asm fragments I've gone with the lowest common
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)    denominator, which also happens to be the hardware I have :->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)    That is, a SPARC without hardware multiply and divide.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) /* basic word size definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define _FP_W_TYPE_SIZE		32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define _FP_W_TYPE		unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define _FP_WS_TYPE		signed int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define _FP_I_TYPE		int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define __ll_B			((UWtype) 1 << (W_TYPE_SIZE / 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define __ll_lowpart(t)		((UWtype) (t) & (__ll_B - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define __ll_highpart(t)	((UWtype) (t) >> (W_TYPE_SIZE / 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) /* You can optionally code some things like addition in asm. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * example, i386 defines __FP_FRAC_ADD_2 as asm. If you don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * then you get a fragment of C code [if you change an #ifdef 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * in op-2.h] or a call to add_ssaaaa (see below).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * Good places to look for asm fragments to use are gcc and glibc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * gcc's longlong.h is useful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) /* We need to know how to multiply and divide. If the host word size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * is >= 2*fracbits you can use FP_MUL_MEAT_n_imm(t,R,X,Y) which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * codes the multiply with whatever gcc does to 'a * b'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * _FP_MUL_MEAT_n_wide(t,R,X,Y,f) is used when you have an asm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * function that can multiply two 1W values and get a 2W result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * Otherwise you're stuck with _FP_MUL_MEAT_n_hard(t,R,X,Y) which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * does bitshifting to avoid overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * For division there is FP_DIV_MEAT_n_imm(t,R,X,Y,f) for word size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * >= 2*fracbits, where f is either _FP_DIV_HELP_imm or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * _FP_DIV_HELP_ldiv (see op-1.h).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * _FP_DIV_MEAT_udiv() is if you have asm to do 2W/1W => (1W, 1W).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * [GCC and glibc have longlong.h which has the asm macro udiv_qrnnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * to do this.]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * In general, 'n' is the number of words required to hold the type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * and 't' is either S, D or Q for single/double/quad.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  *           -- PMM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) /* Example: SPARC64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * #define _FP_MUL_MEAT_S(R,X,Y)	_FP_MUL_MEAT_1_imm(S,R,X,Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * #define _FP_MUL_MEAT_D(R,X,Y)	_FP_MUL_MEAT_1_wide(D,R,X,Y,umul_ppmm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * #define _FP_MUL_MEAT_Q(R,X,Y)	_FP_MUL_MEAT_2_wide(Q,R,X,Y,umul_ppmm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * #define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  * #define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_1_udiv(D,R,X,Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * #define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_2_udiv_64(Q,R,X,Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * Example: i386:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * #define _FP_MUL_MEAT_S(R,X,Y)   _FP_MUL_MEAT_1_wide(S,R,X,Y,_i386_mul_32_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * #define _FP_MUL_MEAT_D(R,X,Y)   _FP_MUL_MEAT_2_wide(D,R,X,Y,_i386_mul_32_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * #define _FP_DIV_MEAT_S(R,X,Y)   _FP_DIV_MEAT_1_udiv(S,R,X,Y,_i386_div_64_32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * #define _FP_DIV_MEAT_D(R,X,Y)   _FP_DIV_MEAT_2_udiv_64(D,R,X,Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define _FP_MUL_MEAT_S(R,X,Y)   _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #define _FP_MUL_MEAT_D(R,X,Y)   _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv_norm(S,R,X,Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) #define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) /* These macros define what NaN looks like. They're supposed to expand to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * a comma-separated set of 32bit unsigned ints that encode NaN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) #define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1), -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define _FP_NANSIGN_S		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #define _FP_NANSIGN_D		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) #define _FP_NANSIGN_Q		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) #define _FP_KEEPNANFRACP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #ifdef FP_EX_BOOKE_E500_SPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define FP_EX_INEXACT		(1 << 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define FP_EX_INVALID		(1 << 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define FP_EX_DIVZERO		(1 << 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define FP_EX_UNDERFLOW		(1 << 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define FP_EX_OVERFLOW		(1 << 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define FP_INHIBIT_RESULTS	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define __FPU_FPSCR	(current->thread.spefscr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define __FPU_ENABLED_EXC		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ({					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	(__FPU_FPSCR >> 2) & 0x1f;	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* Exception flags.  We use the bit positions of the appropriate bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)    in the FPSCR, which also correspond to the FE_* bits.  This makes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)    everything easier ;-).  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define FP_EX_INVALID         (1 << (31 - 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define FP_EX_INVALID_SNAN	EFLAG_VXSNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define FP_EX_INVALID_ISI	EFLAG_VXISI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define FP_EX_INVALID_IDI	EFLAG_VXIDI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define FP_EX_INVALID_ZDZ	EFLAG_VXZDZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define FP_EX_INVALID_IMZ	EFLAG_VXIMZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define FP_EX_OVERFLOW        (1 << (31 - 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define FP_EX_UNDERFLOW       (1 << (31 - 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define FP_EX_DIVZERO         (1 << (31 - 5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define FP_EX_INEXACT         (1 << (31 - 6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define __FPU_FPSCR	(current->thread.fp_state.fpscr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* We only actually write to the destination register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * if exceptions signalled (if any) will not trap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define __FPU_ENABLED_EXC \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ({						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	(__FPU_FPSCR >> 3) & 0x1f;	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * If one NaN is signaling and the other is not,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  * we choose that one, otherwise we choose X.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)   do {								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)     if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	&& !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)       {								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	R##_s = X##_s;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	_FP_FRAC_COPY_##wc(R,X);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)       }								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)     else							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)       {								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	R##_s = Y##_s;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	_FP_FRAC_COPY_##wc(R,Y);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)       }								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)     R##_c = FP_CLS_NAN;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)   } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define __FPU_TRAP_P(bits) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	((__FPU_ENABLED_EXC & (bits)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define __FP_PACK_S(val,X)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ({  int __exc = _FP_PACK_CANONICAL(S,1,X);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)     if(!__exc || !__FPU_TRAP_P(__exc))		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)         _FP_PACK_RAW_1_P(S,val,X);		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)     __exc;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define __FP_PACK_D(val,X)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)    do {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	_FP_PACK_CANONICAL(D, 2, X);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	if (!FP_CUR_EXCEPTIONS || !__FPU_TRAP_P(FP_CUR_EXCEPTIONS))	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		_FP_PACK_RAW_2_P(D, val, X);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)    } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define __FP_PACK_DS(val,X)							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)    do {										\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	   FP_DECL_S(__X);							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	   FP_CONV(S, D, 1, 2, __X, X);						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	   _FP_PACK_CANONICAL(S, 1, __X);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	   if (!FP_CUR_EXCEPTIONS || !__FPU_TRAP_P(FP_CUR_EXCEPTIONS)) {	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		   _FP_UNPACK_CANONICAL(S, 1, __X);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		   FP_CONV(D, S, 2, 1, X, __X);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		   _FP_PACK_CANONICAL(D, 2, X);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		   if (!FP_CUR_EXCEPTIONS || !__FPU_TRAP_P(FP_CUR_EXCEPTIONS))	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		   _FP_PACK_RAW_2_P(D, val, X);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	   }									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)    } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* Obtain the current rounding mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define FP_ROUNDMODE			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ({					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	__FPU_FPSCR & 0x3;		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* the asm fragments go here: all these are taken from glibc-2.0.5's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  * stdlib/longlong.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* add_ssaaaa is used in op-2.h and should be equivalent to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  * #define add_ssaaaa(sh,sl,ah,al,bh,bl) (sh = ah+bh+ (( sl = al+bl) < al))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  * high_addend_2, low_addend_2) adds two UWtype integers, composed by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  * HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  * respectively.  The result is placed in HIGH_SUM and LOW_SUM.  Overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * (i.e. carry out) is not stored anywhere, and is lost.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)   do {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)     if (__builtin_constant_p (bh) && (bh) == 0)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)       __asm__ ("add%I4c %1,%3,%4\n\taddze %0,%2"		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)     else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)       __asm__ ("add%I4c %1,%3,%4\n\taddme %0,%2"		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)     else								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)       __asm__ ("add%I5c %1,%4,%5\n\tadde %0,%2,%3"		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	     : "=r" (sh), "=&r" (sl)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	     : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl));		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)   } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* sub_ddmmss is used in op-2.h and udivmodti4.c and should be equivalent to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  * #define sub_ddmmss(sh, sl, ah, al, bh, bl) (sh = ah-bh - ((sl = al-bl) > al))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)  * sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)  * high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)  * composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  * LOW_SUBTRAHEND_2 respectively.  The result is placed in HIGH_DIFFERENCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  * and LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)  * and is lost.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)   do {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)     if (__builtin_constant_p (ah) && (ah) == 0)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)       __asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2"	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)     else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)       __asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2"	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)     else if (__builtin_constant_p (bh) && (bh) == 0)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)       __asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2"		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)     else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)       __asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2"		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)     else								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)       __asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2"	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	       : "=r" (sh), "=&r" (sl)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	       : "r" (ah), "r" (bh), "rI" (al), "r" (bl));		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)   } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* asm fragments for mul and div */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)  * UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)  * word product in HIGH_PROD and LOW_PROD.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #define umul_ppmm(ph, pl, m0, m1) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)   do {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)     USItype __m0 = (m0), __m1 = (m1);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)     __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)     (pl) = __m0 * __m1;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)   } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)  * denominator) divides a UDWtype, composed by the UWtype integers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)  * HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  * in QUOTIENT and the remainder in REMAINDER.  HIGH_NUMERATOR must be less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  * than DENOMINATOR for correct operation.  If, in addition, the most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  * significant bit of DENOMINATOR must be 1, then the pre-processor symbol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)  * UDIV_NEEDS_NORMALIZATION is defined to 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) #define udiv_qrnnd(q, r, n1, n0, d) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)   do {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)     UWtype __d1, __d0, __q1, __q0;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)     UWtype __r1, __r0, __m;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)     __d1 = __ll_highpart (d);						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)     __d0 = __ll_lowpart (d);						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)     __r1 = (n1) % __d1;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)     __q1 = (n1) / __d1;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)     __m = (UWtype) __q1 * __d0;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)     __r1 = __r1 * __ll_B | __ll_highpart (n0);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)     if (__r1 < __m)							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)       {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	__q1--, __r1 += (d);						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	  if (__r1 < __m)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	    __q1--, __r1 += (d);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)       }									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)     __r1 -= __m;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)     __r0 = __r1 % __d1;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)     __q0 = __r1 / __d1;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)     __m = (UWtype) __q0 * __d0;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)     __r0 = __r0 * __ll_B | __ll_lowpart (n0);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)     if (__r0 < __m)							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)       {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	__q0--, __r0 += (d);						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	if (__r0 >= (d))						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	  if (__r0 < __m)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	    __q0--, __r0 += (d);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)       }									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)     __r0 -= __m;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)     (q) = (UWtype) __q1 * __ll_B | __q0;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)     (r) = __r0;								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)   } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) #define UDIV_NEEDS_NORMALIZATION 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) #define abort()								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	return 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) #ifdef __BIG_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) #define __BYTE_ORDER __BIG_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) #define __BYTE_ORDER __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* Exception flags. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) #define EFLAG_INVALID		(1 << (31 - 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #define EFLAG_OVERFLOW		(1 << (31 - 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) #define EFLAG_UNDERFLOW		(1 << (31 - 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) #define EFLAG_DIVZERO		(1 << (31 - 5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) #define EFLAG_INEXACT		(1 << (31 - 6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #define EFLAG_VXSNAN		(1 << (31 - 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) #define EFLAG_VXISI		(1 << (31 - 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) #define EFLAG_VXIDI		(1 << (31 - 9))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) #define EFLAG_VXZDZ		(1 << (31 - 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) #define EFLAG_VXIMZ		(1 << (31 - 11))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) #define EFLAG_VXVC		(1 << (31 - 12))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) #define EFLAG_VXSOFT		(1 << (31 - 21))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) #define EFLAG_VXSQRT		(1 << (31 - 22))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) #define EFLAG_VXCVI		(1 << (31 - 23))