116 lines
4.2 KiB
C
116 lines
4.2 KiB
C
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
|
|
|
|
Copyright 1991, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, 2002, 2003,
|
|
2004, 2005 Free Software Foundation, Inc.
|
|
|
|
This file is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation; either version 2.1 of the License, or (at your
|
|
option) any later version.
|
|
|
|
This file is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this file; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
MA 02110-1301, USA. */
|
|
|
|
#if defined (__GNUC__)
|
|
|
|
#if (defined (__mc68000__) || defined (__mc68020__) || defined(mc68020) \
|
|
|| defined (__m68k__) || defined (__mc5200__) || defined (__mc5206e__) \
|
|
|| defined (__mc5307__))
|
|
|
|
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
|
|
__asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \
|
|
: "=d" (sh), "=&d" (sl) \
|
|
: "0" ((USItype)(ah)), "d" ((USItype)(bh)), \
|
|
"%1" ((USItype)(al)), "g" ((USItype)(bl)))
|
|
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
|
|
__asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \
|
|
: "=d" (sh), "=&d" (sl) \
|
|
: "0" ((USItype)(ah)), "d" ((USItype)(bh)), \
|
|
"1" ((USItype)(al)), "g" ((USItype)(bl)))
|
|
/* The '020, '030, '040 and CPU32 have 32x32->64 and 64/32->32q-32r. */
|
|
#if defined (__mc68020__) || defined(mc68020) \
|
|
|| defined (__mc68030__) || defined (mc68030) \
|
|
|| defined (__mc68040__) || defined (mc68040) \
|
|
|| defined (__mcpu32__) || defined (mcpu32) \
|
|
|| defined (__NeXT__)
|
|
#define umul_ppmm(w1, w0, u, v) \
|
|
__asm__ ("mulu%.l %3,%1:%0" \
|
|
: "=d" (w0), "=d" (w1) \
|
|
: "%0" ((USItype)(u)), "dmi" ((USItype)(v)))
|
|
#define udiv_qrnnd(q, r, n1, n0, d) \
|
|
__asm__ ("divu%.l %4,%1:%0" \
|
|
: "=d" (q), "=d" (r) \
|
|
: "0" ((USItype)(n0)), "1" ((USItype)(n1)), "dmi" ((USItype)(d)))
|
|
#define sdiv_qrnnd(q, r, n1, n0, d) \
|
|
__asm__ ("divs%.l %4,%1:%0" \
|
|
: "=d" (q), "=d" (r) \
|
|
: "0" ((USItype)(n0)), "1" ((USItype)(n1)), "dmi" ((USItype)(d)))
|
|
#else /* for other 68k family members use 16x16->32 multiplication */
|
|
#define umul_ppmm(xh, xl, a, b) \
|
|
do { USItype __umul_tmp1, __umul_tmp2; \
|
|
__asm__ ("| Inlined umul_ppmm\n" \
|
|
" move%.l %5,%3\n" \
|
|
" move%.l %2,%0\n" \
|
|
" move%.w %3,%1\n" \
|
|
" swap %3\n" \
|
|
" swap %0\n" \
|
|
" mulu%.w %2,%1\n" \
|
|
" mulu%.w %3,%0\n" \
|
|
" mulu%.w %2,%3\n" \
|
|
" swap %2\n" \
|
|
" mulu%.w %5,%2\n" \
|
|
" add%.l %3,%2\n" \
|
|
" jcc 1f\n" \
|
|
" add%.l %#0x10000,%0\n" \
|
|
"1: move%.l %2,%3\n" \
|
|
" clr%.w %2\n" \
|
|
" swap %2\n" \
|
|
" swap %3\n" \
|
|
" clr%.w %3\n" \
|
|
" add%.l %3,%1\n" \
|
|
" addx%.l %2,%0\n" \
|
|
" | End inlined umul_ppmm" \
|
|
: "=&d" (xh), "=&d" (xl), \
|
|
"=d" (__umul_tmp1), "=&d" (__umul_tmp2) \
|
|
: "%2" ((USItype)(a)), "d" ((USItype)(b))); \
|
|
} while (0)
|
|
#endif /* not mc68020 */
|
|
/* The '020, '030, '040 and '060 have bitfield insns.
|
|
GCC 3.4 defines __mc68020__ when in CPU32 mode, check for __mcpu32__ to
|
|
exclude bfffo on that chip (bitfield insns not available). */
|
|
#if (defined (__mc68020__) || defined (mc68020) \
|
|
|| defined (__mc68030__) || defined (mc68030) \
|
|
|| defined (__mc68040__) || defined (mc68040) \
|
|
|| defined (__mc68060__) || defined (mc68060) \
|
|
|| defined (__NeXT__)) \
|
|
&& ! defined (__mcpu32__)
|
|
#define count_leading_zeros(count, x) \
|
|
__asm__ ("bfffo %1{%b2:%b2},%0" \
|
|
: "=d" (count) \
|
|
: "od" ((USItype) (x)), "n" (0))
|
|
#define COUNT_LEADING_ZEROS_0 32
|
|
#endif
|
|
|
|
#endif
|
|
#endif
|
|
|
|
/* As per glibc. */
|
|
#if !defined(BSWAP_LIMB) && defined (__GNUC__)
|
|
#define BSWAP_LIMB(dst, src) \
|
|
do { \
|
|
mp_limb_t __bswapl_src = (src); \
|
|
__asm__ ("ror%.w %#8, %0\n\t" \
|
|
"swap %0\n\t" \
|
|
"ror%.w %#8, %0" \
|
|
: "=d" (dst) \
|
|
: "0" (__bswapl_src)); \
|
|
} while (0)
|
|
#endif
|