Loading crypto/perlasm/x86nasm.pl +41 −13 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ package x86nasm; $lprfx="\@L"; $label="000"; $under=($::netware)?'':'_'; $initseg=""; sub ::generic { my $opcode=shift; Loading Loading @@ -117,15 +118,10 @@ sub ::function_end_B sub ::file_end { # try to detect if SSE2 or MMX extensions were used on Win32... if ($::win32 && grep {/\s+[x]*mm[0-7]/i} @out) { # One can argue that it's wasteful to craft every # 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 if ($::win32 && grep {/\b[x]?mm[0-7]\b|OPENSSL_ia32cap_P\b/i} @out) { # $1<<10 sets a reserved bit to signal that variable # was initialized already... my $tmp=<<___; my $code=<<___; align 16 ${lprfx}OPENSSL_ia32cap_init: lea edx,[${under}OPENSSL_ia32cap_P] Loading @@ -143,27 +139,60 @@ ${lprfx}OPENSSL_ia32cap_init: xor eax,ecx bt eax,21 jnc NEAR ${lprfx}nocpuid push ebp push edi push ebx mov edi,edx xor eax,eax cpuid xor eax,eax cmp ebx,'Genu' setne al mov ebp,eax cmp edx,'ineI' setne al or ebp,eax cmp eax,'ntel' setne al or ebp,eax mov eax,1 cpuid cmp ebp,0 jne ${lprfx}notP4 and ah,15 cmp ah,15 jne ${lprfx}notP4 or edx,1<<20 ${lprfx}notP4: bt edx,28 jnc ${lprfx}done shr ebx,16 cmp bl,1 ja ${lprfx}done and edx,0xefffffff ${lprfx}done: or edx,1<<10 mov DWORD [edi],edx pop ebx pop edi pop ebp ${lprfx}nocpuid: ret segment .CRT\$XCU data align=4 dd ${lprfx}OPENSSL_ia32cap_init ___ my $data=<<___; segment .bss common ${under}OPENSSL_ia32cap_P 4 ___ #<not needed in OpenSSL context>#push (@out,$code); # comment out OPENSSL_ia32cap_P declarations grep {s/(^extern\s+${under}OPENSSL_ia32cap_P)/\;$1/} @out; push (@out,$tmp); push (@out,$data) } push (@out,$initseg) if ($initseg); } sub ::comment { foreach (@_) { push(@out,"\t; $_\n"); } } Loading Loading @@ -216,12 +245,11 @@ sub ::picmeup sub ::initseg { my($f)=$under.shift; if ($::win32) { my($tmp)=<<___; segment .CRT\$XCU rdata align=4 { $initseg=<<___; segment .CRT\$XCU data align=4 extern $f dd $f ___ push(@out,$tmp); } } Loading crypto/perlasm/x86unix.pl +38 −24 Original line number Diff line number Diff line Loading @@ -5,8 +5,6 @@ package x86unix; # GAS actually... *out=\@::out; $label="L000"; $const=""; $constl=0; $align=($::aout)?"4":"16"; $under=($::aout or $::coff)?"_":""; Loading Loading @@ -189,24 +187,20 @@ sub ::set_label sub ::file_end { # try to detect if SSE2 or MMX extensions were used on ELF platform... if ($::elf && grep {/%[x]?mm[0-7]/i} @out){ my $tmp; if ($::elf && grep {/\b%[x]?mm[0-7]\b|OPENSSL_ia32cap_P\b/i} @out) { push (@out,"\n.section\t.bss\n"); push (@out,".comm\t${under}OPENSSL_ia32cap_P,4,4\n"); return; # below is not needed in OpenSSL context push (@out,".section\t.init\n"); # One can argue that it's wasteful to craft every # 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... # &::picmeup("edx","OPENSSL_ia32cap_P"); # $1<<10 sets a reserved bit to signal that variable # was initialized already... &::picmeup("edx","OPENSSL_ia32cap_P"); $tmp=<<___; my $code=<<___; cmpl \$0,(%edx) jne 1f jne 3f movl \$1<<10,(%edx) pushf popl %eax Loading @@ -218,27 +212,47 @@ sub ::file_end popl %eax xorl %ecx,%eax btl \$21,%eax jnc 1f jnc 3f pushl %ebp pushl %edi pushl %ebx movl %edx,%edi movl \$1,%eax xor %eax,%eax .byte 0x0f,0xa2 orl \$1<<10,%edx xorl %eax,%eax cmpl $1970169159,%ebx setne %al movl %eax,%ebp cmpl $1231384169,%edx setne %al orl %eax,%ebp cmpl $1818588270,%ecx setne %al orl %eax,%ebp movl $1,%eax .byte 0x0f,0xa2 cmpl $0,%ebp jne 1f andb $15,%ah cmpb $15,%ah jne 1f orl $1048576,%edx 1: btl $28,%edx jnc 2f shrl $16,%ebx cmpb $1,%bl ja 2f andl $4026531839,%edx 2: orl \$1<<10,%edx movl %edx,0(%edi) popl %ebx popl %edi jmp 1f popl %ebp jmp 3f .align $align 1: 3: ___ push (@out,$tmp); } if ($const ne "") { push(@out,".section .rodata\n"); push(@out,$const); $const=""; push (@out,$code); } } Loading Loading
crypto/perlasm/x86nasm.pl +41 −13 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ package x86nasm; $lprfx="\@L"; $label="000"; $under=($::netware)?'':'_'; $initseg=""; sub ::generic { my $opcode=shift; Loading Loading @@ -117,15 +118,10 @@ sub ::function_end_B sub ::file_end { # try to detect if SSE2 or MMX extensions were used on Win32... if ($::win32 && grep {/\s+[x]*mm[0-7]/i} @out) { # One can argue that it's wasteful to craft every # 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 if ($::win32 && grep {/\b[x]?mm[0-7]\b|OPENSSL_ia32cap_P\b/i} @out) { # $1<<10 sets a reserved bit to signal that variable # was initialized already... my $tmp=<<___; my $code=<<___; align 16 ${lprfx}OPENSSL_ia32cap_init: lea edx,[${under}OPENSSL_ia32cap_P] Loading @@ -143,27 +139,60 @@ ${lprfx}OPENSSL_ia32cap_init: xor eax,ecx bt eax,21 jnc NEAR ${lprfx}nocpuid push ebp push edi push ebx mov edi,edx xor eax,eax cpuid xor eax,eax cmp ebx,'Genu' setne al mov ebp,eax cmp edx,'ineI' setne al or ebp,eax cmp eax,'ntel' setne al or ebp,eax mov eax,1 cpuid cmp ebp,0 jne ${lprfx}notP4 and ah,15 cmp ah,15 jne ${lprfx}notP4 or edx,1<<20 ${lprfx}notP4: bt edx,28 jnc ${lprfx}done shr ebx,16 cmp bl,1 ja ${lprfx}done and edx,0xefffffff ${lprfx}done: or edx,1<<10 mov DWORD [edi],edx pop ebx pop edi pop ebp ${lprfx}nocpuid: ret segment .CRT\$XCU data align=4 dd ${lprfx}OPENSSL_ia32cap_init ___ my $data=<<___; segment .bss common ${under}OPENSSL_ia32cap_P 4 ___ #<not needed in OpenSSL context>#push (@out,$code); # comment out OPENSSL_ia32cap_P declarations grep {s/(^extern\s+${under}OPENSSL_ia32cap_P)/\;$1/} @out; push (@out,$tmp); push (@out,$data) } push (@out,$initseg) if ($initseg); } sub ::comment { foreach (@_) { push(@out,"\t; $_\n"); } } Loading Loading @@ -216,12 +245,11 @@ sub ::picmeup sub ::initseg { my($f)=$under.shift; if ($::win32) { my($tmp)=<<___; segment .CRT\$XCU rdata align=4 { $initseg=<<___; segment .CRT\$XCU data align=4 extern $f dd $f ___ push(@out,$tmp); } } Loading
crypto/perlasm/x86unix.pl +38 −24 Original line number Diff line number Diff line Loading @@ -5,8 +5,6 @@ package x86unix; # GAS actually... *out=\@::out; $label="L000"; $const=""; $constl=0; $align=($::aout)?"4":"16"; $under=($::aout or $::coff)?"_":""; Loading Loading @@ -189,24 +187,20 @@ sub ::set_label sub ::file_end { # try to detect if SSE2 or MMX extensions were used on ELF platform... if ($::elf && grep {/%[x]?mm[0-7]/i} @out){ my $tmp; if ($::elf && grep {/\b%[x]?mm[0-7]\b|OPENSSL_ia32cap_P\b/i} @out) { push (@out,"\n.section\t.bss\n"); push (@out,".comm\t${under}OPENSSL_ia32cap_P,4,4\n"); return; # below is not needed in OpenSSL context push (@out,".section\t.init\n"); # One can argue that it's wasteful to craft every # 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... # &::picmeup("edx","OPENSSL_ia32cap_P"); # $1<<10 sets a reserved bit to signal that variable # was initialized already... &::picmeup("edx","OPENSSL_ia32cap_P"); $tmp=<<___; my $code=<<___; cmpl \$0,(%edx) jne 1f jne 3f movl \$1<<10,(%edx) pushf popl %eax Loading @@ -218,27 +212,47 @@ sub ::file_end popl %eax xorl %ecx,%eax btl \$21,%eax jnc 1f jnc 3f pushl %ebp pushl %edi pushl %ebx movl %edx,%edi movl \$1,%eax xor %eax,%eax .byte 0x0f,0xa2 orl \$1<<10,%edx xorl %eax,%eax cmpl $1970169159,%ebx setne %al movl %eax,%ebp cmpl $1231384169,%edx setne %al orl %eax,%ebp cmpl $1818588270,%ecx setne %al orl %eax,%ebp movl $1,%eax .byte 0x0f,0xa2 cmpl $0,%ebp jne 1f andb $15,%ah cmpb $15,%ah jne 1f orl $1048576,%edx 1: btl $28,%edx jnc 2f shrl $16,%ebx cmpb $1,%bl ja 2f andl $4026531839,%edx 2: orl \$1<<10,%edx movl %edx,0(%edi) popl %ebx popl %edi jmp 1f popl %ebp jmp 3f .align $align 1: 3: ___ push (@out,$tmp); } if ($const ne "") { push(@out,".section .rodata\n"); push(@out,$const); $const=""; push (@out,$code); } } Loading