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