Tizen 2.1 base
[external/gmp.git] / mpn / x86 / pentium4 / sse2 / addlsh1_n.asm
1 dnl  Intel Pentium-4 mpn_addlsh1_n -- mpn x+2*y.
2
3 dnl  Copyright 2001, 2002, 2003, 2004, 2006 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          cycles/limb (approx)
24 C          dst!=src1,2  dst==src1  dst==src2
25 C P4 m2:      4.5         ?7.25      ?6.75
26 C P4 m3:      5.3         ?          ?
27
28 C mp_limb_t mpn_addlsh1_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
29 C                          mp_size_t size);
30 C
31 C The slightly strange combination of indexing and pointer incrementing
32 C that's used seems to work best.  Not sure why, but %ecx,4 with src1 and/or
33 C src2 is a slowdown.
34 C
35 C The dependent chain is simply the paddq of x+2*y to the previous carry,
36 C then psrlq to get the new carry.  That makes 4 c/l the target speed, which
37 C is almost achieved for separate src/dst but when src==dst the write
38 C combining anomalies slow it down.
39
40 defframe(PARAM_SIZE, 16)
41 defframe(PARAM_SRC2, 12)
42 defframe(PARAM_SRC1, 8)
43 defframe(PARAM_DST,  4)
44
45 dnl  re-use parameter space
46 define(SAVE_EBX,`PARAM_SRC1')
47
48         TEXT
49         ALIGN(8)
50
51 PROLOGUE(mpn_addlsh1_n)
52 deflit(`FRAME',0)
53
54         movl    PARAM_SRC1, %eax
55         movl    %ebx, SAVE_EBX
56
57         movl    PARAM_SRC2, %ebx
58         pxor    %mm0, %mm0              C initial carry
59
60         movl    PARAM_DST, %edx
61
62         movl    PARAM_SIZE, %ecx
63
64         leal    (%edx,%ecx,4), %edx     C dst end
65         negl    %ecx                    C -size
66
67 L(top):
68         C eax   src1 end
69         C ebx   src2 end
70         C ecx   counter, limbs, negative
71         C edx   dst end
72         C mm0   carry
73
74         movd    (%eax), %mm1
75         movd    (%ebx), %mm2
76         psrlq   $32, %mm0
77         leal    4(%eax), %eax
78         leal    4(%ebx), %ebx
79
80         paddq   %mm2, %mm1
81         paddq   %mm2, %mm1
82
83         paddq   %mm1, %mm0
84
85         movd    %mm0, (%edx,%ecx,4)
86         addl    $1, %ecx
87         jnz     L(top)
88
89
90         psrlq   $32, %mm0
91         movl    SAVE_EBX, %ebx
92         movd    %mm0, %eax
93         emms
94         ret
95
96 EPILOGUE()