Tizen 2.1 base
[external/gmp.git] / mpn / alpha / com.asm
1 dnl  Alpha mpn_com -- mpn one's complement.
2
3 dnl  Copyright 2003 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
24 C EV4:    4.75
25 C EV5:    2.0
26 C EV6:    1.5
27
28
29 C mp_limb_t mpn_com (mp_ptr dst, mp_srcptr src, mp_size_t size);
30 C
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.
34 C
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
38 C loop.
39 C
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
43 C can issue together.
44 C
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).
48 C
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].
52 C
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.
55
56
57 ASM_START()
58
59 FLOAT64(L(dat), 2.0)
60
61         ALIGN(16)
62
63 PROLOGUE(mpn_com,gp)
64
65         C r16   dst
66         C r17   src
67         C r18   size
68
69         lda     r30, -16(r30)           C temporary stack space
70         lda     r7, -3(r18)             C size - 3
71
72         ldq     r20, 0(r17)             C src[0]
73         srl     r7, 1, r6               C (size-3)/2
74
75         stq     r6, 8(r30)              C (size-3)/2
76         and     r7, 1, r5               C 1 if size even
77
78         LEA(    r8, L(dat))
79         s8addq  r5, r17, r17            C skip src[0] if even
80
81         ornot   r31, r20, r20           C ~src[0]
82         unop
83
84         ldt     f0, 8(r30)              C (size-3)/2
85         ldq     r24, 0(r17)             C src[0 or 1]
86
87         stq     r20, 0(r16)             C dst[0]
88         s8addq  r5, r16, r19            C skip dst[0] if even
89
90         ldt     f1, 0(r8)               C data 2.0
91         lda     r30, 16(r30)            C restore stack
92         unop
93         cvtqt   f0, f0                  C (size-3)/2 as float
94
95         ornot   r31, r24, r24
96         blt     r7, L(done_1)           C if size<=2
97         unop
98         unop
99
100
101         C 16-byte alignment here
102 L(top):
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
107         C f1    2.0
108
109         ldq     r20, 8(r17)             C src[i+1]
110         ldq     r21, 16(r17)            C src[i+2]
111         unop
112         unop
113
114         fbeq    f0, L(done_2)
115         unop
116         ldq     r22, 24(r17)            C src[i+3]
117         ldq     r23, 32(r17)            C src[i+4]
118
119         stq     r24, 0(r19)             C dst[i]
120         ornot   r31, r20, r20
121         subt    f0, f1, f0              C count -= 2
122         unop
123
124         stq     r20, 8(r19)             C dst[i+1]
125         ornot   r31, r21, r21
126         unop
127         unop
128
129         stq     r21, 16(r19)            C dst[i+2]
130         ornot   r31, r22, r22
131
132         stq     r22, 24(r19)            C dst[i+3]
133         ornot   r31, r23, r24
134
135         lda     r17, 32(r17)            C src += 4
136         lda     r19, 32(r19)            C dst += 4
137         unop
138         fbge    f0, L(top)
139
140
141 L(done_1):
142         C r19   &dst[size-1]
143         C r24   result for dst[size-1]
144
145         stq     r24, 0(r19)             C dst[size-1]
146         ret     r31, (r26), 1
147
148
149 L(done_2):
150         C r19   &dst[size-3]
151         C r20   src[size-2]
152         C r21   src[size-1]
153         C r24   result for dst[size-3]
154
155         stq     r24, 0(r19)             C dst[size-3]
156         ornot   r31, r20, r20
157
158         stq     r20, 8(r19)             C dst[size-2]
159         ornot   r31, r21, r21
160
161         stq     r21, 16(r19)            C dst[size-1]
162         ret     r31, (r26), 1
163
164 EPILOGUE()
165 ASM_END()