Annotation of OpenXM_contrib/pari/src/kernel/ix86/level0.h, Revision 1.1
1.1 ! maekawa 1: /* $Id: level0.h,v 1.1.1.1 1999/09/16 13:47:46 karim Exp $ */
! 2:
! 3: /* This file defines some "level 0" kernel functions for Intel x386 */
! 4: /* It is intended for use with an external "asm" definition */
! 5:
! 6: #ifndef ASMINLINE
! 7: #define LOCAL_OVERFLOW
! 8: #define SAVE_OVERFLOW
! 9: #define LOCAL_HIREMAINDER
! 10: #define SAVE_HIREMAINDER
! 11:
! 12: BEGINEXTERN
! 13: extern ulong overflow;
! 14: extern ulong hiremainder;
! 15: extern long addll(ulong x, ulong y);
! 16: extern long addllx(ulong x, ulong y);
! 17: extern long subll(ulong x, ulong y);
! 18: extern long subllx(ulong x, ulong y);
! 19: extern long shiftl(ulong x, ulong y);
! 20: extern long shiftlr(ulong x, ulong y);
! 21: extern long mulll(ulong x, ulong y);
! 22: extern long addmul(ulong x, ulong y);
! 23: extern long divll(ulong x, ulong y);
! 24: extern int bfffo(ulong x);
! 25: ENDEXTERN
! 26:
! 27: #else /* ASMINLINE */
! 28:
! 29: /* $Id: level0.h,v 1.1.1.1 1999/09/16 13:47:46 karim Exp $ */
! 30: /* Written by Bruno Haible, 1996-1998. */
! 31:
! 32: /* This file can assume the GNU C extensions.
! 33: (It is included only if __GNUC__ is defined.) */
! 34:
! 35:
! 36: /* Use local variables whenever possible. */
! 37: #define LOCAL_HIREMAINDER register unsigned long hiremainder
! 38: #define SAVE_OVERFLOW \
! 39: { unsigned long _temp_overf = overflow; \
! 40: extern unsigned long overflow; \
! 41: overflow = _temp_overf; }
! 42: #define LOCAL_OVERFLOW unsigned long overflow
! 43: #define SAVE_HIREMAINDER \
! 44: { unsigned long _temp_hirem = hiremainder; \
! 45: extern unsigned long hiremainder; \
! 46: hiremainder = _temp_hirem; }
! 47: /* The global variable `hiremainder' is still necessary for the 2nd value of
! 48: divss, divis, divsi. The global variable `overflow' is not necessary. */
! 49: extern ulong overflow;
! 50: extern ulong hiremainder;
! 51:
! 52:
! 53: /* Different assemblers have different syntax for the "shldl" and "shrdl"
! 54: instructions. */
! 55: #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)
! 56: # define SHCL "%%cl,"
! 57: #else
! 58: # define SHCL
! 59: #endif
! 60:
! 61:
! 62: #define addll(a,b) \
! 63: ({ unsigned long __value, __arg1 = (a), __arg2 = (b); \
! 64: __asm__ ("addl %3,%0 ; adcl %1,%1" \
! 65: : "=r" (__value), "=r" (overflow) \
! 66: : "0" (__arg1), "g" (__arg2), "1" ((unsigned long)0) \
! 67: : "cc"); \
! 68: __value; \
! 69: })
! 70:
! 71: #define addllx(a,b) \
! 72: ({ unsigned long __value, __arg1 = (a), __arg2 = (b), __temp; \
! 73: __asm__ ("subl %5,%2 ; adcl %4,%0 ; adcl %1,%1" \
! 74: : "=r" (__value), "=r" (overflow), "=r" (__temp) \
! 75: : "0" (__arg1), "g" (__arg2), "g" (overflow), "1" ((unsigned long)0), "2" ((unsigned long)0) \
! 76: : "cc"); \
! 77: __value; \
! 78: })
! 79:
! 80:
! 81: #define subll(a,b) \
! 82: ({ unsigned long __value, __arg1 = (a), __arg2 = (b); \
! 83: __asm__ ("subl %3,%0 ; adcl %1,%1" \
! 84: : "=r" (__value), "=r" (overflow) \
! 85: : "0" (__arg1), "g" (__arg2), "1" ((unsigned long)0) \
! 86: : "cc"); \
! 87: __value; \
! 88: })
! 89:
! 90: #define subllx(a,b) \
! 91: ({ unsigned long __value, __arg1 = (a), __arg2 = (b), __temp; \
! 92: __asm__ ("subl %5,%2 ; sbbl %4,%0 ; adcl %1,%1" \
! 93: : "=r" (__value), "=r" (overflow), "=r" (__temp) \
! 94: : "0" (__arg1), "g" (__arg2), "g" (overflow), "1" ((unsigned long)0), "2" ((unsigned long)0) \
! 95: : "cc"); \
! 96: __value; \
! 97: })
! 98:
! 99:
! 100: #if 1
! 101: #define shiftl(a,c) \
! 102: ({ unsigned long __valuelo = (a), __count = (c), __valuehi; \
! 103: __asm__ ("shldl "SHCL"%2,%0" /* shift %0 left by %cl bits, feeding in %2 from the right */ \
! 104: : "=q" (__valuehi) \
! 105: : "0" ((unsigned long)0), "q" (__valuelo), "c" /* %ecx */ (__count)); \
! 106: hiremainder = __valuehi; \
! 107: __valuelo << __count; \
! 108: })
! 109: #define shiftlr(a,c) \
! 110: ({ unsigned long __valuehi = (a), __count = (c), __valuelo; \
! 111: __asm__ ("shrdl "SHCL"%2,%0" /* shift %0 right by %cl bits, feeding in %2 from the left */ \
! 112: : "=q" (__valuelo) \
! 113: : "0" ((unsigned long)0), "q" (__valuehi), "c" /* %ecx */ (__count)); \
! 114: hiremainder = __valuelo; \
! 115: __valuehi >> __count; \
! 116: })
! 117: #else
! 118: #define shiftl(a,c) \
! 119: ({ unsigned long __valuelo = (a), __count = (c), __valuehi; \
! 120: __asm__ ("shldl "SHCL"%2,%0" /* shift %0 left by %cl bits, feeding in %2 from the right */ \
! 121: : "=d" (hiremainder) \
! 122: : "0" ((unsigned long)0), "q" (__valuelo), "c" /* %ecx */ (__count)); \
! 123: __valuelo << __count; \
! 124: })
! 125: #define shiftlr(a,c) \
! 126: ({ unsigned long __valuehi = (a), __count = (c), __valuelo; \
! 127: __asm__ ("shrdl "SHCL"%2,%0" /* shift %0 right by %cl bits, feeding in %2 from the left */ \
! 128: : "=d" (hiremainder) \
! 129: : "0" ((unsigned long)0), "q" (__valuehi), "c" /* %ecx */ (__count)); \
! 130: __valuehi >> __count; \
! 131: })
! 132: #endif
! 133:
! 134:
! 135: #define mulll(a,b) \
! 136: ({ unsigned long __valuelo, __arg1 = (a), __arg2 = (b); \
! 137: __asm__ ("mull %3" \
! 138: : "=a" /* %eax */ (__valuelo), "=d" /* %edx */ (hiremainder) \
! 139: : "0" (__arg1), "rm" (__arg2)); \
! 140: __valuelo; \
! 141: })
! 142:
! 143: #define addmul(a,b) \
! 144: ({ unsigned long __valuelo, __arg1 = (a), __arg2 = (b), __temp; \
! 145: __asm__ ("mull %4 ; addl %5,%0 ; adcl %6,%1" \
! 146: : "=a" /* %eax */ (__valuelo), "=&d" /* %edx */ (hiremainder), "=r" (__temp) \
! 147: : "0" (__arg1), "rm" (__arg2), "g" (hiremainder), "2" ((unsigned long)0)); \
! 148: __valuelo; \
! 149: })
! 150:
! 151: #define addmullow(a,b) \
! 152: ({ unsigned long __valuelo, __arg1 = (a), __arg2 = (b), __temp; \
! 153: __asm__ ("mull %3 ; addl %4,%0" \
! 154: : "=a" /* %eax */ (__valuelo), "=&d" /* %edx */ (__temp) \
! 155: : "0" (__arg1), "rm" (__arg2), "g" (hiremainder)); \
! 156: __valuelo; \
! 157: })
! 158:
! 159: #define divll(a,b) \
! 160: ({ unsigned long __value, __arg1 = (a), __arg2 = (b); \
! 161: __asm__ ("divl %4" \
! 162: : "=a" /* %eax */ (__value), "=d" /* %edx */ (hiremainder) \
! 163: : "0" /* %eax */ (__arg1), "1" /* %edx */ (hiremainder), "g" (__arg2)); \
! 164: __value; \
! 165: })
! 166:
! 167: #ifndef _ASMI386INLINE_H_
! 168: # define _ASMI386INLINE_H_
! 169: # ifdef INLINE
! 170: static inline int
! 171: bfffo(unsigned long x)
! 172: {
! 173: int leading_one_position;
! 174: __asm__ ("bsrl %1,%0" : "=r" (leading_one_position) : "rm" (x));
! 175: return 31-leading_one_position;
! 176: }
! 177: # endif
! 178: #endif
! 179:
! 180: #endif /* ASMINLINE */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>