1%ifidn __OUTPUT_FORMAT__,obj
2section	code	use32 class=code align=64
3%elifidn __OUTPUT_FORMAT__,win32
4%ifdef __YASM_VERSION_ID__
5%if __YASM_VERSION_ID__ < 01010000h
6%error yasm version 1.1.0 or later needed.
7%endif
8; Yasm automatically includes .00 and complains about redefining it.
9; https://www.tortall.net/projects/yasm/manual/html/objfmt-win32-safeseh.html
10%else
11$@feat.00 equ 1
12%endif
13section	.text	code align=64
14%else
15section	.text	code
16%endif
17global	_OPENSSL_ia32_cpuid
18align	16
19_OPENSSL_ia32_cpuid:
20L$_OPENSSL_ia32_cpuid_begin:
21	push	ebp
22	push	ebx
23	push	esi
24	push	edi
25	xor	edx,edx
26	pushfd
27	pop	eax
28	mov	ecx,eax
29	xor	eax,2097152
30	push	eax
31	popfd
32	pushfd
33	pop	eax
34	xor	ecx,eax
35	xor	eax,eax
36	bt	ecx,21
37	jnc	NEAR L$000nocpuid
38	mov	esi,DWORD [20+esp]
39	mov	DWORD [8+esi],eax
40	cpuid
41	mov	edi,eax
42	xor	eax,eax
43	cmp	ebx,1970169159
44	setne	al
45	mov	ebp,eax
46	cmp	edx,1231384169
47	setne	al
48	or	ebp,eax
49	cmp	ecx,1818588270
50	setne	al
51	or	ebp,eax
52	jz	NEAR L$001intel
53	cmp	ebx,1752462657
54	setne	al
55	mov	esi,eax
56	cmp	edx,1769238117
57	setne	al
58	or	esi,eax
59	cmp	ecx,1145913699
60	setne	al
61	or	esi,eax
62	jnz	NEAR L$001intel
63	mov	eax,2147483648
64	cpuid
65	cmp	eax,2147483649
66	jb	NEAR L$001intel
67	mov	esi,eax
68	mov	eax,2147483649
69	cpuid
70	or	ebp,ecx
71	and	ebp,2049
72	cmp	esi,2147483656
73	jb	NEAR L$001intel
74	mov	eax,2147483656
75	cpuid
76	movzx	esi,cl
77	inc	esi
78	mov	eax,1
79	xor	ecx,ecx
80	cpuid
81	bt	edx,28
82	jnc	NEAR L$002generic
83	shr	ebx,16
84	and	ebx,255
85	cmp	ebx,esi
86	ja	NEAR L$002generic
87	and	edx,4026531839
88	jmp	NEAR L$002generic
89L$001intel:
90	cmp	edi,7
91	jb	NEAR L$003cacheinfo
92	mov	esi,DWORD [20+esp]
93	mov	eax,7
94	xor	ecx,ecx
95	cpuid
96	mov	DWORD [8+esi],ebx
97L$003cacheinfo:
98	cmp	edi,4
99	mov	edi,-1
100	jb	NEAR L$004nocacheinfo
101	mov	eax,4
102	mov	ecx,0
103	cpuid
104	mov	edi,eax
105	shr	edi,14
106	and	edi,4095
107L$004nocacheinfo:
108	mov	eax,1
109	xor	ecx,ecx
110	cpuid
111	and	edx,3220176895
112	cmp	ebp,0
113	jne	NEAR L$005notintel
114	or	edx,1073741824
115L$005notintel:
116	bt	edx,28
117	jnc	NEAR L$002generic
118	and	edx,4026531839
119	cmp	edi,0
120	je	NEAR L$002generic
121	or	edx,268435456
122	shr	ebx,16
123	cmp	bl,1
124	ja	NEAR L$002generic
125	and	edx,4026531839
126L$002generic:
127	and	ebp,2048
128	and	ecx,4294965247
129	mov	esi,edx
130	or	ebp,ecx
131	bt	ecx,27
132	jnc	NEAR L$006clear_avx
133	xor	ecx,ecx
134db	15,1,208
135	and	eax,6
136	cmp	eax,6
137	je	NEAR L$007done
138	cmp	eax,2
139	je	NEAR L$006clear_avx
140L$008clear_xmm:
141	and	ebp,4261412861
142	and	esi,4278190079
143L$006clear_avx:
144	and	ebp,4026525695
145	mov	edi,DWORD [20+esp]
146	and	DWORD [8+edi],4294967263
147L$007done:
148	mov	eax,esi
149	mov	edx,ebp
150L$000nocpuid:
151	pop	edi
152	pop	esi
153	pop	ebx
154	pop	ebp
155	ret
156;extern	_OPENSSL_ia32cap_P
157global	_OPENSSL_rdtsc
158align	16
159_OPENSSL_rdtsc:
160L$_OPENSSL_rdtsc_begin:
161	xor	eax,eax
162	xor	edx,edx
163	lea	ecx,[_OPENSSL_ia32cap_P]
164	bt	DWORD [ecx],4
165	jnc	NEAR L$009notsc
166	rdtsc
167L$009notsc:
168	ret
169global	_OPENSSL_instrument_halt
170align	16
171_OPENSSL_instrument_halt:
172L$_OPENSSL_instrument_halt_begin:
173	lea	ecx,[_OPENSSL_ia32cap_P]
174	bt	DWORD [ecx],4
175	jnc	NEAR L$010nohalt
176dd	2421723150
177	and	eax,3
178	jnz	NEAR L$010nohalt
179	pushfd
180	pop	eax
181	bt	eax,9
182	jnc	NEAR L$010nohalt
183	rdtsc
184	push	edx
185	push	eax
186	hlt
187	rdtsc
188	sub	eax,DWORD [esp]
189	sbb	edx,DWORD [4+esp]
190	add	esp,8
191	ret
192L$010nohalt:
193	xor	eax,eax
194	xor	edx,edx
195	ret
196global	_OPENSSL_far_spin
197align	16
198_OPENSSL_far_spin:
199L$_OPENSSL_far_spin_begin:
200	pushfd
201	pop	eax
202	bt	eax,9
203	jnc	NEAR L$011nospin
204	mov	eax,DWORD [4+esp]
205	mov	ecx,DWORD [8+esp]
206dd	2430111262
207	xor	eax,eax
208	mov	edx,DWORD [ecx]
209	jmp	NEAR L$012spin
210align	16
211L$012spin:
212	inc	eax
213	cmp	edx,DWORD [ecx]
214	je	NEAR L$012spin
215dd	529567888
216	ret
217L$011nospin:
218	xor	eax,eax
219	xor	edx,edx
220	ret
221global	_OPENSSL_wipe_cpu
222align	16
223_OPENSSL_wipe_cpu:
224L$_OPENSSL_wipe_cpu_begin:
225	xor	eax,eax
226	xor	edx,edx
227	lea	ecx,[_OPENSSL_ia32cap_P]
228	mov	ecx,DWORD [ecx]
229	bt	DWORD [ecx],1
230	jnc	NEAR L$013no_x87
231	and	ecx,83886080
232	cmp	ecx,83886080
233	jne	NEAR L$014no_sse2
234	pxor	xmm0,xmm0
235	pxor	xmm1,xmm1
236	pxor	xmm2,xmm2
237	pxor	xmm3,xmm3
238	pxor	xmm4,xmm4
239	pxor	xmm5,xmm5
240	pxor	xmm6,xmm6
241	pxor	xmm7,xmm7
242L$014no_sse2:
243dd	4007259865,4007259865,4007259865,4007259865,2430851995
244L$013no_x87:
245	lea	eax,[4+esp]
246	ret
247global	_OPENSSL_atomic_add
248align	16
249_OPENSSL_atomic_add:
250L$_OPENSSL_atomic_add_begin:
251	mov	edx,DWORD [4+esp]
252	mov	ecx,DWORD [8+esp]
253	push	ebx
254	nop
255	mov	eax,DWORD [edx]
256L$015spin:
257	lea	ebx,[ecx*1+eax]
258	nop
259dd	447811568
260	jne	NEAR L$015spin
261	mov	eax,ebx
262	pop	ebx
263	ret
264global	_OPENSSL_indirect_call
265align	16
266_OPENSSL_indirect_call:
267L$_OPENSSL_indirect_call_begin:
268	push	ebp
269	mov	ebp,esp
270	sub	esp,28
271	mov	ecx,DWORD [12+ebp]
272	mov	DWORD [esp],ecx
273	mov	edx,DWORD [16+ebp]
274	mov	DWORD [4+esp],edx
275	mov	eax,DWORD [20+ebp]
276	mov	DWORD [8+esp],eax
277	mov	eax,DWORD [24+ebp]
278	mov	DWORD [12+esp],eax
279	mov	eax,DWORD [28+ebp]
280	mov	DWORD [16+esp],eax
281	mov	eax,DWORD [32+ebp]
282	mov	DWORD [20+esp],eax
283	mov	eax,DWORD [36+ebp]
284	mov	DWORD [24+esp],eax
285	call	DWORD [8+ebp]
286	mov	esp,ebp
287	pop	ebp
288	ret
289global	_OPENSSL_ia32_rdrand
290align	16
291_OPENSSL_ia32_rdrand:
292L$_OPENSSL_ia32_rdrand_begin:
293	mov	ecx,8
294L$016loop:
295db	15,199,240
296	jc	NEAR L$017break
297	loop	L$016loop
298L$017break:
299	cmp	eax,0
300	cmove	eax,ecx
301	ret
302segment	.bss
303common	_OPENSSL_ia32cap_P 16
304