diff options
author | Andy Polyakov <appro@openssl.org> | 2013-03-31 14:32:05 +0200 |
---|---|---|
committer | Andy Polyakov <appro@openssl.org> | 2013-03-31 14:32:05 +0200 |
commit | c5d975a74313268a36b6a6103cd37221724137c2 (patch) | |
tree | 9307057b720536601f7c9981d7e7a82302d6cad9 /crypto/perlasm/sparcv9_modes.pl | |
parent | d8f3ed23062539c4a6f7b4153633f921ce16a15f (diff) |
Add support for SPARC T4 DES opcode.
Diffstat (limited to 'crypto/perlasm/sparcv9_modes.pl')
-rw-r--r-- | crypto/perlasm/sparcv9_modes.pl | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/crypto/perlasm/sparcv9_modes.pl b/crypto/perlasm/sparcv9_modes.pl index 363da32d59..a13ffcec2d 100644 --- a/crypto/perlasm/sparcv9_modes.pl +++ b/crypto/perlasm/sparcv9_modes.pl @@ -1582,6 +1582,63 @@ my %movxopf = ( "movdtox" => 0x110, } } +sub undes { +my ($mnemonic)=shift; +my @args=@_; +my ($ref,$opf); +my %desopf = ( "des_round" => 0b1001, + "des_ip" => 0b100110100, + "des_iip" => 0b100110101, + "des_kexpand" => 0b100110110 ); + + $ref = "$mnemonic\t".join(",",@_); + + if (defined($opf=$desopf{$mnemonic})) { # 4-arg + if ($mnemonic eq "des_round") { + foreach (@args[0..3]) { + return $ref if (!/%f([0-9]{1,2})/); + $_=$1; + if ($1>=32) { + return $ref if ($1&1); + # re-encode for upper double register addressing + $_=($1|$1>>5)&31; + } + } + return sprintf ".word\t0x%08x !%s", + 2<<30|0b011001<<19|$opf<<5|$args[0]<<14|$args[1]|$args[2]<<9|$args[3]<<25, + $ref; + } elsif ($mnemonic eq "des_kexpand") { # 3-arg + foreach (@args[0..2]) { + return $ref if (!/(%f)?([0-9]{1,2})/); + $_=$2; + if ($2>=32) { + return $ref if ($2&1); + # re-encode for upper double register addressing + $_=($2|$2>>5)&31; + } + } + return sprintf ".word\t0x%08x !%s", + 2<<30|0b110110<<19|$opf<<5|$args[0]<<14|$args[1]|$args[2]<<25, + $ref; + } else { # 2-arg + foreach (@args[0..1]) { + return $ref if (!/%f([0-9]{1,2})/); + $_=$1; + if ($1>=32) { + return $ref if ($2&1); + # re-encode for upper double register addressing + $_=($1|$1>>5)&31; + } + } + return sprintf ".word\t0x%08x !%s", + 2<<30|0b110110<<19|$opf<<5|$args[0]<<14|$args[1]<<25, + $ref; + } + } else { + return $ref; + } +} + sub emit_assembler { foreach (split("\n",$::code)) { s/\`([^\`]*)\`/eval $1/ge; @@ -1600,6 +1657,9 @@ sub emit_assembler { s/\b(camellia_[^s]+)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/ &uncamellia3($1,$2,$3,$4) /geo or + s/\b(des_\w+)\s+(?<rs1>%f[0-9]{1,2}),\s*(?<rs2>[%fx0-9]+)(,\s*(?<rs3>%f[0-9]{1,2})(,\s*(?<rs4>%f[0-9]{1,2}))?)?/ + &undes($1,$+{rs1},$+{rs2},$+{rs3},$+{rs4}) + /geo or s/\b(mov[ds]to\w+)\s+(%f[0-9]{1,2}),\s*(%[goli][0-7])/ &unmovxtox($1,$2,$3) /geo or |