1#!/usr/bin/env perl
2
3$flavour = shift;
4$output = shift;
5open STDOUT,">$output";
6
7if ($flavour =~ /64/) {
8	$LEVEL		="2.0W";
9	$SIZE_T		=8;
10	$ST		="std";
11} else {
12	$LEVEL		="1.1";
13	$SIZE_T		=4;
14	$ST		="stw";
15}
16
17$rp="%r2";
18$sp="%r30";
19$rv="%r28";
20
21$code=<<___;
22	.LEVEL	$LEVEL
23	.SPACE	\$TEXT\$
24	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
25
26	.EXPORT	OPENSSL_cpuid_setup,ENTRY
27	.ALIGN	8
28OPENSSL_cpuid_setup
29	.PROC
30	.CALLINFO	NO_CALLS
31	.ENTRY
32	bv	($rp)
33	.EXIT
34	nop
35	.PROCEND
36
37	.EXPORT	OPENSSL_rdtsc,ENTRY
38	.ALIGN	8
39OPENSSL_rdtsc
40	.PROC
41	.CALLINFO	NO_CALLS
42	.ENTRY
43	mfctl	%cr16,$rv
44	bv	($rp)
45	.EXIT
46	nop
47	.PROCEND
48
49	.EXPORT	OPENSSL_wipe_cpu,ENTRY
50	.ALIGN	8
51OPENSSL_wipe_cpu
52	.PROC
53	.CALLINFO	NO_CALLS
54	.ENTRY
55	xor		%r0,%r0,%r1
56	fcpy,dbl	%fr0,%fr4
57	xor		%r0,%r0,%r19
58	fcpy,dbl	%fr0,%fr5
59	xor		%r0,%r0,%r20
60	fcpy,dbl	%fr0,%fr6
61	xor		%r0,%r0,%r21
62	fcpy,dbl	%fr0,%fr7
63	xor		%r0,%r0,%r22
64	fcpy,dbl	%fr0,%fr8
65	xor		%r0,%r0,%r23
66	fcpy,dbl	%fr0,%fr9
67	xor		%r0,%r0,%r24
68	fcpy,dbl	%fr0,%fr10
69	xor		%r0,%r0,%r25
70	fcpy,dbl	%fr0,%fr11
71	xor		%r0,%r0,%r26
72	fcpy,dbl	%fr0,%fr22
73	xor		%r0,%r0,%r29
74	fcpy,dbl	%fr0,%fr23
75	xor		%r0,%r0,%r31
76	fcpy,dbl	%fr0,%fr24
77	fcpy,dbl	%fr0,%fr25
78	fcpy,dbl	%fr0,%fr26
79	fcpy,dbl	%fr0,%fr27
80	fcpy,dbl	%fr0,%fr28
81	fcpy,dbl	%fr0,%fr29
82	fcpy,dbl	%fr0,%fr30
83	fcpy,dbl	%fr0,%fr31
84	bv		($rp)
85	.EXIT
86	ldo		0($sp),$rv
87	.PROCEND
88___
89{
90my $inp="%r26";
91my $len="%r25";
92
93$code.=<<___;
94	.EXPORT	OPENSSL_cleanse,ENTRY,ARGW0=GR,ARGW1=GR
95	.ALIGN	8
96OPENSSL_cleanse
97	.PROC
98	.CALLINFO	NO_CALLS
99	.ENTRY
100	cmpib,*=	0,$len,L\$done
101	nop
102	cmpib,*>>=	15,$len,L\$ittle
103	ldi		$SIZE_T-1,%r1
104
105L\$align
106	and,*<>		$inp,%r1,%r28
107	b,n		L\$aligned
108	stb		%r0,0($inp)
109	ldo		-1($len),$len
110	b		L\$align
111	ldo		1($inp),$inp
112
113L\$aligned
114	andcm		$len,%r1,%r28
115L\$ot
116	$ST		%r0,0($inp)
117	addib,*<>	-$SIZE_T,%r28,L\$ot
118	ldo		$SIZE_T($inp),$inp
119
120	and,*<>		$len,%r1,$len
121	b,n		L\$done
122L\$ittle
123	stb		%r0,0($inp)
124	addib,*<>	-1,$len,L\$ittle
125	ldo		1($inp),$inp
126L\$done
127	bv		($rp)
128	.EXIT
129	nop
130	.PROCEND
131___
132}
133{
134my ($out,$cnt,$max)=("%r26","%r25","%r24");
135my ($tick,$lasttick)=("%r23","%r22");
136my ($diff,$lastdiff)=("%r21","%r20");
137
138$code.=<<___;
139	.EXPORT	OPENSSL_instrument_bus,ENTRY,ARGW0=GR,ARGW1=GR
140	.ALIGN	8
141OPENSSL_instrument_bus
142	.PROC
143	.CALLINFO	NO_CALLS
144	.ENTRY
145	copy		$cnt,$rv
146	mfctl		%cr16,$tick
147	copy		$tick,$lasttick
148	ldi		0,$diff
149
150	fdc		0($out)
151	ldw		0($out),$tick
152	add		$diff,$tick,$tick
153	stw		$tick,0($out)
154L\$oop
155	mfctl		%cr16,$tick
156	sub		$tick,$lasttick,$diff
157	copy		$tick,$lasttick
158
159	fdc		0($out)
160	ldw		0($out),$tick
161	add		$diff,$tick,$tick
162	stw		$tick,0($out)
163
164	addib,<>	-1,$cnt,L\$oop
165	addi		4,$out,$out
166
167	bv		($rp)
168	.EXIT
169	sub		$rv,$cnt,$rv
170	.PROCEND
171
172	.EXPORT	OPENSSL_instrument_bus2,ENTRY,ARGW0=GR,ARGW1=GR
173	.ALIGN	8
174OPENSSL_instrument_bus2
175	.PROC
176	.CALLINFO	NO_CALLS
177	.ENTRY
178	copy		$cnt,$rv
179	sub		%r0,$cnt,$cnt
180
181	mfctl		%cr16,$tick
182	copy		$tick,$lasttick
183	ldi		0,$diff
184
185	fdc		0($out)
186	ldw		0($out),$tick
187	add		$diff,$tick,$tick
188	stw		$tick,0($out)
189
190	mfctl		%cr16,$tick
191	sub		$tick,$lasttick,$diff
192	copy		$tick,$lasttick
193L\$oop2
194	copy		$diff,$lastdiff
195	fdc		0($out)
196	ldw		0($out),$tick
197	add		$diff,$tick,$tick
198	stw		$tick,0($out)
199
200	addib,=		-1,$max,L\$done2
201	nop
202
203	mfctl		%cr16,$tick
204	sub		$tick,$lasttick,$diff
205	copy		$tick,$lasttick
206	cmpclr,<>	$lastdiff,$diff,$tick
207	ldi		1,$tick
208
209	ldi		1,%r1
210	xor		%r1,$tick,$tick
211	addb,<>		$tick,$cnt,L\$oop2
212	shladd,l	$tick,2,$out,$out
213L\$done2
214	bv		($rp)
215	.EXIT
216	add		$rv,$cnt,$rv
217	.PROCEND
218___
219}
220$code =~ s/cmpib,\*/comib,/gm	if ($SIZE_T==4);
221$code =~ s/,\*/,/gm		if ($SIZE_T==4);
222$code =~ s/\bbv\b/bve/gm	if ($SIZE_T==8);
223print $code;
224close STDOUT;
225
226