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

memtest: 386 support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Apr 30 16:35:54 2021 +0000 (2021-04-30)
parents
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_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 #endif
200 #if PROP_LP != 0
201 movb posState2(BP), %dl
202 # ifdef ONLY8086
203 movb $PROP_LC, %cl
204 shl %cl, DX
205 # else
206 shl $PROP_LC, DX
207 # endif
208 movb $0, %bh
209 add BX, DX
210 #endif
212 movb $3, %ah
213 mul BX // dx = 3*bh
214 add $1846, AX
216 // int symbol = 1;
218 CWD
219 inc DX // symbol = 1
220 xchg AX, CX // save prob
222 // if (state >= kNumLitStates /*7*/) { /* previous was string */
223 // if (state < 4) state = 0;
225 lzd6z:
226 subb $3, (BP, DI)
228 // if (state < 4) state = 0;
230 jnc lzd6
231 movb %dh, (BP, DI) // %dh = 0
233 lzd6:
234 // else if (state < 10) state -= 3;
236 cmpb $10-3, (BP, DI)
238 // else state -= 6;
240 jnb lzd6z
241 cmpb $7-3-1, (BP, DI)
242 jbe lzd3
244 // int matchByte = outStream[nowPos - rep0];
246 call DicoRep02ESDI // %bl = outStream[nowPos - rep0];
248 // do {
249 // int bit;
250 // CProb *probLit;
251 // matchByte <<= 1; bit = (matchByte & 0x100);
253 movb $1, %bh
254 lzd4:
255 shlb $1, %bl // matchByte <<= 1
256 sbb DI, DI // save bit=C
258 // probLit = prob + 0x100 + bit + symbol;
260 mov CX, AX // restore prob
261 adcb %bh, %ah // + bit + 0x100
263 // RC_GET_BIT2(probLit, symbol, if (bit) break, if (!bit) break)
265 call Bit1axdx // C,%ax = Bit1(prob+%ax)
266 rclb $1, %dl // symbol <<= 1; symbol |= C
267 jc lzd5 // if symbol >= 0x100
268 cmp DI, AX
269 jz lzd4 // if bit == Bit1(prob+%ax)
271 // } while (symbol < 0x100);
272 // }
273 lzd3:
274 // while (symbol < 0x100) {
275 // CProb *probLit = prob + symbol;
276 // RC_GET_BIT(probLit, symbol)
277 // }
279 xor BX, BX
280 jmp lzd4
281 lzd5:
283 // outStream[nowPos++] = previousByte = (Byte)symbol;
285 xchg AX, DX
286 call outchar // %bl = outStream[nowPos++] = %al;
287 jmp lzdmainlp
289 // }
291 lzdstring:
292 mov $1, CX
294 // else { /* string */
295 // prob = p + IsRep /*192*/ + state;
297 movb $192, %dl
298 addb (BP, DI), %dl
299 mov $rep0, DI
301 // if (Bit0(prob)) {
303 call Bit1dx // Bit1(prob)
304 jc lzd8
306 // rep3 = rep2; rep2 = rep1; rep1 = rep0;
307 // state = (state < kNumLitStates /*7*/) ? 0 : 3;
309 stc
311 // prob = p + LenCoder /*818*/;
313 mov $818, DX
315 // }
317 jmp lzd11a
319 // else {
320 lzd8:
321 // prob += kNumStates /*12*/;
322 // if (Bit0(prob)) {
323 call Bit1dx12 // prob += 12; Bit1(prob)
324 jc lzd11
325 // prob = p + IsRep0Long /*240*/ + (state << kNumPosBitsMax /*4*/)
326 // + posState;
327 movb $240, %dl // dh=0
329 // if (Bit0(prob)) {
331 call Bit1state // Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
332 jc lzd12
334 // // if (nowPos == 0) return LZMA_RESULT_DATA_ERROR;
335 // state = (state < kNumLitStates /*7*/) ? 9 : 11;
337 movb $9, %dl
339 // len++; goto string;
340 jmp lzd13string // ax = 0
341 // }
342 // }
343 // else {
344 lzd11:
345 // UInt32 distance = rep1;
346 // prob += kNumStates /*12*/;
347 // if (!Bit0(prob)) {
349 call Bit1dx12 // prob += 12; Bit1(prob)
350 jnc lzd11z
352 // prob += kNumStates /*12*/;
353 // if (Bit0(prob)) distance = rep2;
355 call Bit1dx12 // prob += 12; Bit1(prob)
356 lzd11a:
357 adcb %cl, %cl
359 // else { distance = rep3; rep3 = rep2; }
360 // rep2 = rep1;
361 // }
362 // rep1 = rep0; rep0 = distance;
364 lzd11z:
365 # ifdef ONLY8086
366 shl $1, CX
367 shl $1, CX // 8->32 bits
368 sub CX, DI // &rep[cx]
369 movw (BP, DI), %ax
370 pushw 2(BP, DI)
371 rotreplp:
372 movb 4(BP, DI), %bl
373 movb %bl, (BP, DI)
374 inc DI
375 loop rotreplp
376 popw %bx
377 testb %dh, %dh
378 jnz lzd10
379 movw %ax, (BP, DI)
380 movw %bx, 2(BP, DI)
381 # else
382 shl $2, CX // 8->32 bits
383 sub CX, DI // &rep[cx]
384 movl (BP, DI), %eax
385 rotreplp:
386 movb 4(BP, DI), %bl
387 movb %bl, (BP, DI)
388 inc DI
389 loop rotreplp
390 testb %dh, %dh
391 jnz lzd10
392 movl %eax, (BP, DI)
393 # endif
395 // }
396 lzd12:
397 // state = (state < kNumLitStates /*7*/) ? 8 : 11;
399 movb $0x08, %cl
401 // prob = p + RepLenCoder /*1332*/;
403 mov $1332, DX
405 // }
406 lzd10:
407 push CX // CX = 0
409 // { /* get len */
410 // int numBits, offset;
411 // CProb *probLen = prob + LenChoice /*0*/;
412 // numBits = kLenNumLowBits /*3*/;
414 movb $8, %cl // numBits : 3,3,8
416 // if (Bit0(probLen)) {
418 call Bit1dx // Bit1(prob)
419 xchg AX, BX
420 inc DX
421 jnc lzd15 // bx=0
423 // probLen = prob + LenLow/*2*/ + (posState << kLenNumLowBits/*3*/);
424 // offset = 0;
425 // }
426 // else {
427 // probLen = prob + LenChoice2 /*1*/;
429 call Bit1dx // Bit1(prob)
430 add AX, BX
432 #if PROP_PB != 0
433 inc AX // ah=0
434 #endif
435 jc lzd16 // %ax=0, %bx=-2
436 lzd15:
437 #if PROP_PB != 0
438 movb $8, %al
439 mulb posState(BP)
440 #endif
442 // if (Bit0(probLen)) {
443 // probLen = prob + LenMid/*130*/ + (posState << kLenNumMidBits/*3*/);
445 movb $3, %cl // numBits : 3,3,8
446 lzd16:
447 #if PROP_PB != 0
448 add $2-128-1, AX // probLen : 2,130,258
449 #else
450 mov $2-128-1, AX // probLen : 2,130,258
451 #endif
452 add DX, AX
453 mov $-8+1, DX // offset : 0,8,16
454 lzdargslp:
455 add $8, DX
456 add $128, AX
457 inc BX
458 jle lzdargslp // leave with bx=1
460 // offset = kLenNumLowSymbols /*8*/;
461 // //numBits = kLenNumMidBits /*3*/;
462 // }
463 // else {
464 // probLen = prob + LenHigh /*258*/;
465 // offset = kLenNumLowSymbols /*8*/ + kLenNumMidSymbols /*8*/;
466 // numBits = kLenNumHighBits /*8*/;
467 // }
468 // }
469 // RangeDecoderBitTreeDecode(probLen, numBits, len); len += offset;
471 push DX
472 call RangeDecoder // %ax=probs, %cx=numLevels, %ax=res
473 pop DX
474 add DX, AX // offset
475 pop DX // 0
476 lzd13string:
477 push AX
479 // state = (state < kNumLitStates /*7*/) ? dl : dl|3;
481 movb $7, %cl
482 cmpb %cl, state(BP)
483 jb new_state
484 orb $3, %dl
485 new_state:
486 movb %dl, state(BP)
488 // } /* get len */
489 // if (state < 4) {
491 cmpb $4-1, %dl
492 ja lzd19
494 // int posSlot;
495 // state += kNumLitStates /*7*/;
497 addb %cl, state(BP)
499 // prob = p + PosSlot /*432*/ + (((len < kNumLenToPosStates /*4*/) ?
500 // len : kNumLenToPosStates - 1) << kNumPosSlotBits /*6*/);
502 cmp $4+1, AX
503 jb lzd21
504 mov $3+1, AX
506 lzd21:
508 dec CX // cx = 6
509 shl %cl, AX
510 add $432-64, AX
512 // RangeDecoderBitTreeDecode(prob, kNumPosSlotBits /*6*/, posSlot);
514 call RangeDecoder // %ax=probs, %cx=numLevels, %ax=res
516 // if (posSlot >= kStartPosModelIndex /*4*/) {
517 // int numDirectBits = ((posSlot >> 1) - 1);
519 #ifndef FLAT32
520 movw %cx, 2(%bp, %di) // %cx = 0
521 #endif
522 mov AX, (BP, DI)
523 mov AX, CX
524 shrw $1, CX
525 dec CX
526 cmpb $4, %al
527 jb lzd22
529 // rep0 = (2 | ((UInt32)posSlot & 1));
531 andb %bl, (BP, DI) // %bx=1
532 orb $2, (BP, DI)
534 // if (posSlot < kEndPosModelIndex /*14*/) {
536 cmpb $14, %al
537 jnb lzd23
539 // rep0 <<= numDirectBits;
541 neg AX
542 # ifdef ONLY8086
543 pushw %cx
544 movb $0, %ch
545 shllrep0:
546 shlw $1, (BP, DI)
547 rclw $1, 2(BP, DI)
548 loop shllrep0
549 popw %cx
550 # else
551 shll %cl, (BP, DI)
552 # endif
553 add (BP, DI), AX
555 // prob = p + SpecPos /*688*/ + rep0 - posSlot - 1;
557 add $687, AX
558 jmp lzd24
560 // }
561 // else {
562 lzd23:
563 // numDirectBits -= kNumAlignBits /*4*/;
564 // do {
565 // RC_NORMALIZE; Range >>= 1; rep0 <<= 1;
566 // if (Code >= Range) { Code -= Range; rep0 |= 1; }
568 lzd23z:
569 call RC_NORMALIZE
570 # ifdef ONLY8086
571 pushw %dx
572 shrw $1, Range+2(BP)
573 rcrw $1, Range(BP)
574 movw Range(BP), %ax
575 movw Range+2(BP), %dx
576 cmpw Code+2(BP), %dx
577 ja lzd25
578 jb lzd25x
579 cmpw Code(BP), %ax
580 ja lzd25
581 lzd25x:
582 subw %ax, Code(BP)
583 sbbw %dx, Code+2(BP)
584 stc
585 lzd25:
586 popw %dx
587 rclw $1, (BP, DI)
588 rclw $1, 2(BP, DI)
589 # else
590 shrl $1, Range(BP)
591 movl Range(BP), %eax
592 cmpl Code(BP), %eax
593 ja lzd25
594 subl %eax, Code(BP)
595 stc
596 lzd25:
597 rcll $1, (BP, DI)
598 # endif
600 // } while (--numDirectBits != 0);
602 cmpb $4+1, %cl
603 loopne lzd23z
605 // prob = p + Align /* 802 */; numDirectBits = kNumAlignBits /*4*/;
606 // rep0 <<= numDirectBits;
608 # ifdef ONLY8086
609 pushw %cx
610 movb $0, %ch
611 shlrep0:
612 shlw $1, (BP, DI)
613 rclw $1, 2(BP, DI)
614 loop shlrep0
615 popw %cx
616 # else
617 shll %cl, (BP, DI)
618 # endif
619 mov $802, AX
620 // }
622 lzd24:
623 call RangeDecoder // %ax=probs, %cx=numLevels, %ax=res
625 // {
626 // int i = 1, mi = 1;
627 // do {
628 // CProb *prob3 = prob + mi;
629 // RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
631 orb %dh, (BP, DI) // update rep0 with DirectBits
633 // i <<= 1;
634 // } while(--numDirectBits != 0);
635 // }
636 // } else rep0 = posSlot;
637 lzd22:
638 // if (++rep0 == (UInt32)(0)) break; /* EOF */
640 # ifdef ONLY8086
641 incw (BP, DI)
642 jnz lzd19
643 incw 2(BP, DI)
644 # else
645 incl (BP, DI)
646 # endif
648 lzd19:
649 pop CX
650 jz lzdone
652 // }
653 // len += kMatchMinLen;/*2*/
655 inc CX
657 // string: // if (rep0 > nowPos) return LZMA_RESULT_DATA_ERROR;
658 // do {
659 lzd13z:
660 // previousByte = outStream[nowPos - rep0];
661 // outStream[nowPos++] = previousByte;
663 call outcharDico // %bl = outStream[nowPos++] = outStream[nowPos - rep0]
665 // } while(--len != 0);
667 loop lzd13z
669 // } /* char/string */
670 // }
672 jmp lzdmainlp
674 lzdone:
675 // //RC_NORMALIZE;
676 // //*inSizeProcessed = (SizeT)(Buffer - inStream); *outSizeProcessed = nowPos;
677 // return LZMA_RESULT_OK;
678 call Dico2ESDI // set es & di (rep0 = 0)
679 lea ws2(BP), SP // dealloc
680 ret
681 // }
683 // al = outStream[nowPos - rep0];
685 /*
686 * output es:di, al
687 * scratch bh, cl, flags
688 */
690 DicoRep02ESDI:
691 stc
693 // bl = outStream[nowPos];
695 /*
696 * output es:di, bl
697 * scratch bh, cl, flags
698 */
700 Dico2ESDI:
701 #if !defined(FLAT32) && !defined(FLAT16OUT)
702 # ifdef ONLY8086
703 pushw %ax
704 movw nowPos(%bp), %bx
705 movw nowPos+2(%bp), %ax
706 jnc Dico2ESDIz
707 subw rep0(%bp), %bx
708 sbbw rep0+2(%bp), %ax
709 Dico2ESDIz:
710 movw $0xF, %di
711 andw %bx, %di
712 pushw %cx
713 movb $4, %cl
714 shrw %cl, %bx
715 shlw %cl, %ax
716 popw %cx
717 addb %al, %bh
718 popw %ax
719 # else
720 movl nowPos(%bp), %ebx
721 jnc Dico2ESDIz
722 subl rep0(%bp), %ebx
723 Dico2ESDIz:
724 movw %bx, %di
725 xorw %bx, %bx
726 shrl $4, %ebx
727 # endif
728 movw %bx, %es
729 #else
730 mov nowPos(BP), DI
731 jnc Dico2ESDIz
732 sub rep0(BP), DI
733 Dico2ESDIz:
734 #endif
735 #ifdef FLAT32
736 movb (DI), %bl
737 #else
738 movb %es:(%di), %bl
739 #endif
740 ret
742 outcharDico:
744 // bl = outStream[nowPos++] = outStream[nowPos - rep0]
746 /*
747 * output es:di, bl
748 * update nowPos
749 * scratch ax, dx, bh, cl, flags
750 */
752 call DicoRep02ESDI // %bl = outStream[nowPos - rep0]
753 xchg AX, BX
754 outchar:
756 // bl = outStream[nowPos++] = previousByte = al;
758 /*
759 * output bl
760 * update nowPos
761 * scratch ax, dx, bh, di, cl, flags
762 */
764 clc
765 call Dico2ESDI
766 stosb
767 xchg AX, BX // previous byte
769 // int posState = (int)((nowPos) & posStateMask);
771 #if PROP_PB != 0 && PROP_LP != 0
772 addw $0x0101, posState2(BP)
773 andb $(((1 << PROP_PB) -1)<<8)+((1 << PROP_LP) -1), posState2(BP)
774 #else
775 # if PROP_PB != 0
776 incb posState(BP)
777 andb $((1 << PROP_PB) -1), posState(BP)
778 # endif
779 # if PROP_LP != 0
780 incb posState2(BP)
781 andb $((1 << PROP_LP) -1), posState2(BP)
782 # endif
783 #endif
784 #ifdef ONLY8086
785 incw nowPos(BP)
786 jnz incnowPosDone
787 incw nowPos+2(BP)
788 incnowPosDone:
789 #else
790 incl nowPos(BP)
791 #endif
792 ret
794 //
795 // #define RC_NORMALIZE if (Range < kTopValue)
796 // { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
798 /*
799 * update Range, Code, ds:si
800 * scratch flags
801 */
803 RC_NORMALIZE:
804 cmpb $0, Range+3(BP)
805 jne RC_NORMALIZE_1
806 RC_LOAD_BYTE:
807 push AX
808 #ifdef ONLY8086
809 movw Range+1(BP), %ax
810 movw %ax, Range+2(BP)
811 movw Code+1(BP), %ax
812 movw %ax, Code+2(BP)
813 xorw %ax, %ax
814 movb Range(BP), %ah
815 movw %ax, Range(BP)
816 movb Code(BP), %ah
817 movw %ax, Code(BP)
818 #else
819 shll $8, Range(BP)
820 shll $8, Code(BP)
821 #endif
822 #if !defined(FLAT16) && !defined(FLAT32)
823 testw %si, %si
824 jns RC_READ_BYTE
825 movw %ds, %ax
826 incw %ax
827 movw %ax, %ds
828 addw $-16, %si
829 RC_READ_BYTE:
830 #endif
831 lodsb
832 movb %al, Code(BP)
833 pop AX
834 RC_NORMALIZE_1:
835 ret
837 // Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
839 Bit1state:
840 movb $16, %al
841 mulb state(BP)
842 # if PROP_PB != 0
843 addb posState(BP), %al
844 # endif
845 Bit1axdx:
846 add DX, AX
847 jmp Bit1
849 // prob += 12; Bit1(prob)
851 Bit1dx12:
852 add $12, DX
853 Bit1dx:
854 mov DX, AX
856 // static int Bit1(CProb *p)
858 Bit1:
859 /*
860 * input ax=p
861 * output C, ax
862 * update bound, Range, Code, ds:si
863 * scratch flags
864 */
866 // {
867 // RC_NORMALIZE;
869 call RC_NORMALIZE // kill %ax, update %si
871 #ifdef ONLY8086
872 pushw %ax
873 pushw %cx
874 pushw %dx
875 pushw %di
876 #else
877 pushal
878 #endif
880 xchg AX, DI
881 add DI, DI // short *
884 // bound = (Range>>kNumBitModelTotalBits /*11*/) * *(p);
886 #ifdef ONLY8086
887 movw Range(BP), %dx
888 movw Range+2(BP), %ax
889 movw $11, %cx
890 shr11lp:
891 shrw $1, %ax
892 rcrw $1, %dx
893 loop shr11lp
894 movw %dx, %cx
895 mulw (BP, DI)
896 xchgw %ax, %cx
897 mulw (BP, DI)
898 addw %cx, %dx
899 #else
900 movl Range(BP), %eax
901 shrl $11, %eax
902 movzwl (BP, DI), %edx
903 mull %edx
904 #endif
906 // if (Code < bound) {
908 #ifdef ONLY8086
909 cmpw Code+2(BP), %dx
910 jb Bit1_1
911 ja Bit1_1x
912 cmpw Code(BP), %ax
913 jbe Bit1_1
914 Bit1_1x:
916 // Range = bound;
918 movw %ax, Range(BP)
919 movw %dx, Range+2(BP)
920 #else
921 cmpl Code(BP), %eax
922 jbe Bit1_1
924 // Range = bound;
926 movl %eax, Range(BP)
927 #endif
929 // *(p) += (kBitModelTotal /*2048*/ - *(p)) >> kNumMoveBits /*5*/;
931 movw $2048, %ax
933 // return 0;
935 jmp Bit1_2
937 // }
938 // else {
940 Bit1_1:
942 // Range -= bound; Code -= bound;
944 #ifdef ONLY8086
945 subw %ax, Range(BP)
946 sbbw %dx, Range+2(BP)
947 subw %ax, Code(BP)
948 sbbw %dx, Code+2(BP)
949 #else
950 subl %eax, Range(BP)
951 subl %eax, Code(BP)
952 #endif
954 // *(p) -= (*(p)) >> kNumMoveBits /*5*/;
956 movw $31, %ax
958 // return 1;
960 stc
961 Bit1_2:
962 pushf
963 subw (BP, DI), %ax
964 #ifdef ONLY8086
965 movb $5, %cl
966 sarw %cl, %ax
967 #else
968 sarw $5, %ax
969 #endif
970 addw %ax, (BP, DI)
971 popf
972 #ifdef ONLY8086
973 popw %di
974 popw %dx
975 popw %cx
976 popw %ax
977 #else
978 popal
979 #endif
980 sbb AX, AX
982 // }
983 // }
985 ret
987 RangeDecoder:
989 /*
990 * input ax=probs cx=numLevels (< 8) bx=1
991 * output ax=res (backward), dh (forward)
992 * update bound, Range, Code, ds:si
993 * scratch flags, cx=0, dl
994 */
996 push BX
998 // { int i = numLevels; res = 1;
999 mov BX, DX // res = 1
1001 // do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0);
1003 RangeDecoder_1:
1004 push AX
1005 call Bit1axdx // C,%ax = Bit1(prob+%ax)
1006 rclb $1, %dl // res <<= 1; res |= C
1007 andb %bl, %al // current bit
1008 orb %al, %bh // store in bh
1009 shlb $1, %bl // update max
1010 pop AX
1011 loop RangeDecoder_1
1013 // res -= (1 << numLevels); }
1015 xchg AX, BX // move bh to dh
1016 xchg AX, DX // and dl to al
1017 sub %dl, %al // sub max
1018 pop BX
1019 ret