More overwritten stuff...
[openssl.git] / crypto / x86cpuid.pl
1 #!/usr/bin/env perl
2
3 push(@INC,"perlasm");
4 require "x86asm.pl";
5
6 &asm_init($ARGV[0],"x86cpuid");
7
8 &function_begin("OPENSSL_ia32_cpuid");
9         &xor    ("edx","edx");
10         &pushf  ();
11         &pop    ("eax");
12         &mov    ("ecx","eax");
13         &xor    ("eax",1<<21);
14         &push   ("eax");
15         &popf   ();
16         &pushf  ();
17         &pop    ("eax");
18         &xor    ("ecx","eax");
19         &bt     ("ecx",21);
20         &jnc    (&label("nocpuid"));
21         &mov    ("eax",1);
22         &cpuid  ();
23 &set_label("nocpuid");
24         &mov    ("eax","edx");
25         &mov    ("edx","ecx");
26 &function_end("OPENSSL_ia32_cpuid");
27
28 &external_label("OPENSSL_ia32cap_P");
29
30 &function_begin_B("OPENSSL_rdtsc","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
31         &xor    ("eax","eax");
32         &xor    ("edx","edx");
33         &picmeup("ecx","OPENSSL_ia32cap_P");
34         &bt     (&DWP(0,"ecx"),4);
35         &jnc    (&label("notsc"));
36         &rdtsc  ();
37 &set_label("notsc");
38         &ret    ();
39 &function_end_B("OPENSSL_rdtsc");
40
41 # This works in Ring 0 only [read DJGPP+MS-DOS+privileged DPMI host],
42 # but it's safe to call it on any [supported] 32-bit platform...
43 # Just check for [non-]zero return value...
44 &function_begin_B("OPENSSL_instrument_halt","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
45         &picmeup("ecx","OPENSSL_ia32cap_P");
46         &bt     (&DWP(0,"ecx"),4);
47         &jnc    (&label("nohalt"));     # no TSC
48
49         &data_word(0x9058900e);         # push %cs; pop %eax
50         &and    ("eax",3);
51         &jnz    (&label("nohalt"));     # not enough privileges
52
53         &pushf  ();
54         &pop    ("eax")
55         &bt     ("eax",9);
56         &jnc    (&label("nohalt"));     # interrupts are disabled
57
58         &rdtsc  ();
59         &push   ("edx");
60         &push   ("eax");
61         &halt   ();
62         &rdtsc  ();
63
64         &sub    ("eax",&DWP(0,"esp"));
65         &sbb    ("edx",&DWP(4,"esp"));
66         &add    ("esp",8);
67         &ret    ();
68
69 &set_label("nohalt");
70         &xor    ("eax","eax");
71         &xor    ("edx","edx");
72         &ret    ();
73 &function_end_B("OPENSSL_instrument_halt");
74
75 &initseg("OPENSSL_cpuid_setup");
76
77 &asm_finish();