chacha/asm/chacha-x86.pl: improve [backward] portability.
authorAndy Polyakov <appro@openssl.org>
Tue, 8 Nov 2016 10:11:58 +0000 (11:11 +0100)
committerAndy Polyakov <appro@openssl.org>
Fri, 11 Nov 2016 12:27:53 +0000 (13:27 +0100)
In order to minimize dependency on assembler version a number of
post-SSE2 instructions are encoded manually. But in order to simplify
the procedure only register operands are considered. Non-register
operands are passed down to assembler. Module in question uses pshufb
with memory operands, and old [GNU] assembler can't handle it.
Fortunately in this case it's possible skip just the problematic
segment without skipping SSSE3 support altogether.

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
crypto/chacha/asm/chacha-x86.pl

index f00b7d2..61b3286 100755 (executable)
@@ -50,7 +50,7 @@ for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
 $ymm=1 if ($xmm &&
                `$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
                        =~ /GNU assembler version ([2-9]\.[0-9]+)/ &&
-               $1>=2.19);      # first version supporting AVX
+               ($gasver=$1)>=2.19);    # first version supporting AVX
 
 $ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32n" &&
                `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
@@ -465,6 +465,12 @@ if ($ymm) {
                                    &label("pic_point"),"eax"));
        &movdqu         ("xmm3",&QWP(0,"ebx"));         # counter and nonce
 
+if (defined($gasver) && $gasver>=2.17) {               # even though we encode
+                                                       # pshufb manually, we
+                                                       # handle only register
+                                                       # operands, while this
+                                                       # segment uses memory
+                                                       # operand...
        &cmp            ($len,64*4);
        &jb             (&label("1x"));
 
@@ -646,6 +652,7 @@ if ($ymm) {
        &paddd          ("xmm2",&QWP(16*6,"eax"));      # +four
        &pand           ("xmm3",&QWP(16*7,"eax"));
        &por            ("xmm3","xmm2");                # counter value
+}
 {
 my ($a,$b,$c,$d,$t,$t1,$rot16,$rot24)=map("xmm$_",(0..7));