Annotation of OpenXM_contrib/pari-2.2/src/kernel/ix86/level0.h, Revision 1.1
1.1 ! noro 1: /* $Id: level0.h,v 1.3 2000/11/03 21:00:25 karim Exp $
! 2:
! 3: Copyright (C) 2000 The PARI group.
! 4:
! 5: This file is part of the PARI/GP package.
! 6:
! 7: PARI/GP is free software; you can redistribute it and/or modify it under the
! 8: terms of the GNU General Public License as published by the Free Software
! 9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
! 10: ANY WARRANTY WHATSOEVER.
! 11:
! 12: Check the License for details. You should have received a copy of it, along
! 13: with the package; see the file 'COPYING'. If not, write to the Free Software
! 14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
! 15:
! 16: /* This file defines some "level 0" kernel functions for Intel x386 */
! 17: /* It is intended for use with an external "asm" definition */
! 18:
! 19: #ifndef ASMINLINE
! 20: #define LOCAL_OVERFLOW
! 21: #define SAVE_OVERFLOW
! 22: #define LOCAL_HIREMAINDER
! 23: #define SAVE_HIREMAINDER
! 24:
! 25: BEGINEXTERN
! 26: extern ulong overflow;
! 27: extern ulong hiremainder;
! 28: extern long addll(ulong x, ulong y);
! 29: extern long addllx(ulong x, ulong y);
! 30: extern long subll(ulong x, ulong y);
! 31: extern long subllx(ulong x, ulong y);
! 32: extern long shiftl(ulong x, ulong y);
! 33: extern long shiftlr(ulong x, ulong y);
! 34: extern long mulll(ulong x, ulong y);
! 35: extern long addmul(ulong x, ulong y);
! 36: extern long divll(ulong x, ulong y);
! 37: extern int bfffo(ulong x);
! 38: ENDEXTERN
! 39:
! 40: #else /* ASMINLINE */
! 41:
! 42: /* $Id: level0.h,v 1.3 2000/11/03 21:00:25 karim Exp $ */
! 43: /* Written by Bruno Haible, 1996-1998. */
! 44:
! 45: /* This file can assume the GNU C extensions.
! 46: (It is included only if __GNUC__ is defined.) */
! 47:
! 48:
! 49: /* Use local variables whenever possible. */
! 50: #define LOCAL_HIREMAINDER register ulong hiremainder
! 51: #define SAVE_OVERFLOW \
! 52: { ulong _temp_overf = overflow; \
! 53: extern ulong overflow; \
! 54: overflow = _temp_overf; }
! 55: #define LOCAL_OVERFLOW ulong overflow
! 56: #define SAVE_HIREMAINDER \
! 57: { ulong _temp_hirem = hiremainder; \
! 58: extern ulong hiremainder; \
! 59: hiremainder = _temp_hirem; }
! 60: /* The global variable `hiremainder' is still necessary for the 2nd value of
! 61: divss, divis, divsi. The global variable `overflow' is not necessary. */
! 62: extern ulong overflow;
! 63: extern ulong hiremainder;
! 64:
! 65:
! 66: /* Different assemblers have different syntax for the "shldl" and "shrdl"
! 67: instructions. */
! 68: #if defined(__EMX__) || defined(__DJGCC__) || defined(__GO32__) || (defined(linux) && !defined(__ELF__)) || defined(__386BSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(NeXT) || defined(__CYGWIN32__) || defined(__MINGW32__) || defined(COHERENT)
! 69: # define SHCL "%%cl,"
! 70: #else
! 71: # define SHCL
! 72: #endif
! 73:
! 74:
! 75: #define addll(a,b) \
! 76: ({ ulong __value, __arg1 = (a), __arg2 = (b); \
! 77: __asm__ ("addl %3,%0 ; adcl %1,%1" \
! 78: : "=r" (__value), "=r" (overflow) \
! 79: : "0" (__arg1), "g" (__arg2), "1" ((ulong)0) \
! 80: : "cc"); \
! 81: __value; \
! 82: })
! 83:
! 84: #define addllx(a,b) \
! 85: ({ ulong __value, __arg1 = (a), __arg2 = (b), __temp; \
! 86: __asm__ ("subl %5,%2 ; adcl %4,%0 ; adcl %1,%1" \
! 87: : "=r" (__value), "=r" (overflow), "=r" (__temp) \
! 88: : "0" (__arg1), "g" (__arg2), "g" (overflow), "1" ((ulong)0), "2" ((ulong)0) \
! 89: : "cc"); \
! 90: __value; \
! 91: })
! 92:
! 93:
! 94: #define subll(a,b) \
! 95: ({ ulong __value, __arg1 = (a), __arg2 = (b); \
! 96: __asm__ ("subl %3,%0 ; adcl %1,%1" \
! 97: : "=r" (__value), "=r" (overflow) \
! 98: : "0" (__arg1), "g" (__arg2), "1" ((ulong)0) \
! 99: : "cc"); \
! 100: __value; \
! 101: })
! 102:
! 103: #define subllx(a,b) \
! 104: ({ ulong __value, __arg1 = (a), __arg2 = (b), __temp; \
! 105: __asm__ ("subl %5,%2 ; sbbl %4,%0 ; adcl %1,%1" \
! 106: : "=r" (__value), "=r" (overflow), "=r" (__temp) \
! 107: : "0" (__arg1), "g" (__arg2), "g" (overflow), "1" ((ulong)0), "2" ((ulong)0) \
! 108: : "cc"); \
! 109: __value; \
! 110: })
! 111:
! 112:
! 113: #if 1
! 114: #define shiftl(a,c) \
! 115: ({ ulong __valuelo = (a), __count = (c), __valuehi; \
! 116: __asm__ ("shldl "SHCL"%2,%0" /* shift %0 left by %cl bits, feeding in %2 from the right */ \
! 117: : "=q" (__valuehi) \
! 118: : "0" ((ulong)0), "q" (__valuelo), "c" /* %ecx */ (__count)); \
! 119: hiremainder = __valuehi; \
! 120: __valuelo << __count; \
! 121: })
! 122: #define shiftlr(a,c) \
! 123: ({ ulong __valuehi = (a), __count = (c), __valuelo; \
! 124: __asm__ ("shrdl "SHCL"%2,%0" /* shift %0 right by %cl bits, feeding in %2 from the left */ \
! 125: : "=q" (__valuelo) \
! 126: : "0" ((ulong)0), "q" (__valuehi), "c" /* %ecx */ (__count)); \
! 127: hiremainder = __valuelo; \
! 128: __valuehi >> __count; \
! 129: })
! 130: #else
! 131: #define shiftl(a,c) \
! 132: ({ ulong __valuelo = (a), __count = (c), __valuehi; \
! 133: __asm__ ("shldl "SHCL"%2,%0" /* shift %0 left by %cl bits, feeding in %2 from the right */ \
! 134: : "=d" (hiremainder) \
! 135: : "0" ((ulong)0), "q" (__valuelo), "c" /* %ecx */ (__count)); \
! 136: __valuelo << __count; \
! 137: })
! 138: #define shiftlr(a,c) \
! 139: ({ ulong __valuehi = (a), __count = (c), __valuelo; \
! 140: __asm__ ("shrdl "SHCL"%2,%0" /* shift %0 right by %cl bits, feeding in %2 from the left */ \
! 141: : "=d" (hiremainder) \
! 142: : "0" ((ulong)0), "q" (__valuehi), "c" /* %ecx */ (__count)); \
! 143: __valuehi >> __count; \
! 144: })
! 145: #endif
! 146:
! 147:
! 148: #define mulll(a,b) \
! 149: ({ ulong __valuelo, __arg1 = (a), __arg2 = (b); \
! 150: __asm__ ("mull %3" \
! 151: : "=a" /* %eax */ (__valuelo), "=d" /* %edx */ (hiremainder) \
! 152: : "0" (__arg1), "rm" (__arg2)); \
! 153: __valuelo; \
! 154: })
! 155:
! 156: #define addmul(a,b) \
! 157: ({ ulong __valuelo, __arg1 = (a), __arg2 = (b), __temp; \
! 158: __asm__ ("mull %4 ; addl %5,%0 ; adcl %6,%1" \
! 159: : "=a" /* %eax */ (__valuelo), "=&d" /* %edx */ (hiremainder), "=r" (__temp) \
! 160: : "0" (__arg1), "rm" (__arg2), "g" (hiremainder), "2" ((ulong)0)); \
! 161: __valuelo; \
! 162: })
! 163:
! 164: #define addmullow(a,b) \
! 165: ({ ulong __valuelo, __arg1 = (a), __arg2 = (b), __temp; \
! 166: __asm__ ("mull %3 ; addl %4,%0" \
! 167: : "=a" /* %eax */ (__valuelo), "=&d" /* %edx */ (__temp) \
! 168: : "0" (__arg1), "rm" (__arg2), "g" (hiremainder)); \
! 169: __valuelo; \
! 170: })
! 171:
! 172: #define divll(a,b) \
! 173: ({ ulong __value, __arg1 = (a), __arg2 = (b); \
! 174: __asm__ ("divl %4" \
! 175: : "=a" /* %eax */ (__value), "=d" /* %edx */ (hiremainder) \
! 176: : "0" /* %eax */ (__arg1), "1" /* %edx */ (hiremainder), "g" (__arg2)); \
! 177: __value; \
! 178: })
! 179:
! 180: #ifndef _ASMI386INLINE_H_
! 181: # define _ASMI386INLINE_H_
! 182: # ifdef INLINE
! 183: static inline int
! 184: bfffo(ulong x)
! 185: {
! 186: int leading_one_position;
! 187: __asm__ ("bsrl %1,%0" : "=r" (leading_one_position) : "rm" (x));
! 188: return 31-leading_one_position;
! 189: }
! 190: # endif
! 191: #endif
! 192:
! 193: #endif /* ASMINLINE */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>