Annotation of OpenXM_contrib/pari-2.2/src/kernel/ix86/level0.h, Revision 1.2
1.2 ! noro 1: /* $Id: level0.h,v 1.4 2002/04/15 23:30:28 karim Exp $
1.1 noro 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:
1.2 ! noro 42: /* $Id: level0.h,v 1.4 2002/04/15 23:30:28 karim Exp $ */
1.1 noro 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) \
1.2 ! noro 176: : "0" /* %eax */ (__arg1), "1" /* %edx */ (hiremainder), "mr" (__arg2)); \
1.1 noro 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>