Blame view

kernel/linux-rt-4.4.41/drivers/crypto/vmx/ghashp8-ppc.pl 5.19 KB
5113f6f70   김현기   kernel add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
  #!/usr/bin/env perl
  #
  # ====================================================================
  # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
  # project. The module is, however, dual licensed under OpenSSL and
  # CRYPTOGAMS licenses depending on where you obtain it. For further
  # details see http://www.openssl.org/~appro/cryptogams/.
  # ====================================================================
  #
  # GHASH for for PowerISA v2.07.
  #
  # July 2014
  #
  # Accurate performance measurements are problematic, because it's
  # always virtualized setup with possibly throttled processor.
  # Relative comparison is therefore more informative. This initial
  # version is ~2.1x slower than hardware-assisted AES-128-CTR, ~12x
  # faster than "4-bit" integer-only compiler-generated 64-bit code.
  # "Initial version" means that there is room for futher improvement.
  
  $flavour=shift;
  $output =shift;
  
  if ($flavour =~ /64/) {
  	$SIZE_T=8;
  	$LRSAVE=2*$SIZE_T;
  	$STU="stdu";
  	$POP="ld";
  	$PUSH="std";
  } elsif ($flavour =~ /32/) {
  	$SIZE_T=4;
  	$LRSAVE=$SIZE_T;
  	$STU="stwu";
  	$POP="lwz";
  	$PUSH="stw";
  } else { die "nonsense $flavour"; }
  
  $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
  ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
  ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
  die "can't locate ppc-xlate.pl";
  
  open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!";
  
  my ($Xip,$Htbl,$inp,$len)=map("r$_",(3..6));	# argument block
  
  my ($Xl,$Xm,$Xh,$IN)=map("v$_",(0..3));
  my ($zero,$t0,$t1,$t2,$xC2,$H,$Hh,$Hl,$lemask)=map("v$_",(4..12));
  my $vrsave="r12";
  
  $code=<<___;
  .machine	"any"
  
  .text
  
  .globl	.gcm_init_p8
  	lis		r0,0xfff0
  	li		r8,0x10
  	mfspr		$vrsave,256
  	li		r9,0x20
  	mtspr		256,r0
  	li		r10,0x30
  	lvx_u		$H,0,r4			# load H
  	le?xor		r7,r7,r7
  	le?addi		r7,r7,0x8		# need a vperm start with 08
  	le?lvsr		5,0,r7
  	le?vspltisb	6,0x0f
  	le?vxor		5,5,6			# set a b-endian mask
  	le?vperm	$H,$H,$H,5
  
  	vspltisb	$xC2,-16		# 0xf0
  	vspltisb	$t0,1			# one
  	vaddubm		$xC2,$xC2,$xC2		# 0xe0
  	vxor		$zero,$zero,$zero
  	vor		$xC2,$xC2,$t0		# 0xe1
  	vsldoi		$xC2,$xC2,$zero,15	# 0xe1...
  	vsldoi		$t1,$zero,$t0,1		# ...1
  	vaddubm		$xC2,$xC2,$xC2		# 0xc2...
  	vspltisb	$t2,7
  	vor		$xC2,$xC2,$t1		# 0xc2....01
  	vspltb		$t1,$H,0		# most significant byte
  	vsl		$H,$H,$t0		# H<<=1
  	vsrab		$t1,$t1,$t2		# broadcast carry bit
  	vand		$t1,$t1,$xC2
  	vxor		$H,$H,$t1		# twisted H
  
  	vsldoi		$H,$H,$H,8		# twist even more ...
  	vsldoi		$xC2,$zero,$xC2,8	# 0xc2.0
  	vsldoi		$Hl,$zero,$H,8		# ... and split
  	vsldoi		$Hh,$H,$zero,8
  
  	stvx_u		$xC2,0,r3		# save pre-computed table
  	stvx_u		$Hl,r8,r3
  	stvx_u		$H, r9,r3
  	stvx_u		$Hh,r10,r3
  
  	mtspr		256,$vrsave
  	blr
  	.long		0
  	.byte		0,12,0x14,0,0,0,2,0
  	.long		0
  .size	.gcm_init_p8,.-.gcm_init_p8
  
  .globl	.gcm_gmult_p8
  	lis		r0,0xfff8
  	li		r8,0x10
  	mfspr		$vrsave,256
  	li		r9,0x20
  	mtspr		256,r0
  	li		r10,0x30
  	lvx_u		$IN,0,$Xip		# load Xi
  
  	lvx_u		$Hl,r8,$Htbl		# load pre-computed table
  	 le?lvsl	$lemask,r0,r0
  	lvx_u		$H, r9,$Htbl
  	 le?vspltisb	$t0,0x07
  	lvx_u		$Hh,r10,$Htbl
  	 le?vxor	$lemask,$lemask,$t0
  	lvx_u		$xC2,0,$Htbl
  	 le?vperm	$IN,$IN,$IN,$lemask
  	vxor		$zero,$zero,$zero
  
  	vpmsumd		$Xl,$IN,$Hl		# H.lo·Xi.lo
  	vpmsumd		$Xm,$IN,$H		# H.hi·Xi.lo+H.lo·Xi.hi
  	vpmsumd		$Xh,$IN,$Hh		# H.hi·Xi.hi
  
  	vpmsumd		$t2,$Xl,$xC2		# 1st phase
  
  	vsldoi		$t0,$Xm,$zero,8
  	vsldoi		$t1,$zero,$Xm,8
  	vxor		$Xl,$Xl,$t0
  	vxor		$Xh,$Xh,$t1
  
  	vsldoi		$Xl,$Xl,$Xl,8
  	vxor		$Xl,$Xl,$t2
  
  	vsldoi		$t1,$Xl,$Xl,8		# 2nd phase
  	vpmsumd		$Xl,$Xl,$xC2
  	vxor		$t1,$t1,$Xh
  	vxor		$Xl,$Xl,$t1
  
  	le?vperm	$Xl,$Xl,$Xl,$lemask
  	stvx_u		$Xl,0,$Xip		# write out Xi
  
  	mtspr		256,$vrsave
  	blr
  	.long		0
  	.byte		0,12,0x14,0,0,0,2,0
  	.long		0
  .size	.gcm_gmult_p8,.-.gcm_gmult_p8
  
  .globl	.gcm_ghash_p8
  	lis		r0,0xfff8
  	li		r8,0x10
  	mfspr		$vrsave,256
  	li		r9,0x20
  	mtspr		256,r0
  	li		r10,0x30
  	lvx_u		$Xl,0,$Xip		# load Xi
  
  	lvx_u		$Hl,r8,$Htbl		# load pre-computed table
  	 le?lvsl	$lemask,r0,r0
  	lvx_u		$H, r9,$Htbl
  	 le?vspltisb	$t0,0x07
  	lvx_u		$Hh,r10,$Htbl
  	 le?vxor	$lemask,$lemask,$t0
  	lvx_u		$xC2,0,$Htbl
  	 le?vperm	$Xl,$Xl,$Xl,$lemask
  	vxor		$zero,$zero,$zero
  
  	lvx_u		$IN,0,$inp
  	addi		$inp,$inp,16
  	subi		$len,$len,16
  	 le?vperm	$IN,$IN,$IN,$lemask
  	vxor		$IN,$IN,$Xl
  	b		Loop
  
  .align	5
  Loop:
  	 subic		$len,$len,16
  	vpmsumd		$Xl,$IN,$Hl		# H.lo·Xi.lo
  	 subfe.		r0,r0,r0		# borrow?-1:0
  	vpmsumd		$Xm,$IN,$H		# H.hi·Xi.lo+H.lo·Xi.hi
  	 and		r0,r0,$len
  	vpmsumd		$Xh,$IN,$Hh		# H.hi·Xi.hi
  	 add		$inp,$inp,r0
  
  	vpmsumd		$t2,$Xl,$xC2		# 1st phase
  
  	vsldoi		$t0,$Xm,$zero,8
  	vsldoi		$t1,$zero,$Xm,8
  	vxor		$Xl,$Xl,$t0
  	vxor		$Xh,$Xh,$t1
  
  	vsldoi		$Xl,$Xl,$Xl,8
  	vxor		$Xl,$Xl,$t2
  	 lvx_u		$IN,0,$inp
  	 addi		$inp,$inp,16
  
  	vsldoi		$t1,$Xl,$Xl,8		# 2nd phase
  	vpmsumd		$Xl,$Xl,$xC2
  	 le?vperm	$IN,$IN,$IN,$lemask
  	vxor		$t1,$t1,$Xh
  	vxor		$IN,$IN,$t1
  	vxor		$IN,$IN,$Xl
  	beq		Loop			# did $len-=16 borrow?
  
  	vxor		$Xl,$Xl,$t1
  	le?vperm	$Xl,$Xl,$Xl,$lemask
  	stvx_u		$Xl,0,$Xip		# write out Xi
  
  	mtspr		256,$vrsave
  	blr
  	.long		0
  	.byte		0,12,0x14,0,0,0,4,0
  	.long		0
  .size	.gcm_ghash_p8,.-.gcm_ghash_p8
  
  .asciz  "GHASH for PowerISA 2.07, CRYPTOGAMS by <appro\@openssl.org>"
  .align  2
  ___
  
  foreach (split("
  ",$code)) {
  	if ($flavour =~ /le$/o) {	# little-endian
  	    s/le\?//o		or
  	    s/be\?/#be#/o;
  	} else {
  	    s/le\?/#le#/o	or
  	    s/be\?//o;
  	}
  	print $_,"
  ";
  }
  
  close STDOUT; # enforce flush