wok-tiny view plop/stuff/unlzma.S @ rev 169

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