Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
253 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
/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst)
51
   Actual decompressed length is stored through plen_dst.
52
*/
53
        .code 16  @ THUMB mode
54
        .thumb_func
55
	.byte 0
56
	.byte 0
57
 
58
.thumb_nrv2e_d8:
59
        push {r2,r3,r4,r5,r6,r7,lr}
60
        add srclim,len,src  @ srclim= eof_src;
61
        mov bits,#1; neg off,bits  @ off= -1 initial condition
62
        lsl bits,#31  @ 1<<31: refill next time
63
        mov wrnk,#5
64
        lsl wrnk,#8  @ 0x500  @ nrv2e M2_MAX_OFFSET
65
        b top_n2e
66
 
67
eof_n2e:
68
        pop {r3,r4}  @ r3= orig_dst; r4= plen_dst
69
        sub src,srclim  @ 0 if actual src length equals expected length
70
        sub dst,r3  @ actual dst length
71
        str dst,[r4]
72
        pop {r4,r5,r6,r7}
73
        pop {r1}
74
        bx r1
75
 
76
get1_n2e:  @ In: Carry set [from adding 0x80000000 (1<<31) to itself]
77
          ldrb bits,[src]  @ zero-extend next byte
78
        adc bits,bits  @ double and insert CarryIn as low bit
79
          add src,#1
80
        lsl bits,#24  @ move to top byte, and set CarryOut from old bit 8
81
        mov pc,lr  @ return, stay in current (THUMB) mode
82
 
83
lit_n2e:
84
        ldrb tmp,[src]; add src,#1
85
        strb tmp,[dst]; add dst,#1
86
top_n2e:
87
        jnextb1 lit_n2e
88
        mov cnt,#1; b getoff_n2e
89
 
90
off_n2e:
91
        sub cnt,#1
92
        getnextb(cnt)
93
getoff_n2e:
94
        getnextb(cnt)
95
        jnextb0 off_n2e
96
 
97
        sub tmp,cnt,#3  @ set Carry
98
        mov len,#0  @ Carry unaffected
99
        blo offprev_n2e  @ cnt was 2; tests Carry only
100
        lsl tmp,#8
101
        ldrb off,[src]; add src,#1  @ low 7+1 bits
102
        orr  off,tmp
103
        mvn  off,off; beq eof_n2e  @ off= ~off
104
        asr  off,#1; bcs lenlast_n2e
105
        b lenmore_n2e
106
 
107
offprev_n2e:
108
        jnextb1 lenlast_n2e
109
lenmore_n2e:
110
        mov len,#1
111
        jnextb1 lenlast_n2e
112
len_n2e:
113
        getnextb(len)
114
        jnextb0 len_n2e
115
        add len,#6-2
116
        b gotlen_n2e
117
 
118
lenlast_n2e:
119
        getnextb(len)  @ 0,1,2,3
120
        add len,#2
121
gotlen_n2e:  @ 'cmn': add the inputs, set condition codes, discard the sum
122
        cmn wrnk,off; bcs near_n2e  @ within M2_MAX_OFFSET
123
        add len,#1  @ too far away, so minimum match length is 3
124
near_n2e:
125
        ldrb tmp,[dst]  @ force cacheline allocate
126
copy_n2e:
127
        ldrb tmp,[dst,off]
128
        strb tmp,[dst]; add dst,#1
129
        sub len,#1; bne copy_n2e
130
        b top_n2e
131
 
132
	.code 32
133
	.global _start
134
_start:
135
	msr	cpsr_c, #0xd3
136
	mrc	p15, 0, r0,c1,c0
137
	bic	r0, r0, #5
138
	mcr	p15, 0, r0,c1,c0
139
	mov	r2, #0x22000000
140
	add	sp, r2, #0x2c000
141
	sub	r3, r2, #4
142
	adr	r11, .thumb_nrv2e_d8+1
143
	sub	r0, pc, #0xec0
144
	mov	lr, pc
145
	bx	r11
146
	mov	r0, #0x22000000
147
	add	r0, r0, #1
148
	bx	r0