summaryrefslogtreecommitdiffstats
path: root/crypto/perlasm
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2004-07-26 20:18:55 +0000
committerAndy Polyakov <appro@openssl.org>2004-07-26 20:18:55 +0000
commit14e21f863a3e3278bb8660ea9844e92e52e1f2f7 (patch)
tree5bcc6cfa9002eb94d2788bc3fa8c72eb5b9f188e /crypto/perlasm
parentf10725a6e19f0d72df5789e38601918539e64082 (diff)
Add framework for yet another assembler module dubbed "cpuid." Idea
is to have a placeholder to small routines, which can be written only in assembler. In IA-32 case this includes processor capability identification and access to Time-Stamp Counter. As discussed earlier OPENSSL_ia32cap is introduced to control recently added SSE2 code pathes (see docs/crypto/OPENSSL_ia32cap.pod). For the moment the code is operational on ELF platforms only. I haven't checked it yet, but I have all reasons to believe that Windows build should fail to link too. I'll be looking into it shortly...
Diffstat (limited to 'crypto/perlasm')
-rw-r--r--crypto/perlasm/x86ms.pl4
-rw-r--r--crypto/perlasm/x86nasm.pl4
-rw-r--r--crypto/perlasm/x86unix.pl26
3 files changed, 31 insertions, 3 deletions
diff --git a/crypto/perlasm/x86ms.pl b/crypto/perlasm/x86ms.pl
index dd62348b6a..f6e225c644 100644
--- a/crypto/perlasm/x86ms.pl
+++ b/crypto/perlasm/x86ms.pl
@@ -160,6 +160,8 @@ sub main'jne { &out1("jne",@_); }
sub main'jno { &out1("jno",@_); }
sub main'push { &out1("push",@_); $stack+=4; }
sub main'pop { &out1("pop",@_); $stack-=4; }
+sub main'pushf { &out0("pushf"); $stack+=4; }
+sub main'popf { &out0("popf"); $stack-=4; }
sub main'bswap { &out1("bswap",@_); &using486(); }
sub main'not { &out1("not",@_); }
sub main'call { &out1("call",($_[0]=~/^\$L/?'':'_').$_[0]); }
@@ -168,6 +170,8 @@ sub main'nop { &out0("nop"); }
sub main'test { &out2("test",@_); }
sub main'bt { &out2("bt",@_); }
sub main'leave { &out0("leave"); }
+sub main'cpuid { &out0("cpuid"); }
+sub main'rdtsc { &out0("rdtsc"); }
# SSE2
sub main'emms { &out0("emms"); }
diff --git a/crypto/perlasm/x86nasm.pl b/crypto/perlasm/x86nasm.pl
index da2a1d471b..4cb09ddea6 100644
--- a/crypto/perlasm/x86nasm.pl
+++ b/crypto/perlasm/x86nasm.pl
@@ -169,6 +169,8 @@ sub main'jno { &out1("jno NEAR",@_); }
sub main'push { &out1("push",@_); $stack+=4; }
sub main'pop { &out1("pop",@_); $stack-=4; }
+sub main'pushf { &out0("pushf"); $stack+=4; }
+sub main'popf { &out0("popf"); $stack-=4; }
sub main'bswap { &out1("bswap",@_); &using486(); }
sub main'not { &out1("not",@_); }
sub main'call { &out1("call",($_[0]=~/^\$L/?'':'_').$_[0]); }
@@ -177,6 +179,8 @@ sub main'nop { &out0("nop"); }
sub main'test { &out2("test",@_); }
sub main'bt { &out2("bt",@_); }
sub main'leave { &out0("leave"); }
+sub main'cpuid { &out0("cpuid"); }
+sub main'rdtsc { &out0("rdtsc"); }
# SSE2
sub main'emms { &out0("emms"); }
diff --git a/crypto/perlasm/x86unix.pl b/crypto/perlasm/x86unix.pl
index 99e2865aa0..12ff816ebf 100644
--- a/crypto/perlasm/x86unix.pl
+++ b/crypto/perlasm/x86unix.pl
@@ -199,6 +199,8 @@ sub main'nop { &out0("nop"); }
sub main'test { &out2("testl",@_); }
sub main'bt { &out2("btl",@_); }
sub main'leave { &out0("leave"); }
+sub main'cpuid { &out0(".word\t0xa20f"); }
+sub main'rdtsc { &out0(".word\t0x310f"); }
# SSE2
sub main'emms { &out0("emms"); }
@@ -519,11 +521,14 @@ sub main'file_end
# SSE/MMX module with this snippet... Well, it's 72
# bytes long and for the moment we have two modules.
# Let's argue when we have 7 modules or so...
+ #
+ # $1<<10 sets a reserved bit to signal that variable
+ # was initialized already...
&main'picmeup("edx","OPENSSL_ia32cap");
$tmp=<<___;
cmpl \$0,(%edx)
jne 1f
- movl \$1,(%edx)
+ movl \$1<<10,(%edx)
pushf
popl %eax
movl %eax,%ecx
@@ -539,12 +544,13 @@ sub main'file_end
pushl %ebx
movl %edx,%edi
movl \$1,%eax
- cpuid
- orl \$1,%edx
+ .word 0xa20f
+ orl \$1<<10,%edx
movl %edx,0(%edi)
movl %ecx,4(%edi)
popl %ebx
popl %edi
+ .align 4
1:
___
push (@out,$tmp);
@@ -675,3 +681,17 @@ ___
}
sub main'blindpop { &out1("popl",@_); }
+
+sub main'initseg
+ {
+ local($f)=@_;
+ if ($main'elf)
+ {
+ local($tmp)=<<___;
+.pushsection .init
+ call $under$f
+.popsection
+___
+ push(@out,$tmp);
+ }
+ }