rev |
line source |
pascal@13691
|
1 // #define RC_NORMALIZE if (Range < kTopValue) { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
|
pascal@13691
|
2 //
|
pascal@13691
|
3 // #define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
|
pascal@13691
|
4 // #define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
|
pascal@13691
|
5 // #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
|
pascal@13691
|
6 //
|
pascal@13691
|
7 //#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
|
pascal@13691
|
8 // { UpdateBit0(p); mi <<= 1; A0; } else \
|
pascal@13691
|
9 // { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
|
pascal@13691
|
10 //
|
pascal@13691
|
11 // #define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
|
pascal@13691
|
12 //
|
pascal@13691
|
13 // #define RangeDecoderBitTreeDecode(probs, numLevels, res) \
|
pascal@13691
|
14 // { int i = numLevels; res = 1; \
|
pascal@13691
|
15 // do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
|
pascal@13691
|
16 // res -= (1 << numLevels); }
|
pascal@13691
|
17 /*
|
pascal@13691
|
18 * Compression with : lzma e src dst -eos -pb2 -lp0 -lc3
|
pascal@13691
|
19 */
|
pascal@13691
|
20
|
pascal@13691
|
21 #define PROP_PB 2
|
pascal@13691
|
22 #define PROP_LP 0
|
pascal@13691
|
23 #define PROP_LC 3
|
pascal@13691
|
24 #define PROPS (PROP_LC+(PROP_LP*9)+(PROP_PB*45))
|
pascal@13691
|
25
|
pascal@13691
|
26 // static const Byte *Buffer;
|
pascal@13691
|
27 // static UInt32 bound, Code, Range;
|
pascal@13691
|
28
|
pascal@13691
|
29 /*
|
pascal@13691
|
30 * Buffer register DS:SI
|
pascal@13691
|
31 * all var based ws=ss:bp
|
pascal@13691
|
32 */
|
pascal@13691
|
33
|
pascal@13691
|
34 rep0 = -4 // long
|
pascal@13691
|
35 rep1 = rep0-4 // long
|
pascal@13691
|
36 rep2 = rep0-8 // long
|
pascal@13691
|
37 rep3 = rep0-12 // long
|
pascal@13691
|
38 state = -17 // byte, 0..11
|
pascal@13691
|
39 posState = state-1 // byte, 0..15
|
pascal@13691
|
40 posState2 = posState-1 // byte, 0..15
|
pascal@13691
|
41 scratched = rep0-16 // byte = 1
|
pascal@13691
|
42 Code = -24 // long
|
pascal@13691
|
43 outStream = -28 // long
|
pascal@13691
|
44 nowPos = outStream // long
|
pascal@13691
|
45 Range = Code-8 // long
|
pascal@13691
|
46 #define LOCALS 32
|
pascal@13691
|
47
|
pascal@13691
|
48 // int LzmaDecode(CLzmaDecoderState *vs,
|
pascal@13691
|
49 // const unsigned char *inStream,
|
pascal@13691
|
50 // unsigned char *outStream)
|
pascal@13691
|
51 // {
|
pascal@13691
|
52 // CProb *p = vs->Probs;
|
pascal@13691
|
53 // SizeT nowPos = 0;
|
pascal@13691
|
54 // #define posStateMask = (1 << (vs->Properties.pb)) - 1;
|
pascal@13691
|
55 // #define literalPosMask = (1 << (vs->Properties.lp)) - 1;
|
pascal@13691
|
56 // int lc = vs->Properties.lc, state = 0, len = 0;
|
pascal@13691
|
57 // UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
|
pascal@13691
|
58 //
|
pascal@13691
|
59 // {
|
pascal@13691
|
60 // UInt32 i, numProbs = Literal /*1846*/
|
pascal@13691
|
61 // + ((UInt32)LZMA_LIT_SIZE /*768*/ << (lc + vs->Properties.lp));
|
pascal@13691
|
62 // for (i = 0; i < numProbs; i++) p[i] = kBitModelTotal /*2048*/ >> 1;
|
pascal@13691
|
63
|
pascal@13691
|
64 #define WS (1846+(768<<(PROP_LC+PROP_LP)))
|
pascal@13691
|
65 #if (WS+WS+LOCALS) >= 65000
|
pascal@13691
|
66 /* MAX WS = (1846+(768<<(8+4))) > 3MB! */
|
pascal@13691
|
67 #error invalid (lc,lp,pb) : out of memory
|
pascal@13691
|
68 #endif
|
pascal@13691
|
69
|
pascal@13691
|
70 ws1 = WS
|
pascal@13691
|
71 ws2 = ws1*2
|
pascal@13691
|
72 ws = ws2+LOCALS+15
|
pascal@13691
|
73
|
pascal@13691
|
74 #ifndef FLAT16
|
pascal@13691
|
75 #define INC incl
|
pascal@13691
|
76 #else
|
pascal@13691
|
77 #define INC incw
|
pascal@13691
|
78 #endif
|
pascal@13691
|
79 #ifndef FLAT32
|
pascal@13691
|
80 #define AX %ax
|
pascal@13691
|
81 #define BX %bx
|
pascal@13691
|
82 #define CX %cx
|
pascal@13691
|
83 #define DX %dx
|
pascal@13691
|
84 #define SI %si
|
pascal@13691
|
85 #define DI %di
|
pascal@13691
|
86 #define BP %bp
|
pascal@13691
|
87 #define SP %sp
|
pascal@13691
|
88 #define CWD cwd
|
pascal@13691
|
89 #else
|
pascal@13691
|
90 #define AX %eax
|
pascal@13691
|
91 #define BX %ebx
|
pascal@13691
|
92 #define CX %ecx
|
pascal@13691
|
93 #define DX %edx
|
pascal@13691
|
94 #define SI %esi
|
pascal@13691
|
95 #define DI %edi
|
pascal@13691
|
96 #define BP %ebp
|
pascal@13691
|
97 #define SP %esp
|
pascal@13691
|
98 #define CWD cdq
|
pascal@13691
|
99 #endif
|
pascal@13691
|
100 /*
|
pascal@13691
|
101 * LzmaDecode:
|
pascal@13691
|
102 #ifndef FLAT32
|
pascal@13691
|
103 * input ds:si=inStream, es:di=outStream
|
pascal@13691
|
104 * output outStream[], ds:si, es:di
|
pascal@13691
|
105 .code 16
|
pascal@13691
|
106 #else
|
pascal@13691
|
107 * input esi=inStream, edi=outStream
|
pascal@13691
|
108 * output outStream[], esi, edi
|
pascal@13691
|
109 .code 32
|
pascal@13691
|
110 #endif
|
pascal@13691
|
111 */
|
pascal@13691
|
112
|
pascal@13691
|
113 mov $ws1, CX
|
pascal@13691
|
114 lzd1:
|
pascal@13691
|
115 pushw $2048/2
|
pascal@13691
|
116 loop lzd1
|
pascal@13691
|
117 mov SP, BP
|
pascal@13691
|
118 movb $((LOCALS+3)/4)*2, %cl
|
pascal@13691
|
119 initlocals:
|
pascal@13691
|
120 pushl $1
|
pascal@13691
|
121 loop initlocals
|
pascal@13691
|
122
|
pascal@13691
|
123 #if !defined(FLAT32) && !defined(FLAT16)
|
pascal@13691
|
124 movb $4, %cl
|
pascal@13691
|
125 movw %es, %bx
|
pascal@13691
|
126 shrw %cl, %bx
|
pascal@13691
|
127 movw %es, %dx
|
pascal@13691
|
128 shlw %cl, %dx
|
pascal@13691
|
129 addw %dx, %di
|
pascal@13691
|
130 movw %di, outStream(%bp)
|
pascal@13691
|
131 adcb %bh, outStream+2(%bp)
|
pascal@13691
|
132 incw %cx
|
pascal@13691
|
133 #else
|
pascal@13691
|
134 movb $5, %cl
|
pascal@13691
|
135 mov DI, outStream(BP)
|
pascal@13691
|
136 #endif
|
pascal@13691
|
137
|
pascal@13691
|
138 // Byte previousByte = 0;
|
pascal@13691
|
139 xor BX, BX
|
pascal@13691
|
140
|
pascal@13691
|
141 // #define RC_INIT(buffer)
|
pascal@13691
|
142 // Buffer = buffer; Code = 0; Range = 0xFFFFFFFF;
|
pascal@13691
|
143 // { int i; for(i=0; i<5; i++) { Code = (Code<<8) | RC_READ_BYTE; }}
|
pascal@13691
|
144 // }
|
pascal@13691
|
145 // RC_INIT(inStream);
|
pascal@13691
|
146
|
pascal@13691
|
147 add $13, SI // skip header
|
pascal@13691
|
148 setrep:
|
pascal@13691
|
149 call RC_LOAD_BYTE
|
pascal@13691
|
150 decb Range(BP)
|
pascal@13691
|
151 loop setrep
|
pascal@13691
|
152
|
pascal@13691
|
153 lzdmainlp:
|
pascal@13691
|
154 // while(1) {
|
pascal@13691
|
155 // CProb *prob;
|
pascal@13691
|
156 // int posState = (int)((nowPos) & posStateMask);
|
pascal@13691
|
157 //
|
pascal@13691
|
158 // prob = p + IsMatch /*0*/ + (state << kNumPosBitsMax /*4*/) + posState;
|
pascal@13691
|
159 // if (Bit0(prob)) { /* char */
|
pascal@13691
|
160
|
pascal@13691
|
161 xor DX, DX
|
pascal@13691
|
162 call Bit1state // Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
|
pascal@13691
|
163 mov $state, DI
|
pascal@13691
|
164 jc lzdstring
|
pascal@13691
|
165
|
pascal@13691
|
166 // prob = p + Literal /*1846*/ + (LZMA_LIT_SIZE /*768*/ *
|
pascal@13691
|
167 // ((((nowPos) & literalPosMask) << lc) + (previousByte >> (8 - lc))));
|
pascal@13691
|
168
|
pascal@13691
|
169 #if PROP_LC != 0
|
pascal@13691
|
170 shrb $8-PROP_LC, %bl
|
pascal@13691
|
171 #endif
|
pascal@13691
|
172
|
pascal@13691
|
173 #if PROP_LP != 0
|
pascal@13691
|
174 movb posState2(BP), %dl
|
pascal@13691
|
175 shl $PROP_LC, DX
|
pascal@13691
|
176 movb $0, %bh
|
pascal@13691
|
177 add BX, DX
|
pascal@13691
|
178 #endif
|
pascal@13691
|
179
|
pascal@13691
|
180 movb $3, %ah
|
pascal@13691
|
181 mul BX // dx = 3*bh
|
pascal@13691
|
182 add $1846, AX
|
pascal@13691
|
183
|
pascal@13691
|
184 // int symbol = 1;
|
pascal@13691
|
185
|
pascal@13691
|
186 CWD
|
pascal@13691
|
187 inc DX // symbol = 1
|
pascal@13691
|
188 xchg AX, CX // save prob
|
pascal@13691
|
189
|
pascal@13691
|
190 // if (state >= kNumLitStates /*7*/) { /* previous was string */
|
pascal@13691
|
191 // if (state < 4) state = 0;
|
pascal@13691
|
192
|
pascal@13691
|
193 lzd6z:
|
pascal@13691
|
194 subb $3, (BP, DI)
|
pascal@13691
|
195
|
pascal@13691
|
196 // if (state < 4) state = 0;
|
pascal@13691
|
197
|
pascal@13691
|
198 jnc lzd6
|
pascal@13691
|
199 movb %dh, (BP, DI) // %dh = 0
|
pascal@13691
|
200
|
pascal@13691
|
201 lzd6:
|
pascal@13691
|
202 // else if (state < 10) state -= 3;
|
pascal@13691
|
203
|
pascal@13691
|
204 cmpb $10-3, (BP, DI)
|
pascal@13691
|
205
|
pascal@13691
|
206 // else state -= 6;
|
pascal@13691
|
207
|
pascal@13691
|
208 jnb lzd6z
|
pascal@13691
|
209 cmpb $7-3-1, (BP, DI)
|
pascal@13691
|
210 jbe lzd3
|
pascal@13691
|
211
|
pascal@13691
|
212 // int matchByte = outStream[nowPos - rep0];
|
pascal@13691
|
213
|
pascal@13691
|
214 call DicoRep02ESDI // %bl = outStream[nowPos - rep0];
|
pascal@13691
|
215
|
pascal@13691
|
216 // do {
|
pascal@13691
|
217 // int bit;
|
pascal@13691
|
218 // CProb *probLit;
|
pascal@13691
|
219 // matchByte <<= 1; bit = (matchByte & 0x100);
|
pascal@13691
|
220
|
pascal@13691
|
221 movb $1, %bh
|
pascal@13691
|
222 lzd4:
|
pascal@13691
|
223 shlb $1, %bl // matchByte <<= 1
|
pascal@13691
|
224 sbb DI, DI // save bit=C
|
pascal@13691
|
225
|
pascal@13691
|
226 // probLit = prob + 0x100 + bit + symbol;
|
pascal@13691
|
227
|
pascal@13691
|
228 mov CX, AX // restore prob
|
pascal@13691
|
229 adcb %bh, %ah // + bit + 0x100
|
pascal@13691
|
230
|
pascal@13691
|
231 // RC_GET_BIT2(probLit, symbol, if (bit) break, if (!bit) break)
|
pascal@13691
|
232
|
pascal@13691
|
233 call Bit1axdx // C,%ax = Bit1(prob+%ax)
|
pascal@13691
|
234 rclb $1, %dl // symbol <<= 1; symbol |= C
|
pascal@13691
|
235 jc lzd5 // if symbol >= 0x100
|
pascal@13691
|
236 cmp DI, AX
|
pascal@13691
|
237 jz lzd4 // if bit == Bit1(prob+%ax)
|
pascal@13691
|
238
|
pascal@13691
|
239 // } while (symbol < 0x100);
|
pascal@13691
|
240 // }
|
pascal@13691
|
241 lzd3:
|
pascal@13691
|
242 // while (symbol < 0x100) {
|
pascal@13691
|
243 // CProb *probLit = prob + symbol;
|
pascal@13691
|
244 // RC_GET_BIT(probLit, symbol)
|
pascal@13691
|
245 // }
|
pascal@13691
|
246
|
pascal@13691
|
247 xor BX, BX
|
pascal@13691
|
248 jmp lzd4
|
pascal@13691
|
249 lzd5:
|
pascal@13691
|
250
|
pascal@13691
|
251 // outStream[nowPos++] = previousByte = (Byte)symbol;
|
pascal@13691
|
252
|
pascal@13691
|
253 xchg AX, DX
|
pascal@13691
|
254 call outchar // %bl = outStream[nowPos++] = %al;
|
pascal@13691
|
255 jmp lzdmainlp
|
pascal@13691
|
256
|
pascal@13691
|
257 // }
|
pascal@13691
|
258
|
pascal@13691
|
259 lzdstring:
|
pascal@13691
|
260 mov $1, CX
|
pascal@13691
|
261
|
pascal@13691
|
262 // else { /* string */
|
pascal@13691
|
263 // prob = p + IsRep /*192*/ + state;
|
pascal@13691
|
264
|
pascal@13691
|
265 movb $192, %dl
|
pascal@13691
|
266 addb (BP, DI), %dl
|
pascal@13691
|
267 mov $rep0, DI
|
pascal@13691
|
268
|
pascal@13691
|
269 // if (Bit0(prob)) {
|
pascal@13691
|
270
|
pascal@13691
|
271 call Bit1dx // Bit1(prob)
|
pascal@13691
|
272 jc lzd8
|
pascal@13691
|
273
|
pascal@13691
|
274 // rep3 = rep2; rep2 = rep1; rep1 = rep0;
|
pascal@13691
|
275 // state = (state < kNumLitStates /*7*/) ? 0 : 3;
|
pascal@13691
|
276
|
pascal@13691
|
277 stc
|
pascal@13691
|
278
|
pascal@13691
|
279 // prob = p + LenCoder /*818*/;
|
pascal@13691
|
280
|
pascal@13691
|
281 mov $818, DX
|
pascal@13691
|
282
|
pascal@13691
|
283 // }
|
pascal@13691
|
284
|
pascal@13691
|
285 jmp lzd11a
|
pascal@13691
|
286
|
pascal@13691
|
287 // else {
|
pascal@13691
|
288 lzd8:
|
pascal@13691
|
289 // prob += kNumStates /*12*/;
|
pascal@13691
|
290 // if (Bit0(prob)) {
|
pascal@13691
|
291 call Bit1dx12 // prob += 12; Bit1(prob)
|
pascal@13691
|
292 jc lzd11
|
pascal@13691
|
293 // prob = p + IsRep0Long /*240*/ + (state << kNumPosBitsMax /*4*/)
|
pascal@13691
|
294 // + posState;
|
pascal@13691
|
295 movb $240, %dl // dh=0
|
pascal@13691
|
296
|
pascal@13691
|
297 // if (Bit0(prob)) {
|
pascal@13691
|
298
|
pascal@13691
|
299 call Bit1state // Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
|
pascal@13691
|
300 jc lzd12
|
pascal@13691
|
301
|
pascal@13691
|
302 // // if (nowPos == 0) return LZMA_RESULT_DATA_ERROR;
|
pascal@13691
|
303 // state = (state < kNumLitStates /*7*/) ? 9 : 11;
|
pascal@13691
|
304
|
pascal@13691
|
305 movb $9, %dl
|
pascal@13691
|
306
|
pascal@13691
|
307 // len++; goto string;
|
pascal@13691
|
308 jmp lzd13string // ax = 0
|
pascal@13691
|
309 // }
|
pascal@13691
|
310 // }
|
pascal@13691
|
311 // else {
|
pascal@13691
|
312 lzd11:
|
pascal@13691
|
313 // UInt32 distance = rep1;
|
pascal@13691
|
314 // prob += kNumStates /*12*/;
|
pascal@13691
|
315 // if (!Bit0(prob)) {
|
pascal@13691
|
316
|
pascal@13691
|
317 call Bit1dx12 // prob += 12; Bit1(prob)
|
pascal@13691
|
318 jnc lzd11z
|
pascal@13691
|
319
|
pascal@13691
|
320 // prob += kNumStates /*12*/;
|
pascal@13691
|
321 // if (Bit0(prob)) distance = rep2;
|
pascal@13691
|
322
|
pascal@13691
|
323 call Bit1dx12 // prob += 12; Bit1(prob)
|
pascal@13691
|
324 lzd11a:
|
pascal@13691
|
325 adcb %cl, %cl
|
pascal@13691
|
326
|
pascal@13691
|
327 // else { distance = rep3; rep3 = rep2; }
|
pascal@13691
|
328 // rep2 = rep1;
|
pascal@13691
|
329 // }
|
pascal@13691
|
330 // rep1 = rep0; rep0 = distance;
|
pascal@13691
|
331
|
pascal@13691
|
332 lzd11z:
|
pascal@13691
|
333 shl $2, CX // 8->32 bits
|
pascal@13691
|
334 sub CX, DI // &rep[cx]
|
pascal@13691
|
335 movl (BP, DI), %eax
|
pascal@13691
|
336 rotreplp:
|
pascal@13691
|
337 movb 4(BP, DI), %bl
|
pascal@13691
|
338 movb %bl, (BP, DI)
|
pascal@13691
|
339 inc DI
|
pascal@13691
|
340 loop rotreplp
|
pascal@13691
|
341 testb %dh, %dh
|
pascal@13691
|
342 jnz lzd10
|
pascal@13691
|
343 movl %eax, (BP, DI)
|
pascal@13691
|
344
|
pascal@13691
|
345 // }
|
pascal@13691
|
346 lzd12:
|
pascal@13691
|
347 // state = (state < kNumLitStates /*7*/) ? 8 : 11;
|
pascal@13691
|
348
|
pascal@13691
|
349 movb $0x08, %cl
|
pascal@13691
|
350
|
pascal@13691
|
351 // prob = p + RepLenCoder /*1332*/;
|
pascal@13691
|
352
|
pascal@13691
|
353 mov $1332, DX
|
pascal@13691
|
354
|
pascal@13691
|
355 // }
|
pascal@13691
|
356 lzd10:
|
pascal@13691
|
357 push CX // CX = 0
|
pascal@13691
|
358
|
pascal@13691
|
359 // { /* get len */
|
pascal@13691
|
360 // int numBits, offset;
|
pascal@13691
|
361 // CProb *probLen = prob + LenChoice /*0*/;
|
pascal@13691
|
362 // numBits = kLenNumLowBits /*3*/;
|
pascal@13691
|
363
|
pascal@13691
|
364 movb $8, %cl // numBits : 3,3,8
|
pascal@13691
|
365
|
pascal@13691
|
366 // if (Bit0(probLen)) {
|
pascal@13691
|
367
|
pascal@13691
|
368 call Bit1dx // Bit1(prob)
|
pascal@13691
|
369 xchg AX, BX
|
pascal@13691
|
370 inc DX
|
pascal@13691
|
371 jnc lzd15 // bx=0
|
pascal@13691
|
372
|
pascal@13691
|
373 // probLen = prob + LenLow/*2*/ + (posState << kLenNumLowBits/*3*/);
|
pascal@13691
|
374 // offset = 0;
|
pascal@13691
|
375 // }
|
pascal@13691
|
376 // else {
|
pascal@13691
|
377 // probLen = prob + LenChoice2 /*1*/;
|
pascal@13691
|
378
|
pascal@13691
|
379 call Bit1dx // Bit1(prob)
|
pascal@13691
|
380 add AX, BX
|
pascal@13691
|
381
|
pascal@13691
|
382 #if PROP_PB != 0
|
pascal@13691
|
383 inc AX // ah=0
|
pascal@13691
|
384 #endif
|
pascal@13691
|
385 jc lzd16 // %ax=0, %bx=-2
|
pascal@13691
|
386 lzd15:
|
pascal@13691
|
387 #if PROP_PB != 0
|
pascal@13691
|
388 movb $8, %al
|
pascal@13691
|
389 mulb posState(BP)
|
pascal@13691
|
390 #endif
|
pascal@13691
|
391
|
pascal@13691
|
392 // if (Bit0(probLen)) {
|
pascal@13691
|
393 // probLen = prob + LenMid/*130*/ + (posState << kLenNumMidBits/*3*/);
|
pascal@13691
|
394
|
pascal@13691
|
395 movb $3, %cl // numBits : 3,3,8
|
pascal@13691
|
396 lzd16:
|
pascal@13691
|
397 #if PROP_PB != 0
|
pascal@13691
|
398 add $2-128-1, AX // probLen : 2,130,258
|
pascal@13691
|
399 #else
|
pascal@13691
|
400 mov $2-128-1, AX // probLen : 2,130,258
|
pascal@13691
|
401 #endif
|
pascal@13691
|
402 add DX, AX
|
pascal@13691
|
403 mov $-8+1, DX // offset : 0,8,16
|
pascal@13691
|
404 lzdargslp:
|
pascal@13691
|
405 add $8, DX
|
pascal@13691
|
406 add $128, AX
|
pascal@13691
|
407 inc BX
|
pascal@13691
|
408 jle lzdargslp // leave with bx=1
|
pascal@13691
|
409
|
pascal@13691
|
410 // offset = kLenNumLowSymbols /*8*/;
|
pascal@13691
|
411 // //numBits = kLenNumMidBits /*3*/;
|
pascal@13691
|
412 // }
|
pascal@13691
|
413 // else {
|
pascal@13691
|
414 // probLen = prob + LenHigh /*258*/;
|
pascal@13691
|
415 // offset = kLenNumLowSymbols /*8*/ + kLenNumMidSymbols /*8*/;
|
pascal@13691
|
416 // numBits = kLenNumHighBits /*8*/;
|
pascal@13691
|
417 // }
|
pascal@13691
|
418 // }
|
pascal@13691
|
419 // RangeDecoderBitTreeDecode(probLen, numBits, len); len += offset;
|
pascal@13691
|
420
|
pascal@13691
|
421 push DX
|
pascal@13691
|
422 call RangeDecoder // %ax=probs, %cx=numLevels, %ax=res
|
pascal@13691
|
423 pop DX
|
pascal@13691
|
424 add DX, AX // offset
|
pascal@13691
|
425 pop DX // 0
|
pascal@13691
|
426 lzd13string:
|
pascal@13691
|
427 push AX
|
pascal@13691
|
428
|
pascal@13691
|
429 // state = (state < kNumLitStates /*7*/) ? dl : dl|3;
|
pascal@13691
|
430
|
pascal@13691
|
431 movb $7, %cl
|
pascal@13691
|
432 cmpb %cl, state(BP)
|
pascal@13691
|
433 jb new_state
|
pascal@13691
|
434 orb $3, %dl
|
pascal@13691
|
435 new_state:
|
pascal@13691
|
436 movb %dl, state(BP)
|
pascal@13691
|
437
|
pascal@13691
|
438 // } /* get len */
|
pascal@13691
|
439 // if (state < 4) {
|
pascal@13691
|
440
|
pascal@13691
|
441 cmpb $4-1, %dl
|
pascal@13691
|
442 ja lzd19
|
pascal@13691
|
443
|
pascal@13691
|
444 // int posSlot;
|
pascal@13691
|
445 // state += kNumLitStates /*7*/;
|
pascal@13691
|
446
|
pascal@13691
|
447 addb %cl, state(BP)
|
pascal@13691
|
448
|
pascal@13691
|
449 // prob = p + PosSlot /*432*/ + (((len < kNumLenToPosStates /*4*/) ?
|
pascal@13691
|
450 // len : kNumLenToPosStates - 1) << kNumPosSlotBits /*6*/);
|
pascal@13691
|
451
|
pascal@13691
|
452 cmp $4+1, AX
|
pascal@13691
|
453 jb lzd21
|
pascal@13691
|
454 mov $3+1, AX
|
pascal@13691
|
455
|
pascal@13691
|
456 lzd21:
|
pascal@13691
|
457
|
pascal@13691
|
458 dec CX // cx = 6
|
pascal@13691
|
459 shl %cl, AX
|
pascal@13691
|
460 add $432-64, AX
|
pascal@13691
|
461
|
pascal@13691
|
462 // RangeDecoderBitTreeDecode(prob, kNumPosSlotBits /*6*/, posSlot);
|
pascal@13691
|
463
|
pascal@13691
|
464 call RangeDecoder // %ax=probs, %cx=numLevels, %ax=res
|
pascal@13691
|
465
|
pascal@13691
|
466 // if (posSlot >= kStartPosModelIndex /*4*/) {
|
pascal@13691
|
467 // int numDirectBits = ((posSlot >> 1) - 1);
|
pascal@13691
|
468
|
pascal@13691
|
469 #ifndef FLAT32
|
pascal@13691
|
470 movw %cx, 2(%bp, %di) // %cx = 0
|
pascal@13691
|
471 #endif
|
pascal@13691
|
472 mov AX, (BP, DI)
|
pascal@13691
|
473 mov AX, CX
|
pascal@13691
|
474 shrw $1, CX
|
pascal@13691
|
475 dec CX
|
pascal@13691
|
476 cmpb $4, %al
|
pascal@13691
|
477 jb lzd22
|
pascal@13691
|
478
|
pascal@13691
|
479 // rep0 = (2 | ((UInt32)posSlot & 1));
|
pascal@13691
|
480
|
pascal@13691
|
481 andb %bl, (BP, DI) // %bx=1
|
pascal@13691
|
482 orb $2, (BP, DI)
|
pascal@13691
|
483
|
pascal@13691
|
484 // if (posSlot < kEndPosModelIndex /*14*/) {
|
pascal@13691
|
485
|
pascal@13691
|
486 cmpb $14, %al
|
pascal@13691
|
487 jnb lzd23
|
pascal@13691
|
488
|
pascal@13691
|
489 // rep0 <<= numDirectBits;
|
pascal@13691
|
490
|
pascal@13691
|
491 neg AX
|
pascal@13691
|
492 shll %cl, (BP, DI)
|
pascal@13691
|
493 add (BP, DI), AX
|
pascal@13691
|
494
|
pascal@13691
|
495 // prob = p + SpecPos /*688*/ + rep0 - posSlot - 1;
|
pascal@13691
|
496
|
pascal@13691
|
497 add $687, AX
|
pascal@13691
|
498 jmp lzd24
|
pascal@13691
|
499
|
pascal@13691
|
500 // }
|
pascal@13691
|
501 // else {
|
pascal@13691
|
502 lzd23:
|
pascal@13691
|
503 // numDirectBits -= kNumAlignBits /*4*/;
|
pascal@13691
|
504 // do {
|
pascal@13691
|
505 // RC_NORMALIZE; Range >>= 1; rep0 <<= 1;
|
pascal@13691
|
506 // if (Code >= Range) { Code -= Range; rep0 |= 1; }
|
pascal@13691
|
507
|
pascal@13691
|
508 lzd23z:
|
pascal@13691
|
509 call RC_NORMALIZE
|
pascal@13691
|
510 shrl $1, Range(BP)
|
pascal@13691
|
511 movl Range(BP), %eax
|
pascal@13691
|
512 cmpl Code(BP), %eax
|
pascal@13691
|
513 ja lzd25
|
pascal@13691
|
514 subl %eax, Code(BP)
|
pascal@13691
|
515 stc
|
pascal@13691
|
516 lzd25:
|
pascal@13691
|
517 rcll $1, (BP, DI)
|
pascal@13691
|
518
|
pascal@13691
|
519 // } while (--numDirectBits != 0);
|
pascal@13691
|
520
|
pascal@13691
|
521 cmpb $4+1, %cl
|
pascal@13691
|
522 loopne lzd23z
|
pascal@13691
|
523
|
pascal@13691
|
524 // prob = p + Align /* 802 */; numDirectBits = kNumAlignBits /*4*/;
|
pascal@13691
|
525 // rep0 <<= numDirectBits;
|
pascal@13691
|
526
|
pascal@13691
|
527 shll %cl, (BP, DI)
|
pascal@13691
|
528 mov $802, AX
|
pascal@13691
|
529 // }
|
pascal@13691
|
530
|
pascal@13691
|
531 lzd24:
|
pascal@13691
|
532 call RangeDecoder // %ax=probs, %cx=numLevels, %ax=res
|
pascal@13691
|
533
|
pascal@13691
|
534 // {
|
pascal@13691
|
535 // int i = 1, mi = 1;
|
pascal@13691
|
536 // do {
|
pascal@13691
|
537 // CProb *prob3 = prob + mi;
|
pascal@13691
|
538 // RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
|
pascal@13691
|
539
|
pascal@13691
|
540 orb %dh, (BP, DI) // update rep0 with DirectBits
|
pascal@13691
|
541
|
pascal@13691
|
542 // i <<= 1;
|
pascal@13691
|
543 // } while(--numDirectBits != 0);
|
pascal@13691
|
544 // }
|
pascal@13691
|
545 // } else rep0 = posSlot;
|
pascal@13691
|
546 lzd22:
|
pascal@13691
|
547 // if (++rep0 == (UInt32)(0)) break; /* EOF */
|
pascal@13691
|
548
|
pascal@13691
|
549 incl (BP, DI)
|
pascal@13691
|
550
|
pascal@13691
|
551 lzd19:
|
pascal@13691
|
552 pop CX
|
pascal@13691
|
553 jz lzdone
|
pascal@13691
|
554
|
pascal@13691
|
555 // }
|
pascal@13691
|
556 // len += kMatchMinLen;/*2*/
|
pascal@13691
|
557
|
pascal@13691
|
558 inc CX
|
pascal@13691
|
559
|
pascal@13691
|
560 // string: // if (rep0 > nowPos) return LZMA_RESULT_DATA_ERROR;
|
pascal@13691
|
561 // do {
|
pascal@13691
|
562 lzd13z:
|
pascal@13691
|
563 // previousByte = outStream[nowPos - rep0];
|
pascal@13691
|
564 // outStream[nowPos++] = previousByte;
|
pascal@13691
|
565
|
pascal@13691
|
566 call outcharDico // %bl = outStream[nowPos++] = outStream[nowPos - rep0]
|
pascal@13691
|
567
|
pascal@13691
|
568 // } while(--len != 0);
|
pascal@13691
|
569
|
pascal@13691
|
570 loop lzd13z
|
pascal@13691
|
571
|
pascal@13691
|
572 // } /* char/string */
|
pascal@13691
|
573 // }
|
pascal@13691
|
574
|
pascal@13691
|
575 jmp lzdmainlp
|
pascal@13691
|
576
|
pascal@13691
|
577 lzdone:
|
pascal@13691
|
578 // //RC_NORMALIZE;
|
pascal@13691
|
579 // //*inSizeProcessed = (SizeT)(Buffer - inStream); *outSizeProcessed = nowPos;
|
pascal@13691
|
580 // return LZMA_RESULT_OK;
|
pascal@13691
|
581 call Dico2ESDI // set es & di (rep0 = 0)
|
pascal@13691
|
582 lea ws2(BP), SP // dealloc
|
pascal@13691
|
583 ret
|
pascal@13691
|
584 // }
|
pascal@13691
|
585
|
pascal@13691
|
586 // al = outStream[nowPos - rep0];
|
pascal@13691
|
587
|
pascal@13691
|
588 /*
|
pascal@13691
|
589 * output es:di, al
|
pascal@13691
|
590 * scratch bh, cl, flags
|
pascal@13691
|
591 */
|
pascal@13691
|
592
|
pascal@13691
|
593 DicoRep02ESDI:
|
pascal@13691
|
594 stc
|
pascal@13691
|
595
|
pascal@13691
|
596 // bl = outStream[nowPos];
|
pascal@13691
|
597
|
pascal@13691
|
598 /*
|
pascal@13691
|
599 * output es:di, bl
|
pascal@13691
|
600 * scratch bh, cl, flags
|
pascal@13691
|
601 */
|
pascal@13691
|
602
|
pascal@13691
|
603 Dico2ESDI:
|
pascal@13691
|
604 #if !defined(FLAT32) && !defined(FLAT16)
|
pascal@13691
|
605 movl nowPos(%bp), %ebx
|
pascal@13691
|
606 jnc Dico2ESDIz
|
pascal@13691
|
607 subl rep0(%bp), %ebx
|
pascal@13691
|
608 Dico2ESDIz:
|
pascal@13691
|
609 movw %bx, %di
|
pascal@13691
|
610 xorw %bx, %bx
|
pascal@13691
|
611 shrl $4, %ebx
|
pascal@13691
|
612 movw %bx, %es
|
pascal@13691
|
613 movb %es:(%di), %bl
|
pascal@13691
|
614 #else
|
pascal@13691
|
615 mov nowPos(BP), DI
|
pascal@13691
|
616 jnc Dico2ESDIz
|
pascal@13691
|
617 sub rep0(BP), DI
|
pascal@13691
|
618 Dico2ESDIz:
|
pascal@13691
|
619 movb (DI), %bl
|
pascal@13691
|
620 #endif
|
pascal@13691
|
621 ret
|
pascal@13691
|
622
|
pascal@13691
|
623 outcharDico:
|
pascal@13691
|
624
|
pascal@13691
|
625 // bl = outStream[nowPos++] = outStream[nowPos - rep0]
|
pascal@13691
|
626
|
pascal@13691
|
627 /*
|
pascal@13691
|
628 * output es:di, bl
|
pascal@13691
|
629 * update nowPos
|
pascal@13691
|
630 * scratch ax, dx, bh, cl, flags
|
pascal@13691
|
631 */
|
pascal@13691
|
632
|
pascal@13691
|
633 call DicoRep02ESDI // %bl = outStream[nowPos - rep0]
|
pascal@13691
|
634 xchg AX, BX
|
pascal@13691
|
635 outchar:
|
pascal@13691
|
636
|
pascal@13691
|
637 // bl = outStream[nowPos++] = previousByte = al;
|
pascal@13691
|
638
|
pascal@13691
|
639 /*
|
pascal@13691
|
640 * output bl
|
pascal@13691
|
641 * update nowPos
|
pascal@13691
|
642 * scratch ax, dx, bh, di, cl, flags
|
pascal@13691
|
643 */
|
pascal@13691
|
644
|
pascal@13691
|
645 clc
|
pascal@13691
|
646 call Dico2ESDI
|
pascal@13691
|
647 stosb
|
pascal@13691
|
648 xchg AX, BX // previous byte
|
pascal@13691
|
649
|
pascal@13691
|
650 // int posState = (int)((nowPos) & posStateMask);
|
pascal@13691
|
651
|
pascal@13691
|
652 #if PROP_PB != 0 && PROP_LP != 0
|
pascal@13691
|
653 addw $0x0101, posState2(BP)
|
pascal@13691
|
654 andb $(((1 << PROP_PB) -1)<<8)+((1 << PROP_LP) -1), posState2(BP)
|
pascal@13691
|
655 #else
|
pascal@13691
|
656 # if PROP_PB != 0
|
pascal@13691
|
657 incb posState(BP)
|
pascal@13691
|
658 andb $((1 << PROP_PB) -1), posState(BP)
|
pascal@13691
|
659 # endif
|
pascal@13691
|
660 # if PROP_LP != 0
|
pascal@13691
|
661 incb posState2(BP)
|
pascal@13691
|
662 andb $((1 << PROP_LP) -1), posState2(BP)
|
pascal@13691
|
663 # endif
|
pascal@13691
|
664 #endif
|
pascal@13691
|
665 INC nowPos(BP)
|
pascal@13691
|
666 ret
|
pascal@13691
|
667
|
pascal@13691
|
668 //
|
pascal@13691
|
669 // #define RC_NORMALIZE if (Range < kTopValue)
|
pascal@13691
|
670 // { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
|
pascal@13691
|
671
|
pascal@13691
|
672 /*
|
pascal@13691
|
673 * update Range, Code, ds:si
|
pascal@13691
|
674 * scratch flags
|
pascal@13691
|
675 */
|
pascal@13691
|
676
|
pascal@13691
|
677 RC_NORMALIZE:
|
pascal@13691
|
678 cmpb $0, Range+3(BP)
|
pascal@13691
|
679 jne RC_NORMALIZE_1
|
pascal@13691
|
680 RC_LOAD_BYTE:
|
pascal@13691
|
681 push AX
|
pascal@13691
|
682 shll $8, Range(BP)
|
pascal@13691
|
683 shll $8, Code(BP)
|
pascal@13691
|
684 #if !defined(FLAT32) && !defined(FLAT16)
|
pascal@13691
|
685 testw %si, %si
|
pascal@13691
|
686 jns RC_READ_BYTE
|
pascal@13691
|
687 movw %ds, %ax
|
pascal@13691
|
688 incw %ax
|
pascal@13691
|
689 movw %ax, %ds
|
pascal@13691
|
690 addw $-16, %si
|
pascal@13691
|
691 RC_READ_BYTE:
|
pascal@13691
|
692 #endif
|
pascal@13691
|
693 lodsb
|
pascal@13691
|
694 movb %al, Code(BP)
|
pascal@13691
|
695 pop AX
|
pascal@13691
|
696 RC_NORMALIZE_1:
|
pascal@13691
|
697 ret
|
pascal@13691
|
698
|
pascal@13691
|
699 // Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
|
pascal@13691
|
700
|
pascal@13691
|
701 Bit1state:
|
pascal@13691
|
702 movb $16, %al
|
pascal@13691
|
703 mulb state(BP)
|
pascal@13691
|
704 # if PROP_PB != 0
|
pascal@13691
|
705 addb posState(BP), %al
|
pascal@13691
|
706 # endif
|
pascal@13691
|
707 Bit1axdx:
|
pascal@13691
|
708 add DX, AX
|
pascal@13691
|
709 jmp Bit1
|
pascal@13691
|
710
|
pascal@13691
|
711 // prob += 12; Bit1(prob)
|
pascal@13691
|
712
|
pascal@13691
|
713 Bit1dx12:
|
pascal@13691
|
714 add $12, DX
|
pascal@13691
|
715 Bit1dx:
|
pascal@13691
|
716 mov DX, AX
|
pascal@13691
|
717
|
pascal@13691
|
718 // static int Bit1(CProb *p)
|
pascal@13691
|
719
|
pascal@13691
|
720 Bit1:
|
pascal@13691
|
721 /*
|
pascal@13691
|
722 * input ax=p
|
pascal@13691
|
723 * output C, ax
|
pascal@13691
|
724 * update bound, Range, Code, ds:si
|
pascal@13691
|
725 * scratch flags
|
pascal@13691
|
726 */
|
pascal@13691
|
727
|
pascal@13691
|
728 // {
|
pascal@13691
|
729 // RC_NORMALIZE;
|
pascal@13691
|
730
|
pascal@13691
|
731 call RC_NORMALIZE // kill %ax, update %si
|
pascal@13691
|
732
|
pascal@13691
|
733 pushal
|
pascal@13691
|
734
|
pascal@13691
|
735 xchg AX, DI
|
pascal@13691
|
736 add DI, DI // short *
|
pascal@13691
|
737
|
pascal@13691
|
738
|
pascal@13691
|
739 // bound = (Range>>kNumBitModelTotalBits /*11*/) * *(p);
|
pascal@13691
|
740
|
pascal@13691
|
741 movl Range(BP), %eax
|
pascal@13691
|
742 shrl $11, %eax
|
pascal@13691
|
743 movzwl (BP, DI), %edx
|
pascal@13691
|
744 mull %edx
|
pascal@13691
|
745
|
pascal@13691
|
746 // if (Code < bound) {
|
pascal@13691
|
747
|
pascal@13691
|
748 cmpl Code(BP), %eax
|
pascal@13691
|
749 jbe Bit1_1
|
pascal@13691
|
750
|
pascal@13691
|
751 // Range = bound;
|
pascal@13691
|
752
|
pascal@13691
|
753 movl %eax, Range(BP)
|
pascal@13691
|
754
|
pascal@13691
|
755 // *(p) += (kBitModelTotal /*2048*/ - *(p)) >> kNumMoveBits /*5*/;
|
pascal@13691
|
756
|
pascal@13691
|
757 movw $2048, %ax
|
pascal@13691
|
758
|
pascal@13691
|
759 // return 0;
|
pascal@13691
|
760
|
pascal@13691
|
761 jmp Bit1_2
|
pascal@13691
|
762
|
pascal@13691
|
763 // }
|
pascal@13691
|
764 // else {
|
pascal@13691
|
765
|
pascal@13691
|
766 Bit1_1:
|
pascal@13691
|
767
|
pascal@13691
|
768 // Range -= bound; Code -= bound;
|
pascal@13691
|
769
|
pascal@13691
|
770 subl %eax, Range(BP)
|
pascal@13691
|
771 subl %eax, Code(BP)
|
pascal@13691
|
772
|
pascal@13691
|
773 // *(p) -= (*(p)) >> kNumMoveBits /*5*/;
|
pascal@13691
|
774
|
pascal@13691
|
775 movw $31, %ax
|
pascal@13691
|
776
|
pascal@13691
|
777 // return 1;
|
pascal@13691
|
778
|
pascal@13691
|
779 stc
|
pascal@13691
|
780 Bit1_2:
|
pascal@13691
|
781 pushf
|
pascal@13691
|
782 subw (BP, DI), %ax
|
pascal@13691
|
783 sarw $5, %ax
|
pascal@13691
|
784 addw %ax, (BP, DI)
|
pascal@13691
|
785 popf
|
pascal@13691
|
786 popal
|
pascal@13691
|
787 sbb AX, AX
|
pascal@13691
|
788
|
pascal@13691
|
789 // }
|
pascal@13691
|
790 // }
|
pascal@13691
|
791
|
pascal@13691
|
792 ret
|
pascal@13691
|
793
|
pascal@13691
|
794 RangeDecoder:
|
pascal@13691
|
795
|
pascal@13691
|
796 /*
|
pascal@13691
|
797 * input ax=probs cx=numLevels (< 8) bx=1
|
pascal@13691
|
798 * output ax=res (backward), dh (forward)
|
pascal@13691
|
799 * update bound, Range, Code, ds:si
|
pascal@13691
|
800 * scratch flags, cx=0, dl
|
pascal@13691
|
801 */
|
pascal@13691
|
802
|
pascal@13691
|
803 push BX
|
pascal@13691
|
804
|
pascal@13691
|
805 // { int i = numLevels; res = 1;
|
pascal@13691
|
806 mov BX, DX // res = 1
|
pascal@13691
|
807
|
pascal@13691
|
808 // do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0);
|
pascal@13691
|
809
|
pascal@13691
|
810 RangeDecoder_1:
|
pascal@13691
|
811 push AX
|
pascal@13691
|
812 call Bit1axdx // C,%ax = Bit1(prob+%ax)
|
pascal@13691
|
813 rclb $1, %dl // res <<= 1; res |= C
|
pascal@13691
|
814 andb %bl, %al // current bit
|
pascal@13691
|
815 orb %al, %bh // store in bh
|
pascal@13691
|
816 shlb $1, %bl // update max
|
pascal@13691
|
817 pop AX
|
pascal@13691
|
818 loop RangeDecoder_1
|
pascal@13691
|
819
|
pascal@13691
|
820 // res -= (1 << numLevels); }
|
pascal@13691
|
821
|
pascal@13691
|
822 xchg AX, BX // move bh to dh
|
pascal@13691
|
823 xchg AX, DX // and dl to al
|
pascal@13691
|
824 sub %dl, %al // sub max
|
pascal@13691
|
825 pop BX
|
pascal@13691
|
826 ret
|