remove empty dir
[ghc-hetmet.git] / ghc / rts / gmp / mpn / x86 / k7 / mmx / copyd.asm
1 dnl  AMD K7 mpn_copyd -- copy limb vector, decrementing.
2 dnl 
3 dnl     alignment dst/src, A=0mod8 N=4mod8
4 dnl        A/A   A/N   N/A   N/N
5 dnl  K7    0.75  1.0   1.0   0.75
6
7
8 dnl  Copyright (C) 1999, 2000 Free Software Foundation, Inc.
9 dnl 
10 dnl  This file is part of the GNU MP Library.
11 dnl 
12 dnl  The GNU MP Library is free software; you can redistribute it and/or
13 dnl  modify it under the terms of the GNU Lesser General Public License as
14 dnl  published by the Free Software Foundation; either version 2.1 of the
15 dnl  License, or (at your option) any later version.
16 dnl 
17 dnl  The GNU MP Library is distributed in the hope that it will be useful,
18 dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
19 dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 dnl  Lesser General Public License for more details.
21 dnl 
22 dnl  You should have received a copy of the GNU Lesser General Public
23 dnl  License along with the GNU MP Library; see the file COPYING.LIB.  If
24 dnl  not, write to the Free Software Foundation, Inc., 59 Temple Place -
25 dnl  Suite 330, Boston, MA 02111-1307, USA.
26
27
28 include(`../config.m4')
29
30
31 C void mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t size);
32 C
33 C The various comments in mpn/x86/k7/copyi.asm apply here too.
34
35 defframe(PARAM_SIZE,12)
36 defframe(PARAM_SRC, 8)
37 defframe(PARAM_DST, 4)
38 deflit(`FRAME',0)
39
40 dnl  parameter space reused
41 define(SAVE_EBX,`PARAM_SIZE')
42 define(SAVE_ESI,`PARAM_SRC')
43
44 dnl  minimum 5 since the unrolled code can't handle less than 5
45 deflit(UNROLL_THRESHOLD, 5)
46
47         .text
48         ALIGN(32)
49 PROLOGUE(mpn_copyd)
50
51         movl    PARAM_SIZE, %ecx
52         movl    %ebx, SAVE_EBX
53
54         movl    PARAM_SRC, %eax
55         movl    PARAM_DST, %edx
56
57         cmpl    $UNROLL_THRESHOLD, %ecx
58         jae     L(unroll)
59
60         orl     %ecx, %ecx
61         jz      L(simple_done)
62
63 L(simple):
64         C eax   src
65         C ebx   scratch
66         C ecx   counter
67         C edx   dst
68         C
69         C this loop is 2 cycles/limb
70
71         movl    -4(%eax,%ecx,4), %ebx
72         movl    %ebx, -4(%edx,%ecx,4)
73         decl    %ecx
74         jnz     L(simple)
75
76 L(simple_done):
77         movl    SAVE_EBX, %ebx
78         ret
79
80
81 L(unroll):
82         movl    %esi, SAVE_ESI
83         leal    (%eax,%ecx,4), %ebx
84         leal    (%edx,%ecx,4), %esi
85
86         andl    %esi, %ebx
87         movl    SAVE_ESI, %esi
88         subl    $4, %ecx                C size-4
89
90         testl   $4, %ebx   C testl to pad code closer to 16 bytes for L(top)
91         jz      L(aligned)
92
93         C both src and dst unaligned, process one limb to align them
94         movl    12(%eax,%ecx,4), %ebx
95         movl    %ebx, 12(%edx,%ecx,4)
96         decl    %ecx
97 L(aligned):
98
99
100         ALIGN(16)
101 L(top):
102         C eax   src
103         C ebx
104         C ecx   counter, limbs
105         C edx   dst
106
107         movq    8(%eax,%ecx,4), %mm0
108         movq    (%eax,%ecx,4), %mm1
109         subl    $4, %ecx
110         movq    %mm0, 16+8(%edx,%ecx,4)
111         movq    %mm1, 16(%edx,%ecx,4)
112         jns     L(top)
113
114
115         C now %ecx is -4 to -1 representing respectively 0 to 3 limbs remaining
116
117         testb   $2, %cl
118         jz      L(finish_not_two)
119
120         movq    8(%eax,%ecx,4), %mm0
121         movq    %mm0, 8(%edx,%ecx,4)
122 L(finish_not_two):
123
124         testb   $1, %cl
125         jz      L(done)
126
127         movl    (%eax), %ebx
128         movl    %ebx, (%edx)
129
130 L(done):
131         movl    SAVE_EBX, %ebx
132         emms
133         ret
134
135
136 EPILOGUE()