2009-05-16 Pavel Roskin <proski@gnu.org>
[grub2/bean.git] / kern / i386 / pc / lzo1x.S
blobe942e98d6902332d02c687d29b464ba3785d5049
1 /*
2  *  GRUB  --  GRand Unified Bootloader
3  *  Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
4  *  Copyright (C) 2003,2007  Free Software Foundation, Inc.
5  *
6  *  GRUB is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  GRUB is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
18  */
19         
21  * This code was stolen from the files enter.sh, leave.sh, lzo1x_d.sh,
22  * lzo1x_f.s and lzo_asm.h in LZO version 1.08, and was heavily modified
23  * to adapt it to GRUB's requirement.
24  *
25  * See <http://www.oberhumer.com/opensource/lzo/>, for more information
26  * about LZO.
27  */
29 #define INP     4+16(%esp)
30 #define INS     8+16(%esp)
31 #define OUTP    12+16(%esp)
32 #define NN      3
33 #define N_3     %ebp
34 #define N_255   $255
35 #define LODSB   movb (%esi), %al ;  incl %esi
36 #define NOTL_3(r)       xorl N_3, r
37 #define MOVSL(r1,r2,x)  movl (r1), x ; addl $4, r1 ; movl x, (r2) ; addl $4, r2
38 #define COPYL_C(r1,r2,x,rc)     9: MOVSL(r1,r2,x) ; decl rc ; jnz 9b
39 #define COPYL(r1,r2,x)  COPYL_C(r1,r2,x,%ecx)
40         
41 lzo1x_decompress:
42         pushl   %ebp
43         pushl   %edi
44         pushl   %esi
45         pushl   %ebx
47         cld
49         movl    INP, %esi
50         movl    OUTP, %edi
51         movl    $3, %ebp
53         
54         xorl    %eax, %eax
55         xorl    %ebx, %ebx      /* high bits 9-32 stay 0 */
56         lodsb
57         cmpb    $17, %al
58         jbe     .L01
59         subb    $17-NN, %al
60         jmp     .LFLR
63 /***********************************************************************
64 // literal run
65 ************************************************************************/
67 0:      addl    N_255, %eax
68 1:      movb    (%esi), %bl
69         incl    %esi
70         orb     %bl, %bl
71         jz      0b
72         leal    18+NN(%eax,%ebx), %eax
73         jmp     3f
76 .L00:
77         LODSB
78 .L01:
79         cmpb    $16, %al
80         jae     .LMATCH
82         /* a literal run */
83         orb     %al, %al
84         jz      1b
85         addl    $3+NN, %eax
87 .LFLR:
88         movl    %eax, %ecx
89         NOTL_3(%eax)
90         shrl    $2, %ecx
91         andl    N_3, %eax
92         COPYL(%esi,%edi,%edx)
93         subl    %eax, %esi
94         subl    %eax, %edi
96         LODSB
97         cmpb    $16, %al
98         jae     .LMATCH
101 /***********************************************************************
102 // R1
103 ************************************************************************/
105         shrl    $2, %eax
106         movb    (%esi), %bl
107         leal    -0x801(%edi), %edx
108         leal    (%eax,%ebx,4), %eax
109         incl    %esi
110         subl    %eax, %edx
111         movl    (%edx), %ecx
112         movl    %ecx, (%edi)
113         addl    N_3, %edi
114         jmp     .LMDONE
117 /***********************************************************************
118 // M2
119 ************************************************************************/
121 .LMATCH:
122         cmpb    $64, %al
123         jb      .LM3MATCH
125         /* a M2 match */
126         movl    %eax, %ecx
127         shrl    $2, %eax
128         leal    -1(%edi), %edx
129         andl    $7, %eax
130         movb    (%esi), %bl
131         shrl    $5, %ecx
132         leal    (%eax,%ebx,8), %eax
133         incl    %esi
134         subl    %eax, %edx
136         addl    $1+3, %ecx
138         cmpl    N_3, %eax
139         jae     .LCOPYLONG
140         jmp     .LCOPYBYTE
143 /***********************************************************************
144 // M3
145 ************************************************************************/
147 0:      addl    N_255, %eax
148 1:      movb    (%esi), %bl
149         incl    %esi
150         orb     %bl, %bl
151         jz      0b
152         leal    33+NN(%eax,%ebx), %ecx
153         xorl    %eax, %eax
154         jmp     3f
157 .LM3MATCH:
158         cmpb    $32, %al
159         jb      .LM4MATCH
161         /* a M3 match */
162         andl    $31, %eax
163         jz      1b
164         lea     2+NN(%eax), %ecx
166         movw    (%esi), %ax
167         leal    -1(%edi), %edx
168         shrl    $2, %eax
169         addl    $2, %esi
170         subl    %eax, %edx
172         cmpl    N_3, %eax
173         jb      .LCOPYBYTE
176 /***********************************************************************
177 // copy match
178 ************************************************************************/
180 .LCOPYLONG:                      /* copy match using longwords */
181         leal    -3(%edi,%ecx), %eax
182         shrl    $2, %ecx
183         COPYL(%edx,%edi,%ebx)
184         movl    %eax, %edi
185         xorl    %ebx, %ebx
187 .LMDONE:
188         movb    -2(%esi), %al
189         andl    N_3, %eax
190         jz      .L00
191 .LFLR3:
192         movl    (%esi), %edx
193         addl    %eax, %esi
194         movl    %edx, (%edi)
195         addl    %eax, %edi
197         LODSB
198         jmp     .LMATCH
201 .LCOPYBYTE:                      /* copy match using bytes */
202         xchgl   %edx,%esi
203         subl    N_3,%ecx
205         rep
206         movsb
207         movl    %edx, %esi
208         jmp     .LMDONE
211 /***********************************************************************
212 // M4
213 ************************************************************************/
215 0:      addl    N_255, %ecx
216 1:      movb    (%esi), %bl
217         incl    %esi
218         orb     %bl, %bl
219         jz      0b
220         leal    9+NN(%ebx,%ecx), %ecx
221         jmp     3f
224 .LM4MATCH:
225         cmpb    $16, %al
226         jb      .LM1MATCH
228         /* a M4 match */
229         movl    %eax, %ecx
230         andl    $8, %eax
231         shll    $13, %eax       /* save in bit 16 */
232         andl    $7, %ecx
233         jz      1b
234         addl    $2+NN, %ecx
236         movw    (%esi), %ax
237         addl    $2, %esi
238         leal    -0x4000(%edi), %edx
239         shrl    $2, %eax
240         jz      .LEOF
241         subl    %eax, %edx
242         jmp     .LCOPYLONG
245 /***********************************************************************
246 // M1
247 ************************************************************************/
249 .LM1MATCH:
250         /* a M1 match */
251         shrl    $2, %eax
252         movb    (%esi), %bl
253         leal    -1(%edi), %edx
254         leal    (%eax,%ebx,4), %eax
255         incl    %esi
256         subl    %eax, %edx
258         movb    (%edx), %al     /* we must use this because edx can be edi-1 */
259         movb    %al, (%edi)
260         movb    1(%edx), %bl
261         movb    %bl, 1(%edi)
262         addl    $2, %edi
263         jmp     .LMDONE
266 /***********************************************************************
268 ************************************************************************/
270 .LEOF:
271 /****   xorl    %eax,%eax          eax=0 from above */
273         cmpl    $3+NN, %ecx     /* ecx must be 3/6 */
274         setnz   %al
276         /* check compressed size */
277         movl    INP, %edx
278         addl    INS, %edx
279         cmpl    %edx, %esi       /* check compressed size */
280         ja      .L_input_overrun
281         jb      .L_input_not_consumed
283 .L_leave:
284         negl    %eax
285         jnz     1f
286         
287         subl    OUTP, %edi       /* write back the uncompressed size */
288         movl    %edi, %eax
290 1:      popl    %ebx
291         popl    %esi
292         popl    %edi
293         popl    %ebp
294         ret
296 .L_input_not_consumed:
297         movl    $8, %eax         /* LZO_E_INPUT_NOT_CONSUMED */
298         jmp     .L_leave
300 .L_input_overrun:
301         movl    $4, %eax         /* LZO_E_INPUT_OVERRUN */
302         jmp     .L_leave
304 #undef INP
305 #undef INS
306 #undef OUTP
307 #undef NN
308 #undef NN
309 #undef N_3
310 #undef N_255
311 #undef LODSB
312 #undef NOTL_3
313 #undef MOVSL
314 #undef COPYL_C
315 #undef COPYL