1 dnl Alpha mpn_com -- mpn one's complement.
3 dnl Copyright 2003 Free Software Foundation, Inc.
5 dnl This file is part of the GNU MP Library.
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.
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.
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/.
20 include(`../config.m4')
29 C mp_limb_t mpn_com (mp_ptr dst, mp_srcptr src, mp_size_t size);
31 C For ev5 the main loop is 7 cycles plus 1 taken branch bubble, for a total
32 C 2.0 c/l. In general, a pattern like this unrolled to N limbs per loop
33 C will be 1.5+2/N c/l.
35 C 2 cycles of loop control are unavoidable, for pointer updates and the
36 C taken branch bubble, but also since ldq cannot issue two cycles after stq
37 C (and with a run of stqs that means neither of two cycles at the end of the
40 C The fbeq is forced into the second cycle of the loop using unops, since
41 C the first time through it must wait for the cvtqt result. Once that
42 C result is ready (a 1 cycle stall) then both the branch and following loads
45 C The main loop handles an odd count of limbs, being two limbs loaded before
46 C each size test, plus one pipelined around from the previous iteration (or
47 C setup in the entry sequence).
49 C An even number of limbs is handled by an explicit dst[0]=~src[0] in the
50 C entry sequence, and an increment of the pointers. For an odd size there's
51 C no increment and the first store in the loop (r24) is a repeat of dst[0].
53 C Note that the load for r24 after the possible pointer increment is done
54 C before the explicit store to dst[0], in case src==dst.
69 lda r30, -16(r30) C temporary stack space
70 lda r7, -3(r18) C size - 3
72 ldq r20, 0(r17) C src[0]
73 srl r7, 1, r6 C (size-3)/2
75 stq r6, 8(r30) C (size-3)/2
76 and r7, 1, r5 C 1 if size even
79 s8addq r5, r17, r17 C skip src[0] if even
81 ornot r31, r20, r20 C ~src[0]
84 ldt f0, 8(r30) C (size-3)/2
85 ldq r24, 0(r17) C src[0 or 1]
87 stq r20, 0(r16) C dst[0]
88 s8addq r5, r16, r19 C skip dst[0] if even
90 ldt f1, 0(r8) C data 2.0
91 lda r30, 16(r30) C restore stack
93 cvtqt f0, f0 C (size-3)/2 as float
96 blt r7, L(done_1) C if size<=2
101 C 16-byte alignment here
103 C r17 src, incrementing
104 C r19 dst, incrementing
105 C r24 dst[i] result, ready to store
106 C f0 (size-3)/2, decrementing
109 ldq r20, 8(r17) C src[i+1]
110 ldq r21, 16(r17) C src[i+2]
116 ldq r22, 24(r17) C src[i+3]
117 ldq r23, 32(r17) C src[i+4]
119 stq r24, 0(r19) C dst[i]
121 subt f0, f1, f0 C count -= 2
124 stq r20, 8(r19) C dst[i+1]
129 stq r21, 16(r19) C dst[i+2]
132 stq r22, 24(r19) C dst[i+3]
135 lda r17, 32(r17) C src += 4
136 lda r19, 32(r19) C dst += 4
143 C r24 result for dst[size-1]
145 stq r24, 0(r19) C dst[size-1]
153 C r24 result for dst[size-3]
155 stq r24, 0(r19) C dst[size-3]
158 stq r20, 8(r19) C dst[size-2]
161 stq r21, 16(r19) C dst[size-1]