Tizen 2.1 base
[external/gmp.git] / mpn / x86 / k6 / mmx / rshift.asm
1 dnl  AMD K6 mpn_rshift -- mpn right shift.
2
3 dnl  Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
4 dnl
5 dnl  This file is part of the GNU MP Library.
6 dnl
7 dnl  The GNU MP Library is free software; you can redistribute it and/or
8 dnl  modify it under the terms of the GNU Lesser General Public License as
9 dnl  published by the Free Software Foundation; either version 3 of the
10 dnl  License, or (at your option) any later version.
11 dnl
12 dnl  The GNU MP Library is distributed in the hope that it will be useful,
13 dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 dnl  Lesser General Public License for more details.
16 dnl
17 dnl  You should have received a copy of the GNU Lesser General Public License
18 dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
19
20 include(`../config.m4')
21
22
23 C K6: 3.0 cycles/limb
24
25
26 C mp_limb_t mpn_rshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
27 C                       unsigned shift);
28 C
29 C The loop runs at 3 cycles/limb, limited by decoding and by having 3 mmx
30 C instructions.  This is despite every second fetch being unaligned.
31
32
33 defframe(PARAM_SHIFT,16)
34 defframe(PARAM_SIZE, 12)
35 defframe(PARAM_SRC,  8)
36 defframe(PARAM_DST,  4)
37 deflit(`FRAME',0)
38
39         TEXT
40         ALIGN(32)
41
42 PROLOGUE(mpn_rshift)
43 deflit(`FRAME',0)
44
45         C The 1 limb case can be done without the push %ebx, but it's then
46         C still the same speed.  The push is left as a free helping hand for
47         C the two_or_more code.
48
49         movl    PARAM_SIZE, %eax
50         pushl   %ebx                    FRAME_pushl()
51
52         movl    PARAM_SRC, %ebx
53         decl    %eax
54
55         movl    PARAM_SHIFT, %ecx
56         jnz     L(two_or_more)
57
58         movl    (%ebx), %edx            C src limb
59         movl    PARAM_DST, %ebx
60
61         shrdl(  %cl, %edx, %eax)        C return value
62
63         shrl    %cl, %edx
64
65         movl    %edx, (%ebx)            C dst limb
66         popl    %ebx
67
68         ret
69
70
71         ALIGN(16)       C avoid offset 0x1f
72 L(two_or_more):
73         C eax   size-1
74         C ebx   src
75         C ecx   shift
76         C edx
77
78         movl    (%ebx), %edx    C src low limb
79         negl    %ecx
80
81         addl    $32, %ecx       C 32-shift
82         movd    PARAM_SHIFT, %mm6
83
84         shll    %cl, %edx       C retval
85         movl    PARAM_DST, %ecx
86
87         leal    (%ebx,%eax,4), %ebx
88
89         leal    -4(%ecx,%eax,4), %ecx
90         negl    %eax
91
92
93 L(simple):
94         C eax   counter (negative)
95         C ebx   &src[size-1]
96         C ecx   &dst[size-1]
97         C edx   retval
98         C
99         C mm0   scratch
100         C mm6   shift
101
102 Zdisp(  movq,   0,(%ebx,%eax,4), %mm0)
103         incl    %eax
104
105         psrlq   %mm6, %mm0
106
107 Zdisp(  movd,   %mm0, 0,(%ecx,%eax,4))
108         jnz     L(simple)
109
110
111         movq    %mm0, (%ecx)
112         movl    %edx, %eax
113
114         popl    %ebx
115
116         emms
117         ret
118
119 EPILOGUE()