~ubuntu-branches/ubuntu/wily/openssl/wily

« back to all changes in this revision

Viewing changes to .pc/power8-optimisations.patch/crypto/perlasm/ppc-xlate.pl

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2014-09-26 11:32:32 UTC
  • Revision ID: package-import@ubuntu.com-20140926113232-ds6gavd9wl43wft5
Tags: 1.0.1f-1ubuntu8
Backport collected POWER8 optimisations from upstream (LP: #1290579).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env perl
 
2
 
 
3
# PowerPC assembler distiller by <appro>.
 
4
 
 
5
my $flavour = shift;
 
6
my $output = shift;
 
7
open STDOUT,">$output" || die "can't open $output: $!";
 
8
 
 
9
my %GLOBALS;
 
10
my $dotinlocallabels=($flavour=~/linux/)?1:0;
 
11
 
 
12
################################################################
 
13
# directives which need special treatment on different platforms
 
14
################################################################
 
15
my $globl = sub {
 
16
    my $junk = shift;
 
17
    my $name = shift;
 
18
    my $global = \$GLOBALS{$name};
 
19
    my $ret;
 
20
 
 
21
    $name =~ s|^[\.\_]||;
 
22
 
 
23
    SWITCH: for ($flavour) {
 
24
        /aix/           && do { $name = ".$name";
 
25
                                last;
 
26
                              };
 
27
        /osx/           && do { $name = "_$name";
 
28
                                last;
 
29
                              };
 
30
        /linux.*32/     ||
 
31
        /linux.*64le/   && do { $ret .= ".globl $name\n";
 
32
                                $ret .= ".type  $name,\@function";
 
33
                                last;
 
34
                              };
 
35
        /linux.*64/     && do { $ret .= ".globl $name\n";
 
36
                                $ret .= ".type  $name,\@function\n";
 
37
                                $ret .= ".section       \".opd\",\"aw\"\n";
 
38
                                $ret .= ".align 3\n";
 
39
                                $ret .= "$name:\n";
 
40
                                $ret .= ".quad  .$name,.TOC.\@tocbase,0\n";
 
41
                                $ret .= ".size  $name,24\n";
 
42
                                $ret .= ".previous\n";
 
43
 
 
44
                                $name = ".$name";
 
45
                                last;
 
46
                              };
 
47
    }
 
48
 
 
49
    $ret = ".globl      $name" if (!$ret);
 
50
    $$global = $name;
 
51
    $ret;
 
52
};
 
53
my $text = sub {
 
54
    ($flavour =~ /aix/) ? ".csect" : ".text";
 
55
};
 
56
my $machine = sub {
 
57
    my $junk = shift;
 
58
    my $arch = shift;
 
59
    if ($flavour =~ /osx/)
 
60
    {   $arch =~ s/\"//g;
 
61
        $arch = ($flavour=~/64/) ? "ppc970-64" : "ppc970" if ($arch eq "any");
 
62
    }
 
63
    ".machine   $arch";
 
64
};
 
65
my $size = sub {
 
66
    if ($flavour =~ /linux.*32/ || $flavour =~ /linux.*64le/)
 
67
    {   shift;
 
68
        ".size  " . join(",",@_);
 
69
    }
 
70
    else
 
71
    {   "";     }
 
72
};
 
73
my $asciz = sub {
 
74
    shift;
 
75
    my $line = join(",",@_);
 
76
    if ($line =~ /^"(.*)"$/)
 
77
    {   ".byte  " . join(",",unpack("C*",$1),0) . "\n.align     2";     }
 
78
    else
 
79
    {   "";     }
 
80
};
 
81
my $quad = sub {
 
82
    shift;
 
83
    my @ret;
 
84
    my ($hi,$lo);
 
85
    for (@_) {
 
86
        if (/^0x([0-9a-f]*?)([0-9a-f]{1,8})$/io)
 
87
        {  $hi=$1?"0x$1":"0"; $lo="0x$2";  }
 
88
        elsif (/^([0-9]+)$/o)
 
89
        {  $hi=$1>>32; $lo=$1&0xffffffff;  } # error-prone with 32-bit perl
 
90
        else
 
91
        {  $hi=undef; $lo=$_; }
 
92
 
 
93
        if (defined($hi))
 
94
        {  push(@ret,$flavour=~/le$/o?".long\t$lo,$hi":".long\t$hi,$lo");  }
 
95
        else
 
96
        {  push(@ret,".quad     $lo");  }
 
97
    }
 
98
    join("\n",@ret);
 
99
};
 
100
 
 
101
################################################################
 
102
# simplified mnemonics not handled by at least one assembler
 
103
################################################################
 
104
my $cmplw = sub {
 
105
    my $f = shift;
 
106
    my $cr = 0; $cr = shift if ($#_>1);
 
107
    # Some out-of-date 32-bit GNU assembler just can't handle cmplw...
 
108
    ($flavour =~ /linux.*32/) ?
 
109
        "       .long   ".sprintf "0x%x",31<<26|$cr<<23|$_[0]<<16|$_[1]<<11|64 :
 
110
        "       cmplw   ".join(',',$cr,@_);
 
111
};
 
112
my $bdnz = sub {
 
113
    my $f = shift;
 
114
    my $bo = $f=~/[\+\-]/ ? 16+9 : 16;  # optional "to be taken" hint
 
115
    "   bc      $bo,0,".shift;
 
116
} if ($flavour!~/linux/);
 
117
my $bltlr = sub {
 
118
    my $f = shift;
 
119
    my $bo = $f=~/\-/ ? 12+2 : 12;      # optional "not to be taken" hint
 
120
    ($flavour =~ /linux/) ?             # GNU as doesn't allow most recent hints
 
121
        "       .long   ".sprintf "0x%x",19<<26|$bo<<21|16<<1 :
 
122
        "       bclr    $bo,0";
 
123
};
 
124
my $bnelr = sub {
 
125
    my $f = shift;
 
126
    my $bo = $f=~/\-/ ? 4+2 : 4;        # optional "not to be taken" hint
 
127
    ($flavour =~ /linux/) ?             # GNU as doesn't allow most recent hints
 
128
        "       .long   ".sprintf "0x%x",19<<26|$bo<<21|2<<16|16<<1 :
 
129
        "       bclr    $bo,2";
 
130
};
 
131
my $beqlr = sub {
 
132
    my $f = shift;
 
133
    my $bo = $f=~/-/ ? 12+2 : 12;       # optional "not to be taken" hint
 
134
    ($flavour =~ /linux/) ?             # GNU as doesn't allow most recent hints
 
135
        "       .long   ".sprintf "0x%X",19<<26|$bo<<21|2<<16|16<<1 :
 
136
        "       bclr    $bo,2";
 
137
};
 
138
# GNU assembler can't handle extrdi rA,rS,16,48, or when sum of last two
 
139
# arguments is 64, with "operand out of range" error.
 
140
my $extrdi = sub {
 
141
    my ($f,$ra,$rs,$n,$b) = @_;
 
142
    $b = ($b+$n)&63; $n = 64-$n;
 
143
    "   rldicl  $ra,$rs,$b,$n";
 
144
};
 
145
 
 
146
while($line=<>) {
 
147
 
 
148
    $line =~ s|[#!;].*$||;      # get rid of asm-style comments...
 
149
    $line =~ s|/\*.*\*/||;      # ... and C-style comments...
 
150
    $line =~ s|^\s+||;          # ... and skip white spaces in beginning...
 
151
    $line =~ s|\s+$||;          # ... and at the end
 
152
 
 
153
    {
 
154
        $line =~ s|\b\.L(\w+)|L$1|g;    # common denominator for Locallabel
 
155
        $line =~ s|\bL(\w+)|\.L$1|g     if ($dotinlocallabels);
 
156
    }
 
157
 
 
158
    {
 
159
        $line =~ s|(^[\.\w]+)\:\s*||;
 
160
        my $label = $1;
 
161
        printf "%s:",($GLOBALS{$label} or $label) if ($label);
 
162
    }
 
163
 
 
164
    {
 
165
        $line =~ s|^\s*(\.?)(\w+)([\.\+\-]?)\s*||;
 
166
        my $c = $1; $c = "\t" if ($c eq "");
 
167
        my $mnemonic = $2;
 
168
        my $f = $3;
 
169
        my $opcode = eval("\$$mnemonic");
 
170
        $line =~ s|\bc?[rf]([0-9]+)\b|$1|g if ($c ne "." and $flavour !~ /osx/);
 
171
        if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); }
 
172
        elsif ($mnemonic)           { $line = $c.$mnemonic.$f."\t".$line; }
 
173
    }
 
174
 
 
175
    print $line if ($line);
 
176
    print "\n";
 
177
}
 
178
 
 
179
close STDOUT;