diff options
author | Andy Polyakov <appro@openssl.org> | 2004-09-09 14:50:32 +0000 |
---|---|---|
committer | Andy Polyakov <appro@openssl.org> | 2004-09-09 14:50:32 +0000 |
commit | c85c5c408af0996daa5f807c488f921e7e7ad524 (patch) | |
tree | 478cc1dad44e44de8f7c9aaf7868202d97b273c6 /crypto/x86cpuid.pl | |
parent | 2c1677d7038a4ddaea933f1a62ace0c2255e254e (diff) | |
download | openssl-c85c5c408af0996daa5f807c488f921e7e7ad524.tar.gz |
x86 assembler updates: more instructions, new OPENSSL_instrument_halt
[for DJGPP]...
Diffstat (limited to 'crypto/x86cpuid.pl')
-rw-r--r-- | crypto/x86cpuid.pl | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl index da3e5bcaca..894c49c0a3 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(); |