wok view memtest/stuff/unlzma.S @ rev 19396

Up zstd (1.0.0)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Sep 01 16:30:12 2016 +0200 (2016-09-01)
parents 3b334b26197f
children 1421f93cc28a
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 lzd1:
110 pushw $2048/2
111 loop lzd1
112 mov SP, BP
113 movb $((LOCALS+3)/4)*2, %cl
114 initlocals:
115 pushl $1
116 loop initlocals
118 #if !defined(FLAT32) && !defined(FLAT16OUT)
119 movb $4, %cl
120 movw %es, %bx
121 shrw %cl, %bx
122 movw %es, %dx
123 shlw %cl, %dx
124 addw %dx, %di
125 movw %di, outStream(%bp)
126 adcb %bh, outStream+2(%bp)
127 incw %cx
128 #else
129 movb $5, %cl
130 mov DI, outStream(BP)
131 #endif
133 // Byte previousByte = 0;
134 xor BX, BX
136 // #define RC_INIT(buffer)
137 // Buffer = buffer; Code = 0; Range = 0xFFFFFFFF;
138 // { int i; for(i=0; i<5; i++) { Code = (Code<<8) | RC_READ_BYTE; }}
139 // }
140 // RC_INIT(inStream);
142 #ifndef NO_LZMA_HEADER
143 #ifdef CHECK_LZMA_HEADER
144 cmp.w $0x5A4C, (SI) // lzip header ('LZIP' version:1 dicobits:1)
145 je lzip_header
146 cmp.w $0x5D, (SI) // lzma header (0x5D dicosz:4 orgsz:8)
147 jne no_header
148 add $13-6, SI // skip lzma header
149 lzip_header:
150 add $6, SI // skip lzip header
151 no_header:
152 #else
153 add $13, SI // skip lzma header (0x5D dicosz:4 orgsz:8)
154 #endif
155 #endif
156 setrep:
157 call RC_LOAD_BYTE
158 decb Range(BP)
159 loop setrep
161 lzdmainlp:
162 // while(1) {
163 // CProb *prob;
164 // int posState = (int)((nowPos) & posStateMask);
165 //
166 // prob = p + IsMatch /*0*/ + (state << kNumPosBitsMax /*4*/) + posState;
167 // if (Bit0(prob)) { /* char */
169 xor DX, DX
170 call Bit1state // Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
171 mov $state, DI
172 jc lzdstring
174 // prob = p + Literal /*1846*/ + (LZMA_LIT_SIZE /*768*/ *
175 // ((((nowPos) & literalPosMask) << lc) + (previousByte >> (8 - lc))));
177 #if PROP_LC != 0
178 shrb $8-PROP_LC, %bl
179 #endif
181 #if PROP_LP != 0
182 movb posState2(BP), %dl
183 shl $PROP_LC, DX
184 movb $0, %bh
185 add BX, DX
186 #endif
188 movb $3, %ah
189 mul BX // dx = 3*bh
190 add $1846, AX
192 // int symbol = 1;
194 CWD
195 inc DX // symbol = 1
196 xchg AX, CX // save prob
198 // if (state >= kNumLitStates /*7*/) { /* previous was string */
199 // if (state < 4) state = 0;
201 lzd6z:
202 subb $3, (BP, DI)
204 // if (state < 4) state = 0;
206 jnc lzd6
207 movb %dh, (BP, DI) // %dh = 0
209 lzd6:
210 // else if (state < 10) state -= 3;
212 cmpb $10-3, (BP, DI)
214 // else state -= 6;
216 jnb lzd6z
217 cmpb $7-3-1, (BP, DI)
218 jbe lzd3
220 // int matchByte = outStream[nowPos - rep0];
222 call DicoRep02ESDI // %bl = outStream[nowPos - rep0];
224 // do {
225 // int bit;
226 // CProb *probLit;
227 // matchByte <<= 1; bit = (matchByte & 0x100);
229 movb $1, %bh
230 lzd4:
231 shlb $1, %bl // matchByte <<= 1
232 sbb DI, DI // save bit=C
234 // probLit = prob + 0x100 + bit + symbol;
236 mov CX, AX // restore prob
237 adcb %bh, %ah // + bit + 0x100
239 // RC_GET_BIT2(probLit, symbol, if (bit) break, if (!bit) break)
241 call Bit1axdx // C,%ax = Bit1(prob+%ax)
242 rclb $1, %dl // symbol <<= 1; symbol |= C
243 jc lzd5 // if symbol >= 0x100
244 cmp DI, AX
245 jz lzd4 // if bit == Bit1(prob+%ax)
247 // } while (symbol < 0x100);
248 // }
249 lzd3:
250 // while (symbol < 0x100) {
251 // CProb *probLit = prob + symbol;
252 // RC_GET_BIT(probLit, symbol)
253 // }
255 xor BX, BX
256 jmp lzd4
257 lzd5:
259 // outStream[nowPos++] = previousByte = (Byte)symbol;
261 xchg AX, DX
262 call outchar // %bl = outStream[nowPos++] = %al;
263 jmp lzdmainlp
265 // }
267 lzdstring:
268 mov $1, CX
270 // else { /* string */
271 // prob = p + IsRep /*192*/ + state;
273 movb $192, %dl
274 addb (BP, DI), %dl
275 mov $rep0, DI
277 // if (Bit0(prob)) {
279 call Bit1dx // Bit1(prob)
280 jc lzd8
282 // rep3 = rep2; rep2 = rep1; rep1 = rep0;
283 // state = (state < kNumLitStates /*7*/) ? 0 : 3;
285 stc
287 // prob = p + LenCoder /*818*/;
289 mov $818, DX
291 // }
293 jmp lzd11a
295 // else {
296 lzd8:
297 // prob += kNumStates /*12*/;
298 // if (Bit0(prob)) {
299 call Bit1dx12 // prob += 12; Bit1(prob)
300 jc lzd11
301 // prob = p + IsRep0Long /*240*/ + (state << kNumPosBitsMax /*4*/)
302 // + posState;
303 movb $240, %dl // dh=0
305 // if (Bit0(prob)) {
307 call Bit1state // Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
308 jc lzd12
310 // // if (nowPos == 0) return LZMA_RESULT_DATA_ERROR;
311 // state = (state < kNumLitStates /*7*/) ? 9 : 11;
313 movb $9, %dl
315 // len++; goto string;
316 jmp lzd13string // ax = 0
317 // }
318 // }
319 // else {
320 lzd11:
321 // UInt32 distance = rep1;
322 // prob += kNumStates /*12*/;
323 // if (!Bit0(prob)) {
325 call Bit1dx12 // prob += 12; Bit1(prob)
326 jnc lzd11z
328 // prob += kNumStates /*12*/;
329 // if (Bit0(prob)) distance = rep2;
331 call Bit1dx12 // prob += 12; Bit1(prob)
332 lzd11a:
333 adcb %cl, %cl
335 // else { distance = rep3; rep3 = rep2; }
336 // rep2 = rep1;
337 // }
338 // rep1 = rep0; rep0 = distance;
340 lzd11z:
341 shl $2, CX // 8->32 bits
342 sub CX, DI // &rep[cx]
343 movl (BP, DI), %eax
344 rotreplp:
345 movb 4(BP, DI), %bl
346 movb %bl, (BP, DI)
347 inc DI
348 loop rotreplp
349 testb %dh, %dh
350 jnz lzd10
351 movl %eax, (BP, DI)
353 // }
354 lzd12:
355 // state = (state < kNumLitStates /*7*/) ? 8 : 11;
357 movb $0x08, %cl
359 // prob = p + RepLenCoder /*1332*/;
361 mov $1332, DX
363 // }
364 lzd10:
365 push CX // CX = 0
367 // { /* get len */
368 // int numBits, offset;
369 // CProb *probLen = prob + LenChoice /*0*/;
370 // numBits = kLenNumLowBits /*3*/;
372 movb $8, %cl // numBits : 3,3,8
374 // if (Bit0(probLen)) {
376 call Bit1dx // Bit1(prob)
377 xchg AX, BX
378 inc DX
379 jnc lzd15 // bx=0
381 // probLen = prob + LenLow/*2*/ + (posState << kLenNumLowBits/*3*/);
382 // offset = 0;
383 // }
384 // else {
385 // probLen = prob + LenChoice2 /*1*/;
387 call Bit1dx // Bit1(prob)
388 add AX, BX
390 #if PROP_PB != 0
391 inc AX // ah=0
392 #endif
393 jc lzd16 // %ax=0, %bx=-2
394 lzd15:
395 #if PROP_PB != 0
396 movb $8, %al
397 mulb posState(BP)
398 #endif
400 // if (Bit0(probLen)) {
401 // probLen = prob + LenMid/*130*/ + (posState << kLenNumMidBits/*3*/);
403 movb $3, %cl // numBits : 3,3,8
404 lzd16:
405 #if PROP_PB != 0
406 add $2-128-1, AX // probLen : 2,130,258
407 #else
408 mov $2-128-1, AX // probLen : 2,130,258
409 #endif
410 add DX, AX
411 mov $-8+1, DX // offset : 0,8,16
412 lzdargslp:
413 add $8, DX
414 add $128, AX
415 inc BX
416 jle lzdargslp // leave with bx=1
418 // offset = kLenNumLowSymbols /*8*/;
419 // //numBits = kLenNumMidBits /*3*/;
420 // }
421 // else {
422 // probLen = prob + LenHigh /*258*/;
423 // offset = kLenNumLowSymbols /*8*/ + kLenNumMidSymbols /*8*/;
424 // numBits = kLenNumHighBits /*8*/;
425 // }
426 // }
427 // RangeDecoderBitTreeDecode(probLen, numBits, len); len += offset;
429 push DX
430 call RangeDecoder // %ax=probs, %cx=numLevels, %ax=res
431 pop DX
432 add DX, AX // offset
433 pop DX // 0
434 lzd13string:
435 push AX
437 // state = (state < kNumLitStates /*7*/) ? dl : dl|3;
439 movb $7, %cl
440 cmpb %cl, state(BP)
441 jb new_state
442 orb $3, %dl
443 new_state:
444 movb %dl, state(BP)
446 // } /* get len */
447 // if (state < 4) {
449 cmpb $4-1, %dl
450 ja lzd19
452 // int posSlot;
453 // state += kNumLitStates /*7*/;
455 addb %cl, state(BP)
457 // prob = p + PosSlot /*432*/ + (((len < kNumLenToPosStates /*4*/) ?
458 // len : kNumLenToPosStates - 1) << kNumPosSlotBits /*6*/);
460 cmp $4+1, AX
461 jb lzd21
462 mov $3+1, AX
464 lzd21:
466 dec CX // cx = 6
467 shl %cl, AX
468 add $432-64, AX
470 // RangeDecoderBitTreeDecode(prob, kNumPosSlotBits /*6*/, posSlot);
472 call RangeDecoder // %ax=probs, %cx=numLevels, %ax=res
474 // if (posSlot >= kStartPosModelIndex /*4*/) {
475 // int numDirectBits = ((posSlot >> 1) - 1);
477 #ifndef FLAT32
478 movw %cx, 2(%bp, %di) // %cx = 0
479 #endif
480 mov AX, (BP, DI)
481 mov AX, CX
482 shrw $1, CX
483 dec CX
484 cmpb $4, %al
485 jb lzd22
487 // rep0 = (2 | ((UInt32)posSlot & 1));
489 andb %bl, (BP, DI) // %bx=1
490 orb $2, (BP, DI)
492 // if (posSlot < kEndPosModelIndex /*14*/) {
494 cmpb $14, %al
495 jnb lzd23
497 // rep0 <<= numDirectBits;
499 neg AX
500 shll %cl, (BP, DI)
501 add (BP, DI), AX
503 // prob = p + SpecPos /*688*/ + rep0 - posSlot - 1;
505 add $687, AX
506 jmp lzd24
508 // }
509 // else {
510 lzd23:
511 // numDirectBits -= kNumAlignBits /*4*/;
512 // do {
513 // RC_NORMALIZE; Range >>= 1; rep0 <<= 1;
514 // if (Code >= Range) { Code -= Range; rep0 |= 1; }
516 lzd23z:
517 call RC_NORMALIZE
518 shrl $1, Range(BP)
519 movl Range(BP), %eax
520 cmpl Code(BP), %eax
521 ja lzd25
522 subl %eax, Code(BP)
523 stc
524 lzd25:
525 rcll $1, (BP, DI)
527 // } while (--numDirectBits != 0);
529 cmpb $4+1, %cl
530 loopne lzd23z
532 // prob = p + Align /* 802 */; numDirectBits = kNumAlignBits /*4*/;
533 // rep0 <<= numDirectBits;
535 shll %cl, (BP, DI)
536 mov $802, AX
537 // }
539 lzd24:
540 call RangeDecoder // %ax=probs, %cx=numLevels, %ax=res
542 // {
543 // int i = 1, mi = 1;
544 // do {
545 // CProb *prob3 = prob + mi;
546 // RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
548 orb %dh, (BP, DI) // update rep0 with DirectBits
550 // i <<= 1;
551 // } while(--numDirectBits != 0);
552 // }
553 // } else rep0 = posSlot;
554 lzd22:
555 // if (++rep0 == (UInt32)(0)) break; /* EOF */
557 incl (BP, DI)
559 lzd19:
560 pop CX
561 jz lzdone
563 // }
564 // len += kMatchMinLen;/*2*/
566 inc CX
568 // string: // if (rep0 > nowPos) return LZMA_RESULT_DATA_ERROR;
569 // do {
570 lzd13z:
571 // previousByte = outStream[nowPos - rep0];
572 // outStream[nowPos++] = previousByte;
574 call outcharDico // %bl = outStream[nowPos++] = outStream[nowPos - rep0]
576 // } while(--len != 0);
578 loop lzd13z
580 // } /* char/string */
581 // }
583 jmp lzdmainlp
585 lzdone:
586 // //RC_NORMALIZE;
587 // //*inSizeProcessed = (SizeT)(Buffer - inStream); *outSizeProcessed = nowPos;
588 // return LZMA_RESULT_OK;
589 call Dico2ESDI // set es & di (rep0 = 0)
590 lea ws2(BP), SP // dealloc
591 ret
592 // }
594 // al = outStream[nowPos - rep0];
596 /*
597 * output es:di, al
598 * scratch bh, cl, flags
599 */
601 DicoRep02ESDI:
602 stc
604 // bl = outStream[nowPos];
606 /*
607 * output es:di, bl
608 * scratch bh, cl, flags
609 */
611 Dico2ESDI:
612 #if !defined(FLAT32) && !defined(FLAT16OUT)
613 movl nowPos(%bp), %ebx
614 jnc Dico2ESDIz
615 subl rep0(%bp), %ebx
616 Dico2ESDIz:
617 movw %bx, %di
618 xorw %bx, %bx
619 shrl $4, %ebx
620 movw %bx, %es
621 #else
622 mov nowPos(BP), DI
623 jnc Dico2ESDIz
624 sub rep0(BP), DI
625 Dico2ESDIz:
626 #endif
627 #ifdef FLAT32
628 movb (DI), %bl
629 #else
630 movb %es:(%di), %bl
631 #endif
632 ret
634 outcharDico:
636 // bl = outStream[nowPos++] = outStream[nowPos - rep0]
638 /*
639 * output es:di, bl
640 * update nowPos
641 * scratch ax, dx, bh, cl, flags
642 */
644 call DicoRep02ESDI // %bl = outStream[nowPos - rep0]
645 xchg AX, BX
646 outchar:
648 // bl = outStream[nowPos++] = previousByte = al;
650 /*
651 * output bl
652 * update nowPos
653 * scratch ax, dx, bh, di, cl, flags
654 */
656 clc
657 call Dico2ESDI
658 stosb
659 xchg AX, BX // previous byte
661 // int posState = (int)((nowPos) & posStateMask);
663 #if PROP_PB != 0 && PROP_LP != 0
664 addw $0x0101, posState2(BP)
665 andb $(((1 << PROP_PB) -1)<<8)+((1 << PROP_LP) -1), posState2(BP)
666 #else
667 # if PROP_PB != 0
668 incb posState(BP)
669 andb $((1 << PROP_PB) -1), posState(BP)
670 # endif
671 # if PROP_LP != 0
672 incb posState2(BP)
673 andb $((1 << PROP_LP) -1), posState2(BP)
674 # endif
675 #endif
676 incl nowPos(BP)
677 ret
679 //
680 // #define RC_NORMALIZE if (Range < kTopValue)
681 // { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
683 /*
684 * update Range, Code, ds:si
685 * scratch flags
686 */
688 RC_NORMALIZE:
689 cmpb $0, Range+3(BP)
690 jne RC_NORMALIZE_1
691 RC_LOAD_BYTE:
692 push AX
693 shll $8, Range(BP)
694 shll $8, Code(BP)
695 #if !defined(FLAT16) && !defined(FLAT32)
696 testw %si, %si
697 jns RC_READ_BYTE
698 movw %ds, %ax
699 incw %ax
700 movw %ax, %ds
701 addw $-16, %si
702 RC_READ_BYTE:
703 #endif
704 lodsb
705 movb %al, Code(BP)
706 pop AX
707 RC_NORMALIZE_1:
708 ret
710 // Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
712 Bit1state:
713 movb $16, %al
714 mulb state(BP)
715 # if PROP_PB != 0
716 addb posState(BP), %al
717 # endif
718 Bit1axdx:
719 add DX, AX
720 jmp Bit1
722 // prob += 12; Bit1(prob)
724 Bit1dx12:
725 add $12, DX
726 Bit1dx:
727 mov DX, AX
729 // static int Bit1(CProb *p)
731 Bit1:
732 /*
733 * input ax=p
734 * output C, ax
735 * update bound, Range, Code, ds:si
736 * scratch flags
737 */
739 // {
740 // RC_NORMALIZE;
742 call RC_NORMALIZE // kill %ax, update %si
744 pushal
746 xchg AX, DI
747 add DI, DI // short *
750 // bound = (Range>>kNumBitModelTotalBits /*11*/) * *(p);
752 movl Range(BP), %eax
753 shrl $11, %eax
754 movzwl (BP, DI), %edx
755 mull %edx
757 // if (Code < bound) {
759 cmpl Code(BP), %eax
760 jbe Bit1_1
762 // Range = bound;
764 movl %eax, Range(BP)
766 // *(p) += (kBitModelTotal /*2048*/ - *(p)) >> kNumMoveBits /*5*/;
768 movw $2048, %ax
770 // return 0;
772 jmp Bit1_2
774 // }
775 // else {
777 Bit1_1:
779 // Range -= bound; Code -= bound;
781 subl %eax, Range(BP)
782 subl %eax, Code(BP)
784 // *(p) -= (*(p)) >> kNumMoveBits /*5*/;
786 movw $31, %ax
788 // return 1;
790 stc
791 Bit1_2:
792 pushf
793 subw (BP, DI), %ax
794 sarw $5, %ax
795 addw %ax, (BP, DI)
796 popf
797 popal
798 sbb AX, AX
800 // }
801 // }
803 ret
805 RangeDecoder:
807 /*
808 * input ax=probs cx=numLevels (< 8) bx=1
809 * output ax=res (backward), dh (forward)
810 * update bound, Range, Code, ds:si
811 * scratch flags, cx=0, dl
812 */
814 push BX
816 // { int i = numLevels; res = 1;
817 mov BX, DX // res = 1
819 // do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0);
821 RangeDecoder_1:
822 push AX
823 call Bit1axdx // C,%ax = Bit1(prob+%ax)
824 rclb $1, %dl // res <<= 1; res |= C
825 andb %bl, %al // current bit
826 orb %al, %bh // store in bh
827 shlb $1, %bl // update max
828 pop AX
829 loop RangeDecoder_1
831 // res -= (1 << numLevels); }
833 xchg AX, BX // move bh to dh
834 xchg AX, DX // and dl to al
835 sub %dl, %al // sub max
836 pop BX
837 ret