1238405Sjkim	# $FreeBSD$
2238405Sjkim
3238405Sjkim.hidden	OPENSSL_cpuid_setup
4238405Sjkim.section	.init
5238405Sjkim	call	OPENSSL_cpuid_setup
6238405Sjkim
7238405Sjkim.hidden	OPENSSL_ia32cap_P
8238405Sjkim.comm	OPENSSL_ia32cap_P,8,4
9238405Sjkim
10238405Sjkim.text
11238405Sjkim
12238405Sjkim.globl	OPENSSL_atomic_add
13238405Sjkim.type	OPENSSL_atomic_add,@function
14238405Sjkim.align	16
15238405SjkimOPENSSL_atomic_add:
16238405Sjkim	movl	(%rdi),%eax
17238405Sjkim.Lspin:	leaq	(%rsi,%rax,1),%r8
18238405Sjkim.byte	0xf0
19238405Sjkim	cmpxchgl	%r8d,(%rdi)
20238405Sjkim	jne	.Lspin
21238405Sjkim	movl	%r8d,%eax
22238405Sjkim.byte	0x48,0x98
23238405Sjkim	.byte	0xf3,0xc3
24238405Sjkim.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
25238405Sjkim
26238405Sjkim.globl	OPENSSL_rdtsc
27238405Sjkim.type	OPENSSL_rdtsc,@function
28238405Sjkim.align	16
29238405SjkimOPENSSL_rdtsc:
30238405Sjkim	rdtsc
31238405Sjkim	shlq	$32,%rdx
32238405Sjkim	orq	%rdx,%rax
33238405Sjkim	.byte	0xf3,0xc3
34238405Sjkim.size	OPENSSL_rdtsc,.-OPENSSL_rdtsc
35238405Sjkim
36238405Sjkim.globl	OPENSSL_ia32_cpuid
37238405Sjkim.type	OPENSSL_ia32_cpuid,@function
38238405Sjkim.align	16
39238405SjkimOPENSSL_ia32_cpuid:
40238405Sjkim	movq	%rbx,%r8
41238405Sjkim
42238405Sjkim	xorl	%eax,%eax
43238405Sjkim	cpuid
44238405Sjkim	movl	%eax,%r11d
45238405Sjkim
46238405Sjkim	xorl	%eax,%eax
47238405Sjkim	cmpl	$1970169159,%ebx
48238405Sjkim	setne	%al
49238405Sjkim	movl	%eax,%r9d
50238405Sjkim	cmpl	$1231384169,%edx
51238405Sjkim	setne	%al
52238405Sjkim	orl	%eax,%r9d
53238405Sjkim	cmpl	$1818588270,%ecx
54238405Sjkim	setne	%al
55238405Sjkim	orl	%eax,%r9d
56238405Sjkim	jz	.Lintel
57238405Sjkim
58238405Sjkim	cmpl	$1752462657,%ebx
59238405Sjkim	setne	%al
60238405Sjkim	movl	%eax,%r10d
61238405Sjkim	cmpl	$1769238117,%edx
62238405Sjkim	setne	%al
63238405Sjkim	orl	%eax,%r10d
64238405Sjkim	cmpl	$1145913699,%ecx
65238405Sjkim	setne	%al
66238405Sjkim	orl	%eax,%r10d
67238405Sjkim	jnz	.Lintel
68238405Sjkim
69238405Sjkim
70238405Sjkim	movl	$2147483648,%eax
71238405Sjkim	cpuid
72238405Sjkim	cmpl	$2147483649,%eax
73238405Sjkim	jb	.Lintel
74238405Sjkim	movl	%eax,%r10d
75238405Sjkim	movl	$2147483649,%eax
76238405Sjkim	cpuid
77238405Sjkim	orl	%ecx,%r9d
78238405Sjkim	andl	$2049,%r9d
79238405Sjkim
80238405Sjkim	cmpl	$2147483656,%r10d
81238405Sjkim	jb	.Lintel
82238405Sjkim
83238405Sjkim	movl	$2147483656,%eax
84238405Sjkim	cpuid
85238405Sjkim	movzbq	%cl,%r10
86238405Sjkim	incq	%r10
87238405Sjkim
88238405Sjkim	movl	$1,%eax
89238405Sjkim	cpuid
90238405Sjkim	btl	$28,%edx
91238405Sjkim	jnc	.Lgeneric
92238405Sjkim	shrl	$16,%ebx
93238405Sjkim	cmpb	%r10b,%bl
94238405Sjkim	ja	.Lgeneric
95238405Sjkim	andl	$4026531839,%edx
96238405Sjkim	jmp	.Lgeneric
97238405Sjkim
98238405Sjkim.Lintel:
99238405Sjkim	cmpl	$4,%r11d
100238405Sjkim	movl	$-1,%r10d
101238405Sjkim	jb	.Lnocacheinfo
102238405Sjkim
103238405Sjkim	movl	$4,%eax
104238405Sjkim	movl	$0,%ecx
105238405Sjkim	cpuid
106238405Sjkim	movl	%eax,%r10d
107238405Sjkim	shrl	$14,%r10d
108238405Sjkim	andl	$4095,%r10d
109238405Sjkim
110238405Sjkim.Lnocacheinfo:
111238405Sjkim	movl	$1,%eax
112238405Sjkim	cpuid
113238405Sjkim	andl	$3220176895,%edx
114238405Sjkim	cmpl	$0,%r9d
115238405Sjkim	jne	.Lnotintel
116238405Sjkim	orl	$1073741824,%edx
117238405Sjkim	andb	$15,%ah
118238405Sjkim	cmpb	$15,%ah
119238405Sjkim	jne	.Lnotintel
120238405Sjkim	orl	$1048576,%edx
121238405Sjkim.Lnotintel:
122238405Sjkim	btl	$28,%edx
123238405Sjkim	jnc	.Lgeneric
124238405Sjkim	andl	$4026531839,%edx
125238405Sjkim	cmpl	$0,%r10d
126238405Sjkim	je	.Lgeneric
127238405Sjkim
128238405Sjkim	orl	$268435456,%edx
129238405Sjkim	shrl	$16,%ebx
130238405Sjkim	cmpb	$1,%bl
131238405Sjkim	ja	.Lgeneric
132238405Sjkim	andl	$4026531839,%edx
133238405Sjkim.Lgeneric:
134238405Sjkim	andl	$2048,%r9d
135238405Sjkim	andl	$4294965247,%ecx
136238405Sjkim	orl	%ecx,%r9d
137238405Sjkim
138238405Sjkim	movl	%edx,%r10d
139238405Sjkim	btl	$27,%r9d
140238405Sjkim	jnc	.Lclear_avx
141238405Sjkim	xorl	%ecx,%ecx
142238405Sjkim.byte	0x0f,0x01,0xd0
143238405Sjkim	andl	$6,%eax
144238405Sjkim	cmpl	$6,%eax
145238405Sjkim	je	.Ldone
146238405Sjkim.Lclear_avx:
147238405Sjkim	movl	$4026525695,%eax
148238405Sjkim	andl	%eax,%r9d
149238405Sjkim.Ldone:
150238405Sjkim	shlq	$32,%r9
151238405Sjkim	movl	%r10d,%eax
152238405Sjkim	movq	%r8,%rbx
153238405Sjkim	orq	%r9,%rax
154238405Sjkim	.byte	0xf3,0xc3
155238405Sjkim.size	OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
156238405Sjkim
157238405Sjkim.globl	OPENSSL_cleanse
158238405Sjkim.type	OPENSSL_cleanse,@function
159238405Sjkim.align	16
160238405SjkimOPENSSL_cleanse:
161238405Sjkim	xorq	%rax,%rax
162238405Sjkim	cmpq	$15,%rsi
163238405Sjkim	jae	.Lot
164238405Sjkim	cmpq	$0,%rsi
165238405Sjkim	je	.Lret
166238405Sjkim.Little:
167238405Sjkim	movb	%al,(%rdi)
168238405Sjkim	subq	$1,%rsi
169238405Sjkim	leaq	1(%rdi),%rdi
170238405Sjkim	jnz	.Little
171238405Sjkim.Lret:
172238405Sjkim	.byte	0xf3,0xc3
173238405Sjkim.align	16
174238405Sjkim.Lot:
175238405Sjkim	testq	$7,%rdi
176238405Sjkim	jz	.Laligned
177238405Sjkim	movb	%al,(%rdi)
178238405Sjkim	leaq	-1(%rsi),%rsi
179238405Sjkim	leaq	1(%rdi),%rdi
180238405Sjkim	jmp	.Lot
181238405Sjkim.Laligned:
182238405Sjkim	movq	%rax,(%rdi)
183238405Sjkim	leaq	-8(%rsi),%rsi
184238405Sjkim	testq	$-8,%rsi
185238405Sjkim	leaq	8(%rdi),%rdi
186238405Sjkim	jnz	.Laligned
187238405Sjkim	cmpq	$0,%rsi
188238405Sjkim	jne	.Little
189238405Sjkim	.byte	0xf3,0xc3
190238405Sjkim.size	OPENSSL_cleanse,.-OPENSSL_cleanse
191238405Sjkim.globl	OPENSSL_wipe_cpu
192238405Sjkim.type	OPENSSL_wipe_cpu,@function
193238405Sjkim.align	16
194238405SjkimOPENSSL_wipe_cpu:
195238405Sjkim	pxor	%xmm0,%xmm0
196238405Sjkim	pxor	%xmm1,%xmm1
197238405Sjkim	pxor	%xmm2,%xmm2
198238405Sjkim	pxor	%xmm3,%xmm3
199238405Sjkim	pxor	%xmm4,%xmm4
200238405Sjkim	pxor	%xmm5,%xmm5
201238405Sjkim	pxor	%xmm6,%xmm6
202238405Sjkim	pxor	%xmm7,%xmm7
203238405Sjkim	pxor	%xmm8,%xmm8
204238405Sjkim	pxor	%xmm9,%xmm9
205238405Sjkim	pxor	%xmm10,%xmm10
206238405Sjkim	pxor	%xmm11,%xmm11
207238405Sjkim	pxor	%xmm12,%xmm12
208238405Sjkim	pxor	%xmm13,%xmm13
209238405Sjkim	pxor	%xmm14,%xmm14
210238405Sjkim	pxor	%xmm15,%xmm15
211238405Sjkim	xorq	%rcx,%rcx
212238405Sjkim	xorq	%rdx,%rdx
213238405Sjkim	xorq	%rsi,%rsi
214238405Sjkim	xorq	%rdi,%rdi
215238405Sjkim	xorq	%r8,%r8
216238405Sjkim	xorq	%r9,%r9
217238405Sjkim	xorq	%r10,%r10
218238405Sjkim	xorq	%r11,%r11
219238405Sjkim	leaq	8(%rsp),%rax
220238405Sjkim	.byte	0xf3,0xc3
221238405Sjkim.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
222238405Sjkim.globl	OPENSSL_ia32_rdrand
223238405Sjkim.type	OPENSSL_ia32_rdrand,@function
224238405Sjkim.align	16
225238405SjkimOPENSSL_ia32_rdrand:
226238405Sjkim	movl	$8,%ecx
227238405Sjkim.Loop_rdrand:
228238405Sjkim.byte	72,15,199,240
229238405Sjkim	jc	.Lbreak_rdrand
230238405Sjkim	loop	.Loop_rdrand
231238405Sjkim.Lbreak_rdrand:
232238405Sjkim	cmpq	$0,%rax
233238405Sjkim	cmoveq	%rcx,%rax
234238405Sjkim	.byte	0xf3,0xc3
235238405Sjkim.size	OPENSSL_ia32_rdrand,.-OPENSSL_ia32_rdrand
236