Replace emms with finit in x86cpuid.
[openssl.git] / crypto / x86cpuid.pl
index 894c49c0a3e359d53bd38df178235d2a6290c829..4a58651f0f9d4326971d7ffaf468786b2647c36a 100644 (file)
@@ -5,6 +5,8 @@ require "x86asm.pl";
 
 &asm_init($ARGV[0],"x86cpuid");
 
+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
+
 &function_begin("OPENSSL_ia32_cpuid");
        &xor    ("edx","edx");
        &pushf  ();
@@ -72,6 +74,85 @@ require "x86asm.pl";
        &ret    ();
 &function_end_B("OPENSSL_instrument_halt");
 
+# Essentially there is only one use for this function. Under DJGPP:
+#
+#      #include <go32.h>
+#      ...
+#      i=OPENSSL_far_spin(_dos_ds,0x46c);
+#      ...
+# to obtain the number of spins till closest timer interrupt.
+
+&function_begin_B("OPENSSL_far_spin");
+       &pushf  ();
+       &pop    ("eax")
+       &bt     ("eax",9);
+       &jnc    (&label("nospin"));     # interrupts are disabled
+
+       &mov    ("eax",&DWP(4,"esp"));
+       &mov    ("ecx",&DWP(8,"esp"));
+       &data_word (0x90d88e1e);        # push %ds, mov %eax,%ds
+       &xor    ("eax","eax");
+       &mov    ("edx",&DWP(0,"ecx"));
+       &jmp    (&label("spin"));
+
+       &align  (16);
+&set_label("spin");
+       &inc    ("eax");
+       &cmp    ("edx",&DWP(0,"ecx"));
+       &je     (&label("spin"));
+
+       &data_word (0x1f909090);        # pop   %ds
+       &ret    ();
+
+&set_label("nospin");
+       &xor    ("eax","eax");
+       &xor    ("edx","edx");
+       &ret    ();
+&function_end_B("OPENSSL_far_spin");
+
+&function_begin_B("OPENSSL_wipe_cpu","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
+       &xor    ("eax","eax");
+       &xor    ("edx","edx");
+       &picmeup("ecx","OPENSSL_ia32cap_P");
+       &mov    ("ecx",&DWP(0,"ecx"));
+       &bt     (&DWP(0,"ecx"),1);
+       &jnc    (&label("no_x87"));
+       if ($sse2) {
+               &bt     (&DWP(0,"ecx"),26);
+               &jnc    (&label("no_sse2"));
+               &pxor   ("xmm0","xmm0");
+               &pxor   ("xmm1","xmm1");
+               &pxor   ("xmm2","xmm2");
+               &pxor   ("xmm3","xmm3");
+               &pxor   ("xmm4","xmm4");
+               &pxor   ("xmm5","xmm5");
+               &pxor   ("xmm6","xmm6");
+               &pxor   ("xmm7","xmm7");
+       &set_label("no_sse2");
+       }
+       # just a bunch of fldz to zap the fp/mm bank followed by finit...
+       &data_word(0xeed9eed9,0xeed9eed9,0xeed9eed9,0xeed9eed9,0x90e3db9b);
+&set_label("no_x87");
+       &lea    ("eax",&DWP(4,"esp"));
+       &ret    ();
+&function_end_B("OPENSSL_wipe_cpu");
+
+&function_begin_B("OPENSSL_atomic_add");
+       &mov    ("edx",&DWP(4,"esp"));  # fetch the pointer, 1st arg
+       &mov    ("ecx",&DWP(8,"esp"));  # fetch the increment, 2nd arg
+       &push   ("ebx");
+       &nop    ();
+       &mov    ("eax",&DWP(0,"edx"));
+&set_label("spin");
+       &lea    ("ebx",&DWP(0,"eax","ecx"));
+       &nop    ();
+       &data_word(0x1ab10ff0); # lock; cmpxchg %ebx,(%edx)     # %eax is envolved and is always reloaded
+       &jne    (&label("spin"));
+       &mov    ("eax","ebx");  # OpenSSL expects the new value
+       &pop    ("ebx");
+       &ret    ();
+&function_end_B("OPENSSL_atomic_add");
+
 &initseg("OPENSSL_cpuid_setup");
 
 &asm_finish();