aboutsummaryrefslogtreecommitdiff
path: root/crypto/x86cpuid.pl
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2004-09-09 14:50:32 +0000
committerAndy Polyakov <appro@openssl.org>2004-09-09 14:50:32 +0000
commitc85c5c408af0996daa5f807c488f921e7e7ad524 (patch)
tree478cc1dad44e44de8f7c9aaf7868202d97b273c6 /crypto/x86cpuid.pl
parent2c1677d7038a4ddaea933f1a62ace0c2255e254e (diff)
downloadopenssl-c85c5c408af0996daa5f807c488f921e7e7ad524.zip
openssl-c85c5c408af0996daa5f807c488f921e7e7ad524.tar.gz
openssl-c85c5c408af0996daa5f807c488f921e7e7ad524.tar.bz2
x86 assembler updates: more instructions, new OPENSSL_instrument_halt
[for DJGPP]...
Diffstat (limited to 'crypto/x86cpuid.pl')
-rw-r--r--crypto/x86cpuid.pl34
1 files changed, 34 insertions, 0 deletions
diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl
index da3e5bc..894c49c 100644
--- a/crypto/x86cpuid.pl
+++ b/crypto/x86cpuid.pl
@@ -38,6 +38,40 @@ require "x86asm.pl";
&ret ();
&function_end_B("OPENSSL_rdtsc");
+# This works in Ring 0 only [read DJGPP+MS-DOS+privileged DPMI host],
+# but it's safe to call it on any [supported] 32-bit platform...
+# Just check for [non-]zero return value...
+&function_begin_B("OPENSSL_instrument_halt","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
+ &picmeup("ecx","OPENSSL_ia32cap_P");
+ &bt (&DWP(0,"ecx"),4);
+ &jnc (&label("nohalt")); # no TSC
+
+ &data_word(0x9058900e); # push %cs; pop %eax
+ &and ("eax",3);
+ &jnz (&label("nohalt")); # not enough privileges
+
+ &pushf ();
+ &pop ("eax")
+ &bt ("eax",9);
+ &jnc (&label("nohalt")); # interrupts are disabled
+
+ &rdtsc ();
+ &push ("edx");
+ &push ("eax");
+ &halt ();
+ &rdtsc ();
+
+ &sub ("eax",&DWP(0,"esp"));
+ &sbb ("edx",&DWP(4,"esp"));
+ &add ("esp",8);
+ &ret ();
+
+&set_label("nohalt");
+ &xor ("eax","eax");
+ &xor ("edx","edx");
+ &ret ();
+&function_end_B("OPENSSL_instrument_halt");
+
&initseg("OPENSSL_cpuid_setup");
&asm_finish();