Tizen 2.1 base
[external/gmp.git] / mpn / x86 / pentium / logops_n.asm
1 dnl  Intel Pentium mpn_and_n,...,mpn_xnor_n -- bitwise logical operations.
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: 3.0 c/l  and, ior, xor
24 C     3.5 c/l  andn, iorn, nand, nior, xnor
25
26
27 define(M4_choose_op,
28 `ifdef(`OPERATION_$1',`
29 define(`M4_function', `mpn_$1')
30 define(`M4_want_pre', `$4')
31 define(`M4op',        `$3')
32 define(`M4_want_post',`$2')
33 ')')
34 define(M4pre, `ifelse(M4_want_pre, yes,`$1')')
35 define(M4post,`ifelse(M4_want_post,yes,`$1')')
36
37 M4_choose_op( and_n,     , andl,    )
38 M4_choose_op( andn_n,    , andl, yes)
39 M4_choose_op( nand_n, yes, andl,    )
40 M4_choose_op( ior_n,     ,  orl,    )
41 M4_choose_op( iorn_n,    ,  orl, yes)
42 M4_choose_op( nior_n, yes,  orl,    )
43 M4_choose_op( xor_n,     , xorl,    )
44 M4_choose_op( xnor_n, yes, xorl,    )
45
46 ifdef(`M4_function',,
47 `m4_error(`Unrecognised or undefined OPERATION symbol
48 ')')
49
50 MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
51
52 NAILS_SUPPORT(0-31)
53
54
55 C void M4_function (mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size);
56 C
57 C Nothing complicated here, just some care to avoid data cache bank clashes
58 C and AGIs.
59 C
60 C We're one register short of being able to do a simple 4 loads, 2 ops, 2
61 C stores.  Instead %ebp is juggled a bit and nops are introduced to keep the
62 C pairings as intended.  An in-place operation would free up a register, for
63 C an 0.5 c/l speedup, if that's worth bothering with.
64 C
65 C This code seems best for P55 too.  Data alignment is a big problem for MMX
66 C and the pairing restrictions on movq and integer instructions make life
67 C difficult.
68
69 defframe(PARAM_SIZE,16)
70 defframe(PARAM_YP,  12)
71 defframe(PARAM_XP,   8)
72 defframe(PARAM_WP,   4)
73
74         TEXT
75         ALIGN(8)
76
77 PROLOGUE(M4_function)
78 deflit(`FRAME',0)
79
80         pushl   %ebx    FRAME_pushl()
81         pushl   %esi    FRAME_pushl()
82
83         pushl   %edi    FRAME_pushl()
84         pushl   %ebp    FRAME_pushl()
85
86         movl    PARAM_SIZE, %ecx
87         movl    PARAM_XP, %ebx
88
89         movl    PARAM_YP, %esi
90         movl    PARAM_WP, %edi
91
92         shrl    %ecx
93         jnc     L(entry)
94
95         movl    (%ebx,%ecx,8), %eax     C risk of data cache bank clash here
96         movl    (%esi,%ecx,8), %edx
97
98 M4pre(` notl_or_xorl_GMP_NUMB_MASK(%edx)')
99
100         M4op    %edx, %eax
101
102 M4post(`xorl    $GMP_NUMB_MASK, %eax')
103         orl     %ecx, %ecx
104
105         movl    %eax, (%edi,%ecx,8)
106         jz      L(done)
107
108         jmp     L(entry)
109
110
111 L(top):
112         C eax
113         C ebx   xp
114         C ecx   counter, limb pairs, decrementing
115         C edx
116         C esi   yp
117         C edi   wp
118         C ebp
119
120         M4op    %ebp, %edx
121         nop
122
123 M4post(`xorl    $GMP_NUMB_MASK, %eax')
124 M4post(`xorl    $GMP_NUMB_MASK, %edx')
125
126         movl    %eax, 4(%edi,%ecx,8)
127         movl    %edx, (%edi,%ecx,8)
128
129 L(entry):
130         movl    -4(%ebx,%ecx,8), %ebp
131         nop
132
133         movl    -4(%esi,%ecx,8), %eax
134         movl    -8(%esi,%ecx,8), %edx
135
136 M4pre(` xorl    $GMP_NUMB_MASK, %eax')
137 M4pre(` xorl    $GMP_NUMB_MASK, %edx')
138
139         M4op    %ebp, %eax
140         movl    -8(%ebx,%ecx,8), %ebp
141
142         decl    %ecx
143         jnz     L(top)
144
145
146         M4op    %ebp, %edx
147         nop
148
149 M4post(`xorl    $GMP_NUMB_MASK, %eax')
150 M4post(`xorl    $GMP_NUMB_MASK, %edx')
151
152         movl    %eax, 4(%edi,%ecx,8)
153         movl    %edx, (%edi,%ecx,8)
154
155
156 L(done):
157         popl    %ebp
158         popl    %edi
159
160         popl    %esi
161         popl    %ebx
162
163         ret
164
165 EPILOGUE()