~ubuntu-branches/debian/sid/upx-ucl/sid

« back to all changes in this revision

Viewing changes to src/stub/arm_nrv2e_d8.S

  • Committer: Bazaar Package Importer
  • Author(s): Robert Luberda
  • Date: 2006-06-13 21:23:23 UTC
  • mfrom: (1.3.1 upstream) (3.1.2 edgy)
  • Revision ID: james.westby@ubuntu.com-20060613212323-343yzs4jt6vr5483
* New upstream version.
* Standards-Version: 3.7.2 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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-2004 Markus Franz Xaver Johannes Oberhumer
 
6
   Copyright (C) 1996-2004 Laszlo Molnar
 
7
   Copyright (C) 2000-2006 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
   <mfx@users.sourceforge.net>          <ml1050@users.sourceforge.net>
 
27
 
 
28
   John F. Reiser
 
29
   <jreiser@users.sourceforge.net>
 
30
*/
 
31
#define SAFE 0  /* 1 for src+dst bounds checking: cost 40 bytes */
 
32
 
 
33
#define src  r0
 
34
#define len  r1  /* overlaps 'cnt' */
 
35
#define dst  r2
 
36
#define tmp  r3
 
37
#define bits r4
 
38
#define off  r5
 
39
#define wrnk r6  /* 0x500  M2_MAX_OFFSET before "wrinkle" */
 
40
#define srclim r7
 
41
#if 1==SAFE  /*{*/
 
42
#define dstlim r12
 
43
#endif  /*}*/
 
44
 
 
45
#define cnt  r1  /* overlaps 'len' while reading an offset */
 
46
 
 
47
#if 1==SAFE  /*{*/
 
48
#define CHECK_SRC  cmp src,srclim; bhs bad_src_n2e
 
49
#define CHECK_DST  cmp dst,dstlim; bhs bad_dst_n2e
 
50
#else  /*}{*/
 
51
#define CHECK_SRC  /*empty*/
 
52
#define CHECK_DST  /*empty*/
 
53
#endif  /*}*/
 
54
 
 
55
#if 0  /*{ DEBUG only: check newly-decompressed against original dst */
 
56
#define CHECK_BYTE \
 
57
   push {wrnk}; \
 
58
   ldrb  wrnk,[dst]; \
 
59
   cmp   wrnk,tmp; beq 0f; bkpt; \
 
60
0: pop  {wrnk}
 
61
#else  /*}{*/
 
62
#define CHECK_BYTE  /*empty*/
 
63
#endif  /*}*/
 
64
 
 
65
/* "mov lr,pc; bxx ..." implements conditional subroutine call */
 
66
#define GETBIT  add bits,bits; mov lr,pc; beq get1_n2e
 
67
 
 
68
#define getnextb(reg) GETBIT; adc reg,reg
 
69
#define   jnextb0     GETBIT; bcc
 
70
#define   jnextb1     GETBIT; bcs
 
71
 
 
72
ucl_nrv2e_decompress_8: .globl ucl_nrv2e_decompress_8  @ ARM mode
 
73
        .type ucl_nrv2e_decompress_8, %function
 
74
/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst)
 
75
   Actual decompressed length is stored through plen_dst.
 
76
   For SAFE mode: at call, *plen_dst must be allowed length of output buffer.
 
77
*/
 
78
        adr r12,1+thumb_nrv2e_d8; bx r12  @ enter THUMB mode
 
79
        .code 16  @ THUMB mode
 
80
        .globl thumb_nrv2e_d8
 
81
        .thumb_func
 
82
thumb_nrv2e_d8:
 
83
        push {r2,r3, r4,r5,r6,r7, lr}
 
84
#define sp_DST0 0  /* stack offset of original dst */
 
85
        add srclim,len,src  @ srclim= eof_src;
 
86
#if 1==SAFE  /*{*/
 
87
        ldr tmp,[r3]  @ len_dst
 
88
        add tmp,dst
 
89
        mov dstlim,tmp
 
90
#endif  /*}*/
 
91
        mov bits,#1; neg off,bits  @ off= -1 initial condition
 
92
        lsl bits,#31  @ 1<<31; refill next time
 
93
        mov wrnk,#5
 
94
        lsl wrnk,#8  @ 0x500  @ nrv2e M2_MAX_OFFSET
 
95
        b top_n2e
 
96
 
 
97
#if 1==SAFE  /*{*/
 
98
bad_dst_n2e:  # return value will be 2
 
99
        add src,srclim,#1
 
100
bad_src_n2e:  # return value will be 1
 
101
        add src,#1
 
102
#endif  /*}*/
 
103
eof_n2e:
 
104
        pop {r3,r4}  @ r3= orig_dst; r4= plen_dst
 
105
        sub src,srclim  @ 0 if actual src length equals expected length
 
106
        sub dst,r3  @ actual dst length
 
107
        str dst,[r4]
 
108
        pop {r4,r5,r6,r7 /*,pc*/}
 
109
        pop {r1}; bx r1  @ "pop {,pc}" fails return to ARM mode on ARMv4T
 
110
 
 
111
get1_n2e:  @ In: Carry set [from adding 0x80000000 (1<<31) to itself]
 
112
          ldrb bits,[src]  @ zero-extend next byte
 
113
        adc bits,bits  @ double and insert CarryIn as low bit
 
114
          CHECK_SRC
 
115
          add src,#1
 
116
        lsl bits,#24  @ move to top byte, and set CarryOut from old bit 8
 
117
        mov pc,lr  @ return, stay in current (THUMB) mode
 
118
 
 
119
lit_n2e:
 
120
        CHECK_SRC; ldrb tmp,[src]; add src,#1
 
121
        CHECK_BYTE
 
122
        CHECK_DST; strb tmp,[dst]; add dst,#1
 
123
top_n2e:
 
124
        jnextb1 lit_n2e
 
125
        mov cnt,#1; b getoff_n2e
 
126
 
 
127
off_n2e:
 
128
        sub cnt,#1
 
129
        getnextb(cnt)
 
130
getoff_n2e:
 
131
        getnextb(cnt)
 
132
        jnextb0 off_n2e
 
133
 
 
134
        sub tmp,cnt,#3  @ set Carry
 
135
        mov len,#0  @ Carry unaffected
 
136
        blo offprev_n2e  @ cnt was 2; tests Carry only
 
137
        lsl tmp,#8
 
138
        CHECK_SRC; ldrb off,[src]; add src,#1  @ low 7+1 bits
 
139
        orr  off,tmp
 
140
        mvn  off,off; beq eof_n2e  @ off= ~off
 
141
        asr  off,#1; bcs lenlast_n2e
 
142
        b lenmore_n2e
 
143
 
 
144
offprev_n2e:
 
145
        jnextb1 lenlast_n2e
 
146
lenmore_n2e:
 
147
        mov len,#1
 
148
        jnextb1 lenlast_n2e
 
149
len_n2e:
 
150
        getnextb(len)
 
151
        jnextb0 len_n2e
 
152
        add len,#6-2
 
153
        b gotlen_n2e
 
154
 
 
155
lenlast_n2e:
 
156
        getnextb(len)  @ 0,1,2,3
 
157
        add len,#2
 
158
gotlen_n2e:  @ 'cmn': add the inputs, set condition codes, discard the sum
 
159
        cmn wrnk,off; bcs near_n2e  @ within M2_MAX_OFFSET
 
160
        add len,#1  @ too far away, so minimum match length is 3
 
161
near_n2e:
 
162
#if 1==SAFE  /*{*/
 
163
        ldr tmp,[sp,#sp_DST0]
 
164
        sub tmp,dst
 
165
        sub tmp,off; bhi bad_dst_n2e  @ reaching back too far
 
166
 
 
167
        add tmp,dst,cnt
 
168
        cmp tmp,dstlim; bhi bad_dst_n2e  @ too much output
 
169
#endif  /*}*/
 
170
        ldrb tmp,[dst]  @ force cacheline allocate
 
171
copy_n2e:
 
172
        ldrb tmp,[dst,off]
 
173
        CHECK_BYTE
 
174
        strb tmp,[dst]; add dst,#1
 
175
        sub len,#1; bne copy_n2e
 
176
        b top_n2e
 
177
        .size ucl_nrv2e_decompress_8, .-ucl_nrv2e_decompress_8
 
178
 
 
179
/*
 
180
vi:ts=8:et:nowrap
 
181
 */
 
182