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