1 | #! /usr/bin/env perl
|
---|
2 | # Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | #
|
---|
4 | # Licensed under the OpenSSL license (the "License"). You may not use
|
---|
5 | # this file except in compliance with the License. You can obtain a copy
|
---|
6 | # in the file LICENSE in the source distribution or at
|
---|
7 | # https://www.openssl.org/source/license.html
|
---|
8 |
|
---|
9 | #
|
---|
10 | # ====================================================================
|
---|
11 | # Written by Andy Polyakov <[email protected]> for the OpenSSL
|
---|
12 | # project. The module is, however, dual licensed under OpenSSL and
|
---|
13 | # CRYPTOGAMS licenses depending on where you obtain it. For further
|
---|
14 | # details see http://www.openssl.org/~appro/cryptogams/.
|
---|
15 | # ====================================================================
|
---|
16 |
|
---|
17 | # January 2010
|
---|
18 | #
|
---|
19 | # "Teaser" Montgomery multiplication module for IA-64. There are
|
---|
20 | # several possibilities for improvement:
|
---|
21 | #
|
---|
22 | # - modulo-scheduling outer loop would eliminate quite a number of
|
---|
23 | # stalls after ldf8, xma and getf.sig outside inner loop and
|
---|
24 | # improve shorter key performance;
|
---|
25 | # - shorter vector support [with input vectors being fetched only
|
---|
26 | # once] should be added;
|
---|
27 | # - 2x unroll with help of n0[1] would make the code scalable on
|
---|
28 | # "wider" IA-64, "wider" than Itanium 2 that is, which is not of
|
---|
29 | # acute interest, because upcoming Tukwila's individual cores are
|
---|
30 | # reportedly based on Itanium 2 design;
|
---|
31 | # - dedicated squaring procedure(?);
|
---|
32 | #
|
---|
33 | # January 2010
|
---|
34 | #
|
---|
35 | # Shorter vector support is implemented by zero-padding ap and np
|
---|
36 | # vectors up to 8 elements, or 512 bits. This means that 256-bit
|
---|
37 | # inputs will be processed only 2 times faster than 512-bit inputs,
|
---|
38 | # not 4 [as one would expect, because algorithm complexity is n^2].
|
---|
39 | # The reason for padding is that inputs shorter than 512 bits won't
|
---|
40 | # be processed faster anyway, because minimal critical path of the
|
---|
41 | # core loop happens to match 512-bit timing. Either way, it resulted
|
---|
42 | # in >100% improvement of 512-bit RSA sign benchmark and 50% - of
|
---|
43 | # 1024-bit one [in comparison to original version of *this* module].
|
---|
44 | #
|
---|
45 | # So far 'openssl speed rsa dsa' output on 900MHz Itanium 2 *with*
|
---|
46 | # this module is:
|
---|
47 | # sign verify sign/s verify/s
|
---|
48 | # rsa 512 bits 0.000290s 0.000024s 3452.8 42031.4
|
---|
49 | # rsa 1024 bits 0.000793s 0.000058s 1261.7 17172.0
|
---|
50 | # rsa 2048 bits 0.005908s 0.000148s 169.3 6754.0
|
---|
51 | # rsa 4096 bits 0.033456s 0.000469s 29.9 2133.6
|
---|
52 | # dsa 512 bits 0.000253s 0.000198s 3949.9 5057.0
|
---|
53 | # dsa 1024 bits 0.000585s 0.000607s 1708.4 1647.4
|
---|
54 | # dsa 2048 bits 0.001453s 0.001703s 688.1 587.4
|
---|
55 | #
|
---|
56 | # ... and *without* (but still with ia64.S):
|
---|
57 | #
|
---|
58 | # rsa 512 bits 0.000670s 0.000041s 1491.8 24145.5
|
---|
59 | # rsa 1024 bits 0.001988s 0.000080s 502.9 12499.3
|
---|
60 | # rsa 2048 bits 0.008702s 0.000189s 114.9 5293.9
|
---|
61 | # rsa 4096 bits 0.043860s 0.000533s 22.8 1875.9
|
---|
62 | # dsa 512 bits 0.000441s 0.000427s 2265.3 2340.6
|
---|
63 | # dsa 1024 bits 0.000823s 0.000867s 1215.6 1153.2
|
---|
64 | # dsa 2048 bits 0.001894s 0.002179s 528.1 458.9
|
---|
65 | #
|
---|
66 | # As it can be seen, RSA sign performance improves by 130-30%,
|
---|
67 | # hereafter less for longer keys, while verify - by 74-13%.
|
---|
68 | # DSA performance improves by 115-30%.
|
---|
69 |
|
---|
70 | $output=pop;
|
---|
71 |
|
---|
72 | if ($^O eq "hpux") {
|
---|
73 | $ADDP="addp4";
|
---|
74 | for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
|
---|
75 | } else { $ADDP="add"; }
|
---|
76 |
|
---|
77 | $code=<<___;
|
---|
78 | .explicit
|
---|
79 | .text
|
---|
80 |
|
---|
81 | // int bn_mul_mont (BN_ULONG *rp,const BN_ULONG *ap,
|
---|
82 | // const BN_ULONG *bp,const BN_ULONG *np,
|
---|
83 | // const BN_ULONG *n0p,int num);
|
---|
84 | .align 64
|
---|
85 | .global bn_mul_mont#
|
---|
86 | .proc bn_mul_mont#
|
---|
87 | bn_mul_mont:
|
---|
88 | .prologue
|
---|
89 | .body
|
---|
90 | { .mmi; cmp4.le p6,p7=2,r37;;
|
---|
91 | (p6) cmp4.lt.unc p8,p9=8,r37
|
---|
92 | mov ret0=r0 };;
|
---|
93 | { .bbb;
|
---|
94 | (p9) br.cond.dptk.many bn_mul_mont_8
|
---|
95 | (p8) br.cond.dpnt.many bn_mul_mont_general
|
---|
96 | (p7) br.ret.spnt.many b0 };;
|
---|
97 | .endp bn_mul_mont#
|
---|
98 | |
---|
99 |
|
---|
100 | prevfs=r2; prevpr=r3; prevlc=r10; prevsp=r11;
|
---|
101 |
|
---|
102 | rptr=r8; aptr=r9; bptr=r14; nptr=r15;
|
---|
103 | tptr=r16; // &tp[0]
|
---|
104 | tp_1=r17; // &tp[-1]
|
---|
105 | num=r18; len=r19; lc=r20;
|
---|
106 | topbit=r21; // carry bit from tmp[num]
|
---|
107 |
|
---|
108 | n0=f6;
|
---|
109 | m0=f7;
|
---|
110 | bi=f8;
|
---|
111 |
|
---|
112 | .align 64
|
---|
113 | .local bn_mul_mont_general#
|
---|
114 | .proc bn_mul_mont_general#
|
---|
115 | bn_mul_mont_general:
|
---|
116 | .prologue
|
---|
117 | { .mmi; .save ar.pfs,prevfs
|
---|
118 | alloc prevfs=ar.pfs,6,2,0,8
|
---|
119 | $ADDP aptr=0,in1
|
---|
120 | .save ar.lc,prevlc
|
---|
121 | mov prevlc=ar.lc }
|
---|
122 | { .mmi; .vframe prevsp
|
---|
123 | mov prevsp=sp
|
---|
124 | $ADDP bptr=0,in2
|
---|
125 | .save pr,prevpr
|
---|
126 | mov prevpr=pr };;
|
---|
127 |
|
---|
128 | .body
|
---|
129 | .rotf alo[6],nlo[4],ahi[8],nhi[6]
|
---|
130 | .rotr a[3],n[3],t[2]
|
---|
131 |
|
---|
132 | { .mmi; ldf8 bi=[bptr],8 // (*bp++)
|
---|
133 | ldf8 alo[4]=[aptr],16 // ap[0]
|
---|
134 | $ADDP r30=8,in1 };;
|
---|
135 | { .mmi; ldf8 alo[3]=[r30],16 // ap[1]
|
---|
136 | ldf8 alo[2]=[aptr],16 // ap[2]
|
---|
137 | $ADDP in4=0,in4 };;
|
---|
138 | { .mmi; ldf8 alo[1]=[r30] // ap[3]
|
---|
139 | ldf8 n0=[in4] // n0
|
---|
140 | $ADDP rptr=0,in0 }
|
---|
141 | { .mmi; $ADDP nptr=0,in3
|
---|
142 | mov r31=16
|
---|
143 | zxt4 num=in5 };;
|
---|
144 | { .mmi; ldf8 nlo[2]=[nptr],8 // np[0]
|
---|
145 | shladd len=num,3,r0
|
---|
146 | shladd r31=num,3,r31 };;
|
---|
147 | { .mmi; ldf8 nlo[1]=[nptr],8 // np[1]
|
---|
148 | add lc=-5,num
|
---|
149 | sub r31=sp,r31 };;
|
---|
150 | { .mfb; and sp=-16,r31 // alloca
|
---|
151 | xmpy.hu ahi[2]=alo[4],bi // ap[0]*bp[0]
|
---|
152 | nop.b 0 }
|
---|
153 | { .mfb; nop.m 0
|
---|
154 | xmpy.lu alo[4]=alo[4],bi
|
---|
155 | brp.loop.imp .L1st_ctop,.L1st_cend-16
|
---|
156 | };;
|
---|
157 | { .mfi; nop.m 0
|
---|
158 | xma.hu ahi[1]=alo[3],bi,ahi[2] // ap[1]*bp[0]
|
---|
159 | add tp_1=8,sp }
|
---|
160 | { .mfi; nop.m 0
|
---|
161 | xma.lu alo[3]=alo[3],bi,ahi[2]
|
---|
162 | mov pr.rot=0x20001f<<16
|
---|
163 | // ------^----- (p40) at first (p23)
|
---|
164 | // ----------^^ p[16:20]=1
|
---|
165 | };;
|
---|
166 | { .mfi; nop.m 0
|
---|
167 | xmpy.lu m0=alo[4],n0 // (ap[0]*bp[0])*n0
|
---|
168 | mov ar.lc=lc }
|
---|
169 | { .mfi; nop.m 0
|
---|
170 | fcvt.fxu.s1 nhi[1]=f0
|
---|
171 | mov ar.ec=8 };;
|
---|
172 |
|
---|
173 | .align 32
|
---|
174 | .L1st_ctop:
|
---|
175 | .pred.rel "mutex",p40,p42
|
---|
176 | { .mfi; (p16) ldf8 alo[0]=[aptr],8 // *(aptr++)
|
---|
177 | (p18) xma.hu ahi[0]=alo[2],bi,ahi[1]
|
---|
178 | (p40) add n[2]=n[2],a[2] } // (p23) }
|
---|
179 | { .mfi; (p18) ldf8 nlo[0]=[nptr],8 // *(nptr++)(p16)
|
---|
180 | (p18) xma.lu alo[2]=alo[2],bi,ahi[1]
|
---|
181 | (p42) add n[2]=n[2],a[2],1 };; // (p23)
|
---|
182 | { .mfi; (p21) getf.sig a[0]=alo[5]
|
---|
183 | (p20) xma.hu nhi[0]=nlo[2],m0,nhi[1]
|
---|
184 | (p42) cmp.leu p41,p39=n[2],a[2] } // (p23)
|
---|
185 | { .mfi; (p23) st8 [tp_1]=n[2],8
|
---|
186 | (p20) xma.lu nlo[2]=nlo[2],m0,nhi[1]
|
---|
187 | (p40) cmp.ltu p41,p39=n[2],a[2] } // (p23)
|
---|
188 | { .mmb; (p21) getf.sig n[0]=nlo[3]
|
---|
189 | (p16) nop.m 0
|
---|
190 | br.ctop.sptk .L1st_ctop };;
|
---|
191 | .L1st_cend:
|
---|
192 |
|
---|
193 | { .mmi; getf.sig a[0]=ahi[6] // (p24)
|
---|
194 | getf.sig n[0]=nhi[4]
|
---|
195 | add num=-1,num };; // num--
|
---|
196 | { .mmi; .pred.rel "mutex",p40,p42
|
---|
197 | (p40) add n[0]=n[0],a[0]
|
---|
198 | (p42) add n[0]=n[0],a[0],1
|
---|
199 | sub aptr=aptr,len };; // rewind
|
---|
200 | { .mmi; .pred.rel "mutex",p40,p42
|
---|
201 | (p40) cmp.ltu p41,p39=n[0],a[0]
|
---|
202 | (p42) cmp.leu p41,p39=n[0],a[0]
|
---|
203 | sub nptr=nptr,len };;
|
---|
204 | { .mmi; .pred.rel "mutex",p39,p41
|
---|
205 | (p39) add topbit=r0,r0
|
---|
206 | (p41) add topbit=r0,r0,1
|
---|
207 | nop.i 0 }
|
---|
208 | { .mmi; st8 [tp_1]=n[0]
|
---|
209 | add tptr=16,sp
|
---|
210 | add tp_1=8,sp };;
|
---|
211 | |
---|
212 |
|
---|
213 | .Louter:
|
---|
214 | { .mmi; ldf8 bi=[bptr],8 // (*bp++)
|
---|
215 | ldf8 ahi[3]=[tptr] // tp[0]
|
---|
216 | add r30=8,aptr };;
|
---|
217 | { .mmi; ldf8 alo[4]=[aptr],16 // ap[0]
|
---|
218 | ldf8 alo[3]=[r30],16 // ap[1]
|
---|
219 | add r31=8,nptr };;
|
---|
220 | { .mfb; ldf8 alo[2]=[aptr],16 // ap[2]
|
---|
221 | xma.hu ahi[2]=alo[4],bi,ahi[3] // ap[0]*bp[i]+tp[0]
|
---|
222 | brp.loop.imp .Linner_ctop,.Linner_cend-16
|
---|
223 | }
|
---|
224 | { .mfb; ldf8 alo[1]=[r30] // ap[3]
|
---|
225 | xma.lu alo[4]=alo[4],bi,ahi[3]
|
---|
226 | clrrrb.pr };;
|
---|
227 | { .mfi; ldf8 nlo[2]=[nptr],16 // np[0]
|
---|
228 | xma.hu ahi[1]=alo[3],bi,ahi[2] // ap[1]*bp[i]
|
---|
229 | nop.i 0 }
|
---|
230 | { .mfi; ldf8 nlo[1]=[r31] // np[1]
|
---|
231 | xma.lu alo[3]=alo[3],bi,ahi[2]
|
---|
232 | mov pr.rot=0x20101f<<16
|
---|
233 | // ------^----- (p40) at first (p23)
|
---|
234 | // --------^--- (p30) at first (p22)
|
---|
235 | // ----------^^ p[16:20]=1
|
---|
236 | };;
|
---|
237 | { .mfi; st8 [tptr]=r0 // tp[0] is already accounted
|
---|
238 | xmpy.lu m0=alo[4],n0 // (ap[0]*bp[i]+tp[0])*n0
|
---|
239 | mov ar.lc=lc }
|
---|
240 | { .mfi;
|
---|
241 | fcvt.fxu.s1 nhi[1]=f0
|
---|
242 | mov ar.ec=8 };;
|
---|
243 |
|
---|
244 | // This loop spins in 4*(n+7) ticks on Itanium 2 and should spin in
|
---|
245 | // 7*(n+7) ticks on Itanium (the one codenamed Merced). Factor of 7
|
---|
246 | // in latter case accounts for two-tick pipeline stall, which means
|
---|
247 | // that its performance would be ~20% lower than optimal one. No
|
---|
248 | // attempt was made to address this, because original Itanium is
|
---|
249 | // hardly represented out in the wild...
|
---|
250 | .align 32
|
---|
251 | .Linner_ctop:
|
---|
252 | .pred.rel "mutex",p40,p42
|
---|
253 | .pred.rel "mutex",p30,p32
|
---|
254 | { .mfi; (p16) ldf8 alo[0]=[aptr],8 // *(aptr++)
|
---|
255 | (p18) xma.hu ahi[0]=alo[2],bi,ahi[1]
|
---|
256 | (p40) add n[2]=n[2],a[2] } // (p23)
|
---|
257 | { .mfi; (p16) nop.m 0
|
---|
258 | (p18) xma.lu alo[2]=alo[2],bi,ahi[1]
|
---|
259 | (p42) add n[2]=n[2],a[2],1 };; // (p23)
|
---|
260 | { .mfi; (p21) getf.sig a[0]=alo[5]
|
---|
261 | (p16) nop.f 0
|
---|
262 | (p40) cmp.ltu p41,p39=n[2],a[2] } // (p23)
|
---|
263 | { .mfi; (p21) ld8 t[0]=[tptr],8
|
---|
264 | (p16) nop.f 0
|
---|
265 | (p42) cmp.leu p41,p39=n[2],a[2] };; // (p23)
|
---|
266 | { .mfi; (p18) ldf8 nlo[0]=[nptr],8 // *(nptr++)
|
---|
267 | (p20) xma.hu nhi[0]=nlo[2],m0,nhi[1]
|
---|
268 | (p30) add a[1]=a[1],t[1] } // (p22)
|
---|
269 | { .mfi; (p16) nop.m 0
|
---|
270 | (p20) xma.lu nlo[2]=nlo[2],m0,nhi[1]
|
---|
271 | (p32) add a[1]=a[1],t[1],1 };; // (p22)
|
---|
272 | { .mmi; (p21) getf.sig n[0]=nlo[3]
|
---|
273 | (p16) nop.m 0
|
---|
274 | (p30) cmp.ltu p31,p29=a[1],t[1] } // (p22)
|
---|
275 | { .mmb; (p23) st8 [tp_1]=n[2],8
|
---|
276 | (p32) cmp.leu p31,p29=a[1],t[1] // (p22)
|
---|
277 | br.ctop.sptk .Linner_ctop };;
|
---|
278 | .Linner_cend:
|
---|
279 |
|
---|
280 | { .mmi; getf.sig a[0]=ahi[6] // (p24)
|
---|
281 | getf.sig n[0]=nhi[4]
|
---|
282 | nop.i 0 };;
|
---|
283 |
|
---|
284 | { .mmi; .pred.rel "mutex",p31,p33
|
---|
285 | (p31) add a[0]=a[0],topbit
|
---|
286 | (p33) add a[0]=a[0],topbit,1
|
---|
287 | mov topbit=r0 };;
|
---|
288 | { .mfi; .pred.rel "mutex",p31,p33
|
---|
289 | (p31) cmp.ltu p32,p30=a[0],topbit
|
---|
290 | (p33) cmp.leu p32,p30=a[0],topbit
|
---|
291 | }
|
---|
292 | { .mfi; .pred.rel "mutex",p40,p42
|
---|
293 | (p40) add n[0]=n[0],a[0]
|
---|
294 | (p42) add n[0]=n[0],a[0],1
|
---|
295 | };;
|
---|
296 | { .mmi; .pred.rel "mutex",p44,p46
|
---|
297 | (p40) cmp.ltu p41,p39=n[0],a[0]
|
---|
298 | (p42) cmp.leu p41,p39=n[0],a[0]
|
---|
299 | (p32) add topbit=r0,r0,1 }
|
---|
300 |
|
---|
301 | { .mmi; st8 [tp_1]=n[0],8
|
---|
302 | cmp4.ne p6,p0=1,num
|
---|
303 | sub aptr=aptr,len };; // rewind
|
---|
304 | { .mmi; sub nptr=nptr,len
|
---|
305 | (p41) add topbit=r0,r0,1
|
---|
306 | add tptr=16,sp }
|
---|
307 | { .mmb; add tp_1=8,sp
|
---|
308 | add num=-1,num // num--
|
---|
309 | (p6) br.cond.sptk.many .Louter };;
|
---|
310 | |
---|
311 |
|
---|
312 | { .mbb; add lc=4,lc
|
---|
313 | brp.loop.imp .Lsub_ctop,.Lsub_cend-16
|
---|
314 | clrrrb.pr };;
|
---|
315 | { .mii; nop.m 0
|
---|
316 | mov pr.rot=0x10001<<16
|
---|
317 | // ------^---- (p33) at first (p17)
|
---|
318 | mov ar.lc=lc }
|
---|
319 | { .mii; nop.m 0
|
---|
320 | mov ar.ec=3
|
---|
321 | nop.i 0 };;
|
---|
322 |
|
---|
323 | .Lsub_ctop:
|
---|
324 | .pred.rel "mutex",p33,p35
|
---|
325 | { .mfi; (p16) ld8 t[0]=[tptr],8 // t=*(tp++)
|
---|
326 | (p16) nop.f 0
|
---|
327 | (p33) sub n[1]=t[1],n[1] } // (p17)
|
---|
328 | { .mfi; (p16) ld8 n[0]=[nptr],8 // n=*(np++)
|
---|
329 | (p16) nop.f 0
|
---|
330 | (p35) sub n[1]=t[1],n[1],1 };; // (p17)
|
---|
331 | { .mib; (p18) st8 [rptr]=n[2],8 // *(rp++)=r
|
---|
332 | (p33) cmp.gtu p34,p32=n[1],t[1] // (p17)
|
---|
333 | (p18) nop.b 0 }
|
---|
334 | { .mib; (p18) nop.m 0
|
---|
335 | (p35) cmp.geu p34,p32=n[1],t[1] // (p17)
|
---|
336 | br.ctop.sptk .Lsub_ctop };;
|
---|
337 | .Lsub_cend:
|
---|
338 |
|
---|
339 | { .mmb; .pred.rel "mutex",p34,p36
|
---|
340 | (p34) sub topbit=topbit,r0 // (p19)
|
---|
341 | (p36) sub topbit=topbit,r0,1
|
---|
342 | brp.loop.imp .Lcopy_ctop,.Lcopy_cend-16
|
---|
343 | }
|
---|
344 | { .mmb; sub rptr=rptr,len // rewind
|
---|
345 | sub tptr=tptr,len
|
---|
346 | clrrrb.pr };;
|
---|
347 | { .mmi; mov aptr=rptr
|
---|
348 | mov bptr=tptr
|
---|
349 | mov pr.rot=1<<16 };;
|
---|
350 | { .mii; cmp.eq p0,p6=topbit,r0
|
---|
351 | mov ar.lc=lc
|
---|
352 | mov ar.ec=2 };;
|
---|
353 |
|
---|
354 | .Lcopy_ctop:
|
---|
355 | { .mmi; (p16) ld8 a[0]=[aptr],8
|
---|
356 | (p16) ld8 t[0]=[bptr],8
|
---|
357 | (p6) mov a[1]=t[1] };; // (p17)
|
---|
358 | { .mmb; (p17) st8 [rptr]=a[1],8
|
---|
359 | (p17) st8 [tptr]=r0,8
|
---|
360 | br.ctop.sptk .Lcopy_ctop };;
|
---|
361 | .Lcopy_cend:
|
---|
362 |
|
---|
363 | { .mmi; mov ret0=1 // signal "handled"
|
---|
364 | rum 1<<5 // clear um.mfh
|
---|
365 | mov ar.lc=prevlc }
|
---|
366 | { .mib; .restore sp
|
---|
367 | mov sp=prevsp
|
---|
368 | mov pr=prevpr,0x1ffff
|
---|
369 | br.ret.sptk.many b0 };;
|
---|
370 | .endp bn_mul_mont_general#
|
---|
371 | |
---|
372 |
|
---|
373 | a1=r16; a2=r17; a3=r18; a4=r19; a5=r20; a6=r21; a7=r22; a8=r23;
|
---|
374 | n1=r24; n2=r25; n3=r26; n4=r27; n5=r28; n6=r29; n7=r30; n8=r31;
|
---|
375 | t0=r15;
|
---|
376 |
|
---|
377 | ai0=f8; ai1=f9; ai2=f10; ai3=f11; ai4=f12; ai5=f13; ai6=f14; ai7=f15;
|
---|
378 | ni0=f16; ni1=f17; ni2=f18; ni3=f19; ni4=f20; ni5=f21; ni6=f22; ni7=f23;
|
---|
379 |
|
---|
380 | .align 64
|
---|
381 | .skip 48 // aligns loop body
|
---|
382 | .local bn_mul_mont_8#
|
---|
383 | .proc bn_mul_mont_8#
|
---|
384 | bn_mul_mont_8:
|
---|
385 | .prologue
|
---|
386 | { .mmi; .save ar.pfs,prevfs
|
---|
387 | alloc prevfs=ar.pfs,6,2,0,8
|
---|
388 | .vframe prevsp
|
---|
389 | mov prevsp=sp
|
---|
390 | .save ar.lc,prevlc
|
---|
391 | mov prevlc=ar.lc }
|
---|
392 | { .mmi; add r17=-6*16,sp
|
---|
393 | add sp=-7*16,sp
|
---|
394 | .save pr,prevpr
|
---|
395 | mov prevpr=pr };;
|
---|
396 |
|
---|
397 | { .mmi; .save.gf 0,0x10
|
---|
398 | stf.spill [sp]=f16,-16
|
---|
399 | .save.gf 0,0x20
|
---|
400 | stf.spill [r17]=f17,32
|
---|
401 | add r16=-5*16,prevsp};;
|
---|
402 | { .mmi; .save.gf 0,0x40
|
---|
403 | stf.spill [r16]=f18,32
|
---|
404 | .save.gf 0,0x80
|
---|
405 | stf.spill [r17]=f19,32
|
---|
406 | $ADDP aptr=0,in1 };;
|
---|
407 | { .mmi; .save.gf 0,0x100
|
---|
408 | stf.spill [r16]=f20,32
|
---|
409 | .save.gf 0,0x200
|
---|
410 | stf.spill [r17]=f21,32
|
---|
411 | $ADDP r29=8,in1 };;
|
---|
412 | { .mmi; .save.gf 0,0x400
|
---|
413 | stf.spill [r16]=f22
|
---|
414 | .save.gf 0,0x800
|
---|
415 | stf.spill [r17]=f23
|
---|
416 | $ADDP rptr=0,in0 };;
|
---|
417 | |
---|
418 |
|
---|
419 | .body
|
---|
420 | .rotf bj[8],mj[2],tf[2],alo[10],ahi[10],nlo[10],nhi[10]
|
---|
421 | .rotr t[8]
|
---|
422 |
|
---|
423 | // load input vectors padding them to 8 elements
|
---|
424 | { .mmi; ldf8 ai0=[aptr],16 // ap[0]
|
---|
425 | ldf8 ai1=[r29],16 // ap[1]
|
---|
426 | $ADDP bptr=0,in2 }
|
---|
427 | { .mmi; $ADDP r30=8,in2
|
---|
428 | $ADDP nptr=0,in3
|
---|
429 | $ADDP r31=8,in3 };;
|
---|
430 | { .mmi; ldf8 bj[7]=[bptr],16 // bp[0]
|
---|
431 | ldf8 bj[6]=[r30],16 // bp[1]
|
---|
432 | cmp4.le p4,p5=3,in5 }
|
---|
433 | { .mmi; ldf8 ni0=[nptr],16 // np[0]
|
---|
434 | ldf8 ni1=[r31],16 // np[1]
|
---|
435 | cmp4.le p6,p7=4,in5 };;
|
---|
436 |
|
---|
437 | { .mfi; (p4)ldf8 ai2=[aptr],16 // ap[2]
|
---|
438 | (p5)fcvt.fxu ai2=f0
|
---|
439 | cmp4.le p8,p9=5,in5 }
|
---|
440 | { .mfi; (p6)ldf8 ai3=[r29],16 // ap[3]
|
---|
441 | (p7)fcvt.fxu ai3=f0
|
---|
442 | cmp4.le p10,p11=6,in5 }
|
---|
443 | { .mfi; (p4)ldf8 bj[5]=[bptr],16 // bp[2]
|
---|
444 | (p5)fcvt.fxu bj[5]=f0
|
---|
445 | cmp4.le p12,p13=7,in5 }
|
---|
446 | { .mfi; (p6)ldf8 bj[4]=[r30],16 // bp[3]
|
---|
447 | (p7)fcvt.fxu bj[4]=f0
|
---|
448 | cmp4.le p14,p15=8,in5 }
|
---|
449 | { .mfi; (p4)ldf8 ni2=[nptr],16 // np[2]
|
---|
450 | (p5)fcvt.fxu ni2=f0
|
---|
451 | addp4 r28=-1,in5 }
|
---|
452 | { .mfi; (p6)ldf8 ni3=[r31],16 // np[3]
|
---|
453 | (p7)fcvt.fxu ni3=f0
|
---|
454 | $ADDP in4=0,in4 };;
|
---|
455 |
|
---|
456 | { .mfi; ldf8 n0=[in4]
|
---|
457 | fcvt.fxu tf[1]=f0
|
---|
458 | nop.i 0 }
|
---|
459 |
|
---|
460 | { .mfi; (p8)ldf8 ai4=[aptr],16 // ap[4]
|
---|
461 | (p9)fcvt.fxu ai4=f0
|
---|
462 | mov t[0]=r0 }
|
---|
463 | { .mfi; (p10)ldf8 ai5=[r29],16 // ap[5]
|
---|
464 | (p11)fcvt.fxu ai5=f0
|
---|
465 | mov t[1]=r0 }
|
---|
466 | { .mfi; (p8)ldf8 bj[3]=[bptr],16 // bp[4]
|
---|
467 | (p9)fcvt.fxu bj[3]=f0
|
---|
468 | mov t[2]=r0 }
|
---|
469 | { .mfi; (p10)ldf8 bj[2]=[r30],16 // bp[5]
|
---|
470 | (p11)fcvt.fxu bj[2]=f0
|
---|
471 | mov t[3]=r0 }
|
---|
472 | { .mfi; (p8)ldf8 ni4=[nptr],16 // np[4]
|
---|
473 | (p9)fcvt.fxu ni4=f0
|
---|
474 | mov t[4]=r0 }
|
---|
475 | { .mfi; (p10)ldf8 ni5=[r31],16 // np[5]
|
---|
476 | (p11)fcvt.fxu ni5=f0
|
---|
477 | mov t[5]=r0 };;
|
---|
478 |
|
---|
479 | { .mfi; (p12)ldf8 ai6=[aptr],16 // ap[6]
|
---|
480 | (p13)fcvt.fxu ai6=f0
|
---|
481 | mov t[6]=r0 }
|
---|
482 | { .mfi; (p14)ldf8 ai7=[r29],16 // ap[7]
|
---|
483 | (p15)fcvt.fxu ai7=f0
|
---|
484 | mov t[7]=r0 }
|
---|
485 | { .mfi; (p12)ldf8 bj[1]=[bptr],16 // bp[6]
|
---|
486 | (p13)fcvt.fxu bj[1]=f0
|
---|
487 | mov ar.lc=r28 }
|
---|
488 | { .mfi; (p14)ldf8 bj[0]=[r30],16 // bp[7]
|
---|
489 | (p15)fcvt.fxu bj[0]=f0
|
---|
490 | mov ar.ec=1 }
|
---|
491 | { .mfi; (p12)ldf8 ni6=[nptr],16 // np[6]
|
---|
492 | (p13)fcvt.fxu ni6=f0
|
---|
493 | mov pr.rot=1<<16 }
|
---|
494 | { .mfb; (p14)ldf8 ni7=[r31],16 // np[7]
|
---|
495 | (p15)fcvt.fxu ni7=f0
|
---|
496 | brp.loop.imp .Louter_8_ctop,.Louter_8_cend-16
|
---|
497 | };;
|
---|
498 | |
---|
499 |
|
---|
500 | // The loop is scheduled for 32*n ticks on Itanium 2. Actual attempt
|
---|
501 | // to measure with help of Interval Time Counter indicated that the
|
---|
502 | // factor is a tad higher: 33 or 34, if not 35. Exact measurement and
|
---|
503 | // addressing the issue is problematic, because I don't have access
|
---|
504 | // to platform-specific instruction-level profiler. On Itanium it
|
---|
505 | // should run in 56*n ticks, because of higher xma latency...
|
---|
506 | .Louter_8_ctop:
|
---|
507 | .pred.rel "mutex",p40,p42
|
---|
508 | .pred.rel "mutex",p48,p50
|
---|
509 | { .mfi; (p16) nop.m 0 // 0:
|
---|
510 | (p16) xma.hu ahi[0]=ai0,bj[7],tf[1] // ap[0]*b[i]+t[0]
|
---|
511 | (p40) add a3=a3,n3 } // (p17) a3+=n3
|
---|
512 | { .mfi; (p42) add a3=a3,n3,1
|
---|
513 | (p16) xma.lu alo[0]=ai0,bj[7],tf[1]
|
---|
514 | (p16) nop.i 0 };;
|
---|
515 | { .mii; (p17) getf.sig a7=alo[8] // 1:
|
---|
516 | (p48) add t[6]=t[6],a3 // (p17) t[6]+=a3
|
---|
517 | (p50) add t[6]=t[6],a3,1 };;
|
---|
518 | { .mfi; (p17) getf.sig a8=ahi[8] // 2:
|
---|
519 | (p17) xma.hu nhi[7]=ni6,mj[1],nhi[6] // np[6]*m0
|
---|
520 | (p40) cmp.ltu p43,p41=a3,n3 }
|
---|
521 | { .mfi; (p42) cmp.leu p43,p41=a3,n3
|
---|
522 | (p17) xma.lu nlo[7]=ni6,mj[1],nhi[6]
|
---|
523 | (p16) nop.i 0 };;
|
---|
524 | { .mii; (p17) getf.sig n5=nlo[6] // 3:
|
---|
525 | (p48) cmp.ltu p51,p49=t[6],a3
|
---|
526 | (p50) cmp.leu p51,p49=t[6],a3 };;
|
---|
527 | .pred.rel "mutex",p41,p43
|
---|
528 | .pred.rel "mutex",p49,p51
|
---|
529 | { .mfi; (p16) nop.m 0 // 4:
|
---|
530 | (p16) xma.hu ahi[1]=ai1,bj[7],ahi[0] // ap[1]*b[i]
|
---|
531 | (p41) add a4=a4,n4 } // (p17) a4+=n4
|
---|
532 | { .mfi; (p43) add a4=a4,n4,1
|
---|
533 | (p16) xma.lu alo[1]=ai1,bj[7],ahi[0]
|
---|
534 | (p16) nop.i 0 };;
|
---|
535 | { .mfi; (p49) add t[5]=t[5],a4 // 5: (p17) t[5]+=a4
|
---|
536 | (p16) xmpy.lu mj[0]=alo[0],n0 // (ap[0]*b[i]+t[0])*n0
|
---|
537 | (p51) add t[5]=t[5],a4,1 };;
|
---|
538 | { .mfi; (p16) nop.m 0 // 6:
|
---|
539 | (p17) xma.hu nhi[8]=ni7,mj[1],nhi[7] // np[7]*m0
|
---|
540 | (p41) cmp.ltu p42,p40=a4,n4 }
|
---|
541 | { .mfi; (p43) cmp.leu p42,p40=a4,n4
|
---|
542 | (p17) xma.lu nlo[8]=ni7,mj[1],nhi[7]
|
---|
543 | (p16) nop.i 0 };;
|
---|
544 | { .mii; (p17) getf.sig n6=nlo[7] // 7:
|
---|
545 | (p49) cmp.ltu p50,p48=t[5],a4
|
---|
546 | (p51) cmp.leu p50,p48=t[5],a4 };;
|
---|
547 | .pred.rel "mutex",p40,p42
|
---|
548 | .pred.rel "mutex",p48,p50
|
---|
549 | { .mfi; (p16) nop.m 0 // 8:
|
---|
550 | (p16) xma.hu ahi[2]=ai2,bj[7],ahi[1] // ap[2]*b[i]
|
---|
551 | (p40) add a5=a5,n5 } // (p17) a5+=n5
|
---|
552 | { .mfi; (p42) add a5=a5,n5,1
|
---|
553 | (p16) xma.lu alo[2]=ai2,bj[7],ahi[1]
|
---|
554 | (p16) nop.i 0 };;
|
---|
555 | { .mii; (p16) getf.sig a1=alo[1] // 9:
|
---|
556 | (p48) add t[4]=t[4],a5 // p(17) t[4]+=a5
|
---|
557 | (p50) add t[4]=t[4],a5,1 };;
|
---|
558 | { .mfi; (p16) nop.m 0 // 10:
|
---|
559 | (p16) xma.hu nhi[0]=ni0,mj[0],alo[0] // np[0]*m0
|
---|
560 | (p40) cmp.ltu p43,p41=a5,n5 }
|
---|
561 | { .mfi; (p42) cmp.leu p43,p41=a5,n5
|
---|
562 | (p16) xma.lu nlo[0]=ni0,mj[0],alo[0]
|
---|
563 | (p16) nop.i 0 };;
|
---|
564 | { .mii; (p17) getf.sig n7=nlo[8] // 11:
|
---|
565 | (p48) cmp.ltu p51,p49=t[4],a5
|
---|
566 | (p50) cmp.leu p51,p49=t[4],a5 };;
|
---|
567 | .pred.rel "mutex",p41,p43
|
---|
568 | .pred.rel "mutex",p49,p51
|
---|
569 | { .mfi; (p17) getf.sig n8=nhi[8] // 12:
|
---|
570 | (p16) xma.hu ahi[3]=ai3,bj[7],ahi[2] // ap[3]*b[i]
|
---|
571 | (p41) add a6=a6,n6 } // (p17) a6+=n6
|
---|
572 | { .mfi; (p43) add a6=a6,n6,1
|
---|
573 | (p16) xma.lu alo[3]=ai3,bj[7],ahi[2]
|
---|
574 | (p16) nop.i 0 };;
|
---|
575 | { .mii; (p16) getf.sig a2=alo[2] // 13:
|
---|
576 | (p49) add t[3]=t[3],a6 // (p17) t[3]+=a6
|
---|
577 | (p51) add t[3]=t[3],a6,1 };;
|
---|
578 | { .mfi; (p16) nop.m 0 // 14:
|
---|
579 | (p16) xma.hu nhi[1]=ni1,mj[0],nhi[0] // np[1]*m0
|
---|
580 | (p41) cmp.ltu p42,p40=a6,n6 }
|
---|
581 | { .mfi; (p43) cmp.leu p42,p40=a6,n6
|
---|
582 | (p16) xma.lu nlo[1]=ni1,mj[0],nhi[0]
|
---|
583 | (p16) nop.i 0 };;
|
---|
584 | { .mii; (p16) nop.m 0 // 15:
|
---|
585 | (p49) cmp.ltu p50,p48=t[3],a6
|
---|
586 | (p51) cmp.leu p50,p48=t[3],a6 };;
|
---|
587 | .pred.rel "mutex",p40,p42
|
---|
588 | .pred.rel "mutex",p48,p50
|
---|
589 | { .mfi; (p16) nop.m 0 // 16:
|
---|
590 | (p16) xma.hu ahi[4]=ai4,bj[7],ahi[3] // ap[4]*b[i]
|
---|
591 | (p40) add a7=a7,n7 } // (p17) a7+=n7
|
---|
592 | { .mfi; (p42) add a7=a7,n7,1
|
---|
593 | (p16) xma.lu alo[4]=ai4,bj[7],ahi[3]
|
---|
594 | (p16) nop.i 0 };;
|
---|
595 | { .mii; (p16) getf.sig a3=alo[3] // 17:
|
---|
596 | (p48) add t[2]=t[2],a7 // (p17) t[2]+=a7
|
---|
597 | (p50) add t[2]=t[2],a7,1 };;
|
---|
598 | { .mfi; (p16) nop.m 0 // 18:
|
---|
599 | (p16) xma.hu nhi[2]=ni2,mj[0],nhi[1] // np[2]*m0
|
---|
600 | (p40) cmp.ltu p43,p41=a7,n7 }
|
---|
601 | { .mfi; (p42) cmp.leu p43,p41=a7,n7
|
---|
602 | (p16) xma.lu nlo[2]=ni2,mj[0],nhi[1]
|
---|
603 | (p16) nop.i 0 };;
|
---|
604 | { .mii; (p16) getf.sig n1=nlo[1] // 19:
|
---|
605 | (p48) cmp.ltu p51,p49=t[2],a7
|
---|
606 | (p50) cmp.leu p51,p49=t[2],a7 };;
|
---|
607 | .pred.rel "mutex",p41,p43
|
---|
608 | .pred.rel "mutex",p49,p51
|
---|
609 | { .mfi; (p16) nop.m 0 // 20:
|
---|
610 | (p16) xma.hu ahi[5]=ai5,bj[7],ahi[4] // ap[5]*b[i]
|
---|
611 | (p41) add a8=a8,n8 } // (p17) a8+=n8
|
---|
612 | { .mfi; (p43) add a8=a8,n8,1
|
---|
613 | (p16) xma.lu alo[5]=ai5,bj[7],ahi[4]
|
---|
614 | (p16) nop.i 0 };;
|
---|
615 | { .mii; (p16) getf.sig a4=alo[4] // 21:
|
---|
616 | (p49) add t[1]=t[1],a8 // (p17) t[1]+=a8
|
---|
617 | (p51) add t[1]=t[1],a8,1 };;
|
---|
618 | { .mfi; (p16) nop.m 0 // 22:
|
---|
619 | (p16) xma.hu nhi[3]=ni3,mj[0],nhi[2] // np[3]*m0
|
---|
620 | (p41) cmp.ltu p42,p40=a8,n8 }
|
---|
621 | { .mfi; (p43) cmp.leu p42,p40=a8,n8
|
---|
622 | (p16) xma.lu nlo[3]=ni3,mj[0],nhi[2]
|
---|
623 | (p16) nop.i 0 };;
|
---|
624 | { .mii; (p16) getf.sig n2=nlo[2] // 23:
|
---|
625 | (p49) cmp.ltu p50,p48=t[1],a8
|
---|
626 | (p51) cmp.leu p50,p48=t[1],a8 };;
|
---|
627 | { .mfi; (p16) nop.m 0 // 24:
|
---|
628 | (p16) xma.hu ahi[6]=ai6,bj[7],ahi[5] // ap[6]*b[i]
|
---|
629 | (p16) add a1=a1,n1 } // (p16) a1+=n1
|
---|
630 | { .mfi; (p16) nop.m 0
|
---|
631 | (p16) xma.lu alo[6]=ai6,bj[7],ahi[5]
|
---|
632 | (p17) mov t[0]=r0 };;
|
---|
633 | { .mii; (p16) getf.sig a5=alo[5] // 25:
|
---|
634 | (p16) add t0=t[7],a1 // (p16) t[7]+=a1
|
---|
635 | (p42) add t[0]=t[0],r0,1 };;
|
---|
636 | { .mfi; (p16) setf.sig tf[0]=t0 // 26:
|
---|
637 | (p16) xma.hu nhi[4]=ni4,mj[0],nhi[3] // np[4]*m0
|
---|
638 | (p50) add t[0]=t[0],r0,1 }
|
---|
639 | { .mfi; (p16) cmp.ltu.unc p42,p40=a1,n1
|
---|
640 | (p16) xma.lu nlo[4]=ni4,mj[0],nhi[3]
|
---|
641 | (p16) nop.i 0 };;
|
---|
642 | { .mii; (p16) getf.sig n3=nlo[3] // 27:
|
---|
643 | (p16) cmp.ltu.unc p50,p48=t0,a1
|
---|
644 | (p16) nop.i 0 };;
|
---|
645 | .pred.rel "mutex",p40,p42
|
---|
646 | .pred.rel "mutex",p48,p50
|
---|
647 | { .mfi; (p16) nop.m 0 // 28:
|
---|
648 | (p16) xma.hu ahi[7]=ai7,bj[7],ahi[6] // ap[7]*b[i]
|
---|
649 | (p40) add a2=a2,n2 } // (p16) a2+=n2
|
---|
650 | { .mfi; (p42) add a2=a2,n2,1
|
---|
651 | (p16) xma.lu alo[7]=ai7,bj[7],ahi[6]
|
---|
652 | (p16) nop.i 0 };;
|
---|
653 | { .mii; (p16) getf.sig a6=alo[6] // 29:
|
---|
654 | (p48) add t[6]=t[6],a2 // (p16) t[6]+=a2
|
---|
655 | (p50) add t[6]=t[6],a2,1 };;
|
---|
656 | { .mfi; (p16) nop.m 0 // 30:
|
---|
657 | (p16) xma.hu nhi[5]=ni5,mj[0],nhi[4] // np[5]*m0
|
---|
658 | (p40) cmp.ltu p41,p39=a2,n2 }
|
---|
659 | { .mfi; (p42) cmp.leu p41,p39=a2,n2
|
---|
660 | (p16) xma.lu nlo[5]=ni5,mj[0],nhi[4]
|
---|
661 | (p16) nop.i 0 };;
|
---|
662 | { .mfi; (p16) getf.sig n4=nlo[4] // 31:
|
---|
663 | (p16) nop.f 0
|
---|
664 | (p48) cmp.ltu p49,p47=t[6],a2 }
|
---|
665 | { .mfb; (p50) cmp.leu p49,p47=t[6],a2
|
---|
666 | (p16) nop.f 0
|
---|
667 | br.ctop.sptk.many .Louter_8_ctop };;
|
---|
668 | .Louter_8_cend:
|
---|
669 | |
---|
670 |
|
---|
671 | // above loop has to execute one more time, without (p16), which is
|
---|
672 | // replaced with merged move of np[8] to GPR bank
|
---|
673 | .pred.rel "mutex",p40,p42
|
---|
674 | .pred.rel "mutex",p48,p50
|
---|
675 | { .mmi; (p0) getf.sig n1=ni0 // 0:
|
---|
676 | (p40) add a3=a3,n3 // (p17) a3+=n3
|
---|
677 | (p42) add a3=a3,n3,1 };;
|
---|
678 | { .mii; (p17) getf.sig a7=alo[8] // 1:
|
---|
679 | (p48) add t[6]=t[6],a3 // (p17) t[6]+=a3
|
---|
680 | (p50) add t[6]=t[6],a3,1 };;
|
---|
681 | { .mfi; (p17) getf.sig a8=ahi[8] // 2:
|
---|
682 | (p17) xma.hu nhi[7]=ni6,mj[1],nhi[6] // np[6]*m0
|
---|
683 | (p40) cmp.ltu p43,p41=a3,n3 }
|
---|
684 | { .mfi; (p42) cmp.leu p43,p41=a3,n3
|
---|
685 | (p17) xma.lu nlo[7]=ni6,mj[1],nhi[6]
|
---|
686 | (p0) nop.i 0 };;
|
---|
687 | { .mii; (p17) getf.sig n5=nlo[6] // 3:
|
---|
688 | (p48) cmp.ltu p51,p49=t[6],a3
|
---|
689 | (p50) cmp.leu p51,p49=t[6],a3 };;
|
---|
690 | .pred.rel "mutex",p41,p43
|
---|
691 | .pred.rel "mutex",p49,p51
|
---|
692 | { .mmi; (p0) getf.sig n2=ni1 // 4:
|
---|
693 | (p41) add a4=a4,n4 // (p17) a4+=n4
|
---|
694 | (p43) add a4=a4,n4,1 };;
|
---|
695 | { .mfi; (p49) add t[5]=t[5],a4 // 5: (p17) t[5]+=a4
|
---|
696 | (p0) nop.f 0
|
---|
697 | (p51) add t[5]=t[5],a4,1 };;
|
---|
698 | { .mfi; (p0) getf.sig n3=ni2 // 6:
|
---|
699 | (p17) xma.hu nhi[8]=ni7,mj[1],nhi[7] // np[7]*m0
|
---|
700 | (p41) cmp.ltu p42,p40=a4,n4 }
|
---|
701 | { .mfi; (p43) cmp.leu p42,p40=a4,n4
|
---|
702 | (p17) xma.lu nlo[8]=ni7,mj[1],nhi[7]
|
---|
703 | (p0) nop.i 0 };;
|
---|
704 | { .mii; (p17) getf.sig n6=nlo[7] // 7:
|
---|
705 | (p49) cmp.ltu p50,p48=t[5],a4
|
---|
706 | (p51) cmp.leu p50,p48=t[5],a4 };;
|
---|
707 | .pred.rel "mutex",p40,p42
|
---|
708 | .pred.rel "mutex",p48,p50
|
---|
709 | { .mii; (p0) getf.sig n4=ni3 // 8:
|
---|
710 | (p40) add a5=a5,n5 // (p17) a5+=n5
|
---|
711 | (p42) add a5=a5,n5,1 };;
|
---|
712 | { .mii; (p0) nop.m 0 // 9:
|
---|
713 | (p48) add t[4]=t[4],a5 // p(17) t[4]+=a5
|
---|
714 | (p50) add t[4]=t[4],a5,1 };;
|
---|
715 | { .mii; (p0) nop.m 0 // 10:
|
---|
716 | (p40) cmp.ltu p43,p41=a5,n5
|
---|
717 | (p42) cmp.leu p43,p41=a5,n5 };;
|
---|
718 | { .mii; (p17) getf.sig n7=nlo[8] // 11:
|
---|
719 | (p48) cmp.ltu p51,p49=t[4],a5
|
---|
720 | (p50) cmp.leu p51,p49=t[4],a5 };;
|
---|
721 | .pred.rel "mutex",p41,p43
|
---|
722 | .pred.rel "mutex",p49,p51
|
---|
723 | { .mii; (p17) getf.sig n8=nhi[8] // 12:
|
---|
724 | (p41) add a6=a6,n6 // (p17) a6+=n6
|
---|
725 | (p43) add a6=a6,n6,1 };;
|
---|
726 | { .mii; (p0) getf.sig n5=ni4 // 13:
|
---|
727 | (p49) add t[3]=t[3],a6 // (p17) t[3]+=a6
|
---|
728 | (p51) add t[3]=t[3],a6,1 };;
|
---|
729 | { .mii; (p0) nop.m 0 // 14:
|
---|
730 | (p41) cmp.ltu p42,p40=a6,n6
|
---|
731 | (p43) cmp.leu p42,p40=a6,n6 };;
|
---|
732 | { .mii; (p0) getf.sig n6=ni5 // 15:
|
---|
733 | (p49) cmp.ltu p50,p48=t[3],a6
|
---|
734 | (p51) cmp.leu p50,p48=t[3],a6 };;
|
---|
735 | .pred.rel "mutex",p40,p42
|
---|
736 | .pred.rel "mutex",p48,p50
|
---|
737 | { .mii; (p0) nop.m 0 // 16:
|
---|
738 | (p40) add a7=a7,n7 // (p17) a7+=n7
|
---|
739 | (p42) add a7=a7,n7,1 };;
|
---|
740 | { .mii; (p0) nop.m 0 // 17:
|
---|
741 | (p48) add t[2]=t[2],a7 // (p17) t[2]+=a7
|
---|
742 | (p50) add t[2]=t[2],a7,1 };;
|
---|
743 | { .mii; (p0) nop.m 0 // 18:
|
---|
744 | (p40) cmp.ltu p43,p41=a7,n7
|
---|
745 | (p42) cmp.leu p43,p41=a7,n7 };;
|
---|
746 | { .mii; (p0) getf.sig n7=ni6 // 19:
|
---|
747 | (p48) cmp.ltu p51,p49=t[2],a7
|
---|
748 | (p50) cmp.leu p51,p49=t[2],a7 };;
|
---|
749 | .pred.rel "mutex",p41,p43
|
---|
750 | .pred.rel "mutex",p49,p51
|
---|
751 | { .mii; (p0) nop.m 0 // 20:
|
---|
752 | (p41) add a8=a8,n8 // (p17) a8+=n8
|
---|
753 | (p43) add a8=a8,n8,1 };;
|
---|
754 | { .mmi; (p0) nop.m 0 // 21:
|
---|
755 | (p49) add t[1]=t[1],a8 // (p17) t[1]+=a8
|
---|
756 | (p51) add t[1]=t[1],a8,1 }
|
---|
757 | { .mmi; (p17) mov t[0]=r0
|
---|
758 | (p41) cmp.ltu p42,p40=a8,n8
|
---|
759 | (p43) cmp.leu p42,p40=a8,n8 };;
|
---|
760 | { .mmi; (p0) getf.sig n8=ni7 // 22:
|
---|
761 | (p49) cmp.ltu p50,p48=t[1],a8
|
---|
762 | (p51) cmp.leu p50,p48=t[1],a8 }
|
---|
763 | { .mmi; (p42) add t[0]=t[0],r0,1
|
---|
764 | (p0) add r16=-7*16,prevsp
|
---|
765 | (p0) add r17=-6*16,prevsp };;
|
---|
766 | |
---|
767 |
|
---|
768 | // subtract np[8] from carrybit|tmp[8]
|
---|
769 | // carrybit|tmp[8] layout upon exit from above loop is:
|
---|
770 | // t[0]|t[1]|t[2]|t[3]|t[4]|t[5]|t[6]|t[7]|t0 (least significant)
|
---|
771 | { .mmi; (p50)add t[0]=t[0],r0,1
|
---|
772 | add r18=-5*16,prevsp
|
---|
773 | sub n1=t0,n1 };;
|
---|
774 | { .mmi; cmp.gtu p34,p32=n1,t0;;
|
---|
775 | .pred.rel "mutex",p32,p34
|
---|
776 | (p32)sub n2=t[7],n2
|
---|
777 | (p34)sub n2=t[7],n2,1 };;
|
---|
778 | { .mii; (p32)cmp.gtu p35,p33=n2,t[7]
|
---|
779 | (p34)cmp.geu p35,p33=n2,t[7];;
|
---|
780 | .pred.rel "mutex",p33,p35
|
---|
781 | (p33)sub n3=t[6],n3 }
|
---|
782 | { .mmi; (p35)sub n3=t[6],n3,1;;
|
---|
783 | (p33)cmp.gtu p34,p32=n3,t[6]
|
---|
784 | (p35)cmp.geu p34,p32=n3,t[6] };;
|
---|
785 | .pred.rel "mutex",p32,p34
|
---|
786 | { .mii; (p32)sub n4=t[5],n4
|
---|
787 | (p34)sub n4=t[5],n4,1;;
|
---|
788 | (p32)cmp.gtu p35,p33=n4,t[5] }
|
---|
789 | { .mmi; (p34)cmp.geu p35,p33=n4,t[5];;
|
---|
790 | .pred.rel "mutex",p33,p35
|
---|
791 | (p33)sub n5=t[4],n5
|
---|
792 | (p35)sub n5=t[4],n5,1 };;
|
---|
793 | { .mii; (p33)cmp.gtu p34,p32=n5,t[4]
|
---|
794 | (p35)cmp.geu p34,p32=n5,t[4];;
|
---|
795 | .pred.rel "mutex",p32,p34
|
---|
796 | (p32)sub n6=t[3],n6 }
|
---|
797 | { .mmi; (p34)sub n6=t[3],n6,1;;
|
---|
798 | (p32)cmp.gtu p35,p33=n6,t[3]
|
---|
799 | (p34)cmp.geu p35,p33=n6,t[3] };;
|
---|
800 | .pred.rel "mutex",p33,p35
|
---|
801 | { .mii; (p33)sub n7=t[2],n7
|
---|
802 | (p35)sub n7=t[2],n7,1;;
|
---|
803 | (p33)cmp.gtu p34,p32=n7,t[2] }
|
---|
804 | { .mmi; (p35)cmp.geu p34,p32=n7,t[2];;
|
---|
805 | .pred.rel "mutex",p32,p34
|
---|
806 | (p32)sub n8=t[1],n8
|
---|
807 | (p34)sub n8=t[1],n8,1 };;
|
---|
808 | { .mii; (p32)cmp.gtu p35,p33=n8,t[1]
|
---|
809 | (p34)cmp.geu p35,p33=n8,t[1];;
|
---|
810 | .pred.rel "mutex",p33,p35
|
---|
811 | (p33)sub a8=t[0],r0 }
|
---|
812 | { .mmi; (p35)sub a8=t[0],r0,1;;
|
---|
813 | (p33)cmp.gtu p34,p32=a8,t[0]
|
---|
814 | (p35)cmp.geu p34,p32=a8,t[0] };;
|
---|
815 | |
---|
816 |
|
---|
817 | // save the result, either tmp[num] or tmp[num]-np[num]
|
---|
818 | .pred.rel "mutex",p32,p34
|
---|
819 | { .mmi; (p32)st8 [rptr]=n1,8
|
---|
820 | (p34)st8 [rptr]=t0,8
|
---|
821 | add r19=-4*16,prevsp};;
|
---|
822 | { .mmb; (p32)st8 [rptr]=n2,8
|
---|
823 | (p34)st8 [rptr]=t[7],8
|
---|
824 | (p5)br.cond.dpnt.few .Ldone };;
|
---|
825 | { .mmb; (p32)st8 [rptr]=n3,8
|
---|
826 | (p34)st8 [rptr]=t[6],8
|
---|
827 | (p7)br.cond.dpnt.few .Ldone };;
|
---|
828 | { .mmb; (p32)st8 [rptr]=n4,8
|
---|
829 | (p34)st8 [rptr]=t[5],8
|
---|
830 | (p9)br.cond.dpnt.few .Ldone };;
|
---|
831 | { .mmb; (p32)st8 [rptr]=n5,8
|
---|
832 | (p34)st8 [rptr]=t[4],8
|
---|
833 | (p11)br.cond.dpnt.few .Ldone };;
|
---|
834 | { .mmb; (p32)st8 [rptr]=n6,8
|
---|
835 | (p34)st8 [rptr]=t[3],8
|
---|
836 | (p13)br.cond.dpnt.few .Ldone };;
|
---|
837 | { .mmb; (p32)st8 [rptr]=n7,8
|
---|
838 | (p34)st8 [rptr]=t[2],8
|
---|
839 | (p15)br.cond.dpnt.few .Ldone };;
|
---|
840 | { .mmb; (p32)st8 [rptr]=n8,8
|
---|
841 | (p34)st8 [rptr]=t[1],8
|
---|
842 | nop.b 0 };;
|
---|
843 | .Ldone: // epilogue
|
---|
844 | { .mmi; ldf.fill f16=[r16],64
|
---|
845 | ldf.fill f17=[r17],64
|
---|
846 | nop.i 0 }
|
---|
847 | { .mmi; ldf.fill f18=[r18],64
|
---|
848 | ldf.fill f19=[r19],64
|
---|
849 | mov pr=prevpr,0x1ffff };;
|
---|
850 | { .mmi; ldf.fill f20=[r16]
|
---|
851 | ldf.fill f21=[r17]
|
---|
852 | mov ar.lc=prevlc }
|
---|
853 | { .mmi; ldf.fill f22=[r18]
|
---|
854 | ldf.fill f23=[r19]
|
---|
855 | mov ret0=1 } // signal "handled"
|
---|
856 | { .mib; rum 1<<5
|
---|
857 | .restore sp
|
---|
858 | mov sp=prevsp
|
---|
859 | br.ret.sptk.many b0 };;
|
---|
860 | .endp bn_mul_mont_8#
|
---|
861 |
|
---|
862 | .type copyright#,\@object
|
---|
863 | copyright:
|
---|
864 | stringz "Montgomery multiplication for IA-64, CRYPTOGAMS by <appro\@openssl.org>"
|
---|
865 | ___
|
---|
866 |
|
---|
867 | open STDOUT,">$output" if $output;
|
---|
868 | print $code;
|
---|
869 | close STDOUT or die "error closing STDOUT: $!";
|
---|