wok-tiny view memtest/stuff/unlzma.S @ rev 170

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