This commit was generated by cvs2svn to track changes on a CVS vendor
[openssl.git] / crypto / rc4 / asm / rc4-586.pl
1 #!/usr/local/bin/perl
2
3 # define for pentium pro friendly version
4
5 push(@INC,"perlasm","../../perlasm");
6 require "x86asm.pl";
7
8 &asm_init($ARGV[0],"rc4-586.pl");
9
10 $tx="eax";
11 $ty="ebx";
12 $x="ecx";
13 $y="edx";
14 $in="esi";
15 $out="edi";
16 $d="ebp";
17
18 &RC4("RC4");
19
20 &asm_finish();
21
22 sub RC4_loop
23         {
24         local($n,$p,$char)=@_;
25
26         &comment("Round $n");
27
28         if ($char)
29                 {
30                 if ($p >= 0)
31                         {
32                          &mov($ty,      &swtmp(2));
33                         &cmp($ty,       $in);
34                          &jle(&label("finished"));
35                         &inc($in);
36                         }
37                 else
38                         {
39                         &add($ty,       8);
40                          &inc($in);
41                         &cmp($ty,       $in);
42                          &jl(&label("finished"));
43                         &mov(&swtmp(2), $ty);
44                         }
45                 }
46         # Moved out
47         # &mov( $tx,            &DWP(0,$d,$x,4)) if $p < 0;
48
49          &add(  $y,             $tx);
50         &and(   $y,             0xff);
51          &inc(  $x);                    # NEXT ROUND 
52         &mov(   $ty,            &DWP(0,$d,$y,4));
53          # XXX
54         &mov(   &DWP(-4,$d,$x,4),$ty);                  # AGI
55          &add(  $ty,            $tx);
56         &and(   $x,             0xff);  # NEXT ROUND
57          &and(  $ty,            0xff);
58         &mov(   &DWP(0,$d,$y,4),$tx);
59          &nop();
60         &mov(   $ty,            &DWP(0,$d,$ty,4));
61          &mov(  $tx,            &DWP(0,$d,$x,4)) if $p < 1; # NEXT ROUND
62          # XXX
63
64         if (!$char)
65                 {
66                 #moved up into last round
67                 if ($p >= 1)
68                         {
69                         &add(   $out,   8)
70                         }
71                 &movb(  &BP($n,"esp","",0),     &LB($ty));
72                 }
73         else
74                 {
75                 # Note in+=8 has occured
76                 &movb(  &HB($ty),       &BP(-1,$in,"",0));
77                  # XXX
78                 &xorb(&LB($ty),         &HB($ty));
79                  # XXX
80                 &movb(&BP($n,$out,"",0),&LB($ty));
81                 }
82         }
83
84
85 sub RC4
86         {
87         local($name)=@_;
88
89         &function_begin_B($name,"");
90
91         &comment("");
92
93         &push("ebp");
94          &push("ebx");
95         &mov(   $d,     &wparam(0));    # key
96          &mov(  $ty,    &wparam(1));    # num
97         &push("esi");
98          &push("edi");
99
100         &mov(   $x,     &DWP(0,$d,"",1));
101          &mov(  $y,     &DWP(4,$d,"",1));
102
103         &mov(   $in,    &wparam(2));
104          &inc(  $x);
105
106         &stack_push(3); # 3 temp variables
107          &add(  $d,     8);
108         &and(   $x,             0xff);
109
110          &lea(  $ty,    &DWP(-8,$ty,$in));
111
112         # check for 0 length input
113
114         &mov(   $out,   &wparam(3));
115          &mov(  &swtmp(2),      $ty);   # this is now address to exit at
116         &mov(   $tx,    &DWP(0,$d,$x,4));
117
118          &cmp(  $ty,    $in);
119         &jl(    &label("end")); # less than 8 bytes
120
121         &set_label("start");
122
123         # filling DELAY SLOT
124         &add(   $in,    8);
125
126         &RC4_loop(0,-1,0);
127         &RC4_loop(1,0,0);
128         &RC4_loop(2,0,0);
129         &RC4_loop(3,0,0);
130         &RC4_loop(4,0,0);
131         &RC4_loop(5,0,0);
132         &RC4_loop(6,0,0);
133         &RC4_loop(7,1,0);
134         
135         &comment("apply the cipher text");
136         # xor the cipher data with input
137
138         #&add(  $out,   8); #moved up into last round
139
140         &mov(   $tx,    &swtmp(0));
141          &mov(  $ty,    &DWP(-8,$in,"",0));
142         &xor(   $tx,    $ty);
143          &mov(  $ty,    &DWP(-4,$in,"",0)); 
144         &mov(   &DWP(-8,$out,"",0),     $tx);
145          &mov(  $tx,    &swtmp(1));
146         &xor(   $tx,    $ty);
147          &mov(  $ty,    &swtmp(2));     # load end ptr;
148         &mov(   &DWP(-4,$out,"",0),     $tx);
149          &mov(  $tx,            &DWP(0,$d,$x,4));
150         &cmp($in,       $ty);
151          &jle(&label("start"));
152
153         &set_label("end");
154
155         # There is quite a bit of extra crap in RC4_loop() for this
156         # first round
157         &RC4_loop(0,-1,1);
158         &RC4_loop(1,0,1);
159         &RC4_loop(2,0,1);
160         &RC4_loop(3,0,1);
161         &RC4_loop(4,0,1);
162         &RC4_loop(5,0,1);
163         &RC4_loop(6,1,1);
164
165         &set_label("finished");
166         &dec(   $x);
167          &stack_pop(3);
168         &mov(   &DWP(-4,$d,"",0),$y);
169          &movb( &BP(-8,$d,"",0),&LB($x));
170
171         &function_end($name);
172         }
173