]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Restrict the Arm 'LDR REG, =VALUE' pseudo instruction on Neon, to appease clang
authorTom Cosgrove <tom.cosgrove@arm.com>
Mon, 6 Feb 2023 08:32:46 +0000 (08:32 +0000)
committerTodd Short <todd.short@me.com>
Wed, 8 Feb 2023 14:30:08 +0000 (09:30 -0500)
Unlike gcc, the clang assembler has issues with the maximum value of the literal
in the `ldr REG, #VALUE` pseudo-instruction (where the assembler places the
value into a literal pool and generates a PC-relative load from that pool) when
used with Neon registers.

Specifically, while dN refers to 64-bit Neon registers, and qN refers to 128-bit
Neon registers, clang assembly only supports a maximum of 32-bit loads to
either with this instruction.

Therefore restrict accordingly to avoid breakage when building with clang.

clang appears to support the correct maximums with the scalar registers xN etc.

This will prevent the kind of breakage we saw when #19914 was merged (which has
since been fixed by #20202) - assembly authors will need to manually apply the
literal load, as is done in #20202.

None of the Arm assembler code uses this pseudo-instruction anyway, as it
doesn't seem to avoid duplication of constants.

Change-Id: If52f6ce22c10feb1cc334d996ff71b1efed3218e

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Todd Short <todd.short@me.com>
(Merged from https://github.com/openssl/openssl/pull/20222)

crypto/perlasm/arm-xlate.pl

index df10ddc7fabb87cdbe157ee4ab5c3f39c5373d54..4d1e8874140cd589080ca73b444bb5bdc8be6ba1 100755 (executable)
@@ -198,6 +198,16 @@ while(my $line=<>) {
        }
     }
 
+    # ldr REG, #VALUE psuedo-instruction - avoid clang issue with Neon registers
+    #
+    if ($line =~ /^\s*ldr\s+([qd]\d\d?)\s*,\s*=(\w+)/i) {
+        # Immediate load via literal pool into qN or DN - clang max is 2^32-1
+        my ($reg, $value) = ($1, $2);
+        # If $value is hex, 0x + 8 hex chars = 10 chars total will be okay
+        # If $value is decimal, 2^32 - 1 = 4294967295 will be okay (also 10 chars)
+        die("$line: immediate load via literal pool into $reg: value too large for clang - redo manually") if length($value) > 10;
+    }
+
     print $line if ($line);
     print "\n";
 }