~ubuntu-branches/ubuntu/intrepid/ecl/intrepid

« back to all changes in this revision

Viewing changes to src/gmp/mpn/x86_64/mode1o.asm

  • Committer: Bazaar Package Importer
  • Author(s): Peter Van Eynde
  • Date: 2007-04-09 11:51:51 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070409115151-ql8cr0kalzx1jmla
Tags: 0.9i-20070324-2
Upload to unstable. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
dnl  AMD64 mpn_modexact_1_odd -- exact division style remainder.
 
2
 
 
3
dnl  Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
 
4
dnl  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., 51 Franklin Street,
 
21
dnl  Fifth Floor, Boston, MA 02110-1301, USA.
 
22
 
 
23
include(`../config.m4')
 
24
 
 
25
 
 
26
C                   cycles/limb
 
27
C Hammer:               10
 
28
C Prescott/Nocona:      33
 
29
 
 
30
 
 
31
C mp_limb_t mpn_modexact_1_odd (mp_srcptr src, mp_size_t size,
 
32
C                               mp_limb_t divisor);
 
33
C mp_limb_t mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size,
 
34
C                                mp_limb_t divisor, mp_limb_t carry);
 
35
C
 
36
C
 
37
C The dependent chain in the main loop is
 
38
C
 
39
C                            cycles
 
40
C       subq    %rdx, %rax      1
 
41
C       imulq   %r9, %rax       4
 
42
C       mulq    %r8             5
 
43
C                             ----
 
44
C       total                  10
 
45
C
 
46
C The movq load from src seems to need to be scheduled back before the jz to
 
47
C achieve this speed, out-of-order execution apparently can't completely
 
48
C hide the latency otherwise.
 
49
C
 
50
C The l=src[i]-cbit step is rotated back too, since that allows us to avoid
 
51
C it for the first iteration (where there's no cbit).
 
52
C
 
53
C The code alignment used (32-byte) for the loop also seems necessary.
 
54
C Without that the non-PIC case has adcq crossing the 0x60 offset,
 
55
C apparently making it run at 11 cycles instead of 10.
 
56
C
 
57
C Not done:
 
58
C
 
59
C divq for size==1 was measured at about 79 cycles, compared to the inverse
 
60
C at about 25 cycles (both including function call overheads), so that's not
 
61
C used.
 
62
C
 
63
C Enhancements:
 
64
C
 
65
C For PIC, we shouldn't really need the GOT fetch for modlimb_invert_table,
 
66
C it'll be in rodata or text in libgmp.so and can be accessed directly %rip
 
67
C relative.  This would be for small model only (something we don't
 
68
C presently detect, but which is all that gcc 3.3.3 supports), since 8-byte
 
69
C PC-relative relocations are apparently not available.  Some rough
 
70
C experiments with binutils 2.13 looked worrylingly like it might come out
 
71
C with an unwanted text segment relocation though, even with ".protected".
 
72
 
 
73
 
 
74
        TEXT
 
75
 
 
76
        ALIGN(32)
 
77
PROLOGUE(mpn_modexact_1_odd)
 
78
 
 
79
        movl    $0, %ecx
 
80
 
 
81
PROLOGUE(mpn_modexact_1c_odd)
 
82
 
 
83
        C rdi   src
 
84
        C rsi   size
 
85
        C rdx   divisor
 
86
        C rcx   carry
 
87
 
 
88
        movq    %rdx, %r8               C d
 
89
        shrl    %edx                    C d/2
 
90
ifdef(`PIC',`
 
91
        movq    modlimb_invert_table@GOTPCREL(%rip), %r9
 
92
',`
 
93
        movabsq $modlimb_invert_table, %r9
 
94
')
 
95
 
 
96
        andl    $127, %edx
 
97
        movq    %rcx, %r10              C initial carry
 
98
 
 
99
        movzbl  (%r9,%rdx), %edx        C inv 8 bits
 
100
 
 
101
        movq    (%rdi), %rax            C src[0]
 
102
        leaq    (%rdi,%rsi,8), %r11     C src end
 
103
        movq    %r8, %rdi               C d, made available to imull
 
104
 
 
105
        leal    (%rdx,%rdx), %ecx       C 2*inv
 
106
        imull   %edx, %edx              C inv*inv
 
107
 
 
108
        negq    %rsi                    C -size
 
109
 
 
110
        imull   %edi, %edx              C inv*inv*d
 
111
 
 
112
        subl    %edx, %ecx              C inv = 2*inv - inv*inv*d, 16 bits
 
113
 
 
114
        leal    (%rcx,%rcx), %edx       C 2*inv
 
115
        imull   %ecx, %ecx              C inv*inv
 
116
 
 
117
        imull   %edi, %ecx              C inv*inv*d
 
118
 
 
119
        subl    %ecx, %edx              C inv = 2*inv - inv*inv*d, 32 bits
 
120
        xorl    %ecx, %ecx              C initial cbit
 
121
 
 
122
        leaq    (%rdx,%rdx), %r9        C 2*inv
 
123
        imulq   %rdx, %rdx              C inv*inv
 
124
 
 
125
        imulq   %r8, %rdx               C inv*inv*d
 
126
 
 
127
        subq    %rdx, %r9               C inv = 2*inv - inv*inv*d, 64 bits
 
128
        movq    %r10, %rdx              C initial climb
 
129
 
 
130
        ASSERT(e,`      C d*inv == 1 mod 2^64
 
131
        movq    %r8, %r10
 
132
        imulq   %r9, %r10
 
133
        cmpq    $1, %r10')
 
134
 
 
135
        incq    %rsi
 
136
        jz      L(one)
 
137
 
 
138
 
 
139
        ALIGN(16)
 
140
L(top):
 
141
        C rax   l = src[i]-cbit
 
142
        C rcx   new cbit, 0 or 1
 
143
        C rdx   climb, high of last product
 
144
        C rsi   counter, limbs, negative
 
145
        C rdi
 
146
        C r8    divisor
 
147
        C r9    inverse
 
148
        C r11   src end ptr
 
149
 
 
150
        subq    %rdx, %rax              C l = src[i]-cbit - climb
 
151
 
 
152
        adcq    $0, %rcx                C more cbit
 
153
        imulq   %r9, %rax               C q = l * inverse
 
154
 
 
155
        mulq    %r8                     C climb = high (q * d)
 
156
 
 
157
        movq    (%r11,%rsi,8), %rax     C src[i+1]
 
158
        subq    %rcx, %rax              C next l = src[i+1] - cbit
 
159
        setc    %cl                     C new cbit
 
160
 
 
161
        incq    %rsi
 
162
        jnz     L(top)
 
163
 
 
164
 
 
165
L(one):
 
166
        subq    %rdx, %rax              C l = src[i]-cbit - climb
 
167
 
 
168
        adcq    $0, %rcx                C more cbit
 
169
        imulq   %r9, %rax               C q = l * inverse
 
170
 
 
171
        mulq    %r8                     C climb = high (q * d)
 
172
 
 
173
        leaq    (%rcx,%rdx), %rax       C climb+cbit
 
174
        ret
 
175
 
 
176
EPILOGUE(mpn_modexact_1c_odd)
 
177
EPILOGUE(mpn_modexact_1_odd)