Subversion Repositories freemyipod

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 theseven 1
/* arm_nrv2e_d8.S -- ARM decompressor for NRV2E
2
 
3
   This file is part of the UPX executable compressor.
4
 
5
   Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer
6
   Copyright (C) 1996-2008 Laszlo Molnar
7
   Copyright (C) 2000-2008 John F. Reiser
8
   All Rights Reserved.
9
 
10
   UPX and the UCL library are free software; you can redistribute them
11
   and/or modify them under the terms of the GNU General Public License as
12
   published by the Free Software Foundation; either version 2 of
13
   the License, or (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program; see the file COPYING.
22
   If not, write to the Free Software Foundation, Inc.,
23
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
 
25
   Markus F.X.J. Oberhumer              Laszlo Molnar
26
   <markus@oberhumer.com>               <ml1050@users.sourceforge.net>
27
 
28
   John F. Reiser
29
   <jreiser@users.sourceforge.net>
30
*/
31
 
32
#define src  r0
33
#define len  r1  /* overlaps 'cnt' */
34
#define dst  r2
35
#define tmp  r3
36
#define bits r4
37
#define off  r5
38
#define wrnk r6  /* 0x500  M2_MAX_OFFSET before "wrinkle" */
39
#define srclim r7
40
 
41
#define cnt  r1  /* overlaps 'len' while reading an offset */
42
 
43
/* "mov lr,pc; bxx ..." implements conditional subroutine call */
44
#define GETBIT  add bits,bits; mov lr,pc; beq get1_n2e
45
 
46
#define getnextb(reg) GETBIT; adc reg,reg
47
#define   jnextb0     GETBIT; bcc
48
#define   jnextb1     GETBIT; bcs
49
 
50
.section .icode.ucl_decompress, "ax", %progbits
51
.align 2
89 theseven 52
ucl_decompress: .globl ucl_decompress  @ ARM mode
53
        .type ucl_decompress, %function
2 theseven 54
/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst)
55
   Actual decompressed length is stored through plen_dst.
56
*/
57
        adr r12,1+.thumb_nrv2e_d8; bx r12  @ enter THUMB mode
58
        .code 16  @ THUMB mode
59
        .thumb_func
60
 
61
.thumb_nrv2e_d8:
62
        push {r2,r3,r4,r5,r6,r7,lr}
63
        add srclim,len,src  @ srclim= eof_src;
64
        mov bits,#1; neg off,bits  @ off= -1 initial condition
65
        lsl bits,#31  @ 1<<31: refill next time
66
        mov wrnk,#5
67
        lsl wrnk,#8  @ 0x500  @ nrv2e M2_MAX_OFFSET
68
        b top_n2e
69
 
70
eof_n2e:
71
        pop {r3,r4}  @ r3= orig_dst; r4= plen_dst
72
        sub src,srclim  @ 0 if actual src length equals expected length
73
        sub dst,r3  @ actual dst length
74
        str dst,[r4]
75
        pop {r4,r5,r6,r7}
76
        pop {r1}
77
        bx r1
78
 
79
get1_n2e:  @ In: Carry set [from adding 0x80000000 (1<<31) to itself]
80
          ldrb bits,[src]  @ zero-extend next byte
81
        adc bits,bits  @ double and insert CarryIn as low bit
82
          add src,#1
83
        lsl bits,#24  @ move to top byte, and set CarryOut from old bit 8
84
        mov pc,lr  @ return, stay in current (THUMB) mode
85
 
86
lit_n2e:
87
        ldrb tmp,[src]; add src,#1
88
        strb tmp,[dst]; add dst,#1
89
top_n2e:
90
        jnextb1 lit_n2e
91
        mov cnt,#1; b getoff_n2e
92
 
93
off_n2e:
94
        sub cnt,#1
95
        getnextb(cnt)
96
getoff_n2e:
97
        getnextb(cnt)
98
        jnextb0 off_n2e
99
 
100
        sub tmp,cnt,#3  @ set Carry
101
        mov len,#0  @ Carry unaffected
102
        blo offprev_n2e  @ cnt was 2; tests Carry only
103
        lsl tmp,#8
104
        ldrb off,[src]; add src,#1  @ low 7+1 bits
105
        orr  off,tmp
106
        mvn  off,off; beq eof_n2e  @ off= ~off
107
        asr  off,#1; bcs lenlast_n2e
108
        b lenmore_n2e
109
 
110
offprev_n2e:
111
        jnextb1 lenlast_n2e
112
lenmore_n2e:
113
        mov len,#1
114
        jnextb1 lenlast_n2e
115
len_n2e:
116
        getnextb(len)
117
        jnextb0 len_n2e
118
        add len,#6-2
119
        b gotlen_n2e
120
 
121
lenlast_n2e:
122
        getnextb(len)  @ 0,1,2,3
123
        add len,#2
124
gotlen_n2e:  @ 'cmn': add the inputs, set condition codes, discard the sum
125
        cmn wrnk,off; bcs near_n2e  @ within M2_MAX_OFFSET
126
        add len,#1  @ too far away, so minimum match length is 3
127
near_n2e:
128
        ldrb tmp,[dst]  @ force cacheline allocate
129
copy_n2e:
130
        ldrb tmp,[dst,off]
131
        strb tmp,[dst]; add dst,#1
132
        sub len,#1; bne copy_n2e
133
        b top_n2e
134
 
135
        .size ucl_decompress, .-ucl_decompress