1#!/usr/bin/env perl
2
3$output=shift;
4$masm=1 if ($output =~ /\.asm/);
5open STDOUT,">$output" || die "can't open $output: $!";
6
7print<<___ if(defined($masm));
8_TEXT	SEGMENT
9PUBLIC	OPENSSL_rdtsc
10
11PUBLIC	OPENSSL_atomic_add
12ALIGN	16
13OPENSSL_atomic_add	PROC
14	mov	eax,DWORD PTR[rcx]
15\$Lspin:	lea	r8,DWORD PTR[rdx+rax]
16lock	cmpxchg	DWORD PTR[rcx],r8d
17	jne	\$Lspin
18	mov	eax,r8d
19	cdqe
20	ret
21OPENSSL_atomic_add	ENDP
22
23PUBLIC	OPENSSL_wipe_cpu
24ALIGN	16
25OPENSSL_wipe_cpu	PROC
26	pxor	xmm0,xmm0
27	pxor	xmm1,xmm1
28	pxor	xmm2,xmm2
29	pxor	xmm3,xmm3
30	pxor	xmm4,xmm4
31	pxor	xmm5,xmm5
32	xor	rcx,rcx
33	xor	rdx,rdx
34	xor	r8,r8
35	xor	r9,r9
36	xor	r10,r10
37	xor	r11,r11
38	lea	rax,QWORD PTR[rsp+8]
39	ret
40OPENSSL_wipe_cpu	ENDP
41_TEXT	ENDS
42
43CRT\$XIU	SEGMENT
44EXTRN	OPENSSL_cpuid_setup:PROC
45DQ	OPENSSL_cpuid_setup
46CRT\$XIU	ENDS
47
48___
49print<<___ if(!defined($masm));
50.text
51
52.globl	OPENSSL_atomic_add
53.type	OPENSSL_atomic_add,\@function
54.align	16
55OPENSSL_atomic_add:
56	movl	(%rdi),%eax
57.Lspin:	leaq	(%rsi,%rax),%r8
58lock;	cmpxchgl	%r8d,(%rdi)
59	jne	.Lspin
60	movl	%r8d,%eax
61	.byte	0x48,0x98
62	ret
63.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
64
65.globl	OPENSSL_wipe_cpu
66.type	OPENSSL_wipe_cpu,\@function
67.align	16
68OPENSSL_wipe_cpu:
69	pxor	%xmm0,%xmm0
70	pxor	%xmm1,%xmm1
71	pxor	%xmm2,%xmm2
72	pxor	%xmm3,%xmm3
73	pxor	%xmm4,%xmm4
74	pxor	%xmm5,%xmm5
75	pxor	%xmm6,%xmm6
76	pxor	%xmm7,%xmm7
77	pxor	%xmm8,%xmm8
78	pxor	%xmm9,%xmm9
79	pxor	%xmm10,%xmm10
80	pxor	%xmm11,%xmm11
81	pxor	%xmm12,%xmm12
82	pxor	%xmm13,%xmm13
83	pxor	%xmm14,%xmm14
84	pxor	%xmm15,%xmm15
85	xorq	%rcx,%rcx
86	xorq	%rdx,%rdx
87	xorq	%rsi,%rsi
88	xorq	%rdi,%rdi
89	xorq	%r8,%r8
90	xorq	%r9,%r9
91	xorq	%r10,%r10
92	xorq	%r11,%r11
93	leaq	8(%rsp),%rax
94	ret
95.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
96
97.section	.init
98	call	OPENSSL_cpuid_setup
99
100___
101
102open STDOUT,"| $^X perlasm/x86_64-xlate.pl $output";
103print<<___;
104.text
105
106.globl	OPENSSL_rdtsc
107.type	OPENSSL_rdtsc,\@abi-omnipotent
108.align	16
109OPENSSL_rdtsc:
110	rdtsc
111	shl	\$32,%rdx
112	or	%rdx,%rax
113	ret
114.size	OPENSSL_rdtsc,.-OPENSSL_rdtsc
115
116.globl	OPENSSL_ia32_cpuid
117.type	OPENSSL_ia32_cpuid,\@abi-omnipotent
118.align	16
119OPENSSL_ia32_cpuid:
120	mov	%rbx,%r8
121
122	xor	%eax,%eax
123	cpuid
124	xor	%eax,%eax
125	cmp	\$0x756e6547,%ebx	# "Genu"
126	setne	%al
127	mov	%eax,%r9d
128	cmp	\$0x49656e69,%edx	# "ineI"
129	setne	%al
130	or	%eax,%r9d
131	cmp	\$0x6c65746e,%ecx	# "ntel"
132	setne	%al
133	or	%eax,%r9d
134
135	mov	\$1,%eax
136	cpuid
137	cmp	\$0,%r9d
138	jne	.Lnotintel
139	or	\$0x00100000,%edx	# use reserved 20th bit to engage RC4_CHAR
140	and	\$15,%ah
141	cmp	\$15,%ah		# examine Family ID
142	je	.Lnotintel
143	or	\$0x40000000,%edx	# use reserved bit to skip unrolled loop
144.Lnotintel:
145	bt	\$28,%edx		# test hyper-threading bit
146	jnc	.Ldone
147	shr	\$16,%ebx
148	cmp	\$1,%bl			# see if cache is shared
149	ja	.Ldone
150	and	\$0xefffffff,%edx	# ~(1<<28)
151.Ldone:
152	shl	\$32,%rcx
153	mov	%edx,%eax
154	mov	%r8,%rbx
155	or	%rcx,%rax
156	ret
157.size	OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
158___
159close STDOUT;	# flush
160