crypto/armcap.c: detect ARMv8 capabilities [in 32-bit build].
[openssl.git] / crypto / cast / asm / cast-586.pl
1 #!/usr/local/bin/perl
2
3 # define for pentium pro friendly version
4 $ppro=1;
5
6 $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
7 push(@INC,"${dir}","${dir}../../perlasm");
8 require "x86asm.pl";
9 require "cbc.pl";
10
11 &asm_init($ARGV[0],"cast-586.pl",$ARGV[$#ARGV] eq "386");
12
13 $CAST_ROUNDS=16;
14 $L="edi";
15 $R="esi";
16 $K="ebp";
17 $tmp1="ecx";
18 $tmp2="ebx";
19 $tmp3="eax";
20 $tmp4="edx";
21 $S1="CAST_S_table0";
22 $S2="CAST_S_table1";
23 $S3="CAST_S_table2";
24 $S4="CAST_S_table3";
25
26 @F1=("add","xor","sub");
27 @F2=("xor","sub","add");
28 @F3=("sub","add","xor");
29
30 &CAST_encrypt("CAST_encrypt",1);
31 &CAST_encrypt("CAST_decrypt",0);
32 &cbc("CAST_cbc_encrypt","CAST_encrypt","CAST_decrypt",1,4,5,3,-1,-1);
33
34 &asm_finish();
35
36 sub CAST_encrypt {
37     local($name,$enc)=@_;
38
39     local($win_ex)=<<"EOF";
40 EXTERN  _CAST_S_table0:DWORD
41 EXTERN  _CAST_S_table1:DWORD
42 EXTERN  _CAST_S_table2:DWORD
43 EXTERN  _CAST_S_table3:DWORD
44 EOF
45     &main::external_label(
46                           "CAST_S_table0",
47                           "CAST_S_table1",
48                           "CAST_S_table2",
49                           "CAST_S_table3",
50                           );
51
52     &function_begin_B($name,$win_ex);
53
54     &comment("");
55
56     &push("ebp");
57     &push("ebx");
58     &mov($tmp2,&wparam(0));
59     &mov($K,&wparam(1));
60     &push("esi");
61     &push("edi");
62
63     &comment("Load the 2 words");
64     &mov($L,&DWP(0,$tmp2,"",0));
65     &mov($R,&DWP(4,$tmp2,"",0));
66
67     &comment('Get short key flag');
68     &mov($tmp3,&DWP(128,$K,"",0));
69     if($enc) {
70         &push($tmp3);
71     } else {
72         &or($tmp3,$tmp3);
73         &jnz(&label('cast_dec_skip'));
74     }
75
76     &xor($tmp3, $tmp3);
77
78     # encrypting part
79
80     if ($enc) {
81         &E_CAST( 0,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
82         &E_CAST( 1,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
83         &E_CAST( 2,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
84         &E_CAST( 3,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
85         &E_CAST( 4,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
86         &E_CAST( 5,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
87         &E_CAST( 6,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
88         &E_CAST( 7,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
89         &E_CAST( 8,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
90         &E_CAST( 9,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
91         &E_CAST(10,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
92         &E_CAST(11,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
93         &comment('test short key flag');
94         &pop($tmp4);
95         &or($tmp4,$tmp4);
96         &jnz(&label('cast_enc_done'));
97         &E_CAST(12,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
98         &E_CAST(13,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
99         &E_CAST(14,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
100         &E_CAST(15,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
101     } else {
102         &E_CAST(15,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
103         &E_CAST(14,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
104         &E_CAST(13,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
105         &E_CAST(12,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
106         &set_label('cast_dec_skip');
107         &E_CAST(11,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
108         &E_CAST(10,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
109         &E_CAST( 9,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
110         &E_CAST( 8,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
111         &E_CAST( 7,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
112         &E_CAST( 6,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
113         &E_CAST( 5,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
114         &E_CAST( 4,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
115         &E_CAST( 3,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
116         &E_CAST( 2,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
117         &E_CAST( 1,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
118         &E_CAST( 0,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
119     }
120
121     &set_label('cast_enc_done') if $enc;
122 # Why the nop? - Ben 17/1/99
123     &nop();
124     &mov($tmp3,&wparam(0));
125     &mov(&DWP(4,$tmp3,"",0),$L);
126     &mov(&DWP(0,$tmp3,"",0),$R);
127     &function_end($name);
128 }
129
130 sub E_CAST {
131     local($i,$S,$L,$R,$K,$OP1,$OP2,$OP3,$tmp1,$tmp2,$tmp3,$tmp4)=@_;
132     # Ri needs to have 16 pre added.
133
134     &comment("round $i");
135     &mov(       $tmp4,          &DWP($i*8,$K,"",1));
136
137     &mov(       $tmp1,          &DWP($i*8+4,$K,"",1));
138     &$OP1(      $tmp4,          $R);
139
140     &rotl(      $tmp4,          &LB($tmp1));
141
142     if ($ppro) {
143         &mov(   $tmp2,          $tmp4);         # B
144         &xor(   $tmp1,          $tmp1);
145         
146         &movb(  &LB($tmp1),     &HB($tmp4));    # A
147         &and(   $tmp2,          0xff);
148
149         &shr(   $tmp4,          16);            #
150         &xor(   $tmp3,          $tmp3);
151     } else {
152         &mov(   $tmp2,          $tmp4);         # B
153         &movb(  &LB($tmp1),     &HB($tmp4));    # A     # BAD BAD BAD
154         
155         &shr(   $tmp4,          16);            #
156         &and(   $tmp2,          0xff);
157     }
158
159     &movb(      &LB($tmp3),     &HB($tmp4));    # C     # BAD BAD BAD
160     &and(       $tmp4,          0xff);          # D
161
162     &mov(       $tmp1,          &DWP($S1,"",$tmp1,4));
163     &mov(       $tmp2,          &DWP($S2,"",$tmp2,4));
164
165     &$OP2(      $tmp1,          $tmp2);
166     &mov(       $tmp2,          &DWP($S3,"",$tmp3,4));
167
168     &$OP3(      $tmp1,          $tmp2);
169     &mov(       $tmp2,          &DWP($S4,"",$tmp4,4));
170
171     &$OP1(      $tmp1,          $tmp2);
172     # XXX
173
174     &xor(       $L,             $tmp1);
175     # XXX
176 }
177