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