give EC_GROUP_new_by_nid a more meanigful name:
[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 # Essentially there is only one use for this function. Under DJGPP:
76 #
77 #       #include <go32.h>
78 #       ...
79 #       i=OPENSSL_far_spin(_dos_ds,0x46c);
80 #       ...
81 # to obtain the number of spins till closest timer interrupt.
82
83 &function_begin_B("OPENSSL_far_spin");
84         &pushf  ();
85         &pop    ("eax")
86         &bt     ("eax",9);
87         &jnc    (&label("nospin"));     # interrupts are disabled
88
89         &mov    ("eax",&DWP(4,"esp"));
90         &mov    ("ecx",&DWP(8,"esp"));
91         &data_word (0x90d88e1e);        # push %ds, mov %eax,%ds
92         &xor    ("eax","eax");
93         &mov    ("edx",&DWP(0,"ecx"));
94         &jmp    (&label("spin"));
95
96         &align  (16);
97 &set_label("spin");
98         &inc    ("eax");
99         &cmp    ("edx",&DWP(0,"ecx"));
100         &je     (&label("spin"));
101
102         &data_word (0x1f909090);        # pop   %ds
103         &ret    ();
104
105 &set_label("nospin");
106         &xor    ("eax","eax");
107         &xor    ("edx","edx");
108         &ret    ();
109 &function_end_B("OPENSSL_far_spin");
110
111 &function_begin_B("OPENSSL_wipe_cpu","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
112         &xor    ("eax","eax");
113         &xor    ("edx","edx");
114         &picmeup("ecx","OPENSSL_ia32cap_P");
115         &mov    ("ecx",&DWP(0,"ecx"));
116         &bt     (&DWP(0,"ecx"),1);
117         &jnc    (&label("no_x87"));
118         &bt     (&DWP(0,"ecx"),26);
119         &jnc    (&label("no_sse2"));
120         &pxor   ("xmm0","xmm0");
121         &pxor   ("xmm1","xmm1");
122         &pxor   ("xmm2","xmm2");
123         &pxor   ("xmm3","xmm3");
124         &pxor   ("xmm4","xmm4");
125         &pxor   ("xmm5","xmm5");
126         &pxor   ("xmm6","xmm6");
127         &pxor   ("xmm7","xmm7");
128 &set_label("no_sse2");
129         # just a bunch of fldz to zap the fp/mm bank...
130         &data_word(0xeed9eed9,0xeed9eed9,0xeed9eed9,0xeed9eed9);
131         &emms   ();
132 &set_label("no_x87");
133         &lea    ("eax",&DWP(4,"esp"));
134         &ret    ();
135 &function_end_B("OPENSSL_wipe_cpu");
136
137 &function_begin_B("OPENSSL_atomic_add");
138         &mov    ("edx",&DWP(4,"esp"));  # fetch the pointer, 1st arg
139         &mov    ("ecx",&DWP(8,"esp"));  # fetch the increment, 2nd arg
140         &push   ("ebx");
141         &nop    ();
142         &mov    ("eax",&DWP(0,"edx"));
143 &set_label("spin");
144         &lea    ("ebx",&DWP(0,"eax","ecx"));
145         &nop    ();
146         &data_word(0x1ab10ff0); # lock; cmpxchg %ebx,(%edx)     # %eax is envolved and is always reloaded
147         &jne    (&label("spin"));
148         &mov    ("eax","ebx");  # OpenSSL expects the new value
149         &pop    ("ebx");
150         &ret    ();
151 &function_end_B("OPENSSL_atomic_add");
152
153 &initseg("OPENSSL_cpuid_setup");
154
155 &asm_finish();