[BACK]Return to level0.h CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / pari-2.2 / src / kernel / ix86

Annotation of OpenXM_contrib/pari-2.2/src/kernel/ix86/level0.h, Revision 1.1.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>