Comply with optimization manual (no data should share cache-line with code).
[openssl.git] / crypto / x86cpuid.pl
index 894c49c0a3e359d53bd38df178235d2a6290c829..9ad9435ffdc031b3330a71781491d58f3ad09f59 100644 (file)
@@ -72,6 +72,84 @@ 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"));
+       &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...
+       &data_word(0xeed9eed9,0xeed9eed9,0xeed9eed9,0xeed9eed9);
+       &emms   ();
+&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();