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