$flavour=~/64/? map("q$_",(0..6)) : map("q$_",(0..3,8..10));
+#
+# This file generates .s file for 64-bit and 32-bit CPUs.
+# We don't implement .rodata on 32-bit CPUs yet.
+#
+$code.=".rodata\n" if ($flavour =~ /64/);
$code.=<<___;
-.rodata
.align 5
.Lrcon:
.long 0x01,0x01,0x01,0x01
.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d // rotate-n-splat
.long 0x1b,0x1b,0x1b,0x1b
-.previous
+___
+$code.=".previous\n" if ($flavour =~ /64/);
+
+$code.=<<___;
.globl ${prefix}_set_encrypt_key
.type ${prefix}_set_encrypt_key,%function
.align 5
tst $bits,#0x3f
b.ne .Lenc_key_abort
+___
+$code.=<<___ if ($flavour =~ /64/);
adrp $ptr,.Lrcon
add $ptr,$ptr,:lo12:.Lrcon
+___
+$code.=<<___ if ($flavour =~ /32/);
+ adr $ptr,.Lrcon
+___
+$code.=<<___;
cmp $bits,#192
veor $zero,$zero,$zero
my $adrp = sub {
my ($args,$comment) = split(m|\s*//|,shift);
- "\tadrp\t$args\@PAGE";
-} if ($flavour =~ /ios64/);
-
+ if ($flavour =~ /ios64/) {
+ "\tadrp\t$args\@PAGE";
+ } elsif ($flavour =~ /linux/) {
+ #
+ # there seem to be two forms of 'addrp' instruction
+ # to calculate offset:
+ # addrp x3,x3,:lo12:Lrcon
+ # and alternate form:
+ # addrp x3,x3,:#lo12:Lrcon
+ # the '#' is mandatory for some compilers
+ # so make sure our asm always uses '#' here.
+ #
+ $args =~ s/(\w+)#?:lo2:(\.?\w+)/$1#:lo2:$2/;
+ if ($flavour =~ /linux32/) {
+ "\tadr\t$args";
+ } else {
+ "\tadrp\t$args";
+ }
+ }
+} if (($flavour =~ /ios64/) || ($flavour =~ /linux/));
sub range {
my ($r,$sfx,$start,$end) = @_;
$line =~ s/\b(\w+)/$GLOBALS{$1} or $1/ge;
if ($flavour =~ /ios64/) {
- $line =~ s/#:lo12:(\w+)/$1\@PAGEOFF/;
+ $line =~ s/#?:lo12:(\w+)/$1\@PAGEOFF/;
+ } elsif($flavour =~ /linux/) {
+ #
+ # make '#' mandatory for :lo12: (similar to adrp above)
+ #
+ $line =~ s/#?:lo12:(\.?\w+)/\#:lo12:$1/;
}
return $line;