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