xref: /freebsd/crypto/openssl/crypto/ec/asm/x25519-ppc64.pl (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1e71b7053SJung-uk Kim#! /usr/bin/env perl
217f01e99SJung-uk Kim# Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
3e71b7053SJung-uk Kim#
4*b077aed3SPierre Pronchery# Licensed under the Apache License 2.0 (the "License").  You may not use
5e71b7053SJung-uk Kim# this file except in compliance with the License.  You can obtain a copy
6e71b7053SJung-uk Kim# in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim# https://www.openssl.org/source/license.html
8e71b7053SJung-uk Kim#
9e71b7053SJung-uk Kim# ====================================================================
10e71b7053SJung-uk Kim# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
11e71b7053SJung-uk Kim# project. The module is, however, dual licensed under OpenSSL and
12e71b7053SJung-uk Kim# CRYPTOGAMS licenses depending on where you obtain it. For further
13e71b7053SJung-uk Kim# details see http://www.openssl.org/~appro/cryptogams/.
14e71b7053SJung-uk Kim# ====================================================================
15e71b7053SJung-uk Kim#
16e71b7053SJung-uk Kim# X25519 lower-level primitives for PPC64.
17e71b7053SJung-uk Kim#
18e71b7053SJung-uk Kim# July 2018.
19e71b7053SJung-uk Kim#
20e71b7053SJung-uk Kim# Base 2^64 is faster than base 2^51 on pre-POWER8, most notably ~15%
21e71b7053SJung-uk Kim# faster on PPC970/G5. POWER8 on the other hand seems to trip on own
22e71b7053SJung-uk Kim# shoelaces when handling longer carry chains. As base 2^51 has just
23e71b7053SJung-uk Kim# single-carry pairs, it's 25% faster than base 2^64. Since PPC970 is
24e71b7053SJung-uk Kim# pretty old, base 2^64 implementation is not engaged. Comparison to
25e71b7053SJung-uk Kim# compiler-generated code is complicated by the fact that not all
26e71b7053SJung-uk Kim# compilers support 128-bit integers. When compiler doesn't, like xlc,
27e71b7053SJung-uk Kim# this module delivers more than 2x improvement, and when it does,
28e71b7053SJung-uk Kim# from 12% to 30% improvement was measured...
29e71b7053SJung-uk Kim
30*b077aed3SPierre Pronchery# $output is the last argument if it looks like a file (it has an extension)
31*b077aed3SPierre Pronchery# $flavour is the first argument if it doesn't look like a file
32*b077aed3SPierre Pronchery$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
33*b077aed3SPierre Pronchery$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
34e71b7053SJung-uk Kim
35e71b7053SJung-uk Kim$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
36e71b7053SJung-uk Kim( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
37e71b7053SJung-uk Kim( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
38e71b7053SJung-uk Kimdie "can't locate ppc-xlate.pl";
39e71b7053SJung-uk Kim
40*b077aed3SPierre Proncheryopen OUT,"| \"$^X\" $xlate $flavour \"$output\""
41*b077aed3SPierre Pronchery    or die "can't call $xlate: $!";
42e71b7053SJung-uk Kim*STDOUT=*OUT;
43e71b7053SJung-uk Kim
44e71b7053SJung-uk Kimmy $sp = "r1";
45e71b7053SJung-uk Kimmy ($rp,$ap,$bp) = map("r$_",3..5);
46e71b7053SJung-uk Kim
47e71b7053SJung-uk Kim####################################################### base 2^64
48e71b7053SJung-uk Kimif (0) {
49e71b7053SJung-uk Kimmy ($bi,$a0,$a1,$a2,$a3,$t0,$t1, $t2,$t3,
50e71b7053SJung-uk Kim    $acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7) =
51e71b7053SJung-uk Kim    map("r$_",(6..12,22..31));
52e71b7053SJung-uk Kimmy $zero = "r0";
53e71b7053SJung-uk Kimmy $FRAME = 16*8;
54e71b7053SJung-uk Kim
55e71b7053SJung-uk Kim$code.=<<___;
56e71b7053SJung-uk Kim.text
57e71b7053SJung-uk Kim
58e71b7053SJung-uk Kim.globl	x25519_fe64_mul
59e71b7053SJung-uk Kim.type	x25519_fe64_mul,\@function
60e71b7053SJung-uk Kim.align	5
61e71b7053SJung-uk Kimx25519_fe64_mul:
62e71b7053SJung-uk Kim	stdu	$sp,-$FRAME($sp)
63e71b7053SJung-uk Kim	std	r22,`$FRAME-8*10`($sp)
64e71b7053SJung-uk Kim	std	r23,`$FRAME-8*9`($sp)
65e71b7053SJung-uk Kim	std	r24,`$FRAME-8*8`($sp)
66e71b7053SJung-uk Kim	std	r25,`$FRAME-8*7`($sp)
67e71b7053SJung-uk Kim	std	r26,`$FRAME-8*6`($sp)
68e71b7053SJung-uk Kim	std	r27,`$FRAME-8*5`($sp)
69e71b7053SJung-uk Kim	std	r28,`$FRAME-8*4`($sp)
70e71b7053SJung-uk Kim	std	r29,`$FRAME-8*3`($sp)
71e71b7053SJung-uk Kim	std	r30,`$FRAME-8*2`($sp)
72e71b7053SJung-uk Kim	std	r31,`$FRAME-8*1`($sp)
73e71b7053SJung-uk Kim
74e71b7053SJung-uk Kim	ld	$bi,0($bp)
75e71b7053SJung-uk Kim	ld	$a0,0($ap)
76e71b7053SJung-uk Kim	xor	$zero,$zero,$zero
77e71b7053SJung-uk Kim	ld	$a1,8($ap)
78e71b7053SJung-uk Kim	ld	$a2,16($ap)
79e71b7053SJung-uk Kim	ld	$a3,24($ap)
80e71b7053SJung-uk Kim
81e71b7053SJung-uk Kim	mulld	$acc0,$a0,$bi		# a[0]*b[0]
82e71b7053SJung-uk Kim	mulhdu	$t0,$a0,$bi
83e71b7053SJung-uk Kim	mulld	$acc1,$a1,$bi		# a[1]*b[0]
84e71b7053SJung-uk Kim	mulhdu	$t1,$a1,$bi
85e71b7053SJung-uk Kim	mulld	$acc2,$a2,$bi		# a[2]*b[0]
86e71b7053SJung-uk Kim	mulhdu	$t2,$a2,$bi
87e71b7053SJung-uk Kim	mulld	$acc3,$a3,$bi		# a[3]*b[0]
88e71b7053SJung-uk Kim	mulhdu	$t3,$a3,$bi
89e71b7053SJung-uk Kim___
90e71b7053SJung-uk Kimfor(my @acc=($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7),
91e71b7053SJung-uk Kim    my $i=1; $i<4; shift(@acc), $i++) {
92e71b7053SJung-uk Kimmy $acc4 = $i==1? $zero : @acc[4];
93e71b7053SJung-uk Kim
94e71b7053SJung-uk Kim$code.=<<___;
95e71b7053SJung-uk Kim	ld	$bi,`8*$i`($bp)
96e71b7053SJung-uk Kim	addc	@acc[1],@acc[1],$t0	# accumulate high parts
97e71b7053SJung-uk Kim	mulld	$t0,$a0,$bi
98e71b7053SJung-uk Kim	adde	@acc[2],@acc[2],$t1
99e71b7053SJung-uk Kim	mulld	$t1,$a1,$bi
100e71b7053SJung-uk Kim	adde	@acc[3],@acc[3],$t2
101e71b7053SJung-uk Kim	mulld	$t2,$a2,$bi
102e71b7053SJung-uk Kim	adde	@acc[4],$acc4,$t3
103e71b7053SJung-uk Kim	mulld	$t3,$a3,$bi
104e71b7053SJung-uk Kim	addc	@acc[1],@acc[1],$t0	# accumulate low parts
105e71b7053SJung-uk Kim	mulhdu	$t0,$a0,$bi
106e71b7053SJung-uk Kim	adde	@acc[2],@acc[2],$t1
107e71b7053SJung-uk Kim	mulhdu	$t1,$a1,$bi
108e71b7053SJung-uk Kim	adde	@acc[3],@acc[3],$t2
109e71b7053SJung-uk Kim	mulhdu	$t2,$a2,$bi
110e71b7053SJung-uk Kim	adde	@acc[4],@acc[4],$t3
111e71b7053SJung-uk Kim	mulhdu	$t3,$a3,$bi
112e71b7053SJung-uk Kim	adde	@acc[5],$zero,$zero
113e71b7053SJung-uk Kim___
114e71b7053SJung-uk Kim}
115e71b7053SJung-uk Kim$code.=<<___;
116e71b7053SJung-uk Kim	li	$bi,38
117e71b7053SJung-uk Kim	addc	$acc4,$acc4,$t0
118e71b7053SJung-uk Kim	mulld	$t0,$acc4,$bi
119e71b7053SJung-uk Kim	adde	$acc5,$acc5,$t1
120e71b7053SJung-uk Kim	mulld	$t1,$acc5,$bi
121e71b7053SJung-uk Kim	adde	$acc6,$acc6,$t2
122e71b7053SJung-uk Kim	mulld	$t2,$acc6,$bi
123e71b7053SJung-uk Kim	adde	$acc7,$acc7,$t3
124e71b7053SJung-uk Kim	mulld	$t3,$acc7,$bi
125e71b7053SJung-uk Kim
126e71b7053SJung-uk Kim	addc	$acc0,$acc0,$t0
127e71b7053SJung-uk Kim	mulhdu	$t0,$acc4,$bi
128e71b7053SJung-uk Kim	adde	$acc1,$acc1,$t1
129e71b7053SJung-uk Kim	mulhdu	$t1,$acc5,$bi
130e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t2
131e71b7053SJung-uk Kim	mulhdu	$t2,$acc6,$bi
132e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t3
133e71b7053SJung-uk Kim	mulhdu	$t3,$acc7,$bi
134e71b7053SJung-uk Kim	adde	$acc4,$zero,$zero
135e71b7053SJung-uk Kim
136e71b7053SJung-uk Kim	addc	$acc1,$acc1,$t0
137e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t1
138e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t2
139e71b7053SJung-uk Kim	adde	$acc4,$acc4,$t3
140e71b7053SJung-uk Kim
141e71b7053SJung-uk Kim	mulld	$acc4,$acc4,$bi
142e71b7053SJung-uk Kim
143e71b7053SJung-uk Kim	addc	$acc0,$acc0,$acc4
144e71b7053SJung-uk Kim	addze	$acc1,$acc1
145e71b7053SJung-uk Kim	addze	$acc2,$acc2
146e71b7053SJung-uk Kim	addze	$acc3,$acc3
147e71b7053SJung-uk Kim
148e71b7053SJung-uk Kim	subfe	$acc4,$acc4,$acc4	# carry -> ~mask
149e71b7053SJung-uk Kim	std	$acc1,8($rp)
150e71b7053SJung-uk Kim	andc	$acc4,$bi,$acc4
151e71b7053SJung-uk Kim	std	$acc2,16($rp)
152e71b7053SJung-uk Kim	add	$acc0,$acc0,$acc4
153e71b7053SJung-uk Kim	std	$acc3,24($rp)
154e71b7053SJung-uk Kim	std	$acc0,0($rp)
155e71b7053SJung-uk Kim
156e71b7053SJung-uk Kim	ld	r22,`$FRAME-8*10`($sp)
157e71b7053SJung-uk Kim	ld	r23,`$FRAME-8*9`($sp)
158e71b7053SJung-uk Kim	ld	r24,`$FRAME-8*8`($sp)
159e71b7053SJung-uk Kim	ld	r25,`$FRAME-8*7`($sp)
160e71b7053SJung-uk Kim	ld	r26,`$FRAME-8*6`($sp)
161e71b7053SJung-uk Kim	ld	r27,`$FRAME-8*5`($sp)
162e71b7053SJung-uk Kim	ld	r28,`$FRAME-8*4`($sp)
163e71b7053SJung-uk Kim	ld	r29,`$FRAME-8*3`($sp)
164e71b7053SJung-uk Kim	ld	r30,`$FRAME-8*2`($sp)
165e71b7053SJung-uk Kim	ld	r31,`$FRAME-8*1`($sp)
166e71b7053SJung-uk Kim	addi	$sp,$sp,$FRAME
167e71b7053SJung-uk Kim	blr
168e71b7053SJung-uk Kim	.long	0
169e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,10,3,0
170e71b7053SJung-uk Kim	.long	0
171e71b7053SJung-uk Kim.size	x25519_fe64_mul,.-x25519_fe64_mul
172e71b7053SJung-uk Kim
173e71b7053SJung-uk Kim.globl	x25519_fe64_sqr
174e71b7053SJung-uk Kim.type	x25519_fe64_sqr,\@function
175e71b7053SJung-uk Kim.align	5
176e71b7053SJung-uk Kimx25519_fe64_sqr:
177e71b7053SJung-uk Kim	stdu	$sp,-$FRAME($sp)
178e71b7053SJung-uk Kim	std	r22,`$FRAME-8*10`($sp)
179e71b7053SJung-uk Kim	std	r23,`$FRAME-8*9`($sp)
180e71b7053SJung-uk Kim	std	r24,`$FRAME-8*8`($sp)
181e71b7053SJung-uk Kim	std	r25,`$FRAME-8*7`($sp)
182e71b7053SJung-uk Kim	std	r26,`$FRAME-8*6`($sp)
183e71b7053SJung-uk Kim	std	r27,`$FRAME-8*5`($sp)
184e71b7053SJung-uk Kim	std	r28,`$FRAME-8*4`($sp)
185e71b7053SJung-uk Kim	std	r29,`$FRAME-8*3`($sp)
186e71b7053SJung-uk Kim	std	r30,`$FRAME-8*2`($sp)
187e71b7053SJung-uk Kim	std	r31,`$FRAME-8*1`($sp)
188e71b7053SJung-uk Kim
189e71b7053SJung-uk Kim	ld	$a0,0($ap)
190e71b7053SJung-uk Kim	xor	$zero,$zero,$zero
191e71b7053SJung-uk Kim	ld	$a1,8($ap)
192e71b7053SJung-uk Kim	ld	$a2,16($ap)
193e71b7053SJung-uk Kim	ld	$a3,24($ap)
194e71b7053SJung-uk Kim
195e71b7053SJung-uk Kim	################################
196e71b7053SJung-uk Kim	#  |  |  |  |  |  |a1*a0|  |
197e71b7053SJung-uk Kim	#  |  |  |  |  |a2*a0|  |  |
198e71b7053SJung-uk Kim	#  |  |a3*a2|a3*a0|  |  |  |
199e71b7053SJung-uk Kim	#  |  |  |  |a2*a1|  |  |  |
200e71b7053SJung-uk Kim	#  |  |  |a3*a1|  |  |  |  |
201e71b7053SJung-uk Kim	# *|  |  |  |  |  |  |  | 2|
202e71b7053SJung-uk Kim	# +|a3*a3|a2*a2|a1*a1|a0*a0|
203e71b7053SJung-uk Kim	#  |--+--+--+--+--+--+--+--|
204e71b7053SJung-uk Kim	#  |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is $accx, i.e. follow $accx
205e71b7053SJung-uk Kim	#
206e71b7053SJung-uk Kim	#  "can't overflow" below mark carrying into high part of
207e71b7053SJung-uk Kim	#  multiplication result, which can't overflow, because it
208e71b7053SJung-uk Kim	#  can never be all ones.
209e71b7053SJung-uk Kim
210e71b7053SJung-uk Kim	mulld	$acc1,$a1,$a0		# a[1]*a[0]
211e71b7053SJung-uk Kim	mulhdu	$t1,$a1,$a0
212e71b7053SJung-uk Kim	mulld	$acc2,$a2,$a0		# a[2]*a[0]
213e71b7053SJung-uk Kim	mulhdu	$t2,$a2,$a0
214e71b7053SJung-uk Kim	mulld	$acc3,$a3,$a0		# a[3]*a[0]
215e71b7053SJung-uk Kim	mulhdu	$acc4,$a3,$a0
216e71b7053SJung-uk Kim
217e71b7053SJung-uk Kim	addc	$acc2,$acc2,$t1		# accumulate high parts of multiplication
218e71b7053SJung-uk Kim	 mulld	$t0,$a2,$a1		# a[2]*a[1]
219e71b7053SJung-uk Kim	 mulhdu	$t1,$a2,$a1
220e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t2
221e71b7053SJung-uk Kim	 mulld	$t2,$a3,$a1		# a[3]*a[1]
222e71b7053SJung-uk Kim	 mulhdu	$t3,$a3,$a1
223e71b7053SJung-uk Kim	addze	$acc4,$acc4		# can't overflow
224e71b7053SJung-uk Kim
225e71b7053SJung-uk Kim	mulld	$acc5,$a3,$a2		# a[3]*a[2]
226e71b7053SJung-uk Kim	mulhdu	$acc6,$a3,$a2
227e71b7053SJung-uk Kim
228e71b7053SJung-uk Kim	addc	$t1,$t1,$t2		# accumulate high parts of multiplication
229e71b7053SJung-uk Kim	 mulld	$acc0,$a0,$a0		# a[0]*a[0]
230e71b7053SJung-uk Kim	addze	$t2,$t3			# can't overflow
231e71b7053SJung-uk Kim
232e71b7053SJung-uk Kim	addc	$acc3,$acc3,$t0		# accumulate low parts of multiplication
233e71b7053SJung-uk Kim	 mulhdu	$a0,$a0,$a0
234e71b7053SJung-uk Kim	adde	$acc4,$acc4,$t1
235e71b7053SJung-uk Kim	 mulld	$t1,$a1,$a1		# a[1]*a[1]
236e71b7053SJung-uk Kim	adde	$acc5,$acc5,$t2
237e71b7053SJung-uk Kim	 mulhdu	$a1,$a1,$a1
238e71b7053SJung-uk Kim	addze	$acc6,$acc6		# can't overflow
239e71b7053SJung-uk Kim
240e71b7053SJung-uk Kim	addc	$acc1,$acc1,$acc1	# acc[1-6]*=2
241e71b7053SJung-uk Kim	 mulld	$t2,$a2,$a2		# a[2]*a[2]
242e71b7053SJung-uk Kim	adde	$acc2,$acc2,$acc2
243e71b7053SJung-uk Kim	 mulhdu	$a2,$a2,$a2
244e71b7053SJung-uk Kim	adde	$acc3,$acc3,$acc3
245e71b7053SJung-uk Kim	 mulld	$t3,$a3,$a3		# a[3]*a[3]
246e71b7053SJung-uk Kim	adde	$acc4,$acc4,$acc4
247e71b7053SJung-uk Kim	 mulhdu	$a3,$a3,$a3
248e71b7053SJung-uk Kim	adde	$acc5,$acc5,$acc5
249e71b7053SJung-uk Kim	adde	$acc6,$acc6,$acc6
250e71b7053SJung-uk Kim	addze	$acc7,$zero
251e71b7053SJung-uk Kim
252e71b7053SJung-uk Kim	addc	$acc1,$acc1,$a0		# +a[i]*a[i]
253e71b7053SJung-uk Kim	 li	$bi,38
254e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t1
255e71b7053SJung-uk Kim	adde	$acc3,$acc3,$a1
256e71b7053SJung-uk Kim	adde	$acc4,$acc4,$t2
257e71b7053SJung-uk Kim	adde	$acc5,$acc5,$a2
258e71b7053SJung-uk Kim	adde	$acc6,$acc6,$t3
259e71b7053SJung-uk Kim	adde	$acc7,$acc7,$a3
260e71b7053SJung-uk Kim
261e71b7053SJung-uk Kim	mulld	$t0,$acc4,$bi
262e71b7053SJung-uk Kim	mulld	$t1,$acc5,$bi
263e71b7053SJung-uk Kim	mulld	$t2,$acc6,$bi
264e71b7053SJung-uk Kim	mulld	$t3,$acc7,$bi
265e71b7053SJung-uk Kim
266e71b7053SJung-uk Kim	addc	$acc0,$acc0,$t0
267e71b7053SJung-uk Kim	mulhdu	$t0,$acc4,$bi
268e71b7053SJung-uk Kim	adde	$acc1,$acc1,$t1
269e71b7053SJung-uk Kim	mulhdu	$t1,$acc5,$bi
270e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t2
271e71b7053SJung-uk Kim	mulhdu	$t2,$acc6,$bi
272e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t3
273e71b7053SJung-uk Kim	mulhdu	$t3,$acc7,$bi
274e71b7053SJung-uk Kim	addze	$acc4,$zero
275e71b7053SJung-uk Kim
276e71b7053SJung-uk Kim	addc	$acc1,$acc1,$t0
277e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t1
278e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t2
279e71b7053SJung-uk Kim	adde	$acc4,$acc4,$t3
280e71b7053SJung-uk Kim
281e71b7053SJung-uk Kim	mulld	$acc4,$acc4,$bi
282e71b7053SJung-uk Kim
283e71b7053SJung-uk Kim	addc	$acc0,$acc0,$acc4
284e71b7053SJung-uk Kim	addze	$acc1,$acc1
285e71b7053SJung-uk Kim	addze	$acc2,$acc2
286e71b7053SJung-uk Kim	addze	$acc3,$acc3
287e71b7053SJung-uk Kim
288e71b7053SJung-uk Kim	subfe	$acc4,$acc4,$acc4	# carry -> ~mask
289e71b7053SJung-uk Kim	std	$acc1,8($rp)
290e71b7053SJung-uk Kim	andc	$acc4,$bi,$acc4
291e71b7053SJung-uk Kim	std	$acc2,16($rp)
292e71b7053SJung-uk Kim	add	$acc0,$acc0,$acc4
293e71b7053SJung-uk Kim	std	$acc3,24($rp)
294e71b7053SJung-uk Kim	std	$acc0,0($rp)
295e71b7053SJung-uk Kim
296e71b7053SJung-uk Kim	ld	r22,`$FRAME-8*10`($sp)
297e71b7053SJung-uk Kim	ld	r23,`$FRAME-8*9`($sp)
298e71b7053SJung-uk Kim	ld	r24,`$FRAME-8*8`($sp)
299e71b7053SJung-uk Kim	ld	r25,`$FRAME-8*7`($sp)
300e71b7053SJung-uk Kim	ld	r26,`$FRAME-8*6`($sp)
301e71b7053SJung-uk Kim	ld	r27,`$FRAME-8*5`($sp)
302e71b7053SJung-uk Kim	ld	r28,`$FRAME-8*4`($sp)
303e71b7053SJung-uk Kim	ld	r29,`$FRAME-8*3`($sp)
304e71b7053SJung-uk Kim	ld	r30,`$FRAME-8*2`($sp)
305e71b7053SJung-uk Kim	ld	r31,`$FRAME-8*1`($sp)
306e71b7053SJung-uk Kim	addi	$sp,$sp,$FRAME
307e71b7053SJung-uk Kim	blr
308e71b7053SJung-uk Kim	.long	0
309e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,10,2,0
310e71b7053SJung-uk Kim	.long	0
311e71b7053SJung-uk Kim.size	x25519_fe64_sqr,.-x25519_fe64_sqr
312e71b7053SJung-uk Kim
313e71b7053SJung-uk Kim.globl	x25519_fe64_mul121666
314e71b7053SJung-uk Kim.type	x25519_fe64_mul121666,\@function
315e71b7053SJung-uk Kim.align	5
316e71b7053SJung-uk Kimx25519_fe64_mul121666:
317e71b7053SJung-uk Kim	lis	$bi,`65536>>16`
318e71b7053SJung-uk Kim	ori	$bi,$bi,`121666-65536`
319e71b7053SJung-uk Kim
320e71b7053SJung-uk Kim	ld	$t0,0($ap)
321e71b7053SJung-uk Kim	ld	$t1,8($ap)
322e71b7053SJung-uk Kim	ld	$bp,16($ap)
323e71b7053SJung-uk Kim	ld	$ap,24($ap)
324e71b7053SJung-uk Kim
325e71b7053SJung-uk Kim	mulld	$a0,$t0,$bi
326e71b7053SJung-uk Kim	mulhdu	$t0,$t0,$bi
327e71b7053SJung-uk Kim	mulld	$a1,$t1,$bi
328e71b7053SJung-uk Kim	mulhdu	$t1,$t1,$bi
329e71b7053SJung-uk Kim	mulld	$a2,$bp,$bi
330e71b7053SJung-uk Kim	mulhdu	$bp,$bp,$bi
331e71b7053SJung-uk Kim	mulld	$a3,$ap,$bi
332e71b7053SJung-uk Kim	mulhdu	$ap,$ap,$bi
333e71b7053SJung-uk Kim
334e71b7053SJung-uk Kim	addc	$a1,$a1,$t0
335e71b7053SJung-uk Kim	adde	$a2,$a2,$t1
336e71b7053SJung-uk Kim	adde	$a3,$a3,$bp
337e71b7053SJung-uk Kim	addze	$ap,    $ap
338e71b7053SJung-uk Kim
339e71b7053SJung-uk Kim	mulli	$ap,$ap,38
340e71b7053SJung-uk Kim
341e71b7053SJung-uk Kim	addc	$a0,$a0,$ap
342e71b7053SJung-uk Kim	addze	$a1,$a1
343e71b7053SJung-uk Kim	addze	$a2,$a2
344e71b7053SJung-uk Kim	addze	$a3,$a3
345e71b7053SJung-uk Kim
346e71b7053SJung-uk Kim	subfe	$t1,$t1,$t1		# carry -> ~mask
347e71b7053SJung-uk Kim	std	$a1,8($rp)
348e71b7053SJung-uk Kim	andc	$t0,$t0,$t1
349e71b7053SJung-uk Kim	std	$a2,16($rp)
350e71b7053SJung-uk Kim	add	$a0,$a0,$t0
351e71b7053SJung-uk Kim	std	$a3,24($rp)
352e71b7053SJung-uk Kim	std	$a0,0($rp)
353e71b7053SJung-uk Kim
354e71b7053SJung-uk Kim	blr
355e71b7053SJung-uk Kim	.long	0
356e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,2,0
357e71b7053SJung-uk Kim	.long	0
358e71b7053SJung-uk Kim.size	x25519_fe64_mul121666,.-x25519_fe64_mul121666
359e71b7053SJung-uk Kim
360e71b7053SJung-uk Kim.globl	x25519_fe64_add
361e71b7053SJung-uk Kim.type	x25519_fe64_add,\@function
362e71b7053SJung-uk Kim.align	5
363e71b7053SJung-uk Kimx25519_fe64_add:
364e71b7053SJung-uk Kim	ld	$a0,0($ap)
365e71b7053SJung-uk Kim	ld	$t0,0($bp)
366e71b7053SJung-uk Kim	ld	$a1,8($ap)
367e71b7053SJung-uk Kim	ld	$t1,8($bp)
368e71b7053SJung-uk Kim	ld	$a2,16($ap)
369e71b7053SJung-uk Kim	ld	$bi,16($bp)
370e71b7053SJung-uk Kim	ld	$a3,24($ap)
371e71b7053SJung-uk Kim	ld	$bp,24($bp)
372e71b7053SJung-uk Kim
373e71b7053SJung-uk Kim	addc	$a0,$a0,$t0
374e71b7053SJung-uk Kim	adde	$a1,$a1,$t1
375e71b7053SJung-uk Kim	adde	$a2,$a2,$bi
376e71b7053SJung-uk Kim	adde	$a3,$a3,$bp
377e71b7053SJung-uk Kim
378e71b7053SJung-uk Kim	li	$t0,38
379e71b7053SJung-uk Kim	subfe	$t1,$t1,$t1		# carry -> ~mask
380e71b7053SJung-uk Kim	andc	$t1,$t0,$t1
381e71b7053SJung-uk Kim
382e71b7053SJung-uk Kim	addc	$a0,$a0,$t1
383e71b7053SJung-uk Kim	addze	$a1,$a1
384e71b7053SJung-uk Kim	addze	$a2,$a2
385e71b7053SJung-uk Kim	addze	$a3,$a3
386e71b7053SJung-uk Kim
387e71b7053SJung-uk Kim	subfe	$t1,$t1,$t1		# carry -> ~mask
388e71b7053SJung-uk Kim	std	$a1,8($rp)
389e71b7053SJung-uk Kim	andc	$t0,$t0,$t1
390e71b7053SJung-uk Kim	std	$a2,16($rp)
391e71b7053SJung-uk Kim	add	$a0,$a0,$t0
392e71b7053SJung-uk Kim	std	$a3,24($rp)
393e71b7053SJung-uk Kim	std	$a0,0($rp)
394e71b7053SJung-uk Kim
395e71b7053SJung-uk Kim	blr
396e71b7053SJung-uk Kim	.long	0
397e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,3,0
398e71b7053SJung-uk Kim	.long	0
399e71b7053SJung-uk Kim.size	x25519_fe64_add,.-x25519_fe64_add
400e71b7053SJung-uk Kim
401e71b7053SJung-uk Kim.globl	x25519_fe64_sub
402e71b7053SJung-uk Kim.type	x25519_fe64_sub,\@function
403e71b7053SJung-uk Kim.align	5
404e71b7053SJung-uk Kimx25519_fe64_sub:
405e71b7053SJung-uk Kim	ld	$a0,0($ap)
406e71b7053SJung-uk Kim	ld	$t0,0($bp)
407e71b7053SJung-uk Kim	ld	$a1,8($ap)
408e71b7053SJung-uk Kim	ld	$t1,8($bp)
409e71b7053SJung-uk Kim	ld	$a2,16($ap)
410e71b7053SJung-uk Kim	ld	$bi,16($bp)
411e71b7053SJung-uk Kim	ld	$a3,24($ap)
412e71b7053SJung-uk Kim	ld	$bp,24($bp)
413e71b7053SJung-uk Kim
414e71b7053SJung-uk Kim	subfc	$a0,$t0,$a0
415e71b7053SJung-uk Kim	subfe	$a1,$t1,$a1
416e71b7053SJung-uk Kim	subfe	$a2,$bi,$a2
417e71b7053SJung-uk Kim	subfe	$a3,$bp,$a3
418e71b7053SJung-uk Kim
419e71b7053SJung-uk Kim	li	$t0,38
420e71b7053SJung-uk Kim	subfe	$t1,$t1,$t1		# borrow -> mask
421e71b7053SJung-uk Kim	xor	$zero,$zero,$zero
422e71b7053SJung-uk Kim	and	$t1,$t0,$t1
423e71b7053SJung-uk Kim
424e71b7053SJung-uk Kim	subfc	$a0,$t1,$a0
425e71b7053SJung-uk Kim	subfe	$a1,$zero,$a1
426e71b7053SJung-uk Kim	subfe	$a2,$zero,$a2
427e71b7053SJung-uk Kim	subfe	$a3,$zero,$a3
428e71b7053SJung-uk Kim
429e71b7053SJung-uk Kim	subfe	$t1,$t1,$t1		# borrow -> mask
430e71b7053SJung-uk Kim	std	$a1,8($rp)
431e71b7053SJung-uk Kim	and	$t0,$t0,$t1
432e71b7053SJung-uk Kim	std	$a2,16($rp)
433e71b7053SJung-uk Kim	subf	$a0,$t0,$a0
434e71b7053SJung-uk Kim	std	$a3,24($rp)
435e71b7053SJung-uk Kim	std	$a0,0($rp)
436e71b7053SJung-uk Kim
437e71b7053SJung-uk Kim	blr
438e71b7053SJung-uk Kim	.long	0
439e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,3,0
440e71b7053SJung-uk Kim	.long	0
441e71b7053SJung-uk Kim.size	x25519_fe64_sub,.-x25519_fe64_sub
442e71b7053SJung-uk Kim
443e71b7053SJung-uk Kim.globl	x25519_fe64_tobytes
444e71b7053SJung-uk Kim.type	x25519_fe64_tobytes,\@function
445e71b7053SJung-uk Kim.align	5
446e71b7053SJung-uk Kimx25519_fe64_tobytes:
447e71b7053SJung-uk Kim	ld	$a3,24($ap)
448e71b7053SJung-uk Kim	ld	$a0,0($ap)
449e71b7053SJung-uk Kim	ld	$a1,8($ap)
450e71b7053SJung-uk Kim	ld	$a2,16($ap)
451e71b7053SJung-uk Kim
452e71b7053SJung-uk Kim	sradi	$t0,$a3,63		# most significant bit -> mask
453e71b7053SJung-uk Kim	li	$t1,19
454e71b7053SJung-uk Kim	and	$t0,$t0,$t1
455e71b7053SJung-uk Kim	sldi	$a3,$a3,1
456e71b7053SJung-uk Kim	add	$t0,$t0,$t1		# compare to modulus in the same go
457da327cd2SJung-uk Kim	srdi	$a3,$a3,1		# most significant bit cleared
458e71b7053SJung-uk Kim
459e71b7053SJung-uk Kim	addc	$a0,$a0,$t0
460e71b7053SJung-uk Kim	addze	$a1,$a1
461e71b7053SJung-uk Kim	addze	$a2,$a2
462e71b7053SJung-uk Kim	addze	$a3,$a3
463e71b7053SJung-uk Kim
464e71b7053SJung-uk Kim	xor	$zero,$zero,$zero
465e71b7053SJung-uk Kim	sradi	$t0,$a3,63		# most significant bit -> mask
466e71b7053SJung-uk Kim	sldi	$a3,$a3,1
467e71b7053SJung-uk Kim	andc	$t0,$t1,$t0
468da327cd2SJung-uk Kim	srdi	$a3,$a3,1		# most significant bit cleared
469e71b7053SJung-uk Kim
470e71b7053SJung-uk Kim	subi	$rp,$rp,1
471e71b7053SJung-uk Kim	subfc	$a0,$t0,$a0
472e71b7053SJung-uk Kim	subfe	$a1,$zero,$a1
473e71b7053SJung-uk Kim	subfe	$a2,$zero,$a2
474e71b7053SJung-uk Kim	subfe	$a3,$zero,$a3
475e71b7053SJung-uk Kim
476e71b7053SJung-uk Kim___
477e71b7053SJung-uk Kimfor (my @a=($a0,$a1,$a2,$a3), my $i=0; $i<4; shift(@a), $i++) {
478e71b7053SJung-uk Kim$code.=<<___;
479e71b7053SJung-uk Kim	srdi	$t0,@a[0],8
480e71b7053SJung-uk Kim	stbu	@a[0],1($rp)
481e71b7053SJung-uk Kim	srdi	@a[0],@a[0],16
482e71b7053SJung-uk Kim	stbu	$t0,1($rp)
483e71b7053SJung-uk Kim	srdi	$t0,@a[0],8
484e71b7053SJung-uk Kim	stbu	@a[0],1($rp)
485e71b7053SJung-uk Kim	srdi	@a[0],@a[0],16
486e71b7053SJung-uk Kim	stbu	$t0,1($rp)
487e71b7053SJung-uk Kim	srdi	$t0,@a[0],8
488e71b7053SJung-uk Kim	stbu	@a[0],1($rp)
489e71b7053SJung-uk Kim	srdi	@a[0],@a[0],16
490e71b7053SJung-uk Kim	stbu	$t0,1($rp)
491e71b7053SJung-uk Kim	srdi	$t0,@a[0],8
492e71b7053SJung-uk Kim	stbu	@a[0],1($rp)
493e71b7053SJung-uk Kim	stbu	$t0,1($rp)
494e71b7053SJung-uk Kim___
495e71b7053SJung-uk Kim}
496e71b7053SJung-uk Kim$code.=<<___;
497e71b7053SJung-uk Kim	blr
498e71b7053SJung-uk Kim	.long	0
499e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,2,0
500e71b7053SJung-uk Kim	.long	0
501e71b7053SJung-uk Kim.size	x25519_fe64_tobytes,.-x25519_fe64_tobytes
502e71b7053SJung-uk Kim___
503e71b7053SJung-uk Kim}
504e71b7053SJung-uk Kim####################################################### base 2^51
505e71b7053SJung-uk Kim{
506e71b7053SJung-uk Kimmy ($bi,$a0,$a1,$a2,$a3,$a4,$t0, $t1,
507e71b7053SJung-uk Kim    $h0lo,$h0hi,$h1lo,$h1hi,$h2lo,$h2hi,$h3lo,$h3hi,$h4lo,$h4hi) =
508e71b7053SJung-uk Kim    map("r$_",(6..12,21..31));
509e71b7053SJung-uk Kimmy $mask = "r0";
510e71b7053SJung-uk Kimmy $FRAME = 18*8;
511e71b7053SJung-uk Kim
512e71b7053SJung-uk Kim$code.=<<___;
513e71b7053SJung-uk Kim.text
514e71b7053SJung-uk Kim
515e71b7053SJung-uk Kim.globl	x25519_fe51_mul
516e71b7053SJung-uk Kim.type	x25519_fe51_mul,\@function
517e71b7053SJung-uk Kim.align	5
518e71b7053SJung-uk Kimx25519_fe51_mul:
519e71b7053SJung-uk Kim	stdu	$sp,-$FRAME($sp)
520e71b7053SJung-uk Kim	std	r21,`$FRAME-8*11`($sp)
521e71b7053SJung-uk Kim	std	r22,`$FRAME-8*10`($sp)
522e71b7053SJung-uk Kim	std	r23,`$FRAME-8*9`($sp)
523e71b7053SJung-uk Kim	std	r24,`$FRAME-8*8`($sp)
524e71b7053SJung-uk Kim	std	r25,`$FRAME-8*7`($sp)
525e71b7053SJung-uk Kim	std	r26,`$FRAME-8*6`($sp)
526e71b7053SJung-uk Kim	std	r27,`$FRAME-8*5`($sp)
527e71b7053SJung-uk Kim	std	r28,`$FRAME-8*4`($sp)
528e71b7053SJung-uk Kim	std	r29,`$FRAME-8*3`($sp)
529e71b7053SJung-uk Kim	std	r30,`$FRAME-8*2`($sp)
530e71b7053SJung-uk Kim	std	r31,`$FRAME-8*1`($sp)
531e71b7053SJung-uk Kim
532e71b7053SJung-uk Kim	ld	$bi,0($bp)
533e71b7053SJung-uk Kim	ld	$a0,0($ap)
534e71b7053SJung-uk Kim	ld	$a1,8($ap)
535e71b7053SJung-uk Kim	ld	$a2,16($ap)
536e71b7053SJung-uk Kim	ld	$a3,24($ap)
537e71b7053SJung-uk Kim	ld	$a4,32($ap)
538e71b7053SJung-uk Kim
539e71b7053SJung-uk Kim	mulld	$h0lo,$a0,$bi		# a[0]*b[0]
540e71b7053SJung-uk Kim	mulhdu	$h0hi,$a0,$bi
541e71b7053SJung-uk Kim
542e71b7053SJung-uk Kim	mulld	$h1lo,$a1,$bi		# a[1]*b[0]
543e71b7053SJung-uk Kim	mulhdu	$h1hi,$a1,$bi
544e71b7053SJung-uk Kim
545e71b7053SJung-uk Kim	 mulld	$h4lo,$a4,$bi		# a[4]*b[0]
546e71b7053SJung-uk Kim	 mulhdu	$h4hi,$a4,$bi
547e71b7053SJung-uk Kim	 ld	$ap,8($bp)
548e71b7053SJung-uk Kim	 mulli	$a4,$a4,19
549e71b7053SJung-uk Kim
550e71b7053SJung-uk Kim	mulld	$h2lo,$a2,$bi		# a[2]*b[0]
551e71b7053SJung-uk Kim	mulhdu	$h2hi,$a2,$bi
552e71b7053SJung-uk Kim
553e71b7053SJung-uk Kim	mulld	$h3lo,$a3,$bi		# a[3]*b[0]
554e71b7053SJung-uk Kim	mulhdu	$h3hi,$a3,$bi
555e71b7053SJung-uk Kim___
556e71b7053SJung-uk Kimfor(my @a=($a0,$a1,$a2,$a3,$a4),
557e71b7053SJung-uk Kim    my $i=1; $i<4; $i++) {
558e71b7053SJung-uk Kim	($ap,$bi) = ($bi,$ap);
559e71b7053SJung-uk Kim$code.=<<___;
560e71b7053SJung-uk Kim	mulld	$t0,@a[4],$bi
561e71b7053SJung-uk Kim	mulhdu	$t1,@a[4],$bi
562e71b7053SJung-uk Kim	addc	$h0lo,$h0lo,$t0
563e71b7053SJung-uk Kim	adde	$h0hi,$h0hi,$t1
564e71b7053SJung-uk Kim
565e71b7053SJung-uk Kim	mulld	$t0,@a[0],$bi
566e71b7053SJung-uk Kim	mulhdu	$t1,@a[0],$bi
567e71b7053SJung-uk Kim	addc	$h1lo,$h1lo,$t0
568e71b7053SJung-uk Kim	adde	$h1hi,$h1hi,$t1
569e71b7053SJung-uk Kim
570e71b7053SJung-uk Kim	 mulld	$t0,@a[3],$bi
571e71b7053SJung-uk Kim	 mulhdu	$t1,@a[3],$bi
572e71b7053SJung-uk Kim	 ld	$ap,`8*($i+1)`($bp)
573e71b7053SJung-uk Kim	 mulli	@a[3],@a[3],19
574e71b7053SJung-uk Kim	 addc	$h4lo,$h4lo,$t0
575e71b7053SJung-uk Kim	 adde	$h4hi,$h4hi,$t1
576e71b7053SJung-uk Kim
577e71b7053SJung-uk Kim	mulld	$t0,@a[1],$bi
578e71b7053SJung-uk Kim	mulhdu	$t1,@a[1],$bi
579e71b7053SJung-uk Kim	addc	$h2lo,$h2lo,$t0
580e71b7053SJung-uk Kim	adde	$h2hi,$h2hi,$t1
581e71b7053SJung-uk Kim
582e71b7053SJung-uk Kim	mulld	$t0,@a[2],$bi
583e71b7053SJung-uk Kim	mulhdu	$t1,@a[2],$bi
584e71b7053SJung-uk Kim	addc	$h3lo,$h3lo,$t0
585e71b7053SJung-uk Kim	adde	$h3hi,$h3hi,$t1
586e71b7053SJung-uk Kim___
587e71b7053SJung-uk Kim	unshift(@a,pop(@a));
588e71b7053SJung-uk Kim}
589e71b7053SJung-uk Kim	($ap,$bi) = ($bi,$ap);
590e71b7053SJung-uk Kim$code.=<<___;
591e71b7053SJung-uk Kim	mulld	$t0,$a1,$bi
592e71b7053SJung-uk Kim	mulhdu	$t1,$a1,$bi
593e71b7053SJung-uk Kim	addc	$h0lo,$h0lo,$t0
594e71b7053SJung-uk Kim	adde	$h0hi,$h0hi,$t1
595e71b7053SJung-uk Kim
596e71b7053SJung-uk Kim	mulld	$t0,$a2,$bi
597e71b7053SJung-uk Kim	mulhdu	$t1,$a2,$bi
598e71b7053SJung-uk Kim	addc	$h1lo,$h1lo,$t0
599e71b7053SJung-uk Kim	adde	$h1hi,$h1hi,$t1
600e71b7053SJung-uk Kim
601e71b7053SJung-uk Kim	mulld	$t0,$a3,$bi
602e71b7053SJung-uk Kim	mulhdu	$t1,$a3,$bi
603e71b7053SJung-uk Kim	addc	$h2lo,$h2lo,$t0
604e71b7053SJung-uk Kim	adde	$h2hi,$h2hi,$t1
605e71b7053SJung-uk Kim
606e71b7053SJung-uk Kim	mulld	$t0,$a4,$bi
607e71b7053SJung-uk Kim	mulhdu	$t1,$a4,$bi
608e71b7053SJung-uk Kim	addc	$h3lo,$h3lo,$t0
609e71b7053SJung-uk Kim	adde	$h3hi,$h3hi,$t1
610e71b7053SJung-uk Kim
611e71b7053SJung-uk Kim	mulld	$t0,$a0,$bi
612e71b7053SJung-uk Kim	mulhdu	$t1,$a0,$bi
613e71b7053SJung-uk Kim	addc	$h4lo,$h4lo,$t0
614e71b7053SJung-uk Kim	adde	$h4hi,$h4hi,$t1
615e71b7053SJung-uk Kim
616e71b7053SJung-uk Kim.Lfe51_reduce:
617e71b7053SJung-uk Kim	li	$mask,-1
618e71b7053SJung-uk Kim	srdi	$mask,$mask,13		# 0x7ffffffffffff
619e71b7053SJung-uk Kim
620e71b7053SJung-uk Kim	srdi	$t0,$h2lo,51
621e71b7053SJung-uk Kim	and	$a2,$h2lo,$mask
622e71b7053SJung-uk Kim	insrdi	$t0,$h2hi,51,0		# h2>>51
623e71b7053SJung-uk Kim	 srdi	$t1,$h0lo,51
624e71b7053SJung-uk Kim	 and	$a0,$h0lo,$mask
625e71b7053SJung-uk Kim	 insrdi	$t1,$h0hi,51,0		# h0>>51
626e71b7053SJung-uk Kim	addc	$h3lo,$h3lo,$t0
627e71b7053SJung-uk Kim	addze	$h3hi,$h3hi
628e71b7053SJung-uk Kim	 addc	$h1lo,$h1lo,$t1
629e71b7053SJung-uk Kim	 addze	$h1hi,$h1hi
630e71b7053SJung-uk Kim
631e71b7053SJung-uk Kim	srdi	$t0,$h3lo,51
632e71b7053SJung-uk Kim	and	$a3,$h3lo,$mask
633e71b7053SJung-uk Kim	insrdi	$t0,$h3hi,51,0		# h3>>51
634e71b7053SJung-uk Kim	 srdi	$t1,$h1lo,51
635e71b7053SJung-uk Kim	 and	$a1,$h1lo,$mask
636e71b7053SJung-uk Kim	 insrdi	$t1,$h1hi,51,0		# h1>>51
637e71b7053SJung-uk Kim	addc	$h4lo,$h4lo,$t0
638e71b7053SJung-uk Kim	addze	$h4hi,$h4hi
639e71b7053SJung-uk Kim	 add	$a2,$a2,$t1
640e71b7053SJung-uk Kim
641e71b7053SJung-uk Kim	srdi	$t0,$h4lo,51
642e71b7053SJung-uk Kim	and	$a4,$h4lo,$mask
643e71b7053SJung-uk Kim	insrdi	$t0,$h4hi,51,0
644e71b7053SJung-uk Kim	mulli	$t0,$t0,19		# (h4 >> 51) * 19
645e71b7053SJung-uk Kim
646e71b7053SJung-uk Kim	add	$a0,$a0,$t0
647e71b7053SJung-uk Kim
648e71b7053SJung-uk Kim	srdi	$t1,$a2,51
649e71b7053SJung-uk Kim	and	$a2,$a2,$mask
650e71b7053SJung-uk Kim	add	$a3,$a3,$t1
651e71b7053SJung-uk Kim
652e71b7053SJung-uk Kim	srdi	$t0,$a0,51
653e71b7053SJung-uk Kim	and	$a0,$a0,$mask
654e71b7053SJung-uk Kim	add	$a1,$a1,$t0
655e71b7053SJung-uk Kim
656e71b7053SJung-uk Kim	std	$a2,16($rp)
657e71b7053SJung-uk Kim	std	$a3,24($rp)
658e71b7053SJung-uk Kim	std	$a4,32($rp)
659e71b7053SJung-uk Kim	std	$a0,0($rp)
660e71b7053SJung-uk Kim	std	$a1,8($rp)
661e71b7053SJung-uk Kim
662e71b7053SJung-uk Kim	ld	r21,`$FRAME-8*11`($sp)
663e71b7053SJung-uk Kim	ld	r22,`$FRAME-8*10`($sp)
664e71b7053SJung-uk Kim	ld	r23,`$FRAME-8*9`($sp)
665e71b7053SJung-uk Kim	ld	r24,`$FRAME-8*8`($sp)
666e71b7053SJung-uk Kim	ld	r25,`$FRAME-8*7`($sp)
667e71b7053SJung-uk Kim	ld	r26,`$FRAME-8*6`($sp)
668e71b7053SJung-uk Kim	ld	r27,`$FRAME-8*5`($sp)
669e71b7053SJung-uk Kim	ld	r28,`$FRAME-8*4`($sp)
670e71b7053SJung-uk Kim	ld	r29,`$FRAME-8*3`($sp)
671e71b7053SJung-uk Kim	ld	r30,`$FRAME-8*2`($sp)
672e71b7053SJung-uk Kim	ld	r31,`$FRAME-8*1`($sp)
673e71b7053SJung-uk Kim	addi	$sp,$sp,$FRAME
674e71b7053SJung-uk Kim	blr
675e71b7053SJung-uk Kim	.long	0
676e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,11,3,0
677e71b7053SJung-uk Kim	.long	0
678e71b7053SJung-uk Kim.size	x25519_fe51_mul,.-x25519_fe51_mul
679e71b7053SJung-uk Kim___
680e71b7053SJung-uk Kim{
681e71b7053SJung-uk Kimmy ($a0,$a1,$a2,$a3,$a4,$t0,$t1) = ($a0,$a1,$a2,$a3,$a4,$t0,$t1);
682e71b7053SJung-uk Kim$code.=<<___;
683e71b7053SJung-uk Kim.globl	x25519_fe51_sqr
684e71b7053SJung-uk Kim.type	x25519_fe51_sqr,\@function
685e71b7053SJung-uk Kim.align	5
686e71b7053SJung-uk Kimx25519_fe51_sqr:
687e71b7053SJung-uk Kim	stdu	$sp,-$FRAME($sp)
688e71b7053SJung-uk Kim	std	r21,`$FRAME-8*11`($sp)
689e71b7053SJung-uk Kim	std	r22,`$FRAME-8*10`($sp)
690e71b7053SJung-uk Kim	std	r23,`$FRAME-8*9`($sp)
691e71b7053SJung-uk Kim	std	r24,`$FRAME-8*8`($sp)
692e71b7053SJung-uk Kim	std	r25,`$FRAME-8*7`($sp)
693e71b7053SJung-uk Kim	std	r26,`$FRAME-8*6`($sp)
694e71b7053SJung-uk Kim	std	r27,`$FRAME-8*5`($sp)
695e71b7053SJung-uk Kim	std	r28,`$FRAME-8*4`($sp)
696e71b7053SJung-uk Kim	std	r29,`$FRAME-8*3`($sp)
697e71b7053SJung-uk Kim	std	r30,`$FRAME-8*2`($sp)
698e71b7053SJung-uk Kim	std	r31,`$FRAME-8*1`($sp)
699e71b7053SJung-uk Kim
700e71b7053SJung-uk Kim	ld	$a0,0($ap)
701e71b7053SJung-uk Kim	ld	$a1,8($ap)
702e71b7053SJung-uk Kim	ld	$a2,16($ap)
703e71b7053SJung-uk Kim	ld	$a3,24($ap)
704e71b7053SJung-uk Kim	ld	$a4,32($ap)
705e71b7053SJung-uk Kim
706e71b7053SJung-uk Kim	add	$bi,$a0,$a0		# a[0]*2
707e71b7053SJung-uk Kim	mulli	$t1,$a4,19		# a[4]*19
708e71b7053SJung-uk Kim
709e71b7053SJung-uk Kim	mulld	$h0lo,$a0,$a0
710e71b7053SJung-uk Kim	mulhdu	$h0hi,$a0,$a0
711e71b7053SJung-uk Kim	mulld	$h1lo,$a1,$bi
712e71b7053SJung-uk Kim	mulhdu	$h1hi,$a1,$bi
713e71b7053SJung-uk Kim	mulld	$h2lo,$a2,$bi
714e71b7053SJung-uk Kim	mulhdu	$h2hi,$a2,$bi
715e71b7053SJung-uk Kim	mulld	$h3lo,$a3,$bi
716e71b7053SJung-uk Kim	mulhdu	$h3hi,$a3,$bi
717e71b7053SJung-uk Kim	mulld	$h4lo,$a4,$bi
718e71b7053SJung-uk Kim	mulhdu	$h4hi,$a4,$bi
719e71b7053SJung-uk Kim	add	$bi,$a1,$a1		# a[1]*2
720e71b7053SJung-uk Kim___
721e71b7053SJung-uk Kim	($a4,$t1) = ($t1,$a4);
722e71b7053SJung-uk Kim$code.=<<___;
723e71b7053SJung-uk Kim	mulld	$t0,$t1,$a4
724e71b7053SJung-uk Kim	mulhdu	$t1,$t1,$a4
725e71b7053SJung-uk Kim	addc	$h3lo,$h3lo,$t0
726e71b7053SJung-uk Kim	adde	$h3hi,$h3hi,$t1
727e71b7053SJung-uk Kim
728e71b7053SJung-uk Kim	mulli	$bp,$a3,19		# a[3]*19
729e71b7053SJung-uk Kim
730e71b7053SJung-uk Kim	mulld	$t0,$a1,$a1
731e71b7053SJung-uk Kim	mulhdu	$t1,$a1,$a1
732e71b7053SJung-uk Kim	addc	$h2lo,$h2lo,$t0
733e71b7053SJung-uk Kim	adde	$h2hi,$h2hi,$t1
734e71b7053SJung-uk Kim	mulld	$t0,$a2,$bi
735e71b7053SJung-uk Kim	mulhdu	$t1,$a2,$bi
736e71b7053SJung-uk Kim	addc	$h3lo,$h3lo,$t0
737e71b7053SJung-uk Kim	adde	$h3hi,$h3hi,$t1
738e71b7053SJung-uk Kim	mulld	$t0,$a3,$bi
739e71b7053SJung-uk Kim	mulhdu	$t1,$a3,$bi
740e71b7053SJung-uk Kim	addc	$h4lo,$h4lo,$t0
741e71b7053SJung-uk Kim	adde	$h4hi,$h4hi,$t1
742e71b7053SJung-uk Kim	mulld	$t0,$a4,$bi
743e71b7053SJung-uk Kim	mulhdu	$t1,$a4,$bi
744e71b7053SJung-uk Kim	add	$bi,$a3,$a3		# a[3]*2
745e71b7053SJung-uk Kim	addc	$h0lo,$h0lo,$t0
746e71b7053SJung-uk Kim	adde	$h0hi,$h0hi,$t1
747e71b7053SJung-uk Kim___
748e71b7053SJung-uk Kim	($a3,$t1) = ($bp,$a3);
749e71b7053SJung-uk Kim$code.=<<___;
750e71b7053SJung-uk Kim	mulld	$t0,$t1,$a3
751e71b7053SJung-uk Kim	mulhdu	$t1,$t1,$a3
752e71b7053SJung-uk Kim	addc	$h1lo,$h1lo,$t0
753e71b7053SJung-uk Kim	adde	$h1hi,$h1hi,$t1
754e71b7053SJung-uk Kim	mulld	$t0,$bi,$a4
755e71b7053SJung-uk Kim	mulhdu	$t1,$bi,$a4
756e71b7053SJung-uk Kim	add	$bi,$a2,$a2		# a[2]*2
757e71b7053SJung-uk Kim	addc	$h2lo,$h2lo,$t0
758e71b7053SJung-uk Kim	adde	$h2hi,$h2hi,$t1
759e71b7053SJung-uk Kim
760e71b7053SJung-uk Kim	mulld	$t0,$a2,$a2
761e71b7053SJung-uk Kim	mulhdu	$t1,$a2,$a2
762e71b7053SJung-uk Kim	addc	$h4lo,$h4lo,$t0
763e71b7053SJung-uk Kim	adde	$h4hi,$h4hi,$t1
764e71b7053SJung-uk Kim	mulld	$t0,$a3,$bi
765e71b7053SJung-uk Kim	mulhdu	$t1,$a3,$bi
766e71b7053SJung-uk Kim	addc	$h0lo,$h0lo,$t0
767e71b7053SJung-uk Kim	adde	$h0hi,$h0hi,$t1
768e71b7053SJung-uk Kim	mulld	$t0,$a4,$bi
769e71b7053SJung-uk Kim	mulhdu	$t1,$a4,$bi
770e71b7053SJung-uk Kim	addc	$h1lo,$h1lo,$t0
771e71b7053SJung-uk Kim	adde	$h1hi,$h1hi,$t1
772e71b7053SJung-uk Kim
773e71b7053SJung-uk Kim	b	.Lfe51_reduce
774e71b7053SJung-uk Kim	.long	0
775e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,11,2,0
776e71b7053SJung-uk Kim	.long	0
777e71b7053SJung-uk Kim.size	x25519_fe51_sqr,.-x25519_fe51_sqr
778e71b7053SJung-uk Kim___
779e71b7053SJung-uk Kim}
780e71b7053SJung-uk Kim$code.=<<___;
781e71b7053SJung-uk Kim.globl	x25519_fe51_mul121666
782e71b7053SJung-uk Kim.type	x25519_fe51_mul121666,\@function
783e71b7053SJung-uk Kim.align	5
784e71b7053SJung-uk Kimx25519_fe51_mul121666:
785e71b7053SJung-uk Kim	stdu	$sp,-$FRAME($sp)
786e71b7053SJung-uk Kim	std	r21,`$FRAME-8*11`($sp)
787e71b7053SJung-uk Kim	std	r22,`$FRAME-8*10`($sp)
788e71b7053SJung-uk Kim	std	r23,`$FRAME-8*9`($sp)
789e71b7053SJung-uk Kim	std	r24,`$FRAME-8*8`($sp)
790e71b7053SJung-uk Kim	std	r25,`$FRAME-8*7`($sp)
791e71b7053SJung-uk Kim	std	r26,`$FRAME-8*6`($sp)
792e71b7053SJung-uk Kim	std	r27,`$FRAME-8*5`($sp)
793e71b7053SJung-uk Kim	std	r28,`$FRAME-8*4`($sp)
794e71b7053SJung-uk Kim	std	r29,`$FRAME-8*3`($sp)
795e71b7053SJung-uk Kim	std	r30,`$FRAME-8*2`($sp)
796e71b7053SJung-uk Kim	std	r31,`$FRAME-8*1`($sp)
797e71b7053SJung-uk Kim
798e71b7053SJung-uk Kim	lis	$bi,`65536>>16`
799e71b7053SJung-uk Kim	ori	$bi,$bi,`121666-65536`
800e71b7053SJung-uk Kim	ld	$a0,0($ap)
801e71b7053SJung-uk Kim	ld	$a1,8($ap)
802e71b7053SJung-uk Kim	ld	$a2,16($ap)
803e71b7053SJung-uk Kim	ld	$a3,24($ap)
804e71b7053SJung-uk Kim	ld	$a4,32($ap)
805e71b7053SJung-uk Kim
806e71b7053SJung-uk Kim	mulld	$h0lo,$a0,$bi		# a[0]*121666
807e71b7053SJung-uk Kim	mulhdu	$h0hi,$a0,$bi
808e71b7053SJung-uk Kim	mulld	$h1lo,$a1,$bi		# a[1]*121666
809e71b7053SJung-uk Kim	mulhdu	$h1hi,$a1,$bi
810e71b7053SJung-uk Kim	mulld	$h2lo,$a2,$bi		# a[2]*121666
811e71b7053SJung-uk Kim	mulhdu	$h2hi,$a2,$bi
812e71b7053SJung-uk Kim	mulld	$h3lo,$a3,$bi		# a[3]*121666
813e71b7053SJung-uk Kim	mulhdu	$h3hi,$a3,$bi
814e71b7053SJung-uk Kim	mulld	$h4lo,$a4,$bi		# a[4]*121666
815e71b7053SJung-uk Kim	mulhdu	$h4hi,$a4,$bi
816e71b7053SJung-uk Kim
817e71b7053SJung-uk Kim	b	.Lfe51_reduce
818e71b7053SJung-uk Kim	.long	0
819e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,11,2,0
820e71b7053SJung-uk Kim	.long	0
821e71b7053SJung-uk Kim.size	x25519_fe51_mul121666,.-x25519_fe51_mul121666
822e71b7053SJung-uk Kim___
823e71b7053SJung-uk Kim}
824e71b7053SJung-uk Kim
825e71b7053SJung-uk Kim$code =~ s/\`([^\`]*)\`/eval $1/gem;
826e71b7053SJung-uk Kimprint $code;
82717f01e99SJung-uk Kimclose STDOUT or die "error closing STDOUT: $!";
828