Annotation of OpenXM_contrib/pari-2.2/src/kernel/ix86/l0asm.c, Revision 1.1.1.1
1.1 noro 1: /* $Id: l0asm.c,v 1.4 2001/03/12 15:28:33 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: /***********************************************************************/
17: /** **/
18: /** Low level arithmetic for PARI **/
19: /** written by Bruno Haible 14.11.1992 **/
20: /** macroified 21.1.1998 **/
21: /** **/
22: /***********************************************************************/
23:
24: /* processor: Intel ix86 in native mode
25: * assembler syntax: GNU or SUN, moves go from left to right
26: * compiler: GNU gcc or SUN cc
27: * parameter passing convention: on the stack 4(%esp),8(%esp),...
28: * registers: %eax,%edx,%ecx may be modified,
29: * everything else must be saved and restored
30: * result: passed in %eax
31: * word length: 32 bits
32: */
33:
34: /* If the C compiler is GNU C, better stuff is contained in asmix86inline.h,
35: but we compile and link this file nevertheless because it defines the
36: global variable `hiremainder'. */
37:
38: /* This should ideally be determined at configure time. */
39: #if defined(__EMX__) || defined(__DJGCC__) || defined(__GO32__) || (defined(linux) && !defined(__ELF__)) || defined(__386BSD__) || defined(__NetBSD__) || (defined(__FreeBSD__) && !defined(__ELF__)) || defined(NeXT) || defined(__CYGWIN32__) || defined(__MINGW32__)
40: # define ASM_UNDERSCORE
41: #endif
42:
43: #include "l0asm.h"
44:
45: #if defined(__EMX__) && defined(__NO_AOUT) /* No underscores, rest as is */
46: # undef C
47: # define C(entrypoint) /**/entrypoint
48: #endif
49:
50:
51: #undef ALIGN
52: #ifdef _MSC_VER
53: #define ALIGN
54: #else
55: #if defined(ASM_UNDERSCORE) && !(defined(__CYGWIN32__) || defined(__MINGW32__))
56: /* BSD syntax assembler */
57: #define ALIGN .align 3
58: #else
59: /* ELF syntax assembler */
60: #define ALIGN .align 8
61: #endif
62: #endif
63:
64: GLOBL(C(addll))
65: GLOBL(C(subll))
66: GLOBL(C(addllx))
67: GLOBL(C(subllx))
68: GLOBL(C(shiftl))
69: GLOBL(C(shiftlr))
70: GLOBL(C(bfffo))
71: GLOBL(C(mulll))
72: GLOBL(C(addmul))
73: GLOBL(C(divll))
74: GLOBL(C(overflow))
75: GLOBL(C(hiremainder))
76:
77: #ifdef _MSC_VER
78: unsigned long overflow, hiremainder;
79: #else
80: #ifdef BSD_SYNTAX
81: # if defined(__EMX__) && defined(__NO_AOUT) /* Otherwise IBM linker will
82: ignore this module */
83: .data
84: .align 2
85: C(overflow):
86: .long 0
87: C(hiremainder):
88: .long 0
89: .text
90: # else
91: .comm C(overflow),4
92: .comm C(hiremainder),4
93: # endif
94: #endif
95: #ifdef ELF_SYNTAX
96: .comm C(overflow),4,4
97: .comm C(hiremainder),4,4
98: #endif
99: #endif
100:
101: TEXT()
102:
103: ALIGN
104: FUNBEGIN(addll)
105: INSN2(xor,l ,R(edx),R(edx)) /* clear %edx */
106: INSN2(mov,l ,X4 MEM_DISP(esp,4),R(eax)) /* get x */
107: INSN2(add,l ,X4 MEM_DISP(esp,8),R(eax)) /* add y */
108: INSN2(adc,l ,R(edx),R(edx)) /* %edx := carry */
109: INSN2(mov,l ,R(edx),C(overflow)) /* set overflow */
110: ret /* return %eax */
111: FUNEND()
112:
113: ALIGN
114: FUNBEGIN(addllx)
115: INSN2(xor,l ,R(edx),R(edx)) /* clear %edx */
116: INSN2(xor,l ,R(eax),R(eax)) /* clear %eax */
117: INSN2(sub,l ,C(overflow),R(eax)) /* set carry */
118: INSN2(mov,l ,X4 MEM_DISP(esp,4),R(eax)) /* get x */
119: INSN2(adc,l ,X4 MEM_DISP(esp,8),R(eax)) /* add y and carry */
120: INSN2(adc,l ,R(edx),R(edx)) /* %edx := carry */
121: INSN2(mov,l ,R(edx),C(overflow)) /* set overflow */
122: ret /* return %eax */
123: FUNEND()
124:
125: ALIGN
126: FUNBEGIN(subll)
127: INSN2(xor,l ,R(edx),R(edx)) /* clear %edx */
128: INSN2(mov,l ,X4 MEM_DISP(esp,4),R(eax)) /* get x */
129: INSN2(sub,l ,X4 MEM_DISP(esp,8),R(eax)) /* subtract y */
130: INSN2(adc,l ,R(edx),R(edx)) /* %edx := carry */
131: INSN2(mov,l ,R(edx),C(overflow)) /* set overflow */
132: ret /* return %eax */
133: FUNEND()
134:
135: ALIGN
136: FUNBEGIN(subllx)
137: INSN2(xor,l ,R(edx),R(edx)) /* clear %edx */
138: INSN2(xor,l ,R(eax),R(eax)) /* clear %eax */
139: INSN2(sub,l ,C(overflow),R(eax)) /* set carry */
140: INSN2(mov,l ,X4 MEM_DISP(esp,4),R(eax)) /* get x */
141: INSN2(sbb,l ,X4 MEM_DISP(esp,8),R(eax)) /* subtract y and carry */
142: INSN2(adc,l ,R(edx),R(edx)) /* %edx := carry */
143: INSN2(mov,l ,R(edx),C(overflow)) /* set overflow */
144: ret /* return %eax */
145: FUNEND()
146:
147: ALIGN
148: FUNBEGIN(shiftl)
149: INSN2(mov,l ,X4 MEM_DISP(esp,4),R(eax)) /* get x */
150: INSN2(mov,b ,X1 MEM_DISP(esp,8),R(cl)) /* get shift count i */
151: INSN2(xor,l ,R(edx),R(edx)) /* clear %edx */
152: INSN2SHCL(shld,l,R(eax),R(edx)) /* shift %edx left by i bits,
153: feeding in %eax from the right */
154: INSN2(shl,l ,R(cl),R(eax)) /* shift %eax left by i bits */
155: INSN2(mov,l ,R(edx),C(hiremainder)) /* set hiremainder */
156: ret /* return %eax */
157: FUNEND()
158:
159: ALIGN
160: FUNBEGIN(shiftlr)
161: INSN2(mov,l ,X4 MEM_DISP(esp,4),R(eax)) /* get x */
162: INSN2(mov,b ,X1 MEM_DISP(esp,8),R(cl)) /* get shift count i */
163: INSN2(xor,l ,R(edx),R(edx)) /* clear %edx */
164: INSN2SHCL(shrd,l,R(eax),R(edx)) /* shift %edx right by i bits,
165: feeding in %eax from the left */
166: INSN2(shr,l ,R(cl),R(eax)) /* shift %eax right by i bits */
167: INSN2(mov,l ,R(edx),C(hiremainder)) /* set hiremainder */
168: ret /* return %eax */
169: FUNEND()
170:
171: ALIGN
172: FUNBEGIN(bfffo)
173: INSN2(mov,l ,X4 MEM_DISP(esp,4),R(eax)) /* get x */
174: INSN2(bsr,l ,R(eax),R(edx)) /* %edx := number of leading bit */
175: INSN2(mov,l ,NUM(31),R(eax))
176: INSN2(sub,l ,R(edx),R(eax)) /* result is 31 - %edx */
177: ret /* return %eax */
178: FUNEND()
179:
180: ALIGN
181: FUNBEGIN(mulll)
182: INSN2(mov,l ,X4 MEM_DISP(esp,4),R(eax)) /* get x */
183: INSN1(mul,l ,X4 MEM_DISP(esp,8)) /* %edx|%eax := x * y */
184: INSN2(mov,l ,R(edx),C(hiremainder)) /* store high word */
185: ret /* return low word %eax */
186: FUNEND()
187:
188: ALIGN
189: FUNBEGIN(addmul)
190: INSN2(xor,l ,R(ecx),R(ecx)) /* clear %ecx */
191: INSN2(mov,l ,X4 MEM_DISP(esp,4),R(eax)) /* get x */
192: INSN1(mul,l ,X4 MEM_DISP(esp,8)) /* %edx|%eax := x * y */
193: INSN2(add,l ,C(hiremainder),R(eax)) /* add 0|hiremainder */
194: INSN2(adc,l ,R(ecx),R(edx))
195: INSN2(mov,l ,R(edx),C(hiremainder)) /* store high word */
196: ret /* return low word %eax */
197: FUNEND()
198:
199: ALIGN
200: FUNBEGIN(divll)
201: INSN2(mov,l ,X4 MEM_DISP(esp,4),R(eax)) /* get low word x */
202: INSN2(mov,l ,C(hiremainder),R(edx)) /* get high word */
203: INSN1(div,l ,X4 MEM_DISP(esp,8)) /* divide %edx|%eax by y */
204: INSN2(mov,l ,R(edx), C(hiremainder)) /* store remainder */
205: ret /* return quotient %eax */
206: FUNEND()
207:
208: ALIGN
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>