1e1051a39Sopenharmony_ci#! /usr/bin/env perl
2e1051a39Sopenharmony_ci# Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci#
4e1051a39Sopenharmony_ci# Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci# this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci# in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci# https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci# ====================================================================
11e1051a39Sopenharmony_ci# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
12e1051a39Sopenharmony_ci# project. The module is, however, dual licensed under OpenSSL and
13e1051a39Sopenharmony_ci# CRYPTOGAMS licenses depending on where you obtain it. For further
14e1051a39Sopenharmony_ci# details see http://www.openssl.org/~appro/cryptogams/.
15e1051a39Sopenharmony_ci# ====================================================================
16e1051a39Sopenharmony_ci
17e1051a39Sopenharmony_ci# I let hardware handle unaligned input(*), except on page boundaries
18e1051a39Sopenharmony_ci# (see below for details). Otherwise straightforward implementation
19e1051a39Sopenharmony_ci# with X vector in register bank.
20e1051a39Sopenharmony_ci#
21e1051a39Sopenharmony_ci# (*) this means that this module is inappropriate for PPC403? Does
22e1051a39Sopenharmony_ci#     anybody know if pre-POWER3 can sustain unaligned load?
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_ci# 			-m64	-m32
25e1051a39Sopenharmony_ci# ----------------------------------
26e1051a39Sopenharmony_ci# PPC970,gcc-4.0.0	+76%	+59%
27e1051a39Sopenharmony_ci# Power6,xlc-7		+68%	+33%
28e1051a39Sopenharmony_ci
29e1051a39Sopenharmony_ci# $output is the last argument if it looks like a file (it has an extension)
30e1051a39Sopenharmony_ci# $flavour is the first argument if it doesn't look like a file
31e1051a39Sopenharmony_ci$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
32e1051a39Sopenharmony_ci$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
33e1051a39Sopenharmony_ci
34e1051a39Sopenharmony_ciif ($flavour =~ /64/) {
35e1051a39Sopenharmony_ci	$SIZE_T	=8;
36e1051a39Sopenharmony_ci	$LRSAVE	=2*$SIZE_T;
37e1051a39Sopenharmony_ci	$UCMP	="cmpld";
38e1051a39Sopenharmony_ci	$STU	="stdu";
39e1051a39Sopenharmony_ci	$POP	="ld";
40e1051a39Sopenharmony_ci	$PUSH	="std";
41e1051a39Sopenharmony_ci} elsif ($flavour =~ /32/) {
42e1051a39Sopenharmony_ci	$SIZE_T	=4;
43e1051a39Sopenharmony_ci	$LRSAVE	=$SIZE_T;
44e1051a39Sopenharmony_ci	$UCMP	="cmplw";
45e1051a39Sopenharmony_ci	$STU	="stwu";
46e1051a39Sopenharmony_ci	$POP	="lwz";
47e1051a39Sopenharmony_ci	$PUSH	="stw";
48e1051a39Sopenharmony_ci} else { die "nonsense $flavour"; }
49e1051a39Sopenharmony_ci
50e1051a39Sopenharmony_ci# Define endianness based on flavour
51e1051a39Sopenharmony_ci# i.e.: linux64le
52e1051a39Sopenharmony_ci$LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0;
53e1051a39Sopenharmony_ci
54e1051a39Sopenharmony_ci$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
55e1051a39Sopenharmony_ci( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
56e1051a39Sopenharmony_ci( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
57e1051a39Sopenharmony_cidie "can't locate ppc-xlate.pl";
58e1051a39Sopenharmony_ci
59e1051a39Sopenharmony_ciopen STDOUT,"| $^X $xlate $flavour \"$output\""
60e1051a39Sopenharmony_ci    or die "can't call $xlate: $!";
61e1051a39Sopenharmony_ci
62e1051a39Sopenharmony_ci$FRAME=24*$SIZE_T+64;
63e1051a39Sopenharmony_ci$LOCALS=6*$SIZE_T;
64e1051a39Sopenharmony_ci
65e1051a39Sopenharmony_ci$K  ="r0";
66e1051a39Sopenharmony_ci$sp ="r1";
67e1051a39Sopenharmony_ci$toc="r2";
68e1051a39Sopenharmony_ci$ctx="r3";
69e1051a39Sopenharmony_ci$inp="r4";
70e1051a39Sopenharmony_ci$num="r5";
71e1051a39Sopenharmony_ci$t0 ="r15";
72e1051a39Sopenharmony_ci$t1 ="r6";
73e1051a39Sopenharmony_ci
74e1051a39Sopenharmony_ci$A  ="r7";
75e1051a39Sopenharmony_ci$B  ="r8";
76e1051a39Sopenharmony_ci$C  ="r9";
77e1051a39Sopenharmony_ci$D  ="r10";
78e1051a39Sopenharmony_ci$E  ="r11";
79e1051a39Sopenharmony_ci$T  ="r12";
80e1051a39Sopenharmony_ci
81e1051a39Sopenharmony_ci@V=($A,$B,$C,$D,$E,$T);
82e1051a39Sopenharmony_ci@X=("r16","r17","r18","r19","r20","r21","r22","r23",
83e1051a39Sopenharmony_ci    "r24","r25","r26","r27","r28","r29","r30","r31");
84e1051a39Sopenharmony_ci
85e1051a39Sopenharmony_cisub loadbe {
86e1051a39Sopenharmony_cimy ($dst, $src, $temp_reg) = @_;
87e1051a39Sopenharmony_ci$code.=<<___ if (!$LITTLE_ENDIAN);
88e1051a39Sopenharmony_ci	lwz	$dst,$src
89e1051a39Sopenharmony_ci___
90e1051a39Sopenharmony_ci$code.=<<___ if ($LITTLE_ENDIAN);
91e1051a39Sopenharmony_ci	lwz	$temp_reg,$src
92e1051a39Sopenharmony_ci	rotlwi	$dst,$temp_reg,8
93e1051a39Sopenharmony_ci	rlwimi	$dst,$temp_reg,24,0,7
94e1051a39Sopenharmony_ci	rlwimi	$dst,$temp_reg,24,16,23
95e1051a39Sopenharmony_ci___
96e1051a39Sopenharmony_ci}
97e1051a39Sopenharmony_ci
98e1051a39Sopenharmony_cisub BODY_00_19 {
99e1051a39Sopenharmony_cimy ($i,$a,$b,$c,$d,$e,$f)=@_;
100e1051a39Sopenharmony_cimy $j=$i+1;
101e1051a39Sopenharmony_ci
102e1051a39Sopenharmony_ci	# Since the last value of $f is discarded, we can use
103e1051a39Sopenharmony_ci	# it as a temp reg to swap byte-order when needed.
104e1051a39Sopenharmony_ci	loadbe("@X[$i]","`$i*4`($inp)",$f) if ($i==0);
105e1051a39Sopenharmony_ci	loadbe("@X[$j]","`$j*4`($inp)",$f) if ($i<15);
106e1051a39Sopenharmony_ci$code.=<<___ if ($i<15);
107e1051a39Sopenharmony_ci	add	$f,$K,$e
108e1051a39Sopenharmony_ci	rotlwi	$e,$a,5
109e1051a39Sopenharmony_ci	add	$f,$f,@X[$i]
110e1051a39Sopenharmony_ci	and	$t0,$c,$b
111e1051a39Sopenharmony_ci	add	$f,$f,$e
112e1051a39Sopenharmony_ci	andc	$t1,$d,$b
113e1051a39Sopenharmony_ci	rotlwi	$b,$b,30
114e1051a39Sopenharmony_ci	or	$t0,$t0,$t1
115e1051a39Sopenharmony_ci	add	$f,$f,$t0
116e1051a39Sopenharmony_ci___
117e1051a39Sopenharmony_ci$code.=<<___ if ($i>=15);
118e1051a39Sopenharmony_ci	add	$f,$K,$e
119e1051a39Sopenharmony_ci	rotlwi	$e,$a,5
120e1051a39Sopenharmony_ci	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
121e1051a39Sopenharmony_ci	add	$f,$f,@X[$i%16]
122e1051a39Sopenharmony_ci	and	$t0,$c,$b
123e1051a39Sopenharmony_ci	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
124e1051a39Sopenharmony_ci	add	$f,$f,$e
125e1051a39Sopenharmony_ci	andc	$t1,$d,$b
126e1051a39Sopenharmony_ci	rotlwi	$b,$b,30
127e1051a39Sopenharmony_ci	or	$t0,$t0,$t1
128e1051a39Sopenharmony_ci	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
129e1051a39Sopenharmony_ci	add	$f,$f,$t0
130e1051a39Sopenharmony_ci	rotlwi	@X[$j%16],@X[$j%16],1
131e1051a39Sopenharmony_ci___
132e1051a39Sopenharmony_ci}
133e1051a39Sopenharmony_ci
134e1051a39Sopenharmony_cisub BODY_20_39 {
135e1051a39Sopenharmony_cimy ($i,$a,$b,$c,$d,$e,$f)=@_;
136e1051a39Sopenharmony_cimy $j=$i+1;
137e1051a39Sopenharmony_ci$code.=<<___ if ($i<79);
138e1051a39Sopenharmony_ci	add	$f,$K,$e
139e1051a39Sopenharmony_ci	xor	$t0,$b,$d
140e1051a39Sopenharmony_ci	rotlwi	$e,$a,5
141e1051a39Sopenharmony_ci	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
142e1051a39Sopenharmony_ci	add	$f,$f,@X[$i%16]
143e1051a39Sopenharmony_ci	xor	$t0,$t0,$c
144e1051a39Sopenharmony_ci	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
145e1051a39Sopenharmony_ci	add	$f,$f,$t0
146e1051a39Sopenharmony_ci	rotlwi	$b,$b,30
147e1051a39Sopenharmony_ci	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
148e1051a39Sopenharmony_ci	add	$f,$f,$e
149e1051a39Sopenharmony_ci	rotlwi	@X[$j%16],@X[$j%16],1
150e1051a39Sopenharmony_ci___
151e1051a39Sopenharmony_ci$code.=<<___ if ($i==79);
152e1051a39Sopenharmony_ci	add	$f,$K,$e
153e1051a39Sopenharmony_ci	xor	$t0,$b,$d
154e1051a39Sopenharmony_ci	rotlwi	$e,$a,5
155e1051a39Sopenharmony_ci	lwz	r16,0($ctx)
156e1051a39Sopenharmony_ci	add	$f,$f,@X[$i%16]
157e1051a39Sopenharmony_ci	xor	$t0,$t0,$c
158e1051a39Sopenharmony_ci	lwz	r17,4($ctx)
159e1051a39Sopenharmony_ci	add	$f,$f,$t0
160e1051a39Sopenharmony_ci	rotlwi	$b,$b,30
161e1051a39Sopenharmony_ci	lwz	r18,8($ctx)
162e1051a39Sopenharmony_ci	lwz	r19,12($ctx)
163e1051a39Sopenharmony_ci	add	$f,$f,$e
164e1051a39Sopenharmony_ci	lwz	r20,16($ctx)
165e1051a39Sopenharmony_ci___
166e1051a39Sopenharmony_ci}
167e1051a39Sopenharmony_ci
168e1051a39Sopenharmony_cisub BODY_40_59 {
169e1051a39Sopenharmony_cimy ($i,$a,$b,$c,$d,$e,$f)=@_;
170e1051a39Sopenharmony_cimy $j=$i+1;
171e1051a39Sopenharmony_ci$code.=<<___;
172e1051a39Sopenharmony_ci	add	$f,$K,$e
173e1051a39Sopenharmony_ci	rotlwi	$e,$a,5
174e1051a39Sopenharmony_ci	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
175e1051a39Sopenharmony_ci	add	$f,$f,@X[$i%16]
176e1051a39Sopenharmony_ci	and	$t0,$b,$c
177e1051a39Sopenharmony_ci	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
178e1051a39Sopenharmony_ci	add	$f,$f,$e
179e1051a39Sopenharmony_ci	or	$t1,$b,$c
180e1051a39Sopenharmony_ci	rotlwi	$b,$b,30
181e1051a39Sopenharmony_ci	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
182e1051a39Sopenharmony_ci	and	$t1,$t1,$d
183e1051a39Sopenharmony_ci	or	$t0,$t0,$t1
184e1051a39Sopenharmony_ci	rotlwi	@X[$j%16],@X[$j%16],1
185e1051a39Sopenharmony_ci	add	$f,$f,$t0
186e1051a39Sopenharmony_ci___
187e1051a39Sopenharmony_ci}
188e1051a39Sopenharmony_ci
189e1051a39Sopenharmony_ci$code=<<___;
190e1051a39Sopenharmony_ci.machine	"any"
191e1051a39Sopenharmony_ci.text
192e1051a39Sopenharmony_ci
193e1051a39Sopenharmony_ci.globl	.sha1_block_data_order
194e1051a39Sopenharmony_ci.align	4
195e1051a39Sopenharmony_ci.sha1_block_data_order:
196e1051a39Sopenharmony_ci	$STU	$sp,-$FRAME($sp)
197e1051a39Sopenharmony_ci	mflr	r0
198e1051a39Sopenharmony_ci	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
199e1051a39Sopenharmony_ci	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
200e1051a39Sopenharmony_ci	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
201e1051a39Sopenharmony_ci	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
202e1051a39Sopenharmony_ci	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
203e1051a39Sopenharmony_ci	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
204e1051a39Sopenharmony_ci	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
205e1051a39Sopenharmony_ci	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
206e1051a39Sopenharmony_ci	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
207e1051a39Sopenharmony_ci	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
208e1051a39Sopenharmony_ci	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
209e1051a39Sopenharmony_ci	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
210e1051a39Sopenharmony_ci	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
211e1051a39Sopenharmony_ci	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
212e1051a39Sopenharmony_ci	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
213e1051a39Sopenharmony_ci	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
214e1051a39Sopenharmony_ci	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
215e1051a39Sopenharmony_ci	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
216e1051a39Sopenharmony_ci	lwz	$A,0($ctx)
217e1051a39Sopenharmony_ci	lwz	$B,4($ctx)
218e1051a39Sopenharmony_ci	lwz	$C,8($ctx)
219e1051a39Sopenharmony_ci	lwz	$D,12($ctx)
220e1051a39Sopenharmony_ci	lwz	$E,16($ctx)
221e1051a39Sopenharmony_ci	andi.	r0,$inp,3
222e1051a39Sopenharmony_ci	bne	Lunaligned
223e1051a39Sopenharmony_ciLaligned:
224e1051a39Sopenharmony_ci	mtctr	$num
225e1051a39Sopenharmony_ci	bl	Lsha1_block_private
226e1051a39Sopenharmony_ci	b	Ldone
227e1051a39Sopenharmony_ci
228e1051a39Sopenharmony_ci; PowerPC specification allows an implementation to be ill-behaved
229e1051a39Sopenharmony_ci; upon unaligned access which crosses page boundary. "Better safe
230e1051a39Sopenharmony_ci; than sorry" principle makes me treat it specially. But I don't
231e1051a39Sopenharmony_ci; look for particular offending word, but rather for 64-byte input
232e1051a39Sopenharmony_ci; block which crosses the boundary. Once found that block is aligned
233e1051a39Sopenharmony_ci; and hashed separately...
234e1051a39Sopenharmony_ci.align	4
235e1051a39Sopenharmony_ciLunaligned:
236e1051a39Sopenharmony_ci	subfic	$t1,$inp,4096
237e1051a39Sopenharmony_ci	andi.	$t1,$t1,4095	; distance to closest page boundary
238e1051a39Sopenharmony_ci	srwi.	$t1,$t1,6	; t1/=64
239e1051a39Sopenharmony_ci	beq	Lcross_page
240e1051a39Sopenharmony_ci	$UCMP	$num,$t1
241e1051a39Sopenharmony_ci	ble	Laligned	; didn't cross the page boundary
242e1051a39Sopenharmony_ci	mtctr	$t1
243e1051a39Sopenharmony_ci	subfc	$num,$t1,$num
244e1051a39Sopenharmony_ci	bl	Lsha1_block_private
245e1051a39Sopenharmony_ciLcross_page:
246e1051a39Sopenharmony_ci	li	$t1,16
247e1051a39Sopenharmony_ci	mtctr	$t1
248e1051a39Sopenharmony_ci	addi	r20,$sp,$LOCALS	; spot within the frame
249e1051a39Sopenharmony_ciLmemcpy:
250e1051a39Sopenharmony_ci	lbz	r16,0($inp)
251e1051a39Sopenharmony_ci	lbz	r17,1($inp)
252e1051a39Sopenharmony_ci	lbz	r18,2($inp)
253e1051a39Sopenharmony_ci	lbz	r19,3($inp)
254e1051a39Sopenharmony_ci	addi	$inp,$inp,4
255e1051a39Sopenharmony_ci	stb	r16,0(r20)
256e1051a39Sopenharmony_ci	stb	r17,1(r20)
257e1051a39Sopenharmony_ci	stb	r18,2(r20)
258e1051a39Sopenharmony_ci	stb	r19,3(r20)
259e1051a39Sopenharmony_ci	addi	r20,r20,4
260e1051a39Sopenharmony_ci	bdnz	Lmemcpy
261e1051a39Sopenharmony_ci
262e1051a39Sopenharmony_ci	$PUSH	$inp,`$FRAME-$SIZE_T*18`($sp)
263e1051a39Sopenharmony_ci	li	$t1,1
264e1051a39Sopenharmony_ci	addi	$inp,$sp,$LOCALS
265e1051a39Sopenharmony_ci	mtctr	$t1
266e1051a39Sopenharmony_ci	bl	Lsha1_block_private
267e1051a39Sopenharmony_ci	$POP	$inp,`$FRAME-$SIZE_T*18`($sp)
268e1051a39Sopenharmony_ci	addic.	$num,$num,-1
269e1051a39Sopenharmony_ci	bne	Lunaligned
270e1051a39Sopenharmony_ci
271e1051a39Sopenharmony_ciLdone:
272e1051a39Sopenharmony_ci	$POP	r0,`$FRAME+$LRSAVE`($sp)
273e1051a39Sopenharmony_ci	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
274e1051a39Sopenharmony_ci	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
275e1051a39Sopenharmony_ci	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
276e1051a39Sopenharmony_ci	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
277e1051a39Sopenharmony_ci	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
278e1051a39Sopenharmony_ci	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
279e1051a39Sopenharmony_ci	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
280e1051a39Sopenharmony_ci	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
281e1051a39Sopenharmony_ci	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
282e1051a39Sopenharmony_ci	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
283e1051a39Sopenharmony_ci	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
284e1051a39Sopenharmony_ci	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
285e1051a39Sopenharmony_ci	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
286e1051a39Sopenharmony_ci	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
287e1051a39Sopenharmony_ci	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
288e1051a39Sopenharmony_ci	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
289e1051a39Sopenharmony_ci	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
290e1051a39Sopenharmony_ci	mtlr	r0
291e1051a39Sopenharmony_ci	addi	$sp,$sp,$FRAME
292e1051a39Sopenharmony_ci	blr
293e1051a39Sopenharmony_ci	.long	0
294e1051a39Sopenharmony_ci	.byte	0,12,4,1,0x80,18,3,0
295e1051a39Sopenharmony_ci	.long	0
296e1051a39Sopenharmony_ci___
297e1051a39Sopenharmony_ci
298e1051a39Sopenharmony_ci# This is private block function, which uses tailored calling
299e1051a39Sopenharmony_ci# interface, namely upon entry SHA_CTX is pre-loaded to given
300e1051a39Sopenharmony_ci# registers and counter register contains amount of chunks to
301e1051a39Sopenharmony_ci# digest...
302e1051a39Sopenharmony_ci$code.=<<___;
303e1051a39Sopenharmony_ci.align	4
304e1051a39Sopenharmony_ciLsha1_block_private:
305e1051a39Sopenharmony_ci___
306e1051a39Sopenharmony_ci$code.=<<___;	# load K_00_19
307e1051a39Sopenharmony_ci	lis	$K,0x5a82
308e1051a39Sopenharmony_ci	ori	$K,$K,0x7999
309e1051a39Sopenharmony_ci___
310e1051a39Sopenharmony_cifor($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
311e1051a39Sopenharmony_ci$code.=<<___;	# load K_20_39
312e1051a39Sopenharmony_ci	lis	$K,0x6ed9
313e1051a39Sopenharmony_ci	ori	$K,$K,0xeba1
314e1051a39Sopenharmony_ci___
315e1051a39Sopenharmony_cifor(;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
316e1051a39Sopenharmony_ci$code.=<<___;	# load K_40_59
317e1051a39Sopenharmony_ci	lis	$K,0x8f1b
318e1051a39Sopenharmony_ci	ori	$K,$K,0xbcdc
319e1051a39Sopenharmony_ci___
320e1051a39Sopenharmony_cifor(;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
321e1051a39Sopenharmony_ci$code.=<<___;	# load K_60_79
322e1051a39Sopenharmony_ci	lis	$K,0xca62
323e1051a39Sopenharmony_ci	ori	$K,$K,0xc1d6
324e1051a39Sopenharmony_ci___
325e1051a39Sopenharmony_cifor(;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
326e1051a39Sopenharmony_ci$code.=<<___;
327e1051a39Sopenharmony_ci	add	r16,r16,$E
328e1051a39Sopenharmony_ci	add	r17,r17,$T
329e1051a39Sopenharmony_ci	add	r18,r18,$A
330e1051a39Sopenharmony_ci	add	r19,r19,$B
331e1051a39Sopenharmony_ci	add	r20,r20,$C
332e1051a39Sopenharmony_ci	stw	r16,0($ctx)
333e1051a39Sopenharmony_ci	mr	$A,r16
334e1051a39Sopenharmony_ci	stw	r17,4($ctx)
335e1051a39Sopenharmony_ci	mr	$B,r17
336e1051a39Sopenharmony_ci	stw	r18,8($ctx)
337e1051a39Sopenharmony_ci	mr	$C,r18
338e1051a39Sopenharmony_ci	stw	r19,12($ctx)
339e1051a39Sopenharmony_ci	mr	$D,r19
340e1051a39Sopenharmony_ci	stw	r20,16($ctx)
341e1051a39Sopenharmony_ci	mr	$E,r20
342e1051a39Sopenharmony_ci	addi	$inp,$inp,`16*4`
343e1051a39Sopenharmony_ci	bdnz	Lsha1_block_private
344e1051a39Sopenharmony_ci	blr
345e1051a39Sopenharmony_ci	.long	0
346e1051a39Sopenharmony_ci	.byte	0,12,0x14,0,0,0,0,0
347e1051a39Sopenharmony_ci.size	.sha1_block_data_order,.-.sha1_block_data_order
348e1051a39Sopenharmony_ci___
349e1051a39Sopenharmony_ci$code.=<<___;
350e1051a39Sopenharmony_ci.asciz	"SHA1 block transform for PPC, CRYPTOGAMS by <appro\@fy.chalmers.se>"
351e1051a39Sopenharmony_ci___
352e1051a39Sopenharmony_ci
353e1051a39Sopenharmony_ci$code =~ s/\`([^\`]*)\`/eval $1/gem;
354e1051a39Sopenharmony_ciprint $code;
355e1051a39Sopenharmony_ciclose STDOUT or die "error closing STDOUT: $!";
356