Tizen 2.1 base
[external/gmp.git] / mpn / x86 / pentium / popcount.asm
1 dnl  Intel P5 mpn_popcount -- mpn bit population count.
2
3 dnl  Copyright 2001, 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 P5: 8.0 cycles/limb
24
25
26 C unsigned long mpn_popcount (mp_srcptr src, mp_size_t size);
27 C
28 C An arithmetic approach has been found to be slower than the table lookup,
29 C due to needing too many instructions.
30
31 C The slightly strange quoting here helps the renaming done by tune/many.pl.
32 deflit(TABLE_NAME,
33 m4_assert_defined(`GSYM_PREFIX')
34 GSYM_PREFIX`'mpn_popcount``'_table')
35
36         RODATA
37         ALIGN(8)
38         GLOBL   TABLE_NAME
39 TABLE_NAME:
40 forloop(i,0,255,
41 `       .byte   m4_popcount(i)
42 ')
43
44 defframe(PARAM_SIZE,8)
45 defframe(PARAM_SRC, 4)
46
47         TEXT
48         ALIGN(8)
49
50 PROLOGUE(mpn_popcount)
51 deflit(`FRAME',0)
52
53         movl    PARAM_SIZE, %ecx
54         pushl   %esi    FRAME_pushl()
55
56 ifdef(`PIC',`
57         pushl   %ebx    FRAME_pushl()
58         pushl   %ebp    FRAME_pushl()
59
60         call    L(here)
61 L(here):
62         popl    %ebp
63         shll    %ecx            C size in byte pairs
64
65         addl    $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ebp
66         movl    PARAM_SRC, %esi
67
68         xorl    %eax, %eax      C total
69         xorl    %ebx, %ebx      C byte
70
71         movl    TABLE_NAME@GOT(%ebp), %ebp
72         xorl    %edx, %edx      C byte
73 define(TABLE,`(%ebp,$1)')
74 ',`
75 dnl non-PIC
76         shll    %ecx            C size in byte pairs
77         movl    PARAM_SRC, %esi
78
79         pushl   %ebx    FRAME_pushl()
80         xorl    %eax, %eax      C total
81
82         xorl    %ebx, %ebx      C byte
83         xorl    %edx, %edx      C byte
84
85 define(TABLE,`TABLE_NAME`'($1)')
86 ')
87
88
89         ALIGN(8)        C necessary on P55 for claimed speed
90 L(top):
91         C eax   total
92         C ebx   byte
93         C ecx   counter, 2*size to 2
94         C edx   byte
95         C esi   src
96         C edi
97         C ebp   [PIC] table
98
99         addl    %ebx, %eax
100         movb    -1(%esi,%ecx,2), %bl
101
102         addl    %edx, %eax
103         movb    -2(%esi,%ecx,2), %dl
104
105         movb    TABLE(%ebx), %bl
106         decl    %ecx
107
108         movb    TABLE(%edx), %dl
109         jnz     L(top)
110
111
112 ifdef(`PIC',`
113         popl    %ebp
114 ')
115         addl    %ebx, %eax
116         popl    %ebx
117
118         addl    %edx, %eax
119         popl    %esi
120
121         ret
122
123 EPILOGUE()