1 dnl AMD K6-2 mpn_and_n, mpn_andn_n, mpn_nand_n, mpn_ior_n, mpn_iorn_n,
2 dnl mpn_nior_n, mpn_xor_n, mpn_xnor_n -- mpn bitwise logical operations.
4 dnl alignment dst/src1/src2, A=0mod8, N=4mod8
5 dnl A/A/A A/A/N A/N/A A/N/N N/A/A N/A/N N/N/A N/N/N
7 dnl K6-2 1.2 1.5 1.5 1.2 1.2 1.5 1.5 1.2 and,andn,ior,xor
8 dnl K6-2 1.5 1.75 2.0 1.75 1.75 2.0 1.75 1.5 iorn,xnor
9 dnl K6-2 1.75 2.0 2.0 2.0 2.0 2.0 2.0 1.75 nand,nior
11 dnl K6 1.5 1.68 1.75 1.2 1.75 1.75 1.68 1.5 and,andn,ior,xor
12 dnl K6 2.0 2.0 2.25 2.25 2.25 2.25 2.0 2.0 iorn,xnor
13 dnl K6 2.0 2.25 2.25 2.25 2.25 2.25 2.25 2.0 nand,nior
16 dnl Copyright (C) 1999, 2000 Free Software Foundation, Inc.
18 dnl This file is part of the GNU MP Library.
20 dnl The GNU MP Library is free software; you can redistribute it and/or
21 dnl modify it under the terms of the GNU Lesser General Public License as
22 dnl published by the Free Software Foundation; either version 2.1 of the
23 dnl License, or (at your option) any later version.
25 dnl The GNU MP Library is distributed in the hope that it will be useful,
26 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
27 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 dnl Lesser General Public License for more details.
30 dnl You should have received a copy of the GNU Lesser General Public
31 dnl License along with the GNU MP Library; see the file COPYING.LIB. If
32 dnl not, write to the Free Software Foundation, Inc., 59 Temple Place -
33 dnl Suite 330, Boston, MA 02111-1307, USA.
36 include(`../config.m4')
39 dnl M4_p and M4_i are the MMX and integer instructions
40 dnl M4_*_neg_dst means whether to negate the final result before writing
41 dnl M4_*_neg_src2 means whether to negate the src2 values before using them
45 `ifdef(`OPERATION_$1',`
46 define(`M4_function', `mpn_$1')
47 define(`M4_operation', `$1')
49 define(`M4_p_neg_dst', `$3')
50 define(`M4_p_neg_src2',`$4')
52 define(`M4_i_neg_dst', `$6')
53 define(`M4_i_neg_src2',`$7')
56 dnl xnor is done in "iorn" style because it's a touch faster than "nior"
57 dnl style (the two are equivalent for xor).
59 M4_choose_op( and_n, pand,0,0, andl,0,0)
60 M4_choose_op( andn_n, pandn,0,0, andl,0,1)
61 M4_choose_op( nand_n, pand,1,0, andl,1,0)
62 M4_choose_op( ior_n, por,0,0, orl,0,0)
63 M4_choose_op( iorn_n, por,0,1, orl,0,1)
64 M4_choose_op( nior_n, por,1,0, orl,1,0)
65 M4_choose_op( xor_n, pxor,0,0, xorl,0,0)
66 M4_choose_op( xnor_n, pxor,0,1, xorl,0,1)
69 `m4_error(`Unrecognised or undefined OPERATION symbol
72 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)
75 C void M4_function (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
78 C Do src1,size M4_operation src2,size, storing the result in dst,size.
80 C Unaligned movq loads and stores are a bit slower than aligned ones. The
81 C test at the start of the routine checks the alignment of src1 and if
82 C necessary processes one limb separately at the low end to make it aligned.
84 C The raw speeds without this alignment switch are as follows.
86 C alignment dst/src1/src2, A=0mod8, N=4mod8
87 C A/A/A A/A/N A/N/A A/N/N N/A/A N/A/N N/N/A N/N/N
89 C K6 1.5 2.0 1.5 2.0 and,andn,ior,xor
90 C K6 1.75 2.2 2.0 2.28 iorn,xnor
91 C K6 2.0 2.25 2.35 2.28 nand,nior
96 C K6 can do one 64-bit load per cycle so each of these routines should be
97 C able to approach 1.0 c/l, if aligned. The basic and/andn/ior/xor might be
98 C able to get 1.0 with just a 4 limb loop, being 3 instructions per 2 limbs.
99 C The others are 4 instructions per 2 limbs, and so can only approach 1.0
100 C because there's nowhere to hide some loop control.
102 defframe(PARAM_SIZE,16)
103 defframe(PARAM_SRC2,12)
104 defframe(PARAM_SRC1,8)
105 defframe(PARAM_DST, 4)
110 PROLOGUE(M4_function)
111 movl PARAM_SIZE, %ecx
114 movl PARAM_SRC1, %eax
115 movl PARAM_SRC2, %ebx
123 ifelse(M4_i_neg_src2,1,`notl %ecx')
125 ifelse(M4_i_neg_dst,1,` notl %ecx')
140 C carry bit is low of size
149 ifelse(M4_i_neg_src2,1,`notl %esi')
152 ifelse(M4_i_neg_dst,1,` notl %esi')
160 jnz L(still_two_or_more)
164 ifelse(M4_i_neg_src2,1,`notl %ecx')
166 ifelse(M4_i_neg_dst,1,` notl %ecx')
172 L(still_two_or_more):
173 ifelse(eval(M4_p_neg_src2 || M4_p_neg_dst),1,`
174 pcmpeqd %mm7, %mm7 C all ones
187 C carry bit is low of size
189 movq -8(%ebx,%ecx,8), %mm0
190 ifelse(M4_p_neg_src2,1,`pxor %mm7, %mm0')
191 M4_p -8(%eax,%ecx,8), %mm0
192 ifelse(M4_p_neg_dst,1,` pxor %mm7, %mm0')
193 movq %mm0, -8(%edx,%ecx,8)
200 movl -4(%ebx,%esi,4), %ebx
201 ifelse(M4_i_neg_src2,1,`notl %ebx')
202 M4_i -4(%eax,%esi,4), %ebx
203 ifelse(M4_i_neg_dst,1,` notl %ebx')
204 movl %ebx, -4(%edx,%esi,4)