VirtualBox

source: vbox/trunk/src/libs/openssl-3.0.1/crypto/bn/asm/ia64-mont.pl@ 94082

Last change on this file since 94082 was 94082, checked in by vboxsync, 3 years ago

libs/openssl-3.0.1: started applying and adjusting our OpenSSL changes to 3.0.1. bugref:10128

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette