1e71b7053SJung-uk Kim#! /usr/bin/env perl
217f01e99SJung-uk Kim# Copyright 2016-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# ====================================================================
11e71b7053SJung-uk Kim# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
12e71b7053SJung-uk Kim# project. The module is, however, dual licensed under OpenSSL and
13e71b7053SJung-uk Kim# CRYPTOGAMS licenses depending on where you obtain it. For further
14e71b7053SJung-uk Kim# details see http://www.openssl.org/~appro/cryptogams/.
15e71b7053SJung-uk Kim# ====================================================================
16e71b7053SJung-uk Kim#
17e71b7053SJung-uk Kim# ECP_NISTZ256 module for PPC64.
18e71b7053SJung-uk Kim#
19e71b7053SJung-uk Kim# August 2016.
20e71b7053SJung-uk Kim#
21e71b7053SJung-uk Kim# Original ECP_NISTZ256 submission targeting x86_64 is detailed in
22e71b7053SJung-uk Kim# http://eprint.iacr.org/2013/816.
23e71b7053SJung-uk Kim#
24e71b7053SJung-uk Kim#			with/without -DECP_NISTZ256_ASM
25e71b7053SJung-uk Kim# POWER7		+260-530%
26e71b7053SJung-uk Kim# POWER8		+220-340%
27e71b7053SJung-uk Kim
28*b077aed3SPierre Pronchery# $output is the last argument if it looks like a file (it has an extension)
29*b077aed3SPierre Pronchery# $flavour is the first argument if it doesn't look like a file
30*b077aed3SPierre Pronchery$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
31*b077aed3SPierre Pronchery$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
32e71b7053SJung-uk Kim
33e71b7053SJung-uk Kim$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
34e71b7053SJung-uk Kim( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
35e71b7053SJung-uk Kim( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
36e71b7053SJung-uk Kimdie "can't locate ppc-xlate.pl";
37e71b7053SJung-uk Kim
38*b077aed3SPierre Proncheryopen OUT,"| \"$^X\" $xlate $flavour \"$output\""
39*b077aed3SPierre Pronchery    or die "can't call $xlate: $!";
40e71b7053SJung-uk Kim*STDOUT=*OUT;
41e71b7053SJung-uk Kim
42e71b7053SJung-uk Kimmy $sp="r1";
43e71b7053SJung-uk Kim
44e71b7053SJung-uk Kim{
45e71b7053SJung-uk Kimmy ($rp,$ap,$bp,$bi,$acc0,$acc1,$acc2,$acc3,$poly1,$poly3,
46e71b7053SJung-uk Kim    $acc4,$acc5,$a0,$a1,$a2,$a3,$t0,$t1,$t2,$t3) =
47e71b7053SJung-uk Kim    map("r$_",(3..12,22..31));
48e71b7053SJung-uk Kim
49e71b7053SJung-uk Kimmy ($acc6,$acc7)=($bp,$bi);	# used in __ecp_nistz256_sqr_mont
50e71b7053SJung-uk Kim
51e71b7053SJung-uk Kim$code.=<<___;
52e71b7053SJung-uk Kim.machine	"any"
53e71b7053SJung-uk Kim.text
54e71b7053SJung-uk Kim___
55e71b7053SJung-uk Kim########################################################################
56e71b7053SJung-uk Kim# Convert ecp_nistz256_table.c to layout expected by ecp_nistz_gather_w7
57e71b7053SJung-uk Kim#
58e71b7053SJung-uk Kim$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
59e71b7053SJung-uk Kimopen TABLE,"<ecp_nistz256_table.c"		or
60e71b7053SJung-uk Kimopen TABLE,"<${dir}../ecp_nistz256_table.c"	or
61e71b7053SJung-uk Kimdie "failed to open ecp_nistz256_table.c:",$!;
62e71b7053SJung-uk Kim
63e71b7053SJung-uk Kimuse integer;
64e71b7053SJung-uk Kim
65e71b7053SJung-uk Kimforeach(<TABLE>) {
66e71b7053SJung-uk Kim	s/TOBN\(\s*(0x[0-9a-f]+),\s*(0x[0-9a-f]+)\s*\)/push @arr,hex($2),hex($1)/geo;
67e71b7053SJung-uk Kim}
68e71b7053SJung-uk Kimclose TABLE;
69e71b7053SJung-uk Kim
70e71b7053SJung-uk Kim# See ecp_nistz256_table.c for explanation for why it's 64*16*37.
71e71b7053SJung-uk Kim# 64*16*37-1 is because $#arr returns last valid index or @arr, not
72e71b7053SJung-uk Kim# amount of elements.
73e71b7053SJung-uk Kimdie "insane number of elements" if ($#arr != 64*16*37-1);
74e71b7053SJung-uk Kim
75e71b7053SJung-uk Kim$code.=<<___;
76e71b7053SJung-uk Kim.type	ecp_nistz256_precomputed,\@object
77e71b7053SJung-uk Kim.globl	ecp_nistz256_precomputed
78e71b7053SJung-uk Kim.align	12
79e71b7053SJung-uk Kimecp_nistz256_precomputed:
80e71b7053SJung-uk Kim___
81e71b7053SJung-uk Kim########################################################################
82e71b7053SJung-uk Kim# this conversion smashes P256_POINT_AFFINE by individual bytes with
83e71b7053SJung-uk Kim# 64 byte interval, similar to
84e71b7053SJung-uk Kim#	1111222233334444
85e71b7053SJung-uk Kim#	1234123412341234
86e71b7053SJung-uk Kimfor(1..37) {
87e71b7053SJung-uk Kim	@tbl = splice(@arr,0,64*16);
88e71b7053SJung-uk Kim	for($i=0;$i<64;$i++) {
89e71b7053SJung-uk Kim		undef @line;
90e71b7053SJung-uk Kim		for($j=0;$j<64;$j++) {
91e71b7053SJung-uk Kim			push @line,(@tbl[$j*16+$i/4]>>(($i%4)*8))&0xff;
92e71b7053SJung-uk Kim		}
93e71b7053SJung-uk Kim		$code.=".byte\t";
94e71b7053SJung-uk Kim		$code.=join(',',map { sprintf "0x%02x",$_} @line);
95e71b7053SJung-uk Kim		$code.="\n";
96e71b7053SJung-uk Kim	}
97e71b7053SJung-uk Kim}
98e71b7053SJung-uk Kim
99e71b7053SJung-uk Kim$code.=<<___;
100e71b7053SJung-uk Kim.size	ecp_nistz256_precomputed,.-ecp_nistz256_precomputed
101e71b7053SJung-uk Kim.asciz	"ECP_NISTZ256 for PPC64, CRYPTOGAMS by <appro\@openssl.org>"
102e71b7053SJung-uk Kim
103e71b7053SJung-uk Kim# void	ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4],
104e71b7053SJung-uk Kim#					     const BN_ULONG x2[4]);
105e71b7053SJung-uk Kim.globl	ecp_nistz256_mul_mont
106e71b7053SJung-uk Kim.align	5
107e71b7053SJung-uk Kimecp_nistz256_mul_mont:
108e71b7053SJung-uk Kim	stdu	$sp,-128($sp)
109e71b7053SJung-uk Kim	mflr	r0
110e71b7053SJung-uk Kim	std	r22,48($sp)
111e71b7053SJung-uk Kim	std	r23,56($sp)
112e71b7053SJung-uk Kim	std	r24,64($sp)
113e71b7053SJung-uk Kim	std	r25,72($sp)
114e71b7053SJung-uk Kim	std	r26,80($sp)
115e71b7053SJung-uk Kim	std	r27,88($sp)
116e71b7053SJung-uk Kim	std	r28,96($sp)
117e71b7053SJung-uk Kim	std	r29,104($sp)
118e71b7053SJung-uk Kim	std	r30,112($sp)
119e71b7053SJung-uk Kim	std	r31,120($sp)
120e71b7053SJung-uk Kim
121e71b7053SJung-uk Kim	ld	$a0,0($ap)
122e71b7053SJung-uk Kim	ld	$bi,0($bp)
123e71b7053SJung-uk Kim	ld	$a1,8($ap)
124e71b7053SJung-uk Kim	ld	$a2,16($ap)
125e71b7053SJung-uk Kim	ld	$a3,24($ap)
126e71b7053SJung-uk Kim
127e71b7053SJung-uk Kim	li	$poly1,-1
128e71b7053SJung-uk Kim	srdi	$poly1,$poly1,32	# 0x00000000ffffffff
129e71b7053SJung-uk Kim	li	$poly3,1
130e71b7053SJung-uk Kim	orc	$poly3,$poly3,$poly1	# 0xffffffff00000001
131e71b7053SJung-uk Kim
132e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont
133e71b7053SJung-uk Kim
134e71b7053SJung-uk Kim	mtlr	r0
135e71b7053SJung-uk Kim	ld	r22,48($sp)
136e71b7053SJung-uk Kim	ld	r23,56($sp)
137e71b7053SJung-uk Kim	ld	r24,64($sp)
138e71b7053SJung-uk Kim	ld	r25,72($sp)
139e71b7053SJung-uk Kim	ld	r26,80($sp)
140e71b7053SJung-uk Kim	ld	r27,88($sp)
141e71b7053SJung-uk Kim	ld	r28,96($sp)
142e71b7053SJung-uk Kim	ld	r29,104($sp)
143e71b7053SJung-uk Kim	ld	r30,112($sp)
144e71b7053SJung-uk Kim	ld	r31,120($sp)
145e71b7053SJung-uk Kim	addi	$sp,$sp,128
146e71b7053SJung-uk Kim	blr
147e71b7053SJung-uk Kim	.long	0
148e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,10,3,0
149e71b7053SJung-uk Kim	.long	0
150e71b7053SJung-uk Kim.size	ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
151e71b7053SJung-uk Kim
152e71b7053SJung-uk Kim# void	ecp_nistz256_sqr_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
153e71b7053SJung-uk Kim.globl	ecp_nistz256_sqr_mont
154e71b7053SJung-uk Kim.align	4
155e71b7053SJung-uk Kimecp_nistz256_sqr_mont:
156e71b7053SJung-uk Kim	stdu	$sp,-128($sp)
157e71b7053SJung-uk Kim	mflr	r0
158e71b7053SJung-uk Kim	std	r22,48($sp)
159e71b7053SJung-uk Kim	std	r23,56($sp)
160e71b7053SJung-uk Kim	std	r24,64($sp)
161e71b7053SJung-uk Kim	std	r25,72($sp)
162e71b7053SJung-uk Kim	std	r26,80($sp)
163e71b7053SJung-uk Kim	std	r27,88($sp)
164e71b7053SJung-uk Kim	std	r28,96($sp)
165e71b7053SJung-uk Kim	std	r29,104($sp)
166e71b7053SJung-uk Kim	std	r30,112($sp)
167e71b7053SJung-uk Kim	std	r31,120($sp)
168e71b7053SJung-uk Kim
169e71b7053SJung-uk Kim	ld	$a0,0($ap)
170e71b7053SJung-uk Kim	ld	$a1,8($ap)
171e71b7053SJung-uk Kim	ld	$a2,16($ap)
172e71b7053SJung-uk Kim	ld	$a3,24($ap)
173e71b7053SJung-uk Kim
174e71b7053SJung-uk Kim	li	$poly1,-1
175e71b7053SJung-uk Kim	srdi	$poly1,$poly1,32	# 0x00000000ffffffff
176e71b7053SJung-uk Kim	li	$poly3,1
177e71b7053SJung-uk Kim	orc	$poly3,$poly3,$poly1	# 0xffffffff00000001
178e71b7053SJung-uk Kim
179e71b7053SJung-uk Kim	bl	__ecp_nistz256_sqr_mont
180e71b7053SJung-uk Kim
181e71b7053SJung-uk Kim	mtlr	r0
182e71b7053SJung-uk Kim	ld	r22,48($sp)
183e71b7053SJung-uk Kim	ld	r23,56($sp)
184e71b7053SJung-uk Kim	ld	r24,64($sp)
185e71b7053SJung-uk Kim	ld	r25,72($sp)
186e71b7053SJung-uk Kim	ld	r26,80($sp)
187e71b7053SJung-uk Kim	ld	r27,88($sp)
188e71b7053SJung-uk Kim	ld	r28,96($sp)
189e71b7053SJung-uk Kim	ld	r29,104($sp)
190e71b7053SJung-uk Kim	ld	r30,112($sp)
191e71b7053SJung-uk Kim	ld	r31,120($sp)
192e71b7053SJung-uk Kim	addi	$sp,$sp,128
193e71b7053SJung-uk Kim	blr
194e71b7053SJung-uk Kim	.long	0
195e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,10,2,0
196e71b7053SJung-uk Kim	.long	0
197e71b7053SJung-uk Kim.size	ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
198e71b7053SJung-uk Kim
199e71b7053SJung-uk Kim# void	ecp_nistz256_add(BN_ULONG x0[4],const BN_ULONG x1[4],
200e71b7053SJung-uk Kim#					const BN_ULONG x2[4]);
201e71b7053SJung-uk Kim.globl	ecp_nistz256_add
202e71b7053SJung-uk Kim.align	4
203e71b7053SJung-uk Kimecp_nistz256_add:
204e71b7053SJung-uk Kim	stdu	$sp,-128($sp)
205e71b7053SJung-uk Kim	mflr	r0
206e71b7053SJung-uk Kim	std	r28,96($sp)
207e71b7053SJung-uk Kim	std	r29,104($sp)
208e71b7053SJung-uk Kim	std	r30,112($sp)
209e71b7053SJung-uk Kim	std	r31,120($sp)
210e71b7053SJung-uk Kim
211e71b7053SJung-uk Kim	ld	$acc0,0($ap)
212e71b7053SJung-uk Kim	ld	$t0,  0($bp)
213e71b7053SJung-uk Kim	ld	$acc1,8($ap)
214e71b7053SJung-uk Kim	ld	$t1,  8($bp)
215e71b7053SJung-uk Kim	ld	$acc2,16($ap)
216e71b7053SJung-uk Kim	ld	$t2,  16($bp)
217e71b7053SJung-uk Kim	ld	$acc3,24($ap)
218e71b7053SJung-uk Kim	ld	$t3,  24($bp)
219e71b7053SJung-uk Kim
220e71b7053SJung-uk Kim	li	$poly1,-1
221e71b7053SJung-uk Kim	srdi	$poly1,$poly1,32	# 0x00000000ffffffff
222e71b7053SJung-uk Kim	li	$poly3,1
223e71b7053SJung-uk Kim	orc	$poly3,$poly3,$poly1	# 0xffffffff00000001
224e71b7053SJung-uk Kim
225e71b7053SJung-uk Kim	bl	__ecp_nistz256_add
226e71b7053SJung-uk Kim
227e71b7053SJung-uk Kim	mtlr	r0
228e71b7053SJung-uk Kim	ld	r28,96($sp)
229e71b7053SJung-uk Kim	ld	r29,104($sp)
230e71b7053SJung-uk Kim	ld	r30,112($sp)
231e71b7053SJung-uk Kim	ld	r31,120($sp)
232e71b7053SJung-uk Kim	addi	$sp,$sp,128
233e71b7053SJung-uk Kim	blr
234e71b7053SJung-uk Kim	.long	0
235e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,4,3,0
236e71b7053SJung-uk Kim	.long	0
237e71b7053SJung-uk Kim.size	ecp_nistz256_add,.-ecp_nistz256_add
238e71b7053SJung-uk Kim
239e71b7053SJung-uk Kim# void	ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]);
240e71b7053SJung-uk Kim.globl	ecp_nistz256_div_by_2
241e71b7053SJung-uk Kim.align	4
242e71b7053SJung-uk Kimecp_nistz256_div_by_2:
243e71b7053SJung-uk Kim	stdu	$sp,-128($sp)
244e71b7053SJung-uk Kim	mflr	r0
245e71b7053SJung-uk Kim	std	r28,96($sp)
246e71b7053SJung-uk Kim	std	r29,104($sp)
247e71b7053SJung-uk Kim	std	r30,112($sp)
248e71b7053SJung-uk Kim	std	r31,120($sp)
249e71b7053SJung-uk Kim
250e71b7053SJung-uk Kim	ld	$acc0,0($ap)
251e71b7053SJung-uk Kim	ld	$acc1,8($ap)
252e71b7053SJung-uk Kim	ld	$acc2,16($ap)
253e71b7053SJung-uk Kim	ld	$acc3,24($ap)
254e71b7053SJung-uk Kim
255e71b7053SJung-uk Kim	li	$poly1,-1
256e71b7053SJung-uk Kim	srdi	$poly1,$poly1,32	# 0x00000000ffffffff
257e71b7053SJung-uk Kim	li	$poly3,1
258e71b7053SJung-uk Kim	orc	$poly3,$poly3,$poly1	# 0xffffffff00000001
259e71b7053SJung-uk Kim
260e71b7053SJung-uk Kim	bl	__ecp_nistz256_div_by_2
261e71b7053SJung-uk Kim
262e71b7053SJung-uk Kim	mtlr	r0
263e71b7053SJung-uk Kim	ld	r28,96($sp)
264e71b7053SJung-uk Kim	ld	r29,104($sp)
265e71b7053SJung-uk Kim	ld	r30,112($sp)
266e71b7053SJung-uk Kim	ld	r31,120($sp)
267e71b7053SJung-uk Kim	addi	$sp,$sp,128
268e71b7053SJung-uk Kim	blr
269e71b7053SJung-uk Kim	.long	0
270e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,4,2,0
271e71b7053SJung-uk Kim	.long	0
272e71b7053SJung-uk Kim.size	ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2
273e71b7053SJung-uk Kim
274e71b7053SJung-uk Kim# void	ecp_nistz256_mul_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]);
275e71b7053SJung-uk Kim.globl	ecp_nistz256_mul_by_2
276e71b7053SJung-uk Kim.align	4
277e71b7053SJung-uk Kimecp_nistz256_mul_by_2:
278e71b7053SJung-uk Kim	stdu	$sp,-128($sp)
279e71b7053SJung-uk Kim	mflr	r0
280e71b7053SJung-uk Kim	std	r28,96($sp)
281e71b7053SJung-uk Kim	std	r29,104($sp)
282e71b7053SJung-uk Kim	std	r30,112($sp)
283e71b7053SJung-uk Kim	std	r31,120($sp)
284e71b7053SJung-uk Kim
285e71b7053SJung-uk Kim	ld	$acc0,0($ap)
286e71b7053SJung-uk Kim	ld	$acc1,8($ap)
287e71b7053SJung-uk Kim	ld	$acc2,16($ap)
288e71b7053SJung-uk Kim	ld	$acc3,24($ap)
289e71b7053SJung-uk Kim
290e71b7053SJung-uk Kim	mr	$t0,$acc0
291e71b7053SJung-uk Kim	mr	$t1,$acc1
292e71b7053SJung-uk Kim	mr	$t2,$acc2
293e71b7053SJung-uk Kim	mr	$t3,$acc3
294e71b7053SJung-uk Kim
295e71b7053SJung-uk Kim	li	$poly1,-1
296e71b7053SJung-uk Kim	srdi	$poly1,$poly1,32	# 0x00000000ffffffff
297e71b7053SJung-uk Kim	li	$poly3,1
298e71b7053SJung-uk Kim	orc	$poly3,$poly3,$poly1	# 0xffffffff00000001
299e71b7053SJung-uk Kim
300e71b7053SJung-uk Kim	bl	__ecp_nistz256_add	# ret = a+a	// 2*a
301e71b7053SJung-uk Kim
302e71b7053SJung-uk Kim	mtlr	r0
303e71b7053SJung-uk Kim	ld	r28,96($sp)
304e71b7053SJung-uk Kim	ld	r29,104($sp)
305e71b7053SJung-uk Kim	ld	r30,112($sp)
306e71b7053SJung-uk Kim	ld	r31,120($sp)
307e71b7053SJung-uk Kim	addi	$sp,$sp,128
308e71b7053SJung-uk Kim	blr
309e71b7053SJung-uk Kim	.long	0
310e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,4,3,0
311e71b7053SJung-uk Kim	.long	0
312e71b7053SJung-uk Kim.size	ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
313e71b7053SJung-uk Kim
314e71b7053SJung-uk Kim# void	ecp_nistz256_mul_by_3(BN_ULONG x0[4],const BN_ULONG x1[4]);
315e71b7053SJung-uk Kim.globl	ecp_nistz256_mul_by_3
316e71b7053SJung-uk Kim.align	4
317e71b7053SJung-uk Kimecp_nistz256_mul_by_3:
318e71b7053SJung-uk Kim	stdu	$sp,-128($sp)
319e71b7053SJung-uk Kim	mflr	r0
320e71b7053SJung-uk Kim	std	r28,96($sp)
321e71b7053SJung-uk Kim	std	r29,104($sp)
322e71b7053SJung-uk Kim	std	r30,112($sp)
323e71b7053SJung-uk Kim	std	r31,120($sp)
324e71b7053SJung-uk Kim
325e71b7053SJung-uk Kim	ld	$acc0,0($ap)
326e71b7053SJung-uk Kim	ld	$acc1,8($ap)
327e71b7053SJung-uk Kim	ld	$acc2,16($ap)
328e71b7053SJung-uk Kim	ld	$acc3,24($ap)
329e71b7053SJung-uk Kim
330e71b7053SJung-uk Kim	mr	$t0,$acc0
331e71b7053SJung-uk Kim	std	$acc0,64($sp)
332e71b7053SJung-uk Kim	mr	$t1,$acc1
333e71b7053SJung-uk Kim	std	$acc1,72($sp)
334e71b7053SJung-uk Kim	mr	$t2,$acc2
335e71b7053SJung-uk Kim	std	$acc2,80($sp)
336e71b7053SJung-uk Kim	mr	$t3,$acc3
337e71b7053SJung-uk Kim	std	$acc3,88($sp)
338e71b7053SJung-uk Kim
339e71b7053SJung-uk Kim	li	$poly1,-1
340e71b7053SJung-uk Kim	srdi	$poly1,$poly1,32	# 0x00000000ffffffff
341e71b7053SJung-uk Kim	li	$poly3,1
342e71b7053SJung-uk Kim	orc	$poly3,$poly3,$poly1	# 0xffffffff00000001
343e71b7053SJung-uk Kim
344e71b7053SJung-uk Kim	bl	__ecp_nistz256_add	# ret = a+a	// 2*a
345e71b7053SJung-uk Kim
346e71b7053SJung-uk Kim	ld	$t0,64($sp)
347e71b7053SJung-uk Kim	ld	$t1,72($sp)
348e71b7053SJung-uk Kim	ld	$t2,80($sp)
349e71b7053SJung-uk Kim	ld	$t3,88($sp)
350e71b7053SJung-uk Kim
351e71b7053SJung-uk Kim	bl	__ecp_nistz256_add	# ret += a	// 2*a+a=3*a
352e71b7053SJung-uk Kim
353e71b7053SJung-uk Kim	mtlr	r0
354e71b7053SJung-uk Kim	ld	r28,96($sp)
355e71b7053SJung-uk Kim	ld	r29,104($sp)
356e71b7053SJung-uk Kim	ld	r30,112($sp)
357e71b7053SJung-uk Kim	ld	r31,120($sp)
358e71b7053SJung-uk Kim	addi	$sp,$sp,128
359e71b7053SJung-uk Kim	blr
360e71b7053SJung-uk Kim	.long	0
361e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,4,2,0
362e71b7053SJung-uk Kim	.long	0
363e71b7053SJung-uk Kim.size	ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
364e71b7053SJung-uk Kim
365e71b7053SJung-uk Kim# void	ecp_nistz256_sub(BN_ULONG x0[4],const BN_ULONG x1[4],
366e71b7053SJung-uk Kim#				        const BN_ULONG x2[4]);
367e71b7053SJung-uk Kim.globl	ecp_nistz256_sub
368e71b7053SJung-uk Kim.align	4
369e71b7053SJung-uk Kimecp_nistz256_sub:
370e71b7053SJung-uk Kim	stdu	$sp,-128($sp)
371e71b7053SJung-uk Kim	mflr	r0
372e71b7053SJung-uk Kim	std	r28,96($sp)
373e71b7053SJung-uk Kim	std	r29,104($sp)
374e71b7053SJung-uk Kim	std	r30,112($sp)
375e71b7053SJung-uk Kim	std	r31,120($sp)
376e71b7053SJung-uk Kim
377e71b7053SJung-uk Kim	ld	$acc0,0($ap)
378e71b7053SJung-uk Kim	ld	$acc1,8($ap)
379e71b7053SJung-uk Kim	ld	$acc2,16($ap)
380e71b7053SJung-uk Kim	ld	$acc3,24($ap)
381e71b7053SJung-uk Kim
382e71b7053SJung-uk Kim	li	$poly1,-1
383e71b7053SJung-uk Kim	srdi	$poly1,$poly1,32	# 0x00000000ffffffff
384e71b7053SJung-uk Kim	li	$poly3,1
385e71b7053SJung-uk Kim	orc	$poly3,$poly3,$poly1	# 0xffffffff00000001
386e71b7053SJung-uk Kim
387e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_from
388e71b7053SJung-uk Kim
389e71b7053SJung-uk Kim	mtlr	r0
390e71b7053SJung-uk Kim	ld	r28,96($sp)
391e71b7053SJung-uk Kim	ld	r29,104($sp)
392e71b7053SJung-uk Kim	ld	r30,112($sp)
393e71b7053SJung-uk Kim	ld	r31,120($sp)
394e71b7053SJung-uk Kim	addi	$sp,$sp,128
395e71b7053SJung-uk Kim	blr
396e71b7053SJung-uk Kim	.long	0
397e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,4,3,0
398e71b7053SJung-uk Kim	.long	0
399e71b7053SJung-uk Kim.size	ecp_nistz256_sub,.-ecp_nistz256_sub
400e71b7053SJung-uk Kim
401e71b7053SJung-uk Kim# void	ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]);
402e71b7053SJung-uk Kim.globl	ecp_nistz256_neg
403e71b7053SJung-uk Kim.align	4
404e71b7053SJung-uk Kimecp_nistz256_neg:
405e71b7053SJung-uk Kim	stdu	$sp,-128($sp)
406e71b7053SJung-uk Kim	mflr	r0
407e71b7053SJung-uk Kim	std	r28,96($sp)
408e71b7053SJung-uk Kim	std	r29,104($sp)
409e71b7053SJung-uk Kim	std	r30,112($sp)
410e71b7053SJung-uk Kim	std	r31,120($sp)
411e71b7053SJung-uk Kim
412e71b7053SJung-uk Kim	mr	$bp,$ap
413e71b7053SJung-uk Kim	li	$acc0,0
414e71b7053SJung-uk Kim	li	$acc1,0
415e71b7053SJung-uk Kim	li	$acc2,0
416e71b7053SJung-uk Kim	li	$acc3,0
417e71b7053SJung-uk Kim
418e71b7053SJung-uk Kim	li	$poly1,-1
419e71b7053SJung-uk Kim	srdi	$poly1,$poly1,32	# 0x00000000ffffffff
420e71b7053SJung-uk Kim	li	$poly3,1
421e71b7053SJung-uk Kim	orc	$poly3,$poly3,$poly1	# 0xffffffff00000001
422e71b7053SJung-uk Kim
423e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_from
424e71b7053SJung-uk Kim
425e71b7053SJung-uk Kim	mtlr	r0
426e71b7053SJung-uk Kim	ld	r28,96($sp)
427e71b7053SJung-uk Kim	ld	r29,104($sp)
428e71b7053SJung-uk Kim	ld	r30,112($sp)
429e71b7053SJung-uk Kim	ld	r31,120($sp)
430e71b7053SJung-uk Kim	addi	$sp,$sp,128
431e71b7053SJung-uk Kim	blr
432e71b7053SJung-uk Kim	.long	0
433e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,4,2,0
434e71b7053SJung-uk Kim	.long	0
435e71b7053SJung-uk Kim.size	ecp_nistz256_neg,.-ecp_nistz256_neg
436e71b7053SJung-uk Kim
437e71b7053SJung-uk Kim# note that __ecp_nistz256_mul_mont expects a[0-3] input pre-loaded
438e71b7053SJung-uk Kim# to $a0-$a3 and b[0] - to $bi
439e71b7053SJung-uk Kim.type	__ecp_nistz256_mul_mont,\@function
440e71b7053SJung-uk Kim.align	4
441e71b7053SJung-uk Kim__ecp_nistz256_mul_mont:
442e71b7053SJung-uk Kim	mulld	$acc0,$a0,$bi		# a[0]*b[0]
443e71b7053SJung-uk Kim	mulhdu	$t0,$a0,$bi
444e71b7053SJung-uk Kim
445e71b7053SJung-uk Kim	mulld	$acc1,$a1,$bi		# a[1]*b[0]
446e71b7053SJung-uk Kim	mulhdu	$t1,$a1,$bi
447e71b7053SJung-uk Kim
448e71b7053SJung-uk Kim	mulld	$acc2,$a2,$bi		# a[2]*b[0]
449e71b7053SJung-uk Kim	mulhdu	$t2,$a2,$bi
450e71b7053SJung-uk Kim
451e71b7053SJung-uk Kim	mulld	$acc3,$a3,$bi		# a[3]*b[0]
452e71b7053SJung-uk Kim	mulhdu	$t3,$a3,$bi
453e71b7053SJung-uk Kim	ld	$bi,8($bp)		# b[1]
454e71b7053SJung-uk Kim
455e71b7053SJung-uk Kim	addc	$acc1,$acc1,$t0		# accumulate high parts of multiplication
456e71b7053SJung-uk Kim	 sldi	$t0,$acc0,32
457e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t1
458e71b7053SJung-uk Kim	 srdi	$t1,$acc0,32
459e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t2
460e71b7053SJung-uk Kim	addze	$acc4,$t3
461e71b7053SJung-uk Kim	li	$acc5,0
462e71b7053SJung-uk Kim___
463e71b7053SJung-uk Kimfor($i=1;$i<4;$i++) {
464e71b7053SJung-uk Kim	################################################################
465e71b7053SJung-uk Kim	# Reduction iteration is normally performed by accumulating
466e71b7053SJung-uk Kim	# result of multiplication of modulus by "magic" digit [and
467e71b7053SJung-uk Kim	# omitting least significant word, which is guaranteed to
468e71b7053SJung-uk Kim	# be 0], but thanks to special form of modulus and "magic"
469e71b7053SJung-uk Kim	# digit being equal to least significant word, it can be
470e71b7053SJung-uk Kim	# performed with additions and subtractions alone. Indeed:
471e71b7053SJung-uk Kim	#
472e71b7053SJung-uk Kim	#            ffff0001.00000000.0000ffff.ffffffff
473e71b7053SJung-uk Kim	# *                                     abcdefgh
474e71b7053SJung-uk Kim	# + xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.abcdefgh
475e71b7053SJung-uk Kim	#
476e71b7053SJung-uk Kim	# Now observing that ff..ff*x = (2^n-1)*x = 2^n*x-x, we
477e71b7053SJung-uk Kim	# rewrite above as:
478e71b7053SJung-uk Kim	#
479e71b7053SJung-uk Kim	#   xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.abcdefgh
480e71b7053SJung-uk Kim	# + abcdefgh.abcdefgh.0000abcd.efgh0000.00000000
481e71b7053SJung-uk Kim	# - 0000abcd.efgh0000.00000000.00000000.abcdefgh
482e71b7053SJung-uk Kim	#
483e71b7053SJung-uk Kim	# or marking redundant operations:
484e71b7053SJung-uk Kim	#
485e71b7053SJung-uk Kim	#   xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.--------
486e71b7053SJung-uk Kim	# + abcdefgh.abcdefgh.0000abcd.efgh0000.--------
487e71b7053SJung-uk Kim	# - 0000abcd.efgh0000.--------.--------.--------
488e71b7053SJung-uk Kim
489e71b7053SJung-uk Kim$code.=<<___;
490e71b7053SJung-uk Kim	subfc	$t2,$t0,$acc0		# "*0xffff0001"
491e71b7053SJung-uk Kim	subfe	$t3,$t1,$acc0
492e71b7053SJung-uk Kim	addc	$acc0,$acc1,$t0		# +=acc[0]<<96 and omit acc[0]
493e71b7053SJung-uk Kim	adde	$acc1,$acc2,$t1
494e71b7053SJung-uk Kim	adde	$acc2,$acc3,$t2		# +=acc[0]*0xffff0001
495e71b7053SJung-uk Kim	adde	$acc3,$acc4,$t3
496e71b7053SJung-uk Kim	addze	$acc4,$acc5
497e71b7053SJung-uk Kim
498e71b7053SJung-uk Kim	mulld	$t0,$a0,$bi		# lo(a[0]*b[i])
499e71b7053SJung-uk Kim	mulld	$t1,$a1,$bi		# lo(a[1]*b[i])
500e71b7053SJung-uk Kim	mulld	$t2,$a2,$bi		# lo(a[2]*b[i])
501e71b7053SJung-uk Kim	mulld	$t3,$a3,$bi		# lo(a[3]*b[i])
502e71b7053SJung-uk Kim	addc	$acc0,$acc0,$t0		# accumulate low parts of multiplication
503e71b7053SJung-uk Kim	 mulhdu	$t0,$a0,$bi		# hi(a[0]*b[i])
504e71b7053SJung-uk Kim	adde	$acc1,$acc1,$t1
505e71b7053SJung-uk Kim	 mulhdu	$t1,$a1,$bi		# hi(a[1]*b[i])
506e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t2
507e71b7053SJung-uk Kim	 mulhdu	$t2,$a2,$bi		# hi(a[2]*b[i])
508e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t3
509e71b7053SJung-uk Kim	 mulhdu	$t3,$a3,$bi		# hi(a[3]*b[i])
510e71b7053SJung-uk Kim	addze	$acc4,$acc4
511e71b7053SJung-uk Kim___
512e71b7053SJung-uk Kim$code.=<<___	if ($i<3);
513e71b7053SJung-uk Kim	ld	$bi,8*($i+1)($bp)	# b[$i+1]
514e71b7053SJung-uk Kim___
515e71b7053SJung-uk Kim$code.=<<___;
516e71b7053SJung-uk Kim	addc	$acc1,$acc1,$t0		# accumulate high parts of multiplication
517e71b7053SJung-uk Kim	 sldi	$t0,$acc0,32
518e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t1
519e71b7053SJung-uk Kim	 srdi	$t1,$acc0,32
520e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t2
521e71b7053SJung-uk Kim	adde	$acc4,$acc4,$t3
522e71b7053SJung-uk Kim	li	$acc5,0
523e71b7053SJung-uk Kim	addze	$acc5,$acc5
524e71b7053SJung-uk Kim___
525e71b7053SJung-uk Kim}
526e71b7053SJung-uk Kim$code.=<<___;
527e71b7053SJung-uk Kim	# last reduction
528e71b7053SJung-uk Kim	subfc	$t2,$t0,$acc0		# "*0xffff0001"
529e71b7053SJung-uk Kim	subfe	$t3,$t1,$acc0
530e71b7053SJung-uk Kim	addc	$acc0,$acc1,$t0		# +=acc[0]<<96 and omit acc[0]
531e71b7053SJung-uk Kim	adde	$acc1,$acc2,$t1
532e71b7053SJung-uk Kim	adde	$acc2,$acc3,$t2		# +=acc[0]*0xffff0001
533e71b7053SJung-uk Kim	adde	$acc3,$acc4,$t3
534e71b7053SJung-uk Kim	addze	$acc4,$acc5
535e71b7053SJung-uk Kim
536e71b7053SJung-uk Kim	li	$t2,0
537e71b7053SJung-uk Kim	addic	$acc0,$acc0,1		# ret -= modulus
538e71b7053SJung-uk Kim	subfe	$acc1,$poly1,$acc1
539e71b7053SJung-uk Kim	subfe	$acc2,$t2,$acc2
540e71b7053SJung-uk Kim	subfe	$acc3,$poly3,$acc3
541e71b7053SJung-uk Kim	subfe	$acc4,$t2,$acc4
542e71b7053SJung-uk Kim
543e71b7053SJung-uk Kim	addc	$acc0,$acc0,$acc4	# ret += modulus if borrow
544e71b7053SJung-uk Kim	and	$t1,$poly1,$acc4
545e71b7053SJung-uk Kim	and	$t3,$poly3,$acc4
546e71b7053SJung-uk Kim	adde	$acc1,$acc1,$t1
547e71b7053SJung-uk Kim	addze	$acc2,$acc2
548e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t3
549e71b7053SJung-uk Kim
550e71b7053SJung-uk Kim	std	$acc0,0($rp)
551e71b7053SJung-uk Kim	std	$acc1,8($rp)
552e71b7053SJung-uk Kim	std	$acc2,16($rp)
553e71b7053SJung-uk Kim	std	$acc3,24($rp)
554e71b7053SJung-uk Kim
555e71b7053SJung-uk Kim	blr
556e71b7053SJung-uk Kim	.long	0
557e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,1,0
558e71b7053SJung-uk Kim	.long	0
559e71b7053SJung-uk Kim.size	__ecp_nistz256_mul_mont,.-__ecp_nistz256_mul_mont
560e71b7053SJung-uk Kim
561e71b7053SJung-uk Kim# note that __ecp_nistz256_sqr_mont expects a[0-3] input pre-loaded
562e71b7053SJung-uk Kim# to $a0-$a3
563e71b7053SJung-uk Kim.type	__ecp_nistz256_sqr_mont,\@function
564e71b7053SJung-uk Kim.align	4
565e71b7053SJung-uk Kim__ecp_nistz256_sqr_mont:
566e71b7053SJung-uk Kim	################################################################
567e71b7053SJung-uk Kim	#  |  |  |  |  |  |a1*a0|  |
568e71b7053SJung-uk Kim	#  |  |  |  |  |a2*a0|  |  |
569e71b7053SJung-uk Kim	#  |  |a3*a2|a3*a0|  |  |  |
570e71b7053SJung-uk Kim	#  |  |  |  |a2*a1|  |  |  |
571e71b7053SJung-uk Kim	#  |  |  |a3*a1|  |  |  |  |
572e71b7053SJung-uk Kim	# *|  |  |  |  |  |  |  | 2|
573e71b7053SJung-uk Kim	# +|a3*a3|a2*a2|a1*a1|a0*a0|
574e71b7053SJung-uk Kim	#  |--+--+--+--+--+--+--+--|
575e71b7053SJung-uk Kim	#  |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is $accx, i.e. follow $accx
576e71b7053SJung-uk Kim	#
577e71b7053SJung-uk Kim	#  "can't overflow" below mark carrying into high part of
578e71b7053SJung-uk Kim	#  multiplication result, which can't overflow, because it
579e71b7053SJung-uk Kim	#  can never be all ones.
580e71b7053SJung-uk Kim
581e71b7053SJung-uk Kim	mulld	$acc1,$a1,$a0		# a[1]*a[0]
582e71b7053SJung-uk Kim	mulhdu	$t1,$a1,$a0
583e71b7053SJung-uk Kim	mulld	$acc2,$a2,$a0		# a[2]*a[0]
584e71b7053SJung-uk Kim	mulhdu	$t2,$a2,$a0
585e71b7053SJung-uk Kim	mulld	$acc3,$a3,$a0		# a[3]*a[0]
586e71b7053SJung-uk Kim	mulhdu	$acc4,$a3,$a0
587e71b7053SJung-uk Kim
588e71b7053SJung-uk Kim	addc	$acc2,$acc2,$t1		# accumulate high parts of multiplication
589e71b7053SJung-uk Kim	 mulld	$t0,$a2,$a1		# a[2]*a[1]
590e71b7053SJung-uk Kim	 mulhdu	$t1,$a2,$a1
591e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t2
592e71b7053SJung-uk Kim	 mulld	$t2,$a3,$a1		# a[3]*a[1]
593e71b7053SJung-uk Kim	 mulhdu	$t3,$a3,$a1
594e71b7053SJung-uk Kim	addze	$acc4,$acc4		# can't overflow
595e71b7053SJung-uk Kim
596e71b7053SJung-uk Kim	mulld	$acc5,$a3,$a2		# a[3]*a[2]
597e71b7053SJung-uk Kim	mulhdu	$acc6,$a3,$a2
598e71b7053SJung-uk Kim
599e71b7053SJung-uk Kim	addc	$t1,$t1,$t2		# accumulate high parts of multiplication
600e71b7053SJung-uk Kim	addze	$t2,$t3			# can't overflow
601e71b7053SJung-uk Kim
602e71b7053SJung-uk Kim	addc	$acc3,$acc3,$t0		# accumulate low parts of multiplication
603e71b7053SJung-uk Kim	adde	$acc4,$acc4,$t1
604e71b7053SJung-uk Kim	adde	$acc5,$acc5,$t2
605e71b7053SJung-uk Kim	addze	$acc6,$acc6		# can't overflow
606e71b7053SJung-uk Kim
607e71b7053SJung-uk Kim	addc	$acc1,$acc1,$acc1	# acc[1-6]*=2
608e71b7053SJung-uk Kim	adde	$acc2,$acc2,$acc2
609e71b7053SJung-uk Kim	adde	$acc3,$acc3,$acc3
610e71b7053SJung-uk Kim	adde	$acc4,$acc4,$acc4
611e71b7053SJung-uk Kim	adde	$acc5,$acc5,$acc5
612e71b7053SJung-uk Kim	adde	$acc6,$acc6,$acc6
613e71b7053SJung-uk Kim	li	$acc7,0
614e71b7053SJung-uk Kim	addze	$acc7,$acc7
615e71b7053SJung-uk Kim
616e71b7053SJung-uk Kim	mulld	$acc0,$a0,$a0		# a[0]*a[0]
617e71b7053SJung-uk Kim	mulhdu	$a0,$a0,$a0
618e71b7053SJung-uk Kim	mulld	$t1,$a1,$a1		# a[1]*a[1]
619e71b7053SJung-uk Kim	mulhdu	$a1,$a1,$a1
620e71b7053SJung-uk Kim	mulld	$t2,$a2,$a2		# a[2]*a[2]
621e71b7053SJung-uk Kim	mulhdu	$a2,$a2,$a2
622e71b7053SJung-uk Kim	mulld	$t3,$a3,$a3		# a[3]*a[3]
623e71b7053SJung-uk Kim	mulhdu	$a3,$a3,$a3
624e71b7053SJung-uk Kim	addc	$acc1,$acc1,$a0		# +a[i]*a[i]
625e71b7053SJung-uk Kim	 sldi	$t0,$acc0,32
626e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t1
627e71b7053SJung-uk Kim	 srdi	$t1,$acc0,32
628e71b7053SJung-uk Kim	adde	$acc3,$acc3,$a1
629e71b7053SJung-uk Kim	adde	$acc4,$acc4,$t2
630e71b7053SJung-uk Kim	adde	$acc5,$acc5,$a2
631e71b7053SJung-uk Kim	adde	$acc6,$acc6,$t3
632e71b7053SJung-uk Kim	adde	$acc7,$acc7,$a3
633e71b7053SJung-uk Kim___
634e71b7053SJung-uk Kimfor($i=0;$i<3;$i++) {			# reductions, see commentary in
635e71b7053SJung-uk Kim					# multiplication for details
636e71b7053SJung-uk Kim$code.=<<___;
637e71b7053SJung-uk Kim	subfc	$t2,$t0,$acc0		# "*0xffff0001"
638e71b7053SJung-uk Kim	subfe	$t3,$t1,$acc0
639e71b7053SJung-uk Kim	addc	$acc0,$acc1,$t0		# +=acc[0]<<96 and omit acc[0]
640e71b7053SJung-uk Kim	 sldi	$t0,$acc0,32
641e71b7053SJung-uk Kim	adde	$acc1,$acc2,$t1
642e71b7053SJung-uk Kim	 srdi	$t1,$acc0,32
643e71b7053SJung-uk Kim	adde	$acc2,$acc3,$t2		# +=acc[0]*0xffff0001
644e71b7053SJung-uk Kim	addze	$acc3,$t3		# can't overflow
645e71b7053SJung-uk Kim___
646e71b7053SJung-uk Kim}
647e71b7053SJung-uk Kim$code.=<<___;
648e71b7053SJung-uk Kim	subfc	$t2,$t0,$acc0		# "*0xffff0001"
649e71b7053SJung-uk Kim	subfe	$t3,$t1,$acc0
650e71b7053SJung-uk Kim	addc	$acc0,$acc1,$t0		# +=acc[0]<<96 and omit acc[0]
651e71b7053SJung-uk Kim	adde	$acc1,$acc2,$t1
652e71b7053SJung-uk Kim	adde	$acc2,$acc3,$t2		# +=acc[0]*0xffff0001
653e71b7053SJung-uk Kim	addze	$acc3,$t3		# can't overflow
654e71b7053SJung-uk Kim
655e71b7053SJung-uk Kim	addc	$acc0,$acc0,$acc4	# accumulate upper half
656e71b7053SJung-uk Kim	adde	$acc1,$acc1,$acc5
657e71b7053SJung-uk Kim	adde	$acc2,$acc2,$acc6
658e71b7053SJung-uk Kim	adde	$acc3,$acc3,$acc7
659e71b7053SJung-uk Kim	li	$t2,0
660e71b7053SJung-uk Kim	addze	$acc4,$t2
661e71b7053SJung-uk Kim
662e71b7053SJung-uk Kim	addic	$acc0,$acc0,1		# ret -= modulus
663e71b7053SJung-uk Kim	subfe	$acc1,$poly1,$acc1
664e71b7053SJung-uk Kim	subfe	$acc2,$t2,$acc2
665e71b7053SJung-uk Kim	subfe	$acc3,$poly3,$acc3
666e71b7053SJung-uk Kim	subfe	$acc4,$t2,$acc4
667e71b7053SJung-uk Kim
668e71b7053SJung-uk Kim	addc	$acc0,$acc0,$acc4	# ret += modulus if borrow
669e71b7053SJung-uk Kim	and	$t1,$poly1,$acc4
670e71b7053SJung-uk Kim	and	$t3,$poly3,$acc4
671e71b7053SJung-uk Kim	adde	$acc1,$acc1,$t1
672e71b7053SJung-uk Kim	addze	$acc2,$acc2
673e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t3
674e71b7053SJung-uk Kim
675e71b7053SJung-uk Kim	std	$acc0,0($rp)
676e71b7053SJung-uk Kim	std	$acc1,8($rp)
677e71b7053SJung-uk Kim	std	$acc2,16($rp)
678e71b7053SJung-uk Kim	std	$acc3,24($rp)
679e71b7053SJung-uk Kim
680e71b7053SJung-uk Kim	blr
681e71b7053SJung-uk Kim	.long	0
682e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,1,0
683e71b7053SJung-uk Kim	.long	0
684e71b7053SJung-uk Kim.size	__ecp_nistz256_sqr_mont,.-__ecp_nistz256_sqr_mont
685e71b7053SJung-uk Kim
686e71b7053SJung-uk Kim# Note that __ecp_nistz256_add expects both input vectors pre-loaded to
687e71b7053SJung-uk Kim# $a0-$a3 and $t0-$t3. This is done because it's used in multiple
688e71b7053SJung-uk Kim# contexts, e.g. in multiplication by 2 and 3...
689e71b7053SJung-uk Kim.type	__ecp_nistz256_add,\@function
690e71b7053SJung-uk Kim.align	4
691e71b7053SJung-uk Kim__ecp_nistz256_add:
692e71b7053SJung-uk Kim	addc	$acc0,$acc0,$t0		# ret = a+b
693e71b7053SJung-uk Kim	adde	$acc1,$acc1,$t1
694e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t2
695e71b7053SJung-uk Kim	li	$t2,0
696e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t3
697e71b7053SJung-uk Kim	addze	$t0,$t2
698e71b7053SJung-uk Kim
699e71b7053SJung-uk Kim	# if a+b >= modulus, subtract modulus
700e71b7053SJung-uk Kim	#
701e71b7053SJung-uk Kim	# But since comparison implies subtraction, we subtract
702e71b7053SJung-uk Kim	# modulus and then add it back if subtraction borrowed.
703e71b7053SJung-uk Kim
704e71b7053SJung-uk Kim	subic	$acc0,$acc0,-1
705e71b7053SJung-uk Kim	subfe	$acc1,$poly1,$acc1
706e71b7053SJung-uk Kim	subfe	$acc2,$t2,$acc2
707e71b7053SJung-uk Kim	subfe	$acc3,$poly3,$acc3
708e71b7053SJung-uk Kim	subfe	$t0,$t2,$t0
709e71b7053SJung-uk Kim
710e71b7053SJung-uk Kim	addc	$acc0,$acc0,$t0
711e71b7053SJung-uk Kim	and	$t1,$poly1,$t0
712e71b7053SJung-uk Kim	and	$t3,$poly3,$t0
713e71b7053SJung-uk Kim	adde	$acc1,$acc1,$t1
714e71b7053SJung-uk Kim	addze	$acc2,$acc2
715e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t3
716e71b7053SJung-uk Kim
717e71b7053SJung-uk Kim	std	$acc0,0($rp)
718e71b7053SJung-uk Kim	std	$acc1,8($rp)
719e71b7053SJung-uk Kim	std	$acc2,16($rp)
720e71b7053SJung-uk Kim	std	$acc3,24($rp)
721e71b7053SJung-uk Kim
722e71b7053SJung-uk Kim	blr
723e71b7053SJung-uk Kim	.long	0
724e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,3,0
725e71b7053SJung-uk Kim	.long	0
726e71b7053SJung-uk Kim.size	__ecp_nistz256_add,.-__ecp_nistz256_add
727e71b7053SJung-uk Kim
728e71b7053SJung-uk Kim.type	__ecp_nistz256_sub_from,\@function
729e71b7053SJung-uk Kim.align	4
730e71b7053SJung-uk Kim__ecp_nistz256_sub_from:
731e71b7053SJung-uk Kim	ld	$t0,0($bp)
732e71b7053SJung-uk Kim	ld	$t1,8($bp)
733e71b7053SJung-uk Kim	ld	$t2,16($bp)
734e71b7053SJung-uk Kim	ld	$t3,24($bp)
735e71b7053SJung-uk Kim	subfc	$acc0,$t0,$acc0		# ret = a-b
736e71b7053SJung-uk Kim	subfe	$acc1,$t1,$acc1
737e71b7053SJung-uk Kim	subfe	$acc2,$t2,$acc2
738e71b7053SJung-uk Kim	subfe	$acc3,$t3,$acc3
739e71b7053SJung-uk Kim	subfe	$t0,$t0,$t0		# t0 = borrow ? -1 : 0
740e71b7053SJung-uk Kim
741e71b7053SJung-uk Kim	# if a-b borrowed, add modulus
742e71b7053SJung-uk Kim
743e71b7053SJung-uk Kim	addc	$acc0,$acc0,$t0		# ret -= modulus & t0
744e71b7053SJung-uk Kim	and	$t1,$poly1,$t0
745e71b7053SJung-uk Kim	and	$t3,$poly3,$t0
746e71b7053SJung-uk Kim	adde	$acc1,$acc1,$t1
747e71b7053SJung-uk Kim	addze	$acc2,$acc2
748e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t3
749e71b7053SJung-uk Kim
750e71b7053SJung-uk Kim	std	$acc0,0($rp)
751e71b7053SJung-uk Kim	std	$acc1,8($rp)
752e71b7053SJung-uk Kim	std	$acc2,16($rp)
753e71b7053SJung-uk Kim	std	$acc3,24($rp)
754e71b7053SJung-uk Kim
755e71b7053SJung-uk Kim	blr
756e71b7053SJung-uk Kim	.long	0
757e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,3,0
758e71b7053SJung-uk Kim	.long	0
759e71b7053SJung-uk Kim.size	__ecp_nistz256_sub_from,.-__ecp_nistz256_sub_from
760e71b7053SJung-uk Kim
761e71b7053SJung-uk Kim.type	__ecp_nistz256_sub_morf,\@function
762e71b7053SJung-uk Kim.align	4
763e71b7053SJung-uk Kim__ecp_nistz256_sub_morf:
764e71b7053SJung-uk Kim	ld	$t0,0($bp)
765e71b7053SJung-uk Kim	ld	$t1,8($bp)
766e71b7053SJung-uk Kim	ld	$t2,16($bp)
767e71b7053SJung-uk Kim	ld	$t3,24($bp)
768e71b7053SJung-uk Kim	subfc	$acc0,$acc0,$t0 	# ret = b-a
769e71b7053SJung-uk Kim	subfe	$acc1,$acc1,$t1
770e71b7053SJung-uk Kim	subfe	$acc2,$acc2,$t2
771e71b7053SJung-uk Kim	subfe	$acc3,$acc3,$t3
772e71b7053SJung-uk Kim	subfe	$t0,$t0,$t0		# t0 = borrow ? -1 : 0
773e71b7053SJung-uk Kim
774e71b7053SJung-uk Kim	# if b-a borrowed, add modulus
775e71b7053SJung-uk Kim
776e71b7053SJung-uk Kim	addc	$acc0,$acc0,$t0		# ret -= modulus & t0
777e71b7053SJung-uk Kim	and	$t1,$poly1,$t0
778e71b7053SJung-uk Kim	and	$t3,$poly3,$t0
779e71b7053SJung-uk Kim	adde	$acc1,$acc1,$t1
780e71b7053SJung-uk Kim	addze	$acc2,$acc2
781e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t3
782e71b7053SJung-uk Kim
783e71b7053SJung-uk Kim	std	$acc0,0($rp)
784e71b7053SJung-uk Kim	std	$acc1,8($rp)
785e71b7053SJung-uk Kim	std	$acc2,16($rp)
786e71b7053SJung-uk Kim	std	$acc3,24($rp)
787e71b7053SJung-uk Kim
788e71b7053SJung-uk Kim	blr
789e71b7053SJung-uk Kim	.long	0
790e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,3,0
791e71b7053SJung-uk Kim	.long	0
792e71b7053SJung-uk Kim.size	__ecp_nistz256_sub_morf,.-__ecp_nistz256_sub_morf
793e71b7053SJung-uk Kim
794e71b7053SJung-uk Kim.type	__ecp_nistz256_div_by_2,\@function
795e71b7053SJung-uk Kim.align	4
796e71b7053SJung-uk Kim__ecp_nistz256_div_by_2:
797e71b7053SJung-uk Kim	andi.	$t0,$acc0,1
798e71b7053SJung-uk Kim	addic	$acc0,$acc0,-1		# a += modulus
799e71b7053SJung-uk Kim	 neg	$t0,$t0
800e71b7053SJung-uk Kim	adde	$acc1,$acc1,$poly1
801e71b7053SJung-uk Kim	 not	$t0,$t0
802e71b7053SJung-uk Kim	addze	$acc2,$acc2
803e71b7053SJung-uk Kim	 li	$t2,0
804e71b7053SJung-uk Kim	adde	$acc3,$acc3,$poly3
805e71b7053SJung-uk Kim	 and	$t1,$poly1,$t0
806e71b7053SJung-uk Kim	addze	$ap,$t2			# ap = carry
807e71b7053SJung-uk Kim	 and	$t3,$poly3,$t0
808e71b7053SJung-uk Kim
809e71b7053SJung-uk Kim	subfc	$acc0,$t0,$acc0		# a -= modulus if a was even
810e71b7053SJung-uk Kim	subfe	$acc1,$t1,$acc1
811e71b7053SJung-uk Kim	subfe	$acc2,$t2,$acc2
812e71b7053SJung-uk Kim	subfe	$acc3,$t3,$acc3
813e71b7053SJung-uk Kim	subfe	$ap,  $t2,$ap
814e71b7053SJung-uk Kim
815e71b7053SJung-uk Kim	srdi	$acc0,$acc0,1
816e71b7053SJung-uk Kim	sldi	$t0,$acc1,63
817e71b7053SJung-uk Kim	srdi	$acc1,$acc1,1
818e71b7053SJung-uk Kim	sldi	$t1,$acc2,63
819e71b7053SJung-uk Kim	srdi	$acc2,$acc2,1
820e71b7053SJung-uk Kim	sldi	$t2,$acc3,63
821e71b7053SJung-uk Kim	srdi	$acc3,$acc3,1
822e71b7053SJung-uk Kim	sldi	$t3,$ap,63
823e71b7053SJung-uk Kim	or	$acc0,$acc0,$t0
824e71b7053SJung-uk Kim	or	$acc1,$acc1,$t1
825e71b7053SJung-uk Kim	or	$acc2,$acc2,$t2
826e71b7053SJung-uk Kim	or	$acc3,$acc3,$t3
827e71b7053SJung-uk Kim
828e71b7053SJung-uk Kim	std	$acc0,0($rp)
829e71b7053SJung-uk Kim	std	$acc1,8($rp)
830e71b7053SJung-uk Kim	std	$acc2,16($rp)
831e71b7053SJung-uk Kim	std	$acc3,24($rp)
832e71b7053SJung-uk Kim
833e71b7053SJung-uk Kim	blr
834e71b7053SJung-uk Kim	.long	0
835e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,1,0
836e71b7053SJung-uk Kim	.long	0
837e71b7053SJung-uk Kim.size	__ecp_nistz256_div_by_2,.-__ecp_nistz256_div_by_2
838e71b7053SJung-uk Kim___
839e71b7053SJung-uk Kim########################################################################
840e71b7053SJung-uk Kim# following subroutines are "literal" implementation of those found in
841e71b7053SJung-uk Kim# ecp_nistz256.c
842e71b7053SJung-uk Kim#
843e71b7053SJung-uk Kim########################################################################
844e71b7053SJung-uk Kim# void ecp_nistz256_point_double(P256_POINT *out,const P256_POINT *inp);
845e71b7053SJung-uk Kim#
846e71b7053SJung-uk Kimif (1) {
847e71b7053SJung-uk Kimmy $FRAME=64+32*4+12*8;
848e71b7053SJung-uk Kimmy ($S,$M,$Zsqr,$tmp0)=map(64+32*$_,(0..3));
849e71b7053SJung-uk Kim# above map() describes stack layout with 4 temporary
850e71b7053SJung-uk Kim# 256-bit vectors on top.
851e71b7053SJung-uk Kimmy ($rp_real,$ap_real) = map("r$_",(20,21));
852e71b7053SJung-uk Kim
853e71b7053SJung-uk Kim$code.=<<___;
854e71b7053SJung-uk Kim.globl	ecp_nistz256_point_double
855e71b7053SJung-uk Kim.align	5
856e71b7053SJung-uk Kimecp_nistz256_point_double:
857e71b7053SJung-uk Kim	stdu	$sp,-$FRAME($sp)
858e71b7053SJung-uk Kim	mflr	r0
859e71b7053SJung-uk Kim	std	r20,$FRAME-8*12($sp)
860e71b7053SJung-uk Kim	std	r21,$FRAME-8*11($sp)
861e71b7053SJung-uk Kim	std	r22,$FRAME-8*10($sp)
862e71b7053SJung-uk Kim	std	r23,$FRAME-8*9($sp)
863e71b7053SJung-uk Kim	std	r24,$FRAME-8*8($sp)
864e71b7053SJung-uk Kim	std	r25,$FRAME-8*7($sp)
865e71b7053SJung-uk Kim	std	r26,$FRAME-8*6($sp)
866e71b7053SJung-uk Kim	std	r27,$FRAME-8*5($sp)
867e71b7053SJung-uk Kim	std	r28,$FRAME-8*4($sp)
868e71b7053SJung-uk Kim	std	r29,$FRAME-8*3($sp)
869e71b7053SJung-uk Kim	std	r30,$FRAME-8*2($sp)
870e71b7053SJung-uk Kim	std	r31,$FRAME-8*1($sp)
871e71b7053SJung-uk Kim
872e71b7053SJung-uk Kim	li	$poly1,-1
873e71b7053SJung-uk Kim	srdi	$poly1,$poly1,32	# 0x00000000ffffffff
874e71b7053SJung-uk Kim	li	$poly3,1
875e71b7053SJung-uk Kim	orc	$poly3,$poly3,$poly1	# 0xffffffff00000001
876e71b7053SJung-uk Kim.Ldouble_shortcut:
877e71b7053SJung-uk Kim	ld	$acc0,32($ap)
878e71b7053SJung-uk Kim	ld	$acc1,40($ap)
879e71b7053SJung-uk Kim	ld	$acc2,48($ap)
880e71b7053SJung-uk Kim	ld	$acc3,56($ap)
881e71b7053SJung-uk Kim	mr	$t0,$acc0
882e71b7053SJung-uk Kim	mr	$t1,$acc1
883e71b7053SJung-uk Kim	mr	$t2,$acc2
884e71b7053SJung-uk Kim	mr	$t3,$acc3
885e71b7053SJung-uk Kim	 ld	$a0,64($ap)		# forward load for p256_sqr_mont
886e71b7053SJung-uk Kim	 ld	$a1,72($ap)
887e71b7053SJung-uk Kim	 ld	$a2,80($ap)
888e71b7053SJung-uk Kim	 ld	$a3,88($ap)
889e71b7053SJung-uk Kim	 mr	$rp_real,$rp
890e71b7053SJung-uk Kim	 mr	$ap_real,$ap
891e71b7053SJung-uk Kim	addi	$rp,$sp,$S
892e71b7053SJung-uk Kim	bl	__ecp_nistz256_add	# p256_mul_by_2(S, in_y);
893e71b7053SJung-uk Kim
894e71b7053SJung-uk Kim	addi	$rp,$sp,$Zsqr
895e71b7053SJung-uk Kim	bl	__ecp_nistz256_sqr_mont	# p256_sqr_mont(Zsqr, in_z);
896e71b7053SJung-uk Kim
897e71b7053SJung-uk Kim	ld	$t0,0($ap_real)
898e71b7053SJung-uk Kim	ld	$t1,8($ap_real)
899e71b7053SJung-uk Kim	ld	$t2,16($ap_real)
900e71b7053SJung-uk Kim	ld	$t3,24($ap_real)
901e71b7053SJung-uk Kim	mr	$a0,$acc0		# put Zsqr aside for p256_sub
902e71b7053SJung-uk Kim	mr	$a1,$acc1
903e71b7053SJung-uk Kim	mr	$a2,$acc2
904e71b7053SJung-uk Kim	mr	$a3,$acc3
905e71b7053SJung-uk Kim	addi	$rp,$sp,$M
906e71b7053SJung-uk Kim	bl	__ecp_nistz256_add	# p256_add(M, Zsqr, in_x);
907e71b7053SJung-uk Kim
908e71b7053SJung-uk Kim	addi	$bp,$ap_real,0
909e71b7053SJung-uk Kim	mr	$acc0,$a0		# restore Zsqr
910e71b7053SJung-uk Kim	mr	$acc1,$a1
911e71b7053SJung-uk Kim	mr	$acc2,$a2
912e71b7053SJung-uk Kim	mr	$acc3,$a3
913e71b7053SJung-uk Kim	 ld	$a0,$S+0($sp)		# forward load for p256_sqr_mont
914e71b7053SJung-uk Kim	 ld	$a1,$S+8($sp)
915e71b7053SJung-uk Kim	 ld	$a2,$S+16($sp)
916e71b7053SJung-uk Kim	 ld	$a3,$S+24($sp)
917e71b7053SJung-uk Kim	addi	$rp,$sp,$Zsqr
918e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_morf	# p256_sub(Zsqr, in_x, Zsqr);
919e71b7053SJung-uk Kim
920e71b7053SJung-uk Kim	addi	$rp,$sp,$S
921e71b7053SJung-uk Kim	bl	__ecp_nistz256_sqr_mont	# p256_sqr_mont(S, S);
922e71b7053SJung-uk Kim
923e71b7053SJung-uk Kim	ld	$bi,32($ap_real)
924e71b7053SJung-uk Kim	ld	$a0,64($ap_real)
925e71b7053SJung-uk Kim	ld	$a1,72($ap_real)
926e71b7053SJung-uk Kim	ld	$a2,80($ap_real)
927e71b7053SJung-uk Kim	ld	$a3,88($ap_real)
928e71b7053SJung-uk Kim	addi	$bp,$ap_real,32
929e71b7053SJung-uk Kim	addi	$rp,$sp,$tmp0
930e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(tmp0, in_z, in_y);
931e71b7053SJung-uk Kim
932e71b7053SJung-uk Kim	mr	$t0,$acc0
933e71b7053SJung-uk Kim	mr	$t1,$acc1
934e71b7053SJung-uk Kim	mr	$t2,$acc2
935e71b7053SJung-uk Kim	mr	$t3,$acc3
936e71b7053SJung-uk Kim	 ld	$a0,$S+0($sp)		# forward load for p256_sqr_mont
937e71b7053SJung-uk Kim	 ld	$a1,$S+8($sp)
938e71b7053SJung-uk Kim	 ld	$a2,$S+16($sp)
939e71b7053SJung-uk Kim	 ld	$a3,$S+24($sp)
940e71b7053SJung-uk Kim	addi	$rp,$rp_real,64
941e71b7053SJung-uk Kim	bl	__ecp_nistz256_add	# p256_mul_by_2(res_z, tmp0);
942e71b7053SJung-uk Kim
943e71b7053SJung-uk Kim	addi	$rp,$sp,$tmp0
944e71b7053SJung-uk Kim	bl	__ecp_nistz256_sqr_mont	# p256_sqr_mont(tmp0, S);
945e71b7053SJung-uk Kim
946e71b7053SJung-uk Kim	 ld	$bi,$Zsqr($sp)		# forward load for p256_mul_mont
947e71b7053SJung-uk Kim	 ld	$a0,$M+0($sp)
948e71b7053SJung-uk Kim	 ld	$a1,$M+8($sp)
949e71b7053SJung-uk Kim	 ld	$a2,$M+16($sp)
950e71b7053SJung-uk Kim	 ld	$a3,$M+24($sp)
951e71b7053SJung-uk Kim	addi	$rp,$rp_real,32
952e71b7053SJung-uk Kim	bl	__ecp_nistz256_div_by_2	# p256_div_by_2(res_y, tmp0);
953e71b7053SJung-uk Kim
954e71b7053SJung-uk Kim	addi	$bp,$sp,$Zsqr
955e71b7053SJung-uk Kim	addi	$rp,$sp,$M
956e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(M, M, Zsqr);
957e71b7053SJung-uk Kim
958e71b7053SJung-uk Kim	mr	$t0,$acc0		# duplicate M
959e71b7053SJung-uk Kim	mr	$t1,$acc1
960e71b7053SJung-uk Kim	mr	$t2,$acc2
961e71b7053SJung-uk Kim	mr	$t3,$acc3
962e71b7053SJung-uk Kim	mr	$a0,$acc0		# put M aside
963e71b7053SJung-uk Kim	mr	$a1,$acc1
964e71b7053SJung-uk Kim	mr	$a2,$acc2
965e71b7053SJung-uk Kim	mr	$a3,$acc3
966e71b7053SJung-uk Kim	addi	$rp,$sp,$M
967e71b7053SJung-uk Kim	bl	__ecp_nistz256_add
968e71b7053SJung-uk Kim	mr	$t0,$a0			# restore M
969e71b7053SJung-uk Kim	mr	$t1,$a1
970e71b7053SJung-uk Kim	mr	$t2,$a2
971e71b7053SJung-uk Kim	mr	$t3,$a3
972e71b7053SJung-uk Kim	 ld	$bi,0($ap_real)		# forward load for p256_mul_mont
973e71b7053SJung-uk Kim	 ld	$a0,$S+0($sp)
974e71b7053SJung-uk Kim	 ld	$a1,$S+8($sp)
975e71b7053SJung-uk Kim	 ld	$a2,$S+16($sp)
976e71b7053SJung-uk Kim	 ld	$a3,$S+24($sp)
977e71b7053SJung-uk Kim	bl	__ecp_nistz256_add	# p256_mul_by_3(M, M);
978e71b7053SJung-uk Kim
979e71b7053SJung-uk Kim	addi	$bp,$ap_real,0
980e71b7053SJung-uk Kim	addi	$rp,$sp,$S
981e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(S, S, in_x);
982e71b7053SJung-uk Kim
983e71b7053SJung-uk Kim	mr	$t0,$acc0
984e71b7053SJung-uk Kim	mr	$t1,$acc1
985e71b7053SJung-uk Kim	mr	$t2,$acc2
986e71b7053SJung-uk Kim	mr	$t3,$acc3
987e71b7053SJung-uk Kim	 ld	$a0,$M+0($sp)		# forward load for p256_sqr_mont
988e71b7053SJung-uk Kim	 ld	$a1,$M+8($sp)
989e71b7053SJung-uk Kim	 ld	$a2,$M+16($sp)
990e71b7053SJung-uk Kim	 ld	$a3,$M+24($sp)
991e71b7053SJung-uk Kim	addi	$rp,$sp,$tmp0
992e71b7053SJung-uk Kim	bl	__ecp_nistz256_add	# p256_mul_by_2(tmp0, S);
993e71b7053SJung-uk Kim
994e71b7053SJung-uk Kim	addi	$rp,$rp_real,0
995e71b7053SJung-uk Kim	bl	__ecp_nistz256_sqr_mont	# p256_sqr_mont(res_x, M);
996e71b7053SJung-uk Kim
997e71b7053SJung-uk Kim	addi	$bp,$sp,$tmp0
998e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_from	# p256_sub(res_x, res_x, tmp0);
999e71b7053SJung-uk Kim
1000e71b7053SJung-uk Kim	addi	$bp,$sp,$S
1001e71b7053SJung-uk Kim	addi	$rp,$sp,$S
1002e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_morf	# p256_sub(S, S, res_x);
1003e71b7053SJung-uk Kim
1004e71b7053SJung-uk Kim	ld	$bi,$M($sp)
1005e71b7053SJung-uk Kim	mr	$a0,$acc0		# copy S
1006e71b7053SJung-uk Kim	mr	$a1,$acc1
1007e71b7053SJung-uk Kim	mr	$a2,$acc2
1008e71b7053SJung-uk Kim	mr	$a3,$acc3
1009e71b7053SJung-uk Kim	addi	$bp,$sp,$M
1010e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(S, S, M);
1011e71b7053SJung-uk Kim
1012e71b7053SJung-uk Kim	addi	$bp,$rp_real,32
1013e71b7053SJung-uk Kim	addi	$rp,$rp_real,32
1014e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_from	# p256_sub(res_y, S, res_y);
1015e71b7053SJung-uk Kim
1016e71b7053SJung-uk Kim	mtlr	r0
1017e71b7053SJung-uk Kim	ld	r20,$FRAME-8*12($sp)
1018e71b7053SJung-uk Kim	ld	r21,$FRAME-8*11($sp)
1019e71b7053SJung-uk Kim	ld	r22,$FRAME-8*10($sp)
1020e71b7053SJung-uk Kim	ld	r23,$FRAME-8*9($sp)
1021e71b7053SJung-uk Kim	ld	r24,$FRAME-8*8($sp)
1022e71b7053SJung-uk Kim	ld	r25,$FRAME-8*7($sp)
1023e71b7053SJung-uk Kim	ld	r26,$FRAME-8*6($sp)
1024e71b7053SJung-uk Kim	ld	r27,$FRAME-8*5($sp)
1025e71b7053SJung-uk Kim	ld	r28,$FRAME-8*4($sp)
1026e71b7053SJung-uk Kim	ld	r29,$FRAME-8*3($sp)
1027e71b7053SJung-uk Kim	ld	r30,$FRAME-8*2($sp)
1028e71b7053SJung-uk Kim	ld	r31,$FRAME-8*1($sp)
1029e71b7053SJung-uk Kim	addi	$sp,$sp,$FRAME
1030e71b7053SJung-uk Kim	blr
1031e71b7053SJung-uk Kim	.long	0
1032e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,12,2,0
1033e71b7053SJung-uk Kim	.long	0
1034e71b7053SJung-uk Kim.size	ecp_nistz256_point_double,.-ecp_nistz256_point_double
1035e71b7053SJung-uk Kim___
1036e71b7053SJung-uk Kim}
1037e71b7053SJung-uk Kim
1038e71b7053SJung-uk Kim########################################################################
1039e71b7053SJung-uk Kim# void ecp_nistz256_point_add(P256_POINT *out,const P256_POINT *in1,
1040e71b7053SJung-uk Kim#			      const P256_POINT *in2);
1041e71b7053SJung-uk Kimif (1) {
1042e71b7053SJung-uk Kimmy $FRAME = 64 + 32*12 + 16*8;
1043e71b7053SJung-uk Kimmy ($res_x,$res_y,$res_z,
1044e71b7053SJung-uk Kim    $H,$Hsqr,$R,$Rsqr,$Hcub,
1045e71b7053SJung-uk Kim    $U1,$U2,$S1,$S2)=map(64+32*$_,(0..11));
1046e71b7053SJung-uk Kimmy ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
1047e71b7053SJung-uk Kim# above map() describes stack layout with 12 temporary
1048e71b7053SJung-uk Kim# 256-bit vectors on top.
1049e71b7053SJung-uk Kimmy ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp)=map("r$_",(16..21));
1050e71b7053SJung-uk Kim
1051e71b7053SJung-uk Kim$code.=<<___;
1052e71b7053SJung-uk Kim.globl	ecp_nistz256_point_add
1053e71b7053SJung-uk Kim.align	5
1054e71b7053SJung-uk Kimecp_nistz256_point_add:
1055e71b7053SJung-uk Kim	stdu	$sp,-$FRAME($sp)
1056e71b7053SJung-uk Kim	mflr	r0
1057e71b7053SJung-uk Kim	std	r16,$FRAME-8*16($sp)
1058e71b7053SJung-uk Kim	std	r17,$FRAME-8*15($sp)
1059e71b7053SJung-uk Kim	std	r18,$FRAME-8*14($sp)
1060e71b7053SJung-uk Kim	std	r19,$FRAME-8*13($sp)
1061e71b7053SJung-uk Kim	std	r20,$FRAME-8*12($sp)
1062e71b7053SJung-uk Kim	std	r21,$FRAME-8*11($sp)
1063e71b7053SJung-uk Kim	std	r22,$FRAME-8*10($sp)
1064e71b7053SJung-uk Kim	std	r23,$FRAME-8*9($sp)
1065e71b7053SJung-uk Kim	std	r24,$FRAME-8*8($sp)
1066e71b7053SJung-uk Kim	std	r25,$FRAME-8*7($sp)
1067e71b7053SJung-uk Kim	std	r26,$FRAME-8*6($sp)
1068e71b7053SJung-uk Kim	std	r27,$FRAME-8*5($sp)
1069e71b7053SJung-uk Kim	std	r28,$FRAME-8*4($sp)
1070e71b7053SJung-uk Kim	std	r29,$FRAME-8*3($sp)
1071e71b7053SJung-uk Kim	std	r30,$FRAME-8*2($sp)
1072e71b7053SJung-uk Kim	std	r31,$FRAME-8*1($sp)
1073e71b7053SJung-uk Kim
1074e71b7053SJung-uk Kim	li	$poly1,-1
1075e71b7053SJung-uk Kim	srdi	$poly1,$poly1,32	# 0x00000000ffffffff
1076e71b7053SJung-uk Kim	li	$poly3,1
1077e71b7053SJung-uk Kim	orc	$poly3,$poly3,$poly1	# 0xffffffff00000001
1078e71b7053SJung-uk Kim
1079e71b7053SJung-uk Kim	ld	$a0,64($bp)		# in2_z
1080e71b7053SJung-uk Kim	ld	$a1,72($bp)
1081e71b7053SJung-uk Kim	ld	$a2,80($bp)
1082e71b7053SJung-uk Kim	ld	$a3,88($bp)
1083e71b7053SJung-uk Kim	 mr	$rp_real,$rp
1084e71b7053SJung-uk Kim	 mr	$ap_real,$ap
1085e71b7053SJung-uk Kim	 mr	$bp_real,$bp
1086e71b7053SJung-uk Kim	or	$t0,$a0,$a1
1087e71b7053SJung-uk Kim	or	$t2,$a2,$a3
1088e71b7053SJung-uk Kim	or	$in2infty,$t0,$t2
1089e71b7053SJung-uk Kim	neg	$t0,$in2infty
1090e71b7053SJung-uk Kim	or	$in2infty,$in2infty,$t0
1091e71b7053SJung-uk Kim	sradi	$in2infty,$in2infty,63	# !in2infty
1092e71b7053SJung-uk Kim	addi	$rp,$sp,$Z2sqr
1093e71b7053SJung-uk Kim	bl	__ecp_nistz256_sqr_mont	# p256_sqr_mont(Z2sqr, in2_z);
1094e71b7053SJung-uk Kim
1095e71b7053SJung-uk Kim	ld	$a0,64($ap_real)	# in1_z
1096e71b7053SJung-uk Kim	ld	$a1,72($ap_real)
1097e71b7053SJung-uk Kim	ld	$a2,80($ap_real)
1098e71b7053SJung-uk Kim	ld	$a3,88($ap_real)
1099e71b7053SJung-uk Kim	or	$t0,$a0,$a1
1100e71b7053SJung-uk Kim	or	$t2,$a2,$a3
1101e71b7053SJung-uk Kim	or	$in1infty,$t0,$t2
1102e71b7053SJung-uk Kim	neg	$t0,$in1infty
1103e71b7053SJung-uk Kim	or	$in1infty,$in1infty,$t0
1104e71b7053SJung-uk Kim	sradi	$in1infty,$in1infty,63	# !in1infty
1105e71b7053SJung-uk Kim	addi	$rp,$sp,$Z1sqr
1106e71b7053SJung-uk Kim	bl	__ecp_nistz256_sqr_mont	# p256_sqr_mont(Z1sqr, in1_z);
1107e71b7053SJung-uk Kim
1108e71b7053SJung-uk Kim	ld	$bi,64($bp_real)
1109e71b7053SJung-uk Kim	ld	$a0,$Z2sqr+0($sp)
1110e71b7053SJung-uk Kim	ld	$a1,$Z2sqr+8($sp)
1111e71b7053SJung-uk Kim	ld	$a2,$Z2sqr+16($sp)
1112e71b7053SJung-uk Kim	ld	$a3,$Z2sqr+24($sp)
1113e71b7053SJung-uk Kim	addi	$bp,$bp_real,64
1114e71b7053SJung-uk Kim	addi	$rp,$sp,$S1
1115e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(S1, Z2sqr, in2_z);
1116e71b7053SJung-uk Kim
1117e71b7053SJung-uk Kim	ld	$bi,64($ap_real)
1118e71b7053SJung-uk Kim	ld	$a0,$Z1sqr+0($sp)
1119e71b7053SJung-uk Kim	ld	$a1,$Z1sqr+8($sp)
1120e71b7053SJung-uk Kim	ld	$a2,$Z1sqr+16($sp)
1121e71b7053SJung-uk Kim	ld	$a3,$Z1sqr+24($sp)
1122e71b7053SJung-uk Kim	addi	$bp,$ap_real,64
1123e71b7053SJung-uk Kim	addi	$rp,$sp,$S2
1124e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(S2, Z1sqr, in1_z);
1125e71b7053SJung-uk Kim
1126e71b7053SJung-uk Kim	ld	$bi,32($ap_real)
1127e71b7053SJung-uk Kim	ld	$a0,$S1+0($sp)
1128e71b7053SJung-uk Kim	ld	$a1,$S1+8($sp)
1129e71b7053SJung-uk Kim	ld	$a2,$S1+16($sp)
1130e71b7053SJung-uk Kim	ld	$a3,$S1+24($sp)
1131e71b7053SJung-uk Kim	addi	$bp,$ap_real,32
1132e71b7053SJung-uk Kim	addi	$rp,$sp,$S1
1133e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(S1, S1, in1_y);
1134e71b7053SJung-uk Kim
1135e71b7053SJung-uk Kim	ld	$bi,32($bp_real)
1136e71b7053SJung-uk Kim	ld	$a0,$S2+0($sp)
1137e71b7053SJung-uk Kim	ld	$a1,$S2+8($sp)
1138e71b7053SJung-uk Kim	ld	$a2,$S2+16($sp)
1139e71b7053SJung-uk Kim	ld	$a3,$S2+24($sp)
1140e71b7053SJung-uk Kim	addi	$bp,$bp_real,32
1141e71b7053SJung-uk Kim	addi	$rp,$sp,$S2
1142e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(S2, S2, in2_y);
1143e71b7053SJung-uk Kim
1144e71b7053SJung-uk Kim	addi	$bp,$sp,$S1
1145e71b7053SJung-uk Kim	 ld	$bi,$Z2sqr($sp)		# forward load for p256_mul_mont
1146e71b7053SJung-uk Kim	 ld	$a0,0($ap_real)
1147e71b7053SJung-uk Kim	 ld	$a1,8($ap_real)
1148e71b7053SJung-uk Kim	 ld	$a2,16($ap_real)
1149e71b7053SJung-uk Kim	 ld	$a3,24($ap_real)
1150e71b7053SJung-uk Kim	addi	$rp,$sp,$R
1151e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_from	# p256_sub(R, S2, S1);
1152e71b7053SJung-uk Kim
1153e71b7053SJung-uk Kim	or	$acc0,$acc0,$acc1	# see if result is zero
1154e71b7053SJung-uk Kim	or	$acc2,$acc2,$acc3
1155e71b7053SJung-uk Kim	or	$temp,$acc0,$acc2
1156e71b7053SJung-uk Kim
1157e71b7053SJung-uk Kim	addi	$bp,$sp,$Z2sqr
1158e71b7053SJung-uk Kim	addi	$rp,$sp,$U1
1159e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(U1, in1_x, Z2sqr);
1160e71b7053SJung-uk Kim
1161e71b7053SJung-uk Kim	ld	$bi,$Z1sqr($sp)
1162e71b7053SJung-uk Kim	ld	$a0,0($bp_real)
1163e71b7053SJung-uk Kim	ld	$a1,8($bp_real)
1164e71b7053SJung-uk Kim	ld	$a2,16($bp_real)
1165e71b7053SJung-uk Kim	ld	$a3,24($bp_real)
1166e71b7053SJung-uk Kim	addi	$bp,$sp,$Z1sqr
1167e71b7053SJung-uk Kim	addi	$rp,$sp,$U2
1168e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(U2, in2_x, Z1sqr);
1169e71b7053SJung-uk Kim
1170e71b7053SJung-uk Kim	addi	$bp,$sp,$U1
1171e71b7053SJung-uk Kim	 ld	$a0,$R+0($sp)		# forward load for p256_sqr_mont
1172e71b7053SJung-uk Kim	 ld	$a1,$R+8($sp)
1173e71b7053SJung-uk Kim	 ld	$a2,$R+16($sp)
1174e71b7053SJung-uk Kim	 ld	$a3,$R+24($sp)
1175e71b7053SJung-uk Kim	addi	$rp,$sp,$H
1176e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_from	# p256_sub(H, U2, U1);
1177e71b7053SJung-uk Kim
1178e71b7053SJung-uk Kim	or	$acc0,$acc0,$acc1	# see if result is zero
1179e71b7053SJung-uk Kim	or	$acc2,$acc2,$acc3
1180e71b7053SJung-uk Kim	or.	$acc0,$acc0,$acc2
1181e71b7053SJung-uk Kim	bne	.Ladd_proceed		# is_equal(U1,U2)?
1182e71b7053SJung-uk Kim
1183e71b7053SJung-uk Kim	and.	$t0,$in1infty,$in2infty
1184e71b7053SJung-uk Kim	beq	.Ladd_proceed		# (in1infty || in2infty)?
1185e71b7053SJung-uk Kim
1186e71b7053SJung-uk Kim	cmpldi	$temp,0
1187e71b7053SJung-uk Kim	beq	.Ladd_double		# is_equal(S1,S2)?
1188e71b7053SJung-uk Kim
1189e71b7053SJung-uk Kim	xor	$a0,$a0,$a0
1190e71b7053SJung-uk Kim	std	$a0,0($rp_real)
1191e71b7053SJung-uk Kim	std	$a0,8($rp_real)
1192e71b7053SJung-uk Kim	std	$a0,16($rp_real)
1193e71b7053SJung-uk Kim	std	$a0,24($rp_real)
1194e71b7053SJung-uk Kim	std	$a0,32($rp_real)
1195e71b7053SJung-uk Kim	std	$a0,40($rp_real)
1196e71b7053SJung-uk Kim	std	$a0,48($rp_real)
1197e71b7053SJung-uk Kim	std	$a0,56($rp_real)
1198e71b7053SJung-uk Kim	std	$a0,64($rp_real)
1199e71b7053SJung-uk Kim	std	$a0,72($rp_real)
1200e71b7053SJung-uk Kim	std	$a0,80($rp_real)
1201e71b7053SJung-uk Kim	std	$a0,88($rp_real)
1202e71b7053SJung-uk Kim	b	.Ladd_done
1203e71b7053SJung-uk Kim
1204e71b7053SJung-uk Kim.align	4
1205e71b7053SJung-uk Kim.Ladd_double:
1206e71b7053SJung-uk Kim	ld	$bp,0($sp)		# back-link
1207e71b7053SJung-uk Kim	mr	$ap,$ap_real
1208e71b7053SJung-uk Kim	mr	$rp,$rp_real
1209e71b7053SJung-uk Kim	ld	r16,$FRAME-8*16($sp)
1210e71b7053SJung-uk Kim	ld	r17,$FRAME-8*15($sp)
1211e71b7053SJung-uk Kim	ld	r18,$FRAME-8*14($sp)
1212e71b7053SJung-uk Kim	ld	r19,$FRAME-8*13($sp)
1213e71b7053SJung-uk Kim	stdu	$bp,$FRAME-288($sp)	# difference in stack frame sizes
1214e71b7053SJung-uk Kim	b	.Ldouble_shortcut
1215e71b7053SJung-uk Kim
1216e71b7053SJung-uk Kim.align	4
1217e71b7053SJung-uk Kim.Ladd_proceed:
1218e71b7053SJung-uk Kim	addi	$rp,$sp,$Rsqr
1219e71b7053SJung-uk Kim	bl	__ecp_nistz256_sqr_mont	# p256_sqr_mont(Rsqr, R);
1220e71b7053SJung-uk Kim
1221e71b7053SJung-uk Kim	ld	$bi,64($ap_real)
1222e71b7053SJung-uk Kim	ld	$a0,$H+0($sp)
1223e71b7053SJung-uk Kim	ld	$a1,$H+8($sp)
1224e71b7053SJung-uk Kim	ld	$a2,$H+16($sp)
1225e71b7053SJung-uk Kim	ld	$a3,$H+24($sp)
1226e71b7053SJung-uk Kim	addi	$bp,$ap_real,64
1227e71b7053SJung-uk Kim	addi	$rp,$sp,$res_z
1228e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(res_z, H, in1_z);
1229e71b7053SJung-uk Kim
1230e71b7053SJung-uk Kim	ld	$a0,$H+0($sp)
1231e71b7053SJung-uk Kim	ld	$a1,$H+8($sp)
1232e71b7053SJung-uk Kim	ld	$a2,$H+16($sp)
1233e71b7053SJung-uk Kim	ld	$a3,$H+24($sp)
1234e71b7053SJung-uk Kim	addi	$rp,$sp,$Hsqr
1235e71b7053SJung-uk Kim	bl	__ecp_nistz256_sqr_mont	# p256_sqr_mont(Hsqr, H);
1236e71b7053SJung-uk Kim
1237e71b7053SJung-uk Kim	ld	$bi,64($bp_real)
1238e71b7053SJung-uk Kim	ld	$a0,$res_z+0($sp)
1239e71b7053SJung-uk Kim	ld	$a1,$res_z+8($sp)
1240e71b7053SJung-uk Kim	ld	$a2,$res_z+16($sp)
1241e71b7053SJung-uk Kim	ld	$a3,$res_z+24($sp)
1242e71b7053SJung-uk Kim	addi	$bp,$bp_real,64
1243e71b7053SJung-uk Kim	addi	$rp,$sp,$res_z
1244e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(res_z, res_z, in2_z);
1245e71b7053SJung-uk Kim
1246e71b7053SJung-uk Kim	ld	$bi,$H($sp)
1247e71b7053SJung-uk Kim	ld	$a0,$Hsqr+0($sp)
1248e71b7053SJung-uk Kim	ld	$a1,$Hsqr+8($sp)
1249e71b7053SJung-uk Kim	ld	$a2,$Hsqr+16($sp)
1250e71b7053SJung-uk Kim	ld	$a3,$Hsqr+24($sp)
1251e71b7053SJung-uk Kim	addi	$bp,$sp,$H
1252e71b7053SJung-uk Kim	addi	$rp,$sp,$Hcub
1253e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(Hcub, Hsqr, H);
1254e71b7053SJung-uk Kim
1255e71b7053SJung-uk Kim	ld	$bi,$Hsqr($sp)
1256e71b7053SJung-uk Kim	ld	$a0,$U1+0($sp)
1257e71b7053SJung-uk Kim	ld	$a1,$U1+8($sp)
1258e71b7053SJung-uk Kim	ld	$a2,$U1+16($sp)
1259e71b7053SJung-uk Kim	ld	$a3,$U1+24($sp)
1260e71b7053SJung-uk Kim	addi	$bp,$sp,$Hsqr
1261e71b7053SJung-uk Kim	addi	$rp,$sp,$U2
1262e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(U2, U1, Hsqr);
1263e71b7053SJung-uk Kim
1264e71b7053SJung-uk Kim	mr	$t0,$acc0
1265e71b7053SJung-uk Kim	mr	$t1,$acc1
1266e71b7053SJung-uk Kim	mr	$t2,$acc2
1267e71b7053SJung-uk Kim	mr	$t3,$acc3
1268e71b7053SJung-uk Kim	addi	$rp,$sp,$Hsqr
1269e71b7053SJung-uk Kim	bl	__ecp_nistz256_add	# p256_mul_by_2(Hsqr, U2);
1270e71b7053SJung-uk Kim
1271e71b7053SJung-uk Kim	addi	$bp,$sp,$Rsqr
1272e71b7053SJung-uk Kim	addi	$rp,$sp,$res_x
1273e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_morf	# p256_sub(res_x, Rsqr, Hsqr);
1274e71b7053SJung-uk Kim
1275e71b7053SJung-uk Kim	addi	$bp,$sp,$Hcub
1276e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_from	# p256_sub(res_x, res_x, Hcub);
1277e71b7053SJung-uk Kim
1278e71b7053SJung-uk Kim	addi	$bp,$sp,$U2
1279e71b7053SJung-uk Kim	 ld	$bi,$Hcub($sp)		# forward load for p256_mul_mont
1280e71b7053SJung-uk Kim	 ld	$a0,$S1+0($sp)
1281e71b7053SJung-uk Kim	 ld	$a1,$S1+8($sp)
1282e71b7053SJung-uk Kim	 ld	$a2,$S1+16($sp)
1283e71b7053SJung-uk Kim	 ld	$a3,$S1+24($sp)
1284e71b7053SJung-uk Kim	addi	$rp,$sp,$res_y
1285e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_morf	# p256_sub(res_y, U2, res_x);
1286e71b7053SJung-uk Kim
1287e71b7053SJung-uk Kim	addi	$bp,$sp,$Hcub
1288e71b7053SJung-uk Kim	addi	$rp,$sp,$S2
1289e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(S2, S1, Hcub);
1290e71b7053SJung-uk Kim
1291e71b7053SJung-uk Kim	ld	$bi,$R($sp)
1292e71b7053SJung-uk Kim	ld	$a0,$res_y+0($sp)
1293e71b7053SJung-uk Kim	ld	$a1,$res_y+8($sp)
1294e71b7053SJung-uk Kim	ld	$a2,$res_y+16($sp)
1295e71b7053SJung-uk Kim	ld	$a3,$res_y+24($sp)
1296e71b7053SJung-uk Kim	addi	$bp,$sp,$R
1297e71b7053SJung-uk Kim	addi	$rp,$sp,$res_y
1298e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(res_y, res_y, R);
1299e71b7053SJung-uk Kim
1300e71b7053SJung-uk Kim	addi	$bp,$sp,$S2
1301e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_from	# p256_sub(res_y, res_y, S2);
1302e71b7053SJung-uk Kim
1303e71b7053SJung-uk Kim	ld	$t0,0($bp_real)		# in2
1304e71b7053SJung-uk Kim	ld	$t1,8($bp_real)
1305e71b7053SJung-uk Kim	ld	$t2,16($bp_real)
1306e71b7053SJung-uk Kim	ld	$t3,24($bp_real)
1307e71b7053SJung-uk Kim	ld	$a0,$res_x+0($sp)	# res
1308e71b7053SJung-uk Kim	ld	$a1,$res_x+8($sp)
1309e71b7053SJung-uk Kim	ld	$a2,$res_x+16($sp)
1310e71b7053SJung-uk Kim	ld	$a3,$res_x+24($sp)
1311e71b7053SJung-uk Kim___
1312e71b7053SJung-uk Kimfor($i=0;$i<64;$i+=32) {		# conditional moves
1313e71b7053SJung-uk Kim$code.=<<___;
1314e71b7053SJung-uk Kim	ld	$acc0,$i+0($ap_real)	# in1
1315e71b7053SJung-uk Kim	ld	$acc1,$i+8($ap_real)
1316e71b7053SJung-uk Kim	ld	$acc2,$i+16($ap_real)
1317e71b7053SJung-uk Kim	ld	$acc3,$i+24($ap_real)
1318e71b7053SJung-uk Kim	andc	$t0,$t0,$in1infty
1319e71b7053SJung-uk Kim	andc	$t1,$t1,$in1infty
1320e71b7053SJung-uk Kim	andc	$t2,$t2,$in1infty
1321e71b7053SJung-uk Kim	andc	$t3,$t3,$in1infty
1322e71b7053SJung-uk Kim	and	$a0,$a0,$in1infty
1323e71b7053SJung-uk Kim	and	$a1,$a1,$in1infty
1324e71b7053SJung-uk Kim	and	$a2,$a2,$in1infty
1325e71b7053SJung-uk Kim	and	$a3,$a3,$in1infty
1326e71b7053SJung-uk Kim	or	$t0,$t0,$a0
1327e71b7053SJung-uk Kim	or	$t1,$t1,$a1
1328e71b7053SJung-uk Kim	or	$t2,$t2,$a2
1329e71b7053SJung-uk Kim	or	$t3,$t3,$a3
1330e71b7053SJung-uk Kim	andc	$acc0,$acc0,$in2infty
1331e71b7053SJung-uk Kim	andc	$acc1,$acc1,$in2infty
1332e71b7053SJung-uk Kim	andc	$acc2,$acc2,$in2infty
1333e71b7053SJung-uk Kim	andc	$acc3,$acc3,$in2infty
1334e71b7053SJung-uk Kim	and	$t0,$t0,$in2infty
1335e71b7053SJung-uk Kim	and	$t1,$t1,$in2infty
1336e71b7053SJung-uk Kim	and	$t2,$t2,$in2infty
1337e71b7053SJung-uk Kim	and	$t3,$t3,$in2infty
1338e71b7053SJung-uk Kim	or	$acc0,$acc0,$t0
1339e71b7053SJung-uk Kim	or	$acc1,$acc1,$t1
1340e71b7053SJung-uk Kim	or	$acc2,$acc2,$t2
1341e71b7053SJung-uk Kim	or	$acc3,$acc3,$t3
1342e71b7053SJung-uk Kim
1343e71b7053SJung-uk Kim	ld	$t0,$i+32($bp_real)	# in2
1344e71b7053SJung-uk Kim	ld	$t1,$i+40($bp_real)
1345e71b7053SJung-uk Kim	ld	$t2,$i+48($bp_real)
1346e71b7053SJung-uk Kim	ld	$t3,$i+56($bp_real)
1347e71b7053SJung-uk Kim	ld	$a0,$res_x+$i+32($sp)
1348e71b7053SJung-uk Kim	ld	$a1,$res_x+$i+40($sp)
1349e71b7053SJung-uk Kim	ld	$a2,$res_x+$i+48($sp)
1350e71b7053SJung-uk Kim	ld	$a3,$res_x+$i+56($sp)
1351e71b7053SJung-uk Kim	std	$acc0,$i+0($rp_real)
1352e71b7053SJung-uk Kim	std	$acc1,$i+8($rp_real)
1353e71b7053SJung-uk Kim	std	$acc2,$i+16($rp_real)
1354e71b7053SJung-uk Kim	std	$acc3,$i+24($rp_real)
1355e71b7053SJung-uk Kim___
1356e71b7053SJung-uk Kim}
1357e71b7053SJung-uk Kim$code.=<<___;
1358e71b7053SJung-uk Kim	ld	$acc0,$i+0($ap_real)	# in1
1359e71b7053SJung-uk Kim	ld	$acc1,$i+8($ap_real)
1360e71b7053SJung-uk Kim	ld	$acc2,$i+16($ap_real)
1361e71b7053SJung-uk Kim	ld	$acc3,$i+24($ap_real)
1362e71b7053SJung-uk Kim	andc	$t0,$t0,$in1infty
1363e71b7053SJung-uk Kim	andc	$t1,$t1,$in1infty
1364e71b7053SJung-uk Kim	andc	$t2,$t2,$in1infty
1365e71b7053SJung-uk Kim	andc	$t3,$t3,$in1infty
1366e71b7053SJung-uk Kim	and	$a0,$a0,$in1infty
1367e71b7053SJung-uk Kim	and	$a1,$a1,$in1infty
1368e71b7053SJung-uk Kim	and	$a2,$a2,$in1infty
1369e71b7053SJung-uk Kim	and	$a3,$a3,$in1infty
1370e71b7053SJung-uk Kim	or	$t0,$t0,$a0
1371e71b7053SJung-uk Kim	or	$t1,$t1,$a1
1372e71b7053SJung-uk Kim	or	$t2,$t2,$a2
1373e71b7053SJung-uk Kim	or	$t3,$t3,$a3
1374e71b7053SJung-uk Kim	andc	$acc0,$acc0,$in2infty
1375e71b7053SJung-uk Kim	andc	$acc1,$acc1,$in2infty
1376e71b7053SJung-uk Kim	andc	$acc2,$acc2,$in2infty
1377e71b7053SJung-uk Kim	andc	$acc3,$acc3,$in2infty
1378e71b7053SJung-uk Kim	and	$t0,$t0,$in2infty
1379e71b7053SJung-uk Kim	and	$t1,$t1,$in2infty
1380e71b7053SJung-uk Kim	and	$t2,$t2,$in2infty
1381e71b7053SJung-uk Kim	and	$t3,$t3,$in2infty
1382e71b7053SJung-uk Kim	or	$acc0,$acc0,$t0
1383e71b7053SJung-uk Kim	or	$acc1,$acc1,$t1
1384e71b7053SJung-uk Kim	or	$acc2,$acc2,$t2
1385e71b7053SJung-uk Kim	or	$acc3,$acc3,$t3
1386e71b7053SJung-uk Kim	std	$acc0,$i+0($rp_real)
1387e71b7053SJung-uk Kim	std	$acc1,$i+8($rp_real)
1388e71b7053SJung-uk Kim	std	$acc2,$i+16($rp_real)
1389e71b7053SJung-uk Kim	std	$acc3,$i+24($rp_real)
1390e71b7053SJung-uk Kim
1391e71b7053SJung-uk Kim.Ladd_done:
1392e71b7053SJung-uk Kim	mtlr	r0
1393e71b7053SJung-uk Kim	ld	r16,$FRAME-8*16($sp)
1394e71b7053SJung-uk Kim	ld	r17,$FRAME-8*15($sp)
1395e71b7053SJung-uk Kim	ld	r18,$FRAME-8*14($sp)
1396e71b7053SJung-uk Kim	ld	r19,$FRAME-8*13($sp)
1397e71b7053SJung-uk Kim	ld	r20,$FRAME-8*12($sp)
1398e71b7053SJung-uk Kim	ld	r21,$FRAME-8*11($sp)
1399e71b7053SJung-uk Kim	ld	r22,$FRAME-8*10($sp)
1400e71b7053SJung-uk Kim	ld	r23,$FRAME-8*9($sp)
1401e71b7053SJung-uk Kim	ld	r24,$FRAME-8*8($sp)
1402e71b7053SJung-uk Kim	ld	r25,$FRAME-8*7($sp)
1403e71b7053SJung-uk Kim	ld	r26,$FRAME-8*6($sp)
1404e71b7053SJung-uk Kim	ld	r27,$FRAME-8*5($sp)
1405e71b7053SJung-uk Kim	ld	r28,$FRAME-8*4($sp)
1406e71b7053SJung-uk Kim	ld	r29,$FRAME-8*3($sp)
1407e71b7053SJung-uk Kim	ld	r30,$FRAME-8*2($sp)
1408e71b7053SJung-uk Kim	ld	r31,$FRAME-8*1($sp)
1409e71b7053SJung-uk Kim	addi	$sp,$sp,$FRAME
1410e71b7053SJung-uk Kim	blr
1411e71b7053SJung-uk Kim	.long	0
1412e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,16,3,0
1413e71b7053SJung-uk Kim	.long	0
1414e71b7053SJung-uk Kim.size	ecp_nistz256_point_add,.-ecp_nistz256_point_add
1415e71b7053SJung-uk Kim___
1416e71b7053SJung-uk Kim}
1417e71b7053SJung-uk Kim
1418e71b7053SJung-uk Kim########################################################################
1419e71b7053SJung-uk Kim# void ecp_nistz256_point_add_affine(P256_POINT *out,const P256_POINT *in1,
1420e71b7053SJung-uk Kim#				     const P256_POINT_AFFINE *in2);
1421e71b7053SJung-uk Kimif (1) {
1422e71b7053SJung-uk Kimmy $FRAME = 64 + 32*10 + 16*8;
1423e71b7053SJung-uk Kimmy ($res_x,$res_y,$res_z,
1424e71b7053SJung-uk Kim    $U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr)=map(64+32*$_,(0..9));
1425e71b7053SJung-uk Kimmy $Z1sqr = $S2;
1426e71b7053SJung-uk Kim# above map() describes stack layout with 10 temporary
1427e71b7053SJung-uk Kim# 256-bit vectors on top.
1428e71b7053SJung-uk Kimmy ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp)=map("r$_",(16..21));
1429e71b7053SJung-uk Kim
1430e71b7053SJung-uk Kim$code.=<<___;
1431e71b7053SJung-uk Kim.globl	ecp_nistz256_point_add_affine
1432e71b7053SJung-uk Kim.align	5
1433e71b7053SJung-uk Kimecp_nistz256_point_add_affine:
1434e71b7053SJung-uk Kim	stdu	$sp,-$FRAME($sp)
1435e71b7053SJung-uk Kim	mflr	r0
1436e71b7053SJung-uk Kim	std	r16,$FRAME-8*16($sp)
1437e71b7053SJung-uk Kim	std	r17,$FRAME-8*15($sp)
1438e71b7053SJung-uk Kim	std	r18,$FRAME-8*14($sp)
1439e71b7053SJung-uk Kim	std	r19,$FRAME-8*13($sp)
1440e71b7053SJung-uk Kim	std	r20,$FRAME-8*12($sp)
1441e71b7053SJung-uk Kim	std	r21,$FRAME-8*11($sp)
1442e71b7053SJung-uk Kim	std	r22,$FRAME-8*10($sp)
1443e71b7053SJung-uk Kim	std	r23,$FRAME-8*9($sp)
1444e71b7053SJung-uk Kim	std	r24,$FRAME-8*8($sp)
1445e71b7053SJung-uk Kim	std	r25,$FRAME-8*7($sp)
1446e71b7053SJung-uk Kim	std	r26,$FRAME-8*6($sp)
1447e71b7053SJung-uk Kim	std	r27,$FRAME-8*5($sp)
1448e71b7053SJung-uk Kim	std	r28,$FRAME-8*4($sp)
1449e71b7053SJung-uk Kim	std	r29,$FRAME-8*3($sp)
1450e71b7053SJung-uk Kim	std	r30,$FRAME-8*2($sp)
1451e71b7053SJung-uk Kim	std	r31,$FRAME-8*1($sp)
1452e71b7053SJung-uk Kim
1453e71b7053SJung-uk Kim	li	$poly1,-1
1454e71b7053SJung-uk Kim	srdi	$poly1,$poly1,32	# 0x00000000ffffffff
1455e71b7053SJung-uk Kim	li	$poly3,1
1456e71b7053SJung-uk Kim	orc	$poly3,$poly3,$poly1	# 0xffffffff00000001
1457e71b7053SJung-uk Kim
1458e71b7053SJung-uk Kim	mr	$rp_real,$rp
1459e71b7053SJung-uk Kim	mr	$ap_real,$ap
1460e71b7053SJung-uk Kim	mr	$bp_real,$bp
1461e71b7053SJung-uk Kim
1462e71b7053SJung-uk Kim	ld	$a0,64($ap)		# in1_z
1463e71b7053SJung-uk Kim	ld	$a1,72($ap)
1464e71b7053SJung-uk Kim	ld	$a2,80($ap)
1465e71b7053SJung-uk Kim	ld	$a3,88($ap)
1466e71b7053SJung-uk Kim	or	$t0,$a0,$a1
1467e71b7053SJung-uk Kim	or	$t2,$a2,$a3
1468e71b7053SJung-uk Kim	or	$in1infty,$t0,$t2
1469e71b7053SJung-uk Kim	neg	$t0,$in1infty
1470e71b7053SJung-uk Kim	or	$in1infty,$in1infty,$t0
1471e71b7053SJung-uk Kim	sradi	$in1infty,$in1infty,63	# !in1infty
1472e71b7053SJung-uk Kim
1473e71b7053SJung-uk Kim	ld	$acc0,0($bp)		# in2_x
1474e71b7053SJung-uk Kim	ld	$acc1,8($bp)
1475e71b7053SJung-uk Kim	ld	$acc2,16($bp)
1476e71b7053SJung-uk Kim	ld	$acc3,24($bp)
1477e71b7053SJung-uk Kim	ld	$t0,32($bp)		# in2_y
1478e71b7053SJung-uk Kim	ld	$t1,40($bp)
1479e71b7053SJung-uk Kim	ld	$t2,48($bp)
1480e71b7053SJung-uk Kim	ld	$t3,56($bp)
1481e71b7053SJung-uk Kim	or	$acc0,$acc0,$acc1
1482e71b7053SJung-uk Kim	or	$acc2,$acc2,$acc3
1483e71b7053SJung-uk Kim	or	$acc0,$acc0,$acc2
1484e71b7053SJung-uk Kim	or	$t0,$t0,$t1
1485e71b7053SJung-uk Kim	or	$t2,$t2,$t3
1486e71b7053SJung-uk Kim	or	$t0,$t0,$t2
1487e71b7053SJung-uk Kim	or	$in2infty,$acc0,$t0
1488e71b7053SJung-uk Kim	neg	$t0,$in2infty
1489e71b7053SJung-uk Kim	or	$in2infty,$in2infty,$t0
1490e71b7053SJung-uk Kim	sradi	$in2infty,$in2infty,63	# !in2infty
1491e71b7053SJung-uk Kim
1492e71b7053SJung-uk Kim	addi	$rp,$sp,$Z1sqr
1493e71b7053SJung-uk Kim	bl	__ecp_nistz256_sqr_mont	# p256_sqr_mont(Z1sqr, in1_z);
1494e71b7053SJung-uk Kim
1495e71b7053SJung-uk Kim	mr	$a0,$acc0
1496e71b7053SJung-uk Kim	mr	$a1,$acc1
1497e71b7053SJung-uk Kim	mr	$a2,$acc2
1498e71b7053SJung-uk Kim	mr	$a3,$acc3
1499e71b7053SJung-uk Kim	ld	$bi,0($bp_real)
1500e71b7053SJung-uk Kim	addi	$bp,$bp_real,0
1501e71b7053SJung-uk Kim	addi	$rp,$sp,$U2
1502e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(U2, Z1sqr, in2_x);
1503e71b7053SJung-uk Kim
1504e71b7053SJung-uk Kim	addi	$bp,$ap_real,0
1505e71b7053SJung-uk Kim	 ld	$bi,64($ap_real)	# forward load for p256_mul_mont
1506e71b7053SJung-uk Kim	 ld	$a0,$Z1sqr+0($sp)
1507e71b7053SJung-uk Kim	 ld	$a1,$Z1sqr+8($sp)
1508e71b7053SJung-uk Kim	 ld	$a2,$Z1sqr+16($sp)
1509e71b7053SJung-uk Kim	 ld	$a3,$Z1sqr+24($sp)
1510e71b7053SJung-uk Kim	addi	$rp,$sp,$H
1511e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_from	# p256_sub(H, U2, in1_x);
1512e71b7053SJung-uk Kim
1513e71b7053SJung-uk Kim	addi	$bp,$ap_real,64
1514e71b7053SJung-uk Kim	addi	$rp,$sp,$S2
1515e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(S2, Z1sqr, in1_z);
1516e71b7053SJung-uk Kim
1517e71b7053SJung-uk Kim	ld	$bi,64($ap_real)
1518e71b7053SJung-uk Kim	ld	$a0,$H+0($sp)
1519e71b7053SJung-uk Kim	ld	$a1,$H+8($sp)
1520e71b7053SJung-uk Kim	ld	$a2,$H+16($sp)
1521e71b7053SJung-uk Kim	ld	$a3,$H+24($sp)
1522e71b7053SJung-uk Kim	addi	$bp,$ap_real,64
1523e71b7053SJung-uk Kim	addi	$rp,$sp,$res_z
1524e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(res_z, H, in1_z);
1525e71b7053SJung-uk Kim
1526e71b7053SJung-uk Kim	ld	$bi,32($bp_real)
1527e71b7053SJung-uk Kim	ld	$a0,$S2+0($sp)
1528e71b7053SJung-uk Kim	ld	$a1,$S2+8($sp)
1529e71b7053SJung-uk Kim	ld	$a2,$S2+16($sp)
1530e71b7053SJung-uk Kim	ld	$a3,$S2+24($sp)
1531e71b7053SJung-uk Kim	addi	$bp,$bp_real,32
1532e71b7053SJung-uk Kim	addi	$rp,$sp,$S2
1533e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(S2, S2, in2_y);
1534e71b7053SJung-uk Kim
1535e71b7053SJung-uk Kim	addi	$bp,$ap_real,32
1536e71b7053SJung-uk Kim	 ld	$a0,$H+0($sp)		# forward load for p256_sqr_mont
1537e71b7053SJung-uk Kim	 ld	$a1,$H+8($sp)
1538e71b7053SJung-uk Kim	 ld	$a2,$H+16($sp)
1539e71b7053SJung-uk Kim	 ld	$a3,$H+24($sp)
1540e71b7053SJung-uk Kim	addi	$rp,$sp,$R
1541e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_from	# p256_sub(R, S2, in1_y);
1542e71b7053SJung-uk Kim
1543e71b7053SJung-uk Kim	addi	$rp,$sp,$Hsqr
1544e71b7053SJung-uk Kim	bl	__ecp_nistz256_sqr_mont	# p256_sqr_mont(Hsqr, H);
1545e71b7053SJung-uk Kim
1546e71b7053SJung-uk Kim	ld	$a0,$R+0($sp)
1547e71b7053SJung-uk Kim	ld	$a1,$R+8($sp)
1548e71b7053SJung-uk Kim	ld	$a2,$R+16($sp)
1549e71b7053SJung-uk Kim	ld	$a3,$R+24($sp)
1550e71b7053SJung-uk Kim	addi	$rp,$sp,$Rsqr
1551e71b7053SJung-uk Kim	bl	__ecp_nistz256_sqr_mont	# p256_sqr_mont(Rsqr, R);
1552e71b7053SJung-uk Kim
1553e71b7053SJung-uk Kim	ld	$bi,$H($sp)
1554e71b7053SJung-uk Kim	ld	$a0,$Hsqr+0($sp)
1555e71b7053SJung-uk Kim	ld	$a1,$Hsqr+8($sp)
1556e71b7053SJung-uk Kim	ld	$a2,$Hsqr+16($sp)
1557e71b7053SJung-uk Kim	ld	$a3,$Hsqr+24($sp)
1558e71b7053SJung-uk Kim	addi	$bp,$sp,$H
1559e71b7053SJung-uk Kim	addi	$rp,$sp,$Hcub
1560e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(Hcub, Hsqr, H);
1561e71b7053SJung-uk Kim
1562e71b7053SJung-uk Kim	ld	$bi,0($ap_real)
1563e71b7053SJung-uk Kim	ld	$a0,$Hsqr+0($sp)
1564e71b7053SJung-uk Kim	ld	$a1,$Hsqr+8($sp)
1565e71b7053SJung-uk Kim	ld	$a2,$Hsqr+16($sp)
1566e71b7053SJung-uk Kim	ld	$a3,$Hsqr+24($sp)
1567e71b7053SJung-uk Kim	addi	$bp,$ap_real,0
1568e71b7053SJung-uk Kim	addi	$rp,$sp,$U2
1569e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(U2, in1_x, Hsqr);
1570e71b7053SJung-uk Kim
1571e71b7053SJung-uk Kim	mr	$t0,$acc0
1572e71b7053SJung-uk Kim	mr	$t1,$acc1
1573e71b7053SJung-uk Kim	mr	$t2,$acc2
1574e71b7053SJung-uk Kim	mr	$t3,$acc3
1575e71b7053SJung-uk Kim	addi	$rp,$sp,$Hsqr
1576e71b7053SJung-uk Kim	bl	__ecp_nistz256_add	# p256_mul_by_2(Hsqr, U2);
1577e71b7053SJung-uk Kim
1578e71b7053SJung-uk Kim	addi	$bp,$sp,$Rsqr
1579e71b7053SJung-uk Kim	addi	$rp,$sp,$res_x
1580e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_morf	# p256_sub(res_x, Rsqr, Hsqr);
1581e71b7053SJung-uk Kim
1582e71b7053SJung-uk Kim	addi	$bp,$sp,$Hcub
1583e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_from	#  p256_sub(res_x, res_x, Hcub);
1584e71b7053SJung-uk Kim
1585e71b7053SJung-uk Kim	addi	$bp,$sp,$U2
1586e71b7053SJung-uk Kim	 ld	$bi,32($ap_real)	# forward load for p256_mul_mont
1587e71b7053SJung-uk Kim	 ld	$a0,$Hcub+0($sp)
1588e71b7053SJung-uk Kim	 ld	$a1,$Hcub+8($sp)
1589e71b7053SJung-uk Kim	 ld	$a2,$Hcub+16($sp)
1590e71b7053SJung-uk Kim	 ld	$a3,$Hcub+24($sp)
1591e71b7053SJung-uk Kim	addi	$rp,$sp,$res_y
1592e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_morf	# p256_sub(res_y, U2, res_x);
1593e71b7053SJung-uk Kim
1594e71b7053SJung-uk Kim	addi	$bp,$ap_real,32
1595e71b7053SJung-uk Kim	addi	$rp,$sp,$S2
1596e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(S2, in1_y, Hcub);
1597e71b7053SJung-uk Kim
1598e71b7053SJung-uk Kim	ld	$bi,$R($sp)
1599e71b7053SJung-uk Kim	ld	$a0,$res_y+0($sp)
1600e71b7053SJung-uk Kim	ld	$a1,$res_y+8($sp)
1601e71b7053SJung-uk Kim	ld	$a2,$res_y+16($sp)
1602e71b7053SJung-uk Kim	ld	$a3,$res_y+24($sp)
1603e71b7053SJung-uk Kim	addi	$bp,$sp,$R
1604e71b7053SJung-uk Kim	addi	$rp,$sp,$res_y
1605e71b7053SJung-uk Kim	bl	__ecp_nistz256_mul_mont	# p256_mul_mont(res_y, res_y, R);
1606e71b7053SJung-uk Kim
1607e71b7053SJung-uk Kim	addi	$bp,$sp,$S2
1608e71b7053SJung-uk Kim	bl	__ecp_nistz256_sub_from	# p256_sub(res_y, res_y, S2);
1609e71b7053SJung-uk Kim
1610e71b7053SJung-uk Kim	ld	$t0,0($bp_real)		# in2
1611e71b7053SJung-uk Kim	ld	$t1,8($bp_real)
1612e71b7053SJung-uk Kim	ld	$t2,16($bp_real)
1613e71b7053SJung-uk Kim	ld	$t3,24($bp_real)
1614e71b7053SJung-uk Kim	ld	$a0,$res_x+0($sp)	# res
1615e71b7053SJung-uk Kim	ld	$a1,$res_x+8($sp)
1616e71b7053SJung-uk Kim	ld	$a2,$res_x+16($sp)
1617e71b7053SJung-uk Kim	ld	$a3,$res_x+24($sp)
1618e71b7053SJung-uk Kim___
1619e71b7053SJung-uk Kimfor($i=0;$i<64;$i+=32) {		# conditional moves
1620e71b7053SJung-uk Kim$code.=<<___;
1621e71b7053SJung-uk Kim	ld	$acc0,$i+0($ap_real)	# in1
1622e71b7053SJung-uk Kim	ld	$acc1,$i+8($ap_real)
1623e71b7053SJung-uk Kim	ld	$acc2,$i+16($ap_real)
1624e71b7053SJung-uk Kim	ld	$acc3,$i+24($ap_real)
1625e71b7053SJung-uk Kim	andc	$t0,$t0,$in1infty
1626e71b7053SJung-uk Kim	andc	$t1,$t1,$in1infty
1627e71b7053SJung-uk Kim	andc	$t2,$t2,$in1infty
1628e71b7053SJung-uk Kim	andc	$t3,$t3,$in1infty
1629e71b7053SJung-uk Kim	and	$a0,$a0,$in1infty
1630e71b7053SJung-uk Kim	and	$a1,$a1,$in1infty
1631e71b7053SJung-uk Kim	and	$a2,$a2,$in1infty
1632e71b7053SJung-uk Kim	and	$a3,$a3,$in1infty
1633e71b7053SJung-uk Kim	or	$t0,$t0,$a0
1634e71b7053SJung-uk Kim	or	$t1,$t1,$a1
1635e71b7053SJung-uk Kim	or	$t2,$t2,$a2
1636e71b7053SJung-uk Kim	or	$t3,$t3,$a3
1637e71b7053SJung-uk Kim	andc	$acc0,$acc0,$in2infty
1638e71b7053SJung-uk Kim	andc	$acc1,$acc1,$in2infty
1639e71b7053SJung-uk Kim	andc	$acc2,$acc2,$in2infty
1640e71b7053SJung-uk Kim	andc	$acc3,$acc3,$in2infty
1641e71b7053SJung-uk Kim	and	$t0,$t0,$in2infty
1642e71b7053SJung-uk Kim	and	$t1,$t1,$in2infty
1643e71b7053SJung-uk Kim	and	$t2,$t2,$in2infty
1644e71b7053SJung-uk Kim	and	$t3,$t3,$in2infty
1645e71b7053SJung-uk Kim	or	$acc0,$acc0,$t0
1646e71b7053SJung-uk Kim	or	$acc1,$acc1,$t1
1647e71b7053SJung-uk Kim	or	$acc2,$acc2,$t2
1648e71b7053SJung-uk Kim	or	$acc3,$acc3,$t3
1649e71b7053SJung-uk Kim___
1650e71b7053SJung-uk Kim$code.=<<___	if ($i==0);
1651e71b7053SJung-uk Kim	ld	$t0,32($bp_real)	# in2
1652e71b7053SJung-uk Kim	ld	$t1,40($bp_real)
1653e71b7053SJung-uk Kim	ld	$t2,48($bp_real)
1654e71b7053SJung-uk Kim	ld	$t3,56($bp_real)
1655e71b7053SJung-uk Kim___
1656e71b7053SJung-uk Kim$code.=<<___	if ($i==32);
1657e71b7053SJung-uk Kim	li	$t0,1			# Lone_mont
1658e71b7053SJung-uk Kim	not	$t1,$poly1
1659e71b7053SJung-uk Kim	li	$t2,-1
1660e71b7053SJung-uk Kim	not	$t3,$poly3
1661e71b7053SJung-uk Kim___
1662e71b7053SJung-uk Kim$code.=<<___;
1663e71b7053SJung-uk Kim	ld	$a0,$res_x+$i+32($sp)
1664e71b7053SJung-uk Kim	ld	$a1,$res_x+$i+40($sp)
1665e71b7053SJung-uk Kim	ld	$a2,$res_x+$i+48($sp)
1666e71b7053SJung-uk Kim	ld	$a3,$res_x+$i+56($sp)
1667e71b7053SJung-uk Kim	std	$acc0,$i+0($rp_real)
1668e71b7053SJung-uk Kim	std	$acc1,$i+8($rp_real)
1669e71b7053SJung-uk Kim	std	$acc2,$i+16($rp_real)
1670e71b7053SJung-uk Kim	std	$acc3,$i+24($rp_real)
1671e71b7053SJung-uk Kim___
1672e71b7053SJung-uk Kim}
1673e71b7053SJung-uk Kim$code.=<<___;
1674e71b7053SJung-uk Kim	ld	$acc0,$i+0($ap_real)	# in1
1675e71b7053SJung-uk Kim	ld	$acc1,$i+8($ap_real)
1676e71b7053SJung-uk Kim	ld	$acc2,$i+16($ap_real)
1677e71b7053SJung-uk Kim	ld	$acc3,$i+24($ap_real)
1678e71b7053SJung-uk Kim	andc	$t0,$t0,$in1infty
1679e71b7053SJung-uk Kim	andc	$t1,$t1,$in1infty
1680e71b7053SJung-uk Kim	andc	$t2,$t2,$in1infty
1681e71b7053SJung-uk Kim	andc	$t3,$t3,$in1infty
1682e71b7053SJung-uk Kim	and	$a0,$a0,$in1infty
1683e71b7053SJung-uk Kim	and	$a1,$a1,$in1infty
1684e71b7053SJung-uk Kim	and	$a2,$a2,$in1infty
1685e71b7053SJung-uk Kim	and	$a3,$a3,$in1infty
1686e71b7053SJung-uk Kim	or	$t0,$t0,$a0
1687e71b7053SJung-uk Kim	or	$t1,$t1,$a1
1688e71b7053SJung-uk Kim	or	$t2,$t2,$a2
1689e71b7053SJung-uk Kim	or	$t3,$t3,$a3
1690e71b7053SJung-uk Kim	andc	$acc0,$acc0,$in2infty
1691e71b7053SJung-uk Kim	andc	$acc1,$acc1,$in2infty
1692e71b7053SJung-uk Kim	andc	$acc2,$acc2,$in2infty
1693e71b7053SJung-uk Kim	andc	$acc3,$acc3,$in2infty
1694e71b7053SJung-uk Kim	and	$t0,$t0,$in2infty
1695e71b7053SJung-uk Kim	and	$t1,$t1,$in2infty
1696e71b7053SJung-uk Kim	and	$t2,$t2,$in2infty
1697e71b7053SJung-uk Kim	and	$t3,$t3,$in2infty
1698e71b7053SJung-uk Kim	or	$acc0,$acc0,$t0
1699e71b7053SJung-uk Kim	or	$acc1,$acc1,$t1
1700e71b7053SJung-uk Kim	or	$acc2,$acc2,$t2
1701e71b7053SJung-uk Kim	or	$acc3,$acc3,$t3
1702e71b7053SJung-uk Kim	std	$acc0,$i+0($rp_real)
1703e71b7053SJung-uk Kim	std	$acc1,$i+8($rp_real)
1704e71b7053SJung-uk Kim	std	$acc2,$i+16($rp_real)
1705e71b7053SJung-uk Kim	std	$acc3,$i+24($rp_real)
1706e71b7053SJung-uk Kim
1707e71b7053SJung-uk Kim	mtlr	r0
1708e71b7053SJung-uk Kim	ld	r16,$FRAME-8*16($sp)
1709e71b7053SJung-uk Kim	ld	r17,$FRAME-8*15($sp)
1710e71b7053SJung-uk Kim	ld	r18,$FRAME-8*14($sp)
1711e71b7053SJung-uk Kim	ld	r19,$FRAME-8*13($sp)
1712e71b7053SJung-uk Kim	ld	r20,$FRAME-8*12($sp)
1713e71b7053SJung-uk Kim	ld	r21,$FRAME-8*11($sp)
1714e71b7053SJung-uk Kim	ld	r22,$FRAME-8*10($sp)
1715e71b7053SJung-uk Kim	ld	r23,$FRAME-8*9($sp)
1716e71b7053SJung-uk Kim	ld	r24,$FRAME-8*8($sp)
1717e71b7053SJung-uk Kim	ld	r25,$FRAME-8*7($sp)
1718e71b7053SJung-uk Kim	ld	r26,$FRAME-8*6($sp)
1719e71b7053SJung-uk Kim	ld	r27,$FRAME-8*5($sp)
1720e71b7053SJung-uk Kim	ld	r28,$FRAME-8*4($sp)
1721e71b7053SJung-uk Kim	ld	r29,$FRAME-8*3($sp)
1722e71b7053SJung-uk Kim	ld	r30,$FRAME-8*2($sp)
1723e71b7053SJung-uk Kim	ld	r31,$FRAME-8*1($sp)
1724e71b7053SJung-uk Kim	addi	$sp,$sp,$FRAME
1725e71b7053SJung-uk Kim	blr
1726e71b7053SJung-uk Kim	.long	0
1727e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,16,3,0
1728e71b7053SJung-uk Kim	.long	0
1729e71b7053SJung-uk Kim.size	ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine
1730e71b7053SJung-uk Kim___
1731e71b7053SJung-uk Kim}
1732e71b7053SJung-uk Kimif (1) {
1733e71b7053SJung-uk Kimmy ($ordk,$ord0,$ord1,$t4) = map("r$_",(18..21));
1734e71b7053SJung-uk Kimmy ($ord2,$ord3,$zr) = ($poly1,$poly3,"r0");
1735e71b7053SJung-uk Kim
1736e71b7053SJung-uk Kim$code.=<<___;
1737e71b7053SJung-uk Kim########################################################################
1738e71b7053SJung-uk Kim# void ecp_nistz256_ord_mul_mont(uint64_t res[4], uint64_t a[4],
1739e71b7053SJung-uk Kim#                                uint64_t b[4]);
1740e71b7053SJung-uk Kim.globl	ecp_nistz256_ord_mul_mont
1741e71b7053SJung-uk Kim.align	5
1742e71b7053SJung-uk Kimecp_nistz256_ord_mul_mont:
1743e71b7053SJung-uk Kim	stdu	$sp,-160($sp)
1744e71b7053SJung-uk Kim	std	r18,48($sp)
1745e71b7053SJung-uk Kim	std	r19,56($sp)
1746e71b7053SJung-uk Kim	std	r20,64($sp)
1747e71b7053SJung-uk Kim	std	r21,72($sp)
1748e71b7053SJung-uk Kim	std	r22,80($sp)
1749e71b7053SJung-uk Kim	std	r23,88($sp)
1750e71b7053SJung-uk Kim	std	r24,96($sp)
1751e71b7053SJung-uk Kim	std	r25,104($sp)
1752e71b7053SJung-uk Kim	std	r26,112($sp)
1753e71b7053SJung-uk Kim	std	r27,120($sp)
1754e71b7053SJung-uk Kim	std	r28,128($sp)
1755e71b7053SJung-uk Kim	std	r29,136($sp)
1756e71b7053SJung-uk Kim	std	r30,144($sp)
1757e71b7053SJung-uk Kim	std	r31,152($sp)
1758e71b7053SJung-uk Kim
1759e71b7053SJung-uk Kim	ld	$a0,0($ap)
1760e71b7053SJung-uk Kim	ld	$bi,0($bp)
1761e71b7053SJung-uk Kim	ld	$a1,8($ap)
1762e71b7053SJung-uk Kim	ld	$a2,16($ap)
1763e71b7053SJung-uk Kim	ld	$a3,24($ap)
1764e71b7053SJung-uk Kim
1765e71b7053SJung-uk Kim	lis	$ordk,0xccd1
1766e71b7053SJung-uk Kim	lis	$ord0,0xf3b9
1767e71b7053SJung-uk Kim	lis	$ord1,0xbce6
1768e71b7053SJung-uk Kim	ori	$ordk,$ordk,0xc8aa
1769e71b7053SJung-uk Kim	ori	$ord0,$ord0,0xcac2
1770e71b7053SJung-uk Kim	ori	$ord1,$ord1,0xfaad
1771e71b7053SJung-uk Kim	sldi	$ordk,$ordk,32
1772e71b7053SJung-uk Kim	sldi	$ord0,$ord0,32
1773e71b7053SJung-uk Kim	sldi	$ord1,$ord1,32
1774e71b7053SJung-uk Kim	oris	$ordk,$ordk,0xee00
1775e71b7053SJung-uk Kim	oris	$ord0,$ord0,0xfc63
1776e71b7053SJung-uk Kim	oris	$ord1,$ord1,0xa717
1777e71b7053SJung-uk Kim	ori	$ordk,$ordk,0xbc4f	# 0xccd1c8aaee00bc4f
1778e71b7053SJung-uk Kim	ori	$ord0,$ord0,0x2551	# 0xf3b9cac2fc632551
1779e71b7053SJung-uk Kim	ori	$ord1,$ord1,0x9e84	# 0xbce6faada7179e84
1780e71b7053SJung-uk Kim	li	$ord2,-1		# 0xffffffffffffffff
1781e71b7053SJung-uk Kim	sldi	$ord3,$ord2,32		# 0xffffffff00000000
1782e71b7053SJung-uk Kim	li	$zr,0
1783e71b7053SJung-uk Kim
1784e71b7053SJung-uk Kim	mulld	$acc0,$a0,$bi		# a[0]*b[0]
1785e71b7053SJung-uk Kim	mulhdu	$t0,$a0,$bi
1786e71b7053SJung-uk Kim
1787e71b7053SJung-uk Kim	mulld	$acc1,$a1,$bi		# a[1]*b[0]
1788e71b7053SJung-uk Kim	mulhdu	$t1,$a1,$bi
1789e71b7053SJung-uk Kim
1790e71b7053SJung-uk Kim	mulld	$acc2,$a2,$bi		# a[2]*b[0]
1791e71b7053SJung-uk Kim	mulhdu	$t2,$a2,$bi
1792e71b7053SJung-uk Kim
1793e71b7053SJung-uk Kim	mulld	$acc3,$a3,$bi		# a[3]*b[0]
1794e71b7053SJung-uk Kim	mulhdu	$acc4,$a3,$bi
1795e71b7053SJung-uk Kim
1796e71b7053SJung-uk Kim	mulld	$t4,$acc0,$ordk
1797e71b7053SJung-uk Kim
1798e71b7053SJung-uk Kim	addc	$acc1,$acc1,$t0		# accumulate high parts of multiplication
1799e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t1
1800e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t2
1801e71b7053SJung-uk Kim	addze	$acc4,$acc4
1802e71b7053SJung-uk Kim	li	$acc5,0
1803e71b7053SJung-uk Kim___
1804e71b7053SJung-uk Kimfor ($i=1;$i<4;$i++) {
1805e71b7053SJung-uk Kim	################################################################
1806e71b7053SJung-uk Kim	#            ffff0000.ffffffff.yyyyyyyy.zzzzzzzz
1807e71b7053SJung-uk Kim	# *                                     abcdefgh
1808e71b7053SJung-uk Kim	# + xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
1809e71b7053SJung-uk Kim	#
1810e71b7053SJung-uk Kim	# Now observing that ff..ff*x = (2^n-1)*x = 2^n*x-x, we
1811e71b7053SJung-uk Kim	# rewrite above as:
1812e71b7053SJung-uk Kim	#
1813e71b7053SJung-uk Kim	#   xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
1814e71b7053SJung-uk Kim	# - 0000abcd.efgh0000.abcdefgh.00000000.00000000
1815e71b7053SJung-uk Kim	# + abcdefgh.abcdefgh.yzayzbyz.cyzdyzey.zfyzgyzh
1816e71b7053SJung-uk Kim$code.=<<___;
1817e71b7053SJung-uk Kim	ld	$bi,8*$i($bp)		# b[i]
1818e71b7053SJung-uk Kim
1819e71b7053SJung-uk Kim	sldi	$t0,$t4,32
1820e71b7053SJung-uk Kim	subfc	$acc2,$t4,$acc2
1821e71b7053SJung-uk Kim	srdi	$t1,$t4,32
1822e71b7053SJung-uk Kim	subfe	$acc3,$t0,$acc3
1823e71b7053SJung-uk Kim	subfe	$acc4,$t1,$acc4
1824e71b7053SJung-uk Kim	subfe	$acc5,$zr,$acc5
1825e71b7053SJung-uk Kim
1826e71b7053SJung-uk Kim	addic	$t0,$acc0,-1		# discarded
1827e71b7053SJung-uk Kim	mulhdu	$t1,$ord0,$t4
1828e71b7053SJung-uk Kim	mulld	$t2,$ord1,$t4
1829e71b7053SJung-uk Kim	mulhdu	$t3,$ord1,$t4
1830e71b7053SJung-uk Kim
1831e71b7053SJung-uk Kim	adde	$t2,$t2,$t1
1832e71b7053SJung-uk Kim	 mulld	$t0,$a0,$bi
1833e71b7053SJung-uk Kim	addze	$t3,$t3
1834e71b7053SJung-uk Kim	 mulld	$t1,$a1,$bi
1835e71b7053SJung-uk Kim
1836e71b7053SJung-uk Kim	addc	$acc0,$acc1,$t2
1837e71b7053SJung-uk Kim	 mulld	$t2,$a2,$bi
1838e71b7053SJung-uk Kim	adde	$acc1,$acc2,$t3
1839e71b7053SJung-uk Kim	 mulld	$t3,$a3,$bi
1840e71b7053SJung-uk Kim	adde	$acc2,$acc3,$t4
1841e71b7053SJung-uk Kim	adde	$acc3,$acc4,$t4
1842e71b7053SJung-uk Kim	addze	$acc4,$acc5
1843e71b7053SJung-uk Kim
1844e71b7053SJung-uk Kim	addc	$acc0,$acc0,$t0		# accumulate low parts
1845e71b7053SJung-uk Kim	mulhdu	$t0,$a0,$bi
1846e71b7053SJung-uk Kim	adde	$acc1,$acc1,$t1
1847e71b7053SJung-uk Kim	mulhdu	$t1,$a1,$bi
1848e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t2
1849e71b7053SJung-uk Kim	mulhdu	$t2,$a2,$bi
1850e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t3
1851e71b7053SJung-uk Kim	mulhdu	$t3,$a3,$bi
1852e71b7053SJung-uk Kim	addze	$acc4,$acc4
1853e71b7053SJung-uk Kim	mulld	$t4,$acc0,$ordk
1854e71b7053SJung-uk Kim	addc	$acc1,$acc1,$t0		# accumulate high parts
1855e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t1
1856e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t2
1857e71b7053SJung-uk Kim	adde	$acc4,$acc4,$t3
1858e71b7053SJung-uk Kim	addze	$acc5,$zr
1859e71b7053SJung-uk Kim___
1860e71b7053SJung-uk Kim}
1861e71b7053SJung-uk Kim$code.=<<___;
1862e71b7053SJung-uk Kim	sldi	$t0,$t4,32		# last reduction
1863e71b7053SJung-uk Kim	subfc	$acc2,$t4,$acc2
1864e71b7053SJung-uk Kim	srdi	$t1,$t4,32
1865e71b7053SJung-uk Kim	subfe	$acc3,$t0,$acc3
1866e71b7053SJung-uk Kim	subfe	$acc4,$t1,$acc4
1867e71b7053SJung-uk Kim	subfe	$acc5,$zr,$acc5
1868e71b7053SJung-uk Kim
1869e71b7053SJung-uk Kim	addic	$t0,$acc0,-1		# discarded
1870e71b7053SJung-uk Kim	mulhdu	$t1,$ord0,$t4
1871e71b7053SJung-uk Kim	mulld	$t2,$ord1,$t4
1872e71b7053SJung-uk Kim	mulhdu	$t3,$ord1,$t4
1873e71b7053SJung-uk Kim
1874e71b7053SJung-uk Kim	adde	$t2,$t2,$t1
1875e71b7053SJung-uk Kim	addze	$t3,$t3
1876e71b7053SJung-uk Kim
1877e71b7053SJung-uk Kim	addc	$acc0,$acc1,$t2
1878e71b7053SJung-uk Kim	adde	$acc1,$acc2,$t3
1879e71b7053SJung-uk Kim	adde	$acc2,$acc3,$t4
1880e71b7053SJung-uk Kim	adde	$acc3,$acc4,$t4
1881e71b7053SJung-uk Kim	addze	$acc4,$acc5
1882e71b7053SJung-uk Kim
1883e71b7053SJung-uk Kim	subfc	$acc0,$ord0,$acc0	# ret -= modulus
1884e71b7053SJung-uk Kim	subfe	$acc1,$ord1,$acc1
1885e71b7053SJung-uk Kim	subfe	$acc2,$ord2,$acc2
1886e71b7053SJung-uk Kim	subfe	$acc3,$ord3,$acc3
1887e71b7053SJung-uk Kim	subfe	$acc4,$zr,$acc4
1888e71b7053SJung-uk Kim
1889e71b7053SJung-uk Kim	and	$t0,$ord0,$acc4
1890e71b7053SJung-uk Kim	and	$t1,$ord1,$acc4
1891e71b7053SJung-uk Kim	addc	$acc0,$acc0,$t0		# ret += modulus if borrow
1892e71b7053SJung-uk Kim	and	$t3,$ord3,$acc4
1893e71b7053SJung-uk Kim	adde	$acc1,$acc1,$t1
1894e71b7053SJung-uk Kim	adde	$acc2,$acc2,$acc4
1895e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t3
1896e71b7053SJung-uk Kim
1897e71b7053SJung-uk Kim	std	$acc0,0($rp)
1898e71b7053SJung-uk Kim	std	$acc1,8($rp)
1899e71b7053SJung-uk Kim	std	$acc2,16($rp)
1900e71b7053SJung-uk Kim	std	$acc3,24($rp)
1901e71b7053SJung-uk Kim
1902e71b7053SJung-uk Kim	ld	r18,48($sp)
1903e71b7053SJung-uk Kim	ld	r19,56($sp)
1904e71b7053SJung-uk Kim	ld	r20,64($sp)
1905e71b7053SJung-uk Kim	ld	r21,72($sp)
1906e71b7053SJung-uk Kim	ld	r22,80($sp)
1907e71b7053SJung-uk Kim	ld	r23,88($sp)
1908e71b7053SJung-uk Kim	ld	r24,96($sp)
1909e71b7053SJung-uk Kim	ld	r25,104($sp)
1910e71b7053SJung-uk Kim	ld	r26,112($sp)
1911e71b7053SJung-uk Kim	ld	r27,120($sp)
1912e71b7053SJung-uk Kim	ld	r28,128($sp)
1913e71b7053SJung-uk Kim	ld	r29,136($sp)
1914e71b7053SJung-uk Kim	ld	r30,144($sp)
1915e71b7053SJung-uk Kim	ld	r31,152($sp)
1916e71b7053SJung-uk Kim	addi	$sp,$sp,160
1917e71b7053SJung-uk Kim	blr
1918e71b7053SJung-uk Kim	.long	0
1919e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,14,3,0
1920e71b7053SJung-uk Kim	.long	0
1921e71b7053SJung-uk Kim.size	ecp_nistz256_ord_mul_mont,.-ecp_nistz256_ord_mul_mont
1922e71b7053SJung-uk Kim
1923e71b7053SJung-uk Kim################################################################################
1924e71b7053SJung-uk Kim# void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4],
1925*b077aed3SPierre Pronchery#                                uint64_t rep);
1926e71b7053SJung-uk Kim.globl	ecp_nistz256_ord_sqr_mont
1927e71b7053SJung-uk Kim.align	5
1928e71b7053SJung-uk Kimecp_nistz256_ord_sqr_mont:
1929e71b7053SJung-uk Kim	stdu	$sp,-160($sp)
1930e71b7053SJung-uk Kim	std	r18,48($sp)
1931e71b7053SJung-uk Kim	std	r19,56($sp)
1932e71b7053SJung-uk Kim	std	r20,64($sp)
1933e71b7053SJung-uk Kim	std	r21,72($sp)
1934e71b7053SJung-uk Kim	std	r22,80($sp)
1935e71b7053SJung-uk Kim	std	r23,88($sp)
1936e71b7053SJung-uk Kim	std	r24,96($sp)
1937e71b7053SJung-uk Kim	std	r25,104($sp)
1938e71b7053SJung-uk Kim	std	r26,112($sp)
1939e71b7053SJung-uk Kim	std	r27,120($sp)
1940e71b7053SJung-uk Kim	std	r28,128($sp)
1941e71b7053SJung-uk Kim	std	r29,136($sp)
1942e71b7053SJung-uk Kim	std	r30,144($sp)
1943e71b7053SJung-uk Kim	std	r31,152($sp)
1944e71b7053SJung-uk Kim
1945e71b7053SJung-uk Kim	mtctr	$bp
1946e71b7053SJung-uk Kim
1947e71b7053SJung-uk Kim	ld	$a0,0($ap)
1948e71b7053SJung-uk Kim	ld	$a1,8($ap)
1949e71b7053SJung-uk Kim	ld	$a2,16($ap)
1950e71b7053SJung-uk Kim	ld	$a3,24($ap)
1951e71b7053SJung-uk Kim
1952e71b7053SJung-uk Kim	lis	$ordk,0xccd1
1953e71b7053SJung-uk Kim	lis	$ord0,0xf3b9
1954e71b7053SJung-uk Kim	lis	$ord1,0xbce6
1955e71b7053SJung-uk Kim	ori	$ordk,$ordk,0xc8aa
1956e71b7053SJung-uk Kim	ori	$ord0,$ord0,0xcac2
1957e71b7053SJung-uk Kim	ori	$ord1,$ord1,0xfaad
1958e71b7053SJung-uk Kim	sldi	$ordk,$ordk,32
1959e71b7053SJung-uk Kim	sldi	$ord0,$ord0,32
1960e71b7053SJung-uk Kim	sldi	$ord1,$ord1,32
1961e71b7053SJung-uk Kim	oris	$ordk,$ordk,0xee00
1962e71b7053SJung-uk Kim	oris	$ord0,$ord0,0xfc63
1963e71b7053SJung-uk Kim	oris	$ord1,$ord1,0xa717
1964e71b7053SJung-uk Kim	ori	$ordk,$ordk,0xbc4f	# 0xccd1c8aaee00bc4f
1965e71b7053SJung-uk Kim	ori	$ord0,$ord0,0x2551	# 0xf3b9cac2fc632551
1966e71b7053SJung-uk Kim	ori	$ord1,$ord1,0x9e84	# 0xbce6faada7179e84
1967e71b7053SJung-uk Kim	li	$ord2,-1		# 0xffffffffffffffff
1968e71b7053SJung-uk Kim	sldi	$ord3,$ord2,32		# 0xffffffff00000000
1969e71b7053SJung-uk Kim	li	$zr,0
1970e71b7053SJung-uk Kim	b	.Loop_ord_sqr
1971e71b7053SJung-uk Kim
1972e71b7053SJung-uk Kim.align	5
1973e71b7053SJung-uk Kim.Loop_ord_sqr:
1974e71b7053SJung-uk Kim	################################################################
1975e71b7053SJung-uk Kim	#  |  |  |  |  |  |a1*a0|  |
1976e71b7053SJung-uk Kim	#  |  |  |  |  |a2*a0|  |  |
1977e71b7053SJung-uk Kim	#  |  |a3*a2|a3*a0|  |  |  |
1978e71b7053SJung-uk Kim	#  |  |  |  |a2*a1|  |  |  |
1979e71b7053SJung-uk Kim	#  |  |  |a3*a1|  |  |  |  |
1980e71b7053SJung-uk Kim	# *|  |  |  |  |  |  |  | 2|
1981e71b7053SJung-uk Kim	# +|a3*a3|a2*a2|a1*a1|a0*a0|
1982e71b7053SJung-uk Kim	#  |--+--+--+--+--+--+--+--|
1983e71b7053SJung-uk Kim	#  |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is $accx, i.e. follow $accx
1984e71b7053SJung-uk Kim	#
1985e71b7053SJung-uk Kim	#  "can't overflow" below mark carrying into high part of
1986e71b7053SJung-uk Kim	#  multiplication result, which can't overflow, because it
1987e71b7053SJung-uk Kim	#  can never be all ones.
1988e71b7053SJung-uk Kim
1989e71b7053SJung-uk Kim	mulld	$acc1,$a1,$a0		# a[1]*a[0]
1990e71b7053SJung-uk Kim	mulhdu	$t1,$a1,$a0
1991e71b7053SJung-uk Kim	mulld	$acc2,$a2,$a0		# a[2]*a[0]
1992e71b7053SJung-uk Kim	mulhdu	$t2,$a2,$a0
1993e71b7053SJung-uk Kim	mulld	$acc3,$a3,$a0		# a[3]*a[0]
1994e71b7053SJung-uk Kim	mulhdu	$acc4,$a3,$a0
1995e71b7053SJung-uk Kim
1996e71b7053SJung-uk Kim	addc	$acc2,$acc2,$t1		# accumulate high parts of multiplication
1997e71b7053SJung-uk Kim	 mulld	$t0,$a2,$a1		# a[2]*a[1]
1998e71b7053SJung-uk Kim	 mulhdu	$t1,$a2,$a1
1999e71b7053SJung-uk Kim	adde	$acc3,$acc3,$t2
2000e71b7053SJung-uk Kim	 mulld	$t2,$a3,$a1		# a[3]*a[1]
2001e71b7053SJung-uk Kim	 mulhdu	$t3,$a3,$a1
2002e71b7053SJung-uk Kim	addze	$acc4,$acc4		# can't overflow
2003e71b7053SJung-uk Kim
2004e71b7053SJung-uk Kim	mulld	$acc5,$a3,$a2		# a[3]*a[2]
2005e71b7053SJung-uk Kim	mulhdu	$acc6,$a3,$a2
2006e71b7053SJung-uk Kim
2007e71b7053SJung-uk Kim	addc	$t1,$t1,$t2		# accumulate high parts of multiplication
2008e71b7053SJung-uk Kim	 mulld	$acc0,$a0,$a0		# a[0]*a[0]
2009e71b7053SJung-uk Kim	addze	$t2,$t3			# can't overflow
2010e71b7053SJung-uk Kim
2011e71b7053SJung-uk Kim	addc	$acc3,$acc3,$t0		# accumulate low parts of multiplication
2012e71b7053SJung-uk Kim	 mulhdu	$a0,$a0,$a0
2013e71b7053SJung-uk Kim	adde	$acc4,$acc4,$t1
2014e71b7053SJung-uk Kim	 mulld	$t1,$a1,$a1		# a[1]*a[1]
2015e71b7053SJung-uk Kim	adde	$acc5,$acc5,$t2
2016e71b7053SJung-uk Kim	 mulhdu	$a1,$a1,$a1
2017e71b7053SJung-uk Kim	addze	$acc6,$acc6		# can't overflow
2018e71b7053SJung-uk Kim
2019e71b7053SJung-uk Kim	addc	$acc1,$acc1,$acc1	# acc[1-6]*=2
2020e71b7053SJung-uk Kim	 mulld	$t2,$a2,$a2		# a[2]*a[2]
2021e71b7053SJung-uk Kim	adde	$acc2,$acc2,$acc2
2022e71b7053SJung-uk Kim	 mulhdu	$a2,$a2,$a2
2023e71b7053SJung-uk Kim	adde	$acc3,$acc3,$acc3
2024e71b7053SJung-uk Kim	 mulld	$t3,$a3,$a3		# a[3]*a[3]
2025e71b7053SJung-uk Kim	adde	$acc4,$acc4,$acc4
2026e71b7053SJung-uk Kim	 mulhdu	$a3,$a3,$a3
2027e71b7053SJung-uk Kim	adde	$acc5,$acc5,$acc5
2028e71b7053SJung-uk Kim	adde	$acc6,$acc6,$acc6
2029e71b7053SJung-uk Kim	addze	$acc7,$zr
2030e71b7053SJung-uk Kim
2031e71b7053SJung-uk Kim	addc	$acc1,$acc1,$a0		# +a[i]*a[i]
2032e71b7053SJung-uk Kim	 mulld	$t4,$acc0,$ordk
2033e71b7053SJung-uk Kim	adde	$acc2,$acc2,$t1
2034e71b7053SJung-uk Kim	adde	$acc3,$acc3,$a1
2035e71b7053SJung-uk Kim	adde	$acc4,$acc4,$t2
2036e71b7053SJung-uk Kim	adde	$acc5,$acc5,$a2
2037e71b7053SJung-uk Kim	adde	$acc6,$acc6,$t3
2038e71b7053SJung-uk Kim	adde	$acc7,$acc7,$a3
2039e71b7053SJung-uk Kim___
2040e71b7053SJung-uk Kimfor($i=0; $i<4; $i++) {			# reductions
2041e71b7053SJung-uk Kim$code.=<<___;
2042e71b7053SJung-uk Kim	addic	$t0,$acc0,-1		# discarded
2043e71b7053SJung-uk Kim	mulhdu	$t1,$ord0,$t4
2044e71b7053SJung-uk Kim	mulld	$t2,$ord1,$t4
2045e71b7053SJung-uk Kim	mulhdu	$t3,$ord1,$t4
2046e71b7053SJung-uk Kim
2047e71b7053SJung-uk Kim	adde	$t2,$t2,$t1
2048e71b7053SJung-uk Kim	addze	$t3,$t3
2049e71b7053SJung-uk Kim
2050e71b7053SJung-uk Kim	addc	$acc0,$acc1,$t2
2051e71b7053SJung-uk Kim	adde	$acc1,$acc2,$t3
2052e71b7053SJung-uk Kim	adde	$acc2,$acc3,$t4
2053e71b7053SJung-uk Kim	adde	$acc3,$zr,$t4		# can't overflow
2054e71b7053SJung-uk Kim___
2055e71b7053SJung-uk Kim$code.=<<___	if ($i<3);
2056e71b7053SJung-uk Kim	mulld	$t3,$acc0,$ordk
2057e71b7053SJung-uk Kim___
2058e71b7053SJung-uk Kim$code.=<<___;
2059e71b7053SJung-uk Kim	sldi	$t0,$t4,32
2060e71b7053SJung-uk Kim	subfc	$acc1,$t4,$acc1
2061e71b7053SJung-uk Kim	srdi	$t1,$t4,32
2062e71b7053SJung-uk Kim	subfe	$acc2,$t0,$acc2
2063e71b7053SJung-uk Kim	subfe	$acc3,$t1,$acc3		# can't borrow
2064e71b7053SJung-uk Kim___
2065e71b7053SJung-uk Kim	($t3,$t4) = ($t4,$t3);
2066e71b7053SJung-uk Kim}
2067e71b7053SJung-uk Kim$code.=<<___;
2068e71b7053SJung-uk Kim	addc	$acc0,$acc0,$acc4	# accumulate upper half
2069e71b7053SJung-uk Kim	adde	$acc1,$acc1,$acc5
2070e71b7053SJung-uk Kim	adde	$acc2,$acc2,$acc6
2071e71b7053SJung-uk Kim	adde	$acc3,$acc3,$acc7
2072e71b7053SJung-uk Kim	addze	$acc4,$zr
2073e71b7053SJung-uk Kim
2074e71b7053SJung-uk Kim	subfc	$acc0,$ord0,$acc0	# ret -= modulus
2075e71b7053SJung-uk Kim	subfe	$acc1,$ord1,$acc1
2076e71b7053SJung-uk Kim	subfe	$acc2,$ord2,$acc2
2077e71b7053SJung-uk Kim	subfe	$acc3,$ord3,$acc3
2078e71b7053SJung-uk Kim	subfe	$acc4,$zr,$acc4
2079e71b7053SJung-uk Kim
2080e71b7053SJung-uk Kim	and	$t0,$ord0,$acc4
2081e71b7053SJung-uk Kim	and	$t1,$ord1,$acc4
2082e71b7053SJung-uk Kim	addc	$a0,$acc0,$t0		# ret += modulus if borrow
2083e71b7053SJung-uk Kim	and	$t3,$ord3,$acc4
2084e71b7053SJung-uk Kim	adde	$a1,$acc1,$t1
2085e71b7053SJung-uk Kim	adde	$a2,$acc2,$acc4
2086e71b7053SJung-uk Kim	adde	$a3,$acc3,$t3
2087e71b7053SJung-uk Kim
2088e71b7053SJung-uk Kim	bdnz	.Loop_ord_sqr
2089e71b7053SJung-uk Kim
2090e71b7053SJung-uk Kim	std	$a0,0($rp)
2091e71b7053SJung-uk Kim	std	$a1,8($rp)
2092e71b7053SJung-uk Kim	std	$a2,16($rp)
2093e71b7053SJung-uk Kim	std	$a3,24($rp)
2094e71b7053SJung-uk Kim
2095e71b7053SJung-uk Kim	ld	r18,48($sp)
2096e71b7053SJung-uk Kim	ld	r19,56($sp)
2097e71b7053SJung-uk Kim	ld	r20,64($sp)
2098e71b7053SJung-uk Kim	ld	r21,72($sp)
2099e71b7053SJung-uk Kim	ld	r22,80($sp)
2100e71b7053SJung-uk Kim	ld	r23,88($sp)
2101e71b7053SJung-uk Kim	ld	r24,96($sp)
2102e71b7053SJung-uk Kim	ld	r25,104($sp)
2103e71b7053SJung-uk Kim	ld	r26,112($sp)
2104e71b7053SJung-uk Kim	ld	r27,120($sp)
2105e71b7053SJung-uk Kim	ld	r28,128($sp)
2106e71b7053SJung-uk Kim	ld	r29,136($sp)
2107e71b7053SJung-uk Kim	ld	r30,144($sp)
2108e71b7053SJung-uk Kim	ld	r31,152($sp)
2109e71b7053SJung-uk Kim	addi	$sp,$sp,160
2110e71b7053SJung-uk Kim	blr
2111e71b7053SJung-uk Kim	.long	0
2112e71b7053SJung-uk Kim	.byte	0,12,4,0,0x80,14,3,0
2113e71b7053SJung-uk Kim	.long	0
2114e71b7053SJung-uk Kim.size	ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont
2115e71b7053SJung-uk Kim___
2116e71b7053SJung-uk Kim}	}
2117e71b7053SJung-uk Kim
2118e71b7053SJung-uk Kim########################################################################
2119e71b7053SJung-uk Kim# scatter-gather subroutines
2120e71b7053SJung-uk Kim{
2121e71b7053SJung-uk Kimmy ($out,$inp,$index,$mask)=map("r$_",(3..7));
2122e71b7053SJung-uk Kim$code.=<<___;
2123e71b7053SJung-uk Kim########################################################################
2124e71b7053SJung-uk Kim# void	ecp_nistz256_scatter_w5(void *out, const P256_POINT *inp,
2125e71b7053SJung-uk Kim#				int index);
2126e71b7053SJung-uk Kim.globl	ecp_nistz256_scatter_w5
2127e71b7053SJung-uk Kim.align	4
2128e71b7053SJung-uk Kimecp_nistz256_scatter_w5:
2129e71b7053SJung-uk Kim	slwi	$index,$index,2
2130e71b7053SJung-uk Kim	add	$out,$out,$index
2131e71b7053SJung-uk Kim
2132e71b7053SJung-uk Kim	ld	r8, 0($inp)		# X
2133e71b7053SJung-uk Kim	ld	r9, 8($inp)
2134e71b7053SJung-uk Kim	ld	r10,16($inp)
2135e71b7053SJung-uk Kim	ld	r11,24($inp)
2136e71b7053SJung-uk Kim
2137e71b7053SJung-uk Kim	stw	r8, 64*0-4($out)
2138e71b7053SJung-uk Kim	srdi	r8, r8, 32
2139e71b7053SJung-uk Kim	stw	r9, 64*1-4($out)
2140e71b7053SJung-uk Kim	srdi	r9, r9, 32
2141e71b7053SJung-uk Kim	stw	r10,64*2-4($out)
2142e71b7053SJung-uk Kim	srdi	r10,r10,32
2143e71b7053SJung-uk Kim	stw	r11,64*3-4($out)
2144e71b7053SJung-uk Kim	srdi	r11,r11,32
2145e71b7053SJung-uk Kim	stw	r8, 64*4-4($out)
2146e71b7053SJung-uk Kim	stw	r9, 64*5-4($out)
2147e71b7053SJung-uk Kim	stw	r10,64*6-4($out)
2148e71b7053SJung-uk Kim	stw	r11,64*7-4($out)
2149e71b7053SJung-uk Kim	addi	$out,$out,64*8
2150e71b7053SJung-uk Kim
2151e71b7053SJung-uk Kim	ld	r8, 32($inp)		# Y
2152e71b7053SJung-uk Kim	ld	r9, 40($inp)
2153e71b7053SJung-uk Kim	ld	r10,48($inp)
2154e71b7053SJung-uk Kim	ld	r11,56($inp)
2155e71b7053SJung-uk Kim
2156e71b7053SJung-uk Kim	stw	r8, 64*0-4($out)
2157e71b7053SJung-uk Kim	srdi	r8, r8, 32
2158e71b7053SJung-uk Kim	stw	r9, 64*1-4($out)
2159e71b7053SJung-uk Kim	srdi	r9, r9, 32
2160e71b7053SJung-uk Kim	stw	r10,64*2-4($out)
2161e71b7053SJung-uk Kim	srdi	r10,r10,32
2162e71b7053SJung-uk Kim	stw	r11,64*3-4($out)
2163e71b7053SJung-uk Kim	srdi	r11,r11,32
2164e71b7053SJung-uk Kim	stw	r8, 64*4-4($out)
2165e71b7053SJung-uk Kim	stw	r9, 64*5-4($out)
2166e71b7053SJung-uk Kim	stw	r10,64*6-4($out)
2167e71b7053SJung-uk Kim	stw	r11,64*7-4($out)
2168e71b7053SJung-uk Kim	addi	$out,$out,64*8
2169e71b7053SJung-uk Kim
2170e71b7053SJung-uk Kim	ld	r8, 64($inp)		# Z
2171e71b7053SJung-uk Kim	ld	r9, 72($inp)
2172e71b7053SJung-uk Kim	ld	r10,80($inp)
2173e71b7053SJung-uk Kim	ld	r11,88($inp)
2174e71b7053SJung-uk Kim
2175e71b7053SJung-uk Kim	stw	r8, 64*0-4($out)
2176e71b7053SJung-uk Kim	srdi	r8, r8, 32
2177e71b7053SJung-uk Kim	stw	r9, 64*1-4($out)
2178e71b7053SJung-uk Kim	srdi	r9, r9, 32
2179e71b7053SJung-uk Kim	stw	r10,64*2-4($out)
2180e71b7053SJung-uk Kim	srdi	r10,r10,32
2181e71b7053SJung-uk Kim	stw	r11,64*3-4($out)
2182e71b7053SJung-uk Kim	srdi	r11,r11,32
2183e71b7053SJung-uk Kim	stw	r8, 64*4-4($out)
2184e71b7053SJung-uk Kim	stw	r9, 64*5-4($out)
2185e71b7053SJung-uk Kim	stw	r10,64*6-4($out)
2186e71b7053SJung-uk Kim	stw	r11,64*7-4($out)
2187e71b7053SJung-uk Kim
2188e71b7053SJung-uk Kim	blr
2189e71b7053SJung-uk Kim	.long	0
2190e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,3,0
2191e71b7053SJung-uk Kim	.long	0
2192e71b7053SJung-uk Kim.size	ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5
2193e71b7053SJung-uk Kim
2194e71b7053SJung-uk Kim########################################################################
2195e71b7053SJung-uk Kim# void	ecp_nistz256_gather_w5(P256_POINT *out, const void *inp,
2196e71b7053SJung-uk Kim#				int index);
2197e71b7053SJung-uk Kim.globl	ecp_nistz256_gather_w5
2198e71b7053SJung-uk Kim.align	4
2199e71b7053SJung-uk Kimecp_nistz256_gather_w5:
2200e71b7053SJung-uk Kim	neg	r0,$index
2201e71b7053SJung-uk Kim	sradi	r0,r0,63
2202e71b7053SJung-uk Kim
2203e71b7053SJung-uk Kim	add	$index,$index,r0
2204e71b7053SJung-uk Kim	slwi	$index,$index,2
2205e71b7053SJung-uk Kim	add	$inp,$inp,$index
2206e71b7053SJung-uk Kim
2207e71b7053SJung-uk Kim	lwz	r5, 64*0($inp)
2208e71b7053SJung-uk Kim	lwz	r6, 64*1($inp)
2209e71b7053SJung-uk Kim	lwz	r7, 64*2($inp)
2210e71b7053SJung-uk Kim	lwz	r8, 64*3($inp)
2211e71b7053SJung-uk Kim	lwz	r9, 64*4($inp)
2212e71b7053SJung-uk Kim	lwz	r10,64*5($inp)
2213e71b7053SJung-uk Kim	lwz	r11,64*6($inp)
2214e71b7053SJung-uk Kim	lwz	r12,64*7($inp)
2215e71b7053SJung-uk Kim	addi	$inp,$inp,64*8
2216e71b7053SJung-uk Kim	sldi	r9, r9, 32
2217e71b7053SJung-uk Kim	sldi	r10,r10,32
2218e71b7053SJung-uk Kim	sldi	r11,r11,32
2219e71b7053SJung-uk Kim	sldi	r12,r12,32
2220e71b7053SJung-uk Kim	or	r5,r5,r9
2221e71b7053SJung-uk Kim	or	r6,r6,r10
2222e71b7053SJung-uk Kim	or	r7,r7,r11
2223e71b7053SJung-uk Kim	or	r8,r8,r12
2224e71b7053SJung-uk Kim	and	r5,r5,r0
2225e71b7053SJung-uk Kim	and	r6,r6,r0
2226e71b7053SJung-uk Kim	and	r7,r7,r0
2227e71b7053SJung-uk Kim	and	r8,r8,r0
2228e71b7053SJung-uk Kim	std	r5,0($out)		# X
2229e71b7053SJung-uk Kim	std	r6,8($out)
2230e71b7053SJung-uk Kim	std	r7,16($out)
2231e71b7053SJung-uk Kim	std	r8,24($out)
2232e71b7053SJung-uk Kim
2233e71b7053SJung-uk Kim	lwz	r5, 64*0($inp)
2234e71b7053SJung-uk Kim	lwz	r6, 64*1($inp)
2235e71b7053SJung-uk Kim	lwz	r7, 64*2($inp)
2236e71b7053SJung-uk Kim	lwz	r8, 64*3($inp)
2237e71b7053SJung-uk Kim	lwz	r9, 64*4($inp)
2238e71b7053SJung-uk Kim	lwz	r10,64*5($inp)
2239e71b7053SJung-uk Kim	lwz	r11,64*6($inp)
2240e71b7053SJung-uk Kim	lwz	r12,64*7($inp)
2241e71b7053SJung-uk Kim	addi	$inp,$inp,64*8
2242e71b7053SJung-uk Kim	sldi	r9, r9, 32
2243e71b7053SJung-uk Kim	sldi	r10,r10,32
2244e71b7053SJung-uk Kim	sldi	r11,r11,32
2245e71b7053SJung-uk Kim	sldi	r12,r12,32
2246e71b7053SJung-uk Kim	or	r5,r5,r9
2247e71b7053SJung-uk Kim	or	r6,r6,r10
2248e71b7053SJung-uk Kim	or	r7,r7,r11
2249e71b7053SJung-uk Kim	or	r8,r8,r12
2250e71b7053SJung-uk Kim	and	r5,r5,r0
2251e71b7053SJung-uk Kim	and	r6,r6,r0
2252e71b7053SJung-uk Kim	and	r7,r7,r0
2253e71b7053SJung-uk Kim	and	r8,r8,r0
2254e71b7053SJung-uk Kim	std	r5,32($out)		# Y
2255e71b7053SJung-uk Kim	std	r6,40($out)
2256e71b7053SJung-uk Kim	std	r7,48($out)
2257e71b7053SJung-uk Kim	std	r8,56($out)
2258e71b7053SJung-uk Kim
2259e71b7053SJung-uk Kim	lwz	r5, 64*0($inp)
2260e71b7053SJung-uk Kim	lwz	r6, 64*1($inp)
2261e71b7053SJung-uk Kim	lwz	r7, 64*2($inp)
2262e71b7053SJung-uk Kim	lwz	r8, 64*3($inp)
2263e71b7053SJung-uk Kim	lwz	r9, 64*4($inp)
2264e71b7053SJung-uk Kim	lwz	r10,64*5($inp)
2265e71b7053SJung-uk Kim	lwz	r11,64*6($inp)
2266e71b7053SJung-uk Kim	lwz	r12,64*7($inp)
2267e71b7053SJung-uk Kim	sldi	r9, r9, 32
2268e71b7053SJung-uk Kim	sldi	r10,r10,32
2269e71b7053SJung-uk Kim	sldi	r11,r11,32
2270e71b7053SJung-uk Kim	sldi	r12,r12,32
2271e71b7053SJung-uk Kim	or	r5,r5,r9
2272e71b7053SJung-uk Kim	or	r6,r6,r10
2273e71b7053SJung-uk Kim	or	r7,r7,r11
2274e71b7053SJung-uk Kim	or	r8,r8,r12
2275e71b7053SJung-uk Kim	and	r5,r5,r0
2276e71b7053SJung-uk Kim	and	r6,r6,r0
2277e71b7053SJung-uk Kim	and	r7,r7,r0
2278e71b7053SJung-uk Kim	and	r8,r8,r0
2279e71b7053SJung-uk Kim	std	r5,64($out)		# Z
2280e71b7053SJung-uk Kim	std	r6,72($out)
2281e71b7053SJung-uk Kim	std	r7,80($out)
2282e71b7053SJung-uk Kim	std	r8,88($out)
2283e71b7053SJung-uk Kim
2284e71b7053SJung-uk Kim	blr
2285e71b7053SJung-uk Kim	.long	0
2286e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,3,0
2287e71b7053SJung-uk Kim	.long	0
2288e71b7053SJung-uk Kim.size	ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5
2289e71b7053SJung-uk Kim
2290e71b7053SJung-uk Kim########################################################################
2291e71b7053SJung-uk Kim# void	ecp_nistz256_scatter_w7(void *out, const P256_POINT_AFFINE *inp,
2292e71b7053SJung-uk Kim#				int index);
2293e71b7053SJung-uk Kim.globl	ecp_nistz256_scatter_w7
2294e71b7053SJung-uk Kim.align	4
2295e71b7053SJung-uk Kimecp_nistz256_scatter_w7:
2296e71b7053SJung-uk Kim	li	r0,8
2297e71b7053SJung-uk Kim	mtctr	r0
2298e71b7053SJung-uk Kim	add	$out,$out,$index
2299e71b7053SJung-uk Kim	subi	$inp,$inp,8
2300e71b7053SJung-uk Kim
2301e71b7053SJung-uk Kim.Loop_scatter_w7:
2302e71b7053SJung-uk Kim	ldu	r0,8($inp)
2303e71b7053SJung-uk Kim	stb	r0,64*0($out)
2304e71b7053SJung-uk Kim	srdi	r0,r0,8
2305e71b7053SJung-uk Kim	stb	r0,64*1($out)
2306e71b7053SJung-uk Kim	srdi	r0,r0,8
2307e71b7053SJung-uk Kim	stb	r0,64*2($out)
2308e71b7053SJung-uk Kim	srdi	r0,r0,8
2309e71b7053SJung-uk Kim	stb	r0,64*3($out)
2310e71b7053SJung-uk Kim	srdi	r0,r0,8
2311e71b7053SJung-uk Kim	stb	r0,64*4($out)
2312e71b7053SJung-uk Kim	srdi	r0,r0,8
2313e71b7053SJung-uk Kim	stb	r0,64*5($out)
2314e71b7053SJung-uk Kim	srdi	r0,r0,8
2315e71b7053SJung-uk Kim	stb	r0,64*6($out)
2316e71b7053SJung-uk Kim	srdi	r0,r0,8
2317e71b7053SJung-uk Kim	stb	r0,64*7($out)
2318e71b7053SJung-uk Kim	addi	$out,$out,64*8
2319e71b7053SJung-uk Kim	bdnz	.Loop_scatter_w7
2320e71b7053SJung-uk Kim
2321e71b7053SJung-uk Kim	blr
2322e71b7053SJung-uk Kim	.long	0
2323e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,3,0
2324e71b7053SJung-uk Kim	.long	0
2325e71b7053SJung-uk Kim.size	ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7
2326e71b7053SJung-uk Kim
2327e71b7053SJung-uk Kim########################################################################
2328e71b7053SJung-uk Kim# void	ecp_nistz256_gather_w7(P256_POINT_AFFINE *out, const void *inp,
2329e71b7053SJung-uk Kim#				int index);
2330e71b7053SJung-uk Kim.globl	ecp_nistz256_gather_w7
2331e71b7053SJung-uk Kim.align	4
2332e71b7053SJung-uk Kimecp_nistz256_gather_w7:
2333e71b7053SJung-uk Kim	li	r0,8
2334e71b7053SJung-uk Kim	mtctr	r0
2335e71b7053SJung-uk Kim	neg	r0,$index
2336e71b7053SJung-uk Kim	sradi	r0,r0,63
2337e71b7053SJung-uk Kim
2338e71b7053SJung-uk Kim	add	$index,$index,r0
2339e71b7053SJung-uk Kim	add	$inp,$inp,$index
2340e71b7053SJung-uk Kim	subi	$out,$out,8
2341e71b7053SJung-uk Kim
2342e71b7053SJung-uk Kim.Loop_gather_w7:
2343e71b7053SJung-uk Kim	lbz	r5, 64*0($inp)
2344e71b7053SJung-uk Kim	lbz	r6, 64*1($inp)
2345e71b7053SJung-uk Kim	lbz	r7, 64*2($inp)
2346e71b7053SJung-uk Kim	lbz	r8, 64*3($inp)
2347e71b7053SJung-uk Kim	lbz	r9, 64*4($inp)
2348e71b7053SJung-uk Kim	lbz	r10,64*5($inp)
2349e71b7053SJung-uk Kim	lbz	r11,64*6($inp)
2350e71b7053SJung-uk Kim	lbz	r12,64*7($inp)
2351e71b7053SJung-uk Kim	addi	$inp,$inp,64*8
2352e71b7053SJung-uk Kim
2353e71b7053SJung-uk Kim	sldi	r6, r6, 8
2354e71b7053SJung-uk Kim	sldi	r7, r7, 16
2355e71b7053SJung-uk Kim	sldi	r8, r8, 24
2356e71b7053SJung-uk Kim	sldi	r9, r9, 32
2357e71b7053SJung-uk Kim	sldi	r10,r10,40
2358e71b7053SJung-uk Kim	sldi	r11,r11,48
2359e71b7053SJung-uk Kim	sldi	r12,r12,56
2360e71b7053SJung-uk Kim
2361e71b7053SJung-uk Kim	or	r5,r5,r6
2362e71b7053SJung-uk Kim	or	r7,r7,r8
2363e71b7053SJung-uk Kim	or	r9,r9,r10
2364e71b7053SJung-uk Kim	or	r11,r11,r12
2365e71b7053SJung-uk Kim	or	r5,r5,r7
2366e71b7053SJung-uk Kim	or	r9,r9,r11
2367e71b7053SJung-uk Kim	or	r5,r5,r9
2368e71b7053SJung-uk Kim	and	r5,r5,r0
2369e71b7053SJung-uk Kim	stdu	r5,8($out)
2370e71b7053SJung-uk Kim	bdnz	.Loop_gather_w7
2371e71b7053SJung-uk Kim
2372e71b7053SJung-uk Kim	blr
2373e71b7053SJung-uk Kim	.long	0
2374e71b7053SJung-uk Kim	.byte	0,12,0x14,0,0,0,3,0
2375e71b7053SJung-uk Kim	.long	0
2376e71b7053SJung-uk Kim.size	ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7
2377e71b7053SJung-uk Kim___
2378e71b7053SJung-uk Kim}
2379e71b7053SJung-uk Kim
2380e71b7053SJung-uk Kimforeach (split("\n",$code)) {
2381e71b7053SJung-uk Kim	s/\`([^\`]*)\`/eval $1/ge;
2382e71b7053SJung-uk Kim
2383e71b7053SJung-uk Kim	print $_,"\n";
2384e71b7053SJung-uk Kim}
238517f01e99SJung-uk Kimclose STDOUT or die "error closing STDOUT: $!";	# enforce flush
2386