FIX BUILD (with GHC 6.2.x): System.Directory.Internals is no more
[ghc-hetmet.git] / rts / gmp / mpn / x86 / mod_1.asm
1 dnl  x86 mpn_mod_1 -- mpn by limb remainder.
2
3
4 dnl  Copyright (C) 1999, 2000 Free Software Foundation, Inc.
5 dnl 
6 dnl  This file is part of the GNU MP Library.
7 dnl 
8 dnl  The GNU MP Library is free software; you can redistribute it and/or
9 dnl  modify it under the terms of the GNU Lesser General Public License as
10 dnl  published by the Free Software Foundation; either version 2.1 of the
11 dnl  License, or (at your option) any later version.
12 dnl 
13 dnl  The GNU MP Library is distributed in the hope that it will be useful,
14 dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 dnl  Lesser General Public License for more details.
17 dnl 
18 dnl  You should have received a copy of the GNU Lesser General Public
19 dnl  License along with the GNU MP Library; see the file COPYING.LIB.  If
20 dnl  not, write to the Free Software Foundation, Inc., 59 Temple Place -
21 dnl  Suite 330, Boston, MA 02111-1307, USA.
22
23
24 dnl        cycles/limb
25 dnl  K6        20
26 dnl  P5        44
27 dnl  P6        39
28 dnl  486   approx 42 maybe
29 dnl
30 dnl  The following have their own optimized mod_1 implementations, but for
31 dnl  reference the code here runs as follows.
32 dnl
33 dnl  P6MMX     39
34 dnl  K7        41
35
36
37 include(`../config.m4')
38
39
40 C mp_limb_t mpn_mod_1 (mp_srcptr src, mp_size_t size, mp_limb_t divisor);
41 C mp_limb_t mpn_mod_1c (mp_srcptr src, mp_size_t size, mp_limb_t divisor,
42 C                       mp_limb_t carry);
43 C
44 C Divide src,size by divisor and return the remainder.  The quotient is
45 C discarded.
46 C
47 C See mpn/x86/divrem_1.asm for some comments.
48
49 defframe(PARAM_CARRY,  16)
50 defframe(PARAM_DIVISOR,12)
51 defframe(PARAM_SIZE,   8)
52 defframe(PARAM_SRC,    4)
53
54         .text
55         ALIGN(16)
56
57 PROLOGUE(mpn_mod_1c)
58 deflit(`FRAME',0)
59
60         movl    PARAM_SIZE, %ecx
61         pushl   %ebx            FRAME_pushl()
62
63         movl    PARAM_SRC, %ebx
64         pushl   %esi            FRAME_pushl()
65
66         movl    PARAM_DIVISOR, %esi
67         orl     %ecx, %ecx
68
69         movl    PARAM_CARRY, %edx
70         jnz     LF(mpn_mod_1,top)
71
72         popl    %esi
73         movl    %edx, %eax
74
75         popl    %ebx
76         
77         ret
78
79 EPILOGUE()
80
81
82 PROLOGUE(mpn_mod_1)
83 deflit(`FRAME',0)
84
85         movl    PARAM_SIZE, %ecx
86         pushl   %ebx            FRAME_pushl()
87
88         movl    PARAM_SRC, %ebx
89         pushl   %esi            FRAME_pushl()
90
91         orl     %ecx, %ecx
92         jz      L(done_zero)
93
94         movl    PARAM_DIVISOR, %esi
95         movl    -4(%ebx,%ecx,4), %eax   C src high limb
96
97         cmpl    %esi, %eax
98
99         sbbl    %edx, %edx              C -1 if high<divisor
100
101         addl    %edx, %ecx              C skip one division if high<divisor
102         jz      L(done_eax)
103
104         andl    %eax, %edx              C carry if high<divisor
105
106
107 L(top):
108         C eax   scratch (quotient)
109         C ebx   src
110         C ecx   counter
111         C edx   carry (remainder)
112         C esi   divisor
113         C edi
114         C ebp
115
116         movl    -4(%ebx,%ecx,4), %eax
117
118         divl    %esi
119
120         loop_or_decljnz L(top)
121
122
123         movl    %edx, %eax
124 L(done_eax):
125         popl    %esi
126
127         popl    %ebx
128
129         ret
130
131
132 L(done_zero):
133         popl    %esi
134         xorl    %eax, %eax
135
136         popl    %ebx
137
138         ret
139         
140
141 EPILOGUE()