1 ; LzmaDecOpt.asm -- ASM version of LzmaDec_DecodeReal_3() function
\r
2 ; 2021-02-23: Igor Pavlov : Public domain
\r
4 ; 3 - is the code compatibility version of LzmaDec_DecodeReal_*()
\r
5 ; function for check at link time.
\r
6 ; That code is tightly coupled with LzmaDec_TryDummy()
\r
7 ; and with another functions in LzmaDec.c file.
\r
8 ; CLzmaDec structure, (probs) array layout, input and output of
\r
9 ; LzmaDec_DecodeReal_*() must be equal in both versions (C / ASM).
\r
13 ; .err <x64_IS_REQUIRED>
\r
20 _TEXT$LZMADECOPT SEGMENT ALIGN(64) 'CODE'
\r
22 MY_ALIGN macro num:req
\r
39 ; _LZMA_SIZE_OPT equ 1
\r
41 ; _LZMA_PROB32 equ 1
\r
45 PLOAD macro dest, mem
\r
46 mov dest, dword ptr [mem]
\r
48 PSTORE macro src, mem
\r
49 mov dword ptr [mem], src
\r
53 PLOAD macro dest, mem
\r
54 movzx dest, word ptr [mem]
\r
56 PSTORE macro src, mem
\r
57 mov word ptr [mem], @CatStr(src, _W)
\r
61 PMULT equ (1 SHL PSHIFT)
\r
62 PMULT_HALF equ (1 SHL (PSHIFT - 1))
\r
63 PMULT_2 equ (1 SHL (PSHIFT + 1))
\r
65 kMatchSpecLen_Error_Data equ (1 SHL 9)
\r
68 ; x1 pbPos / (prob) TREE
\r
69 ; x2 probBranch / prm (MATCHED) / pbPos / cnt
\r
73 ; x6 t1 NORM_CALC / probs_state / dist
\r
74 ; x7 t0 NORM_CALC / prob2 IF_BIT_1
\r
76 ; x9 match (MATCHED) / sym2 / dist2 / lpMask_reg
\r
77 ; x10 kBitModelTotal_reg
\r
79 ; x12 offs (MATCHED) / dic / len_temp
\r
81 ; x14 bit (MATCHED) / dicPos
\r
91 processedPos equ x13
\r
92 kBitModelTotal_reg equ x10
\r
96 probBranch_W equ x2_W
\r
125 probs_state_R equ t1_R
\r
145 kNumBitModelTotalBits equ 11
\r
146 kBitModelTotal equ (1 SHL kNumBitModelTotalBits)
\r
148 kBitModelOffset equ ((1 SHL kNumMoveBits) - 1)
\r
149 kTopValue equ (1 SHL 24)
\r
152 ; movzx t0, BYTE PTR [buf]
\r
154 mov cod_L, BYTE PTR [buf]
\r
162 cmp range, kTopValue
\r
169 ; ---------- Branch MACROS ----------
\r
171 UPDATE_0 macro probsArray:req, probOffset:req, probDisp:req
\r
172 mov prob2, kBitModelTotal_reg
\r
173 sub prob2, probBranch
\r
174 shr prob2, kNumMoveBits
\r
175 add probBranch, prob2
\r
176 PSTORE probBranch, probOffset * 1 + probsArray + probDisp * PMULT
\r
180 UPDATE_1 macro probsArray:req, probOffset:req, probDisp:req
\r
184 mov prob2, probBranch
\r
185 shr probBranch, kNumMoveBits
\r
186 sub prob2, probBranch
\r
187 PSTORE prob2, probOffset * 1 + probsArray + probDisp * PMULT
\r
191 CMP_COD macro probsArray:req, probOffset:req, probDisp:req
\r
192 PLOAD probBranch, probOffset * 1 + probsArray + probDisp * PMULT
\r
195 shr range, kNumBitModelTotalBits
\r
196 imul range, probBranch
\r
201 IF_BIT_1_NOUP macro probsArray:req, probOffset:req, probDisp:req, toLabel:req
\r
202 CMP_COD probsArray, probOffset, probDisp
\r
207 IF_BIT_1 macro probsArray:req, probOffset:req, probDisp:req, toLabel:req
\r
208 IF_BIT_1_NOUP probsArray, probOffset, probDisp, toLabel
\r
209 UPDATE_0 probsArray, probOffset, probDisp
\r
213 IF_BIT_0_NOUP macro probsArray:req, probOffset:req, probDisp:req, toLabel:req
\r
214 CMP_COD probsArray, probOffset, probDisp
\r
219 ; ---------- CMOV MACROS ----------
\r
221 NORM_CALC macro prob:req
\r
224 shr range, kNumBitModelTotalBits
\r
232 PUP macro prob:req, probPtr:req
\r
234 ; only sar works for both 16/32 bit prob modes
\r
235 sar t0, kNumMoveBits
\r
241 PUP_SUB macro prob:req, probPtr:req, symSub:req
\r
247 PUP_COD macro prob:req, probPtr:req, symSub:req
\r
248 mov t0, kBitModelOffset
\r
251 cmovb t0, kBitModelTotal_reg
\r
252 PUP_SUB prob, probPtr, symSub
\r
256 BIT_0 macro prob:req, probNext:req
\r
257 PLOAD prob, probs + 1 * PMULT
\r
258 PLOAD probNext, probs + 1 * PMULT_2
\r
263 PLOAD t0, probs + 1 * PMULT_2 + PMULT
\r
264 cmovae probNext, t0
\r
265 mov t0, kBitModelOffset
\r
267 cmovb t0, kBitModelTotal_reg
\r
269 PUP_SUB prob, probs + 1 * PMULT, 0 - 1
\r
273 BIT_1 macro prob:req, probNext:req
\r
274 PLOAD probNext, probs + sym_R * PMULT_2
\r
280 PLOAD t0, probs + sym_R * PMULT + PMULT
\r
281 cmovae probNext, t0
\r
282 PUP_COD prob, probs + t1_R * PMULT_HALF, 0 - 1
\r
286 BIT_2 macro prob:req, symSub:req
\r
292 PUP_COD prob, probs + t1_R * PMULT_HALF, symSub
\r
296 ; ---------- MATCHED LITERAL ----------
\r
299 mov offs, 256 * PMULT
\r
300 shl match, (PSHIFT + 1)
\r
303 PLOAD x1, probs + 256 * PMULT + bit_R * 1 + 1 * PMULT
\r
304 lea prm, [probs + 256 * PMULT + bit_R * 1 + 1 * PMULT]
\r
305 ; lea prm, [probs + 256 * PMULT + 1 * PMULT]
\r
315 mov t0, kBitModelOffset
\r
317 cmovb t0, kBitModelTotal_reg
\r
319 PUP_SUB x1, prm, -2-1
\r
325 lea prm, [probs + offs_R * 1]
\r
327 PLOAD x1, prm + sym_R * PMULT
\r
337 PUP_COD x1, prm + t1_R * PMULT_HALF, - 1
\r
343 lea prm, [probs + offs_R * 1]
\r
345 PLOAD x1, prm + sym_R * PMULT
\r
351 PUP_COD x1, prm + t1_R * PMULT_HALF, 256 - 1
\r
355 ; ---------- REVERSE BITS ----------
\r
357 REV_0 macro prob:req, probNext:req
\r
358 ; PLOAD prob, probs + 1 * PMULT
\r
359 ; lea sym2_R, [probs + 2 * PMULT]
\r
360 ; PLOAD probNext, probs + 2 * PMULT
\r
361 PLOAD probNext, sym2_R
\r
366 PLOAD t0, probs + 3 * PMULT
\r
367 cmovae probNext, t0
\r
369 mov t0, kBitModelOffset
\r
370 cmovb t0, kBitModelTotal_reg
\r
371 lea t1_R, [probs + 3 * PMULT]
\r
372 cmovae sym2_R, t1_R
\r
373 PUP prob, probs + 1 * PMULT
\r
377 REV_1 macro prob:req, probNext:req, step:req
\r
378 add sym2_R, step * PMULT
\r
379 PLOAD probNext, sym2_R
\r
384 PLOAD t0, sym2_R + step * PMULT
\r
385 cmovae probNext, t0
\r
387 mov t0, kBitModelOffset
\r
388 cmovb t0, kBitModelTotal_reg
\r
389 lea t1_R, [sym2_R + step * PMULT]
\r
390 cmovae sym2_R, t1_R
\r
391 PUP prob, t1_R - step * PMULT_2
\r
395 REV_2 macro prob:req, step:req
\r
403 lea t0, [sym - step]
\r
406 mov t0, kBitModelOffset
\r
407 cmovb t0, kBitModelTotal_reg
\r
408 PUP prob, probs + sym2_R * PMULT
\r
412 REV_1_VAR macro prob:req
\r
420 lea t0_R, [sym_R + 1 * sym2_R]
\r
422 mov t0, kBitModelOffset
\r
424 ; mov t1, kBitModelTotal
\r
426 cmovb t0, kBitModelTotal_reg
\r
434 LIT_PROBS macro lpMaskParam:req
\r
435 ; prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc);
\r
436 mov t0, processedPos
\r
439 and sym, lpMaskParam
\r
440 add probs_state_R, pbPos_R
\r
442 lea sym, dword ptr[sym_R + 2 * sym_R]
\r
443 add probs, Literal * PMULT
\r
446 UPDATE_0 probs_state_R, 0, IsMatch
\r
452 kNumPosBitsMax equ 4
\r
453 kNumPosStatesMax equ (1 SHL kNumPosBitsMax)
\r
455 kLenNumLowBits equ 3
\r
456 kLenNumLowSymbols equ (1 SHL kLenNumLowBits)
\r
457 kLenNumHighBits equ 8
\r
458 kLenNumHighSymbols equ (1 SHL kLenNumHighBits)
\r
459 kNumLenProbs equ (2 * kLenNumLowSymbols * kNumPosStatesMax + kLenNumHighSymbols)
\r
462 LenChoice equ LenLow
\r
463 LenChoice2 equ (LenLow + kLenNumLowSymbols)
\r
464 LenHigh equ (LenLow + 2 * kLenNumLowSymbols * kNumPosStatesMax)
\r
468 kNumLitStates equ 7
\r
470 kStartPosModelIndex equ 4
\r
471 kEndPosModelIndex equ 14
\r
472 kNumFullDistances equ (1 SHL (kEndPosModelIndex SHR 1))
\r
474 kNumPosSlotBits equ 6
\r
475 kNumLenToPosStates equ 4
\r
477 kNumAlignBits equ 4
\r
478 kAlignTableSize equ (1 SHL kNumAlignBits)
\r
481 kMatchSpecLenStart equ (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols)
\r
483 kStartOffset equ 1664
\r
484 SpecPos equ (-kStartOffset)
\r
485 IsRep0Long equ (SpecPos + kNumFullDistances)
\r
486 RepLenCoder equ (IsRep0Long + (kNumStates2 SHL kNumPosBitsMax))
\r
487 LenCoder equ (RepLenCoder + kNumLenProbs)
\r
488 IsMatch equ (LenCoder + kNumLenProbs)
\r
489 kAlign equ (IsMatch + (kNumStates2 SHL kNumPosBitsMax))
\r
490 IsRep equ (kAlign + kAlignTableSize)
\r
491 IsRepG0 equ (IsRep + kNumStates)
\r
492 IsRepG1 equ (IsRepG0 + kNumStates)
\r
493 IsRepG2 equ (IsRepG1 + kNumStates)
\r
494 PosSlot equ (IsRepG2 + kNumStates)
\r
495 Literal equ (PosSlot + (kNumLenToPosStates SHL kNumPosSlotBits))
\r
496 NUM_BASE_PROBS equ (Literal + kStartOffset)
\r
499 .err <Stop_Compiling_Bad_LZMA_kAlign>
\r
502 if NUM_BASE_PROBS ne 1984
\r
503 .err <Stop_Compiling_Bad_LZMA_PROBS>
\r
509 CLzmaDec_Asm struct
\r
516 probs_Spec PTR_FIELD
\r
517 probs_1664 PTR_FIELD
\r
519 dicBufSize PTR_FIELD
\r
520 dicPos_Spec PTR_FIELD
\r
525 processedPos_Spec dd ?
\r
536 CLzmaDec_Asm_Loc struct
\r
542 dicBufSize PTR_FIELD
\r
543 probs_Spec PTR_FIELD
\r
555 dicPos_Spec PTR_FIELD
\r
560 CLzmaDec_Asm_Loc ends
\r
563 GLOB_2 equ [sym_R].CLzmaDec_Asm.
\r
564 GLOB equ [r1].CLzmaDec_Asm.
\r
565 LOC_0 equ [r0].CLzmaDec_Asm_Loc.
\r
566 LOC equ [RSP].CLzmaDec_Asm_Loc.
\r
569 COPY_VAR macro name
\r
570 mov t0, GLOB_2 name
\r
575 RESTORE_VAR macro name
\r
582 IsMatchBranch_Pre macro reg
\r
583 ; prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
\r
584 mov pbPos, LOC pbMask
\r
585 and pbPos, processedPos
\r
586 shl pbPos, (kLenNumLowBits + 1 + PSHIFT)
\r
587 lea probs_state_R, [probs + 1 * state_R]
\r
591 IsMatchBranch macro reg
\r
593 IF_BIT_1 probs_state_R, pbPos_R, IsMatch, IsMatch_label
\r
597 CheckLimits macro reg
\r
598 cmp buf, LOC bufLimit
\r
600 cmp dicPos, LOC limit
\r
606 ; RSP is (16x + 8) bytes aligned in WIN64-x64
\r
607 ; LocalSize equ ((((SIZEOF CLzmaDec_Asm_Loc) + 7) / 16 * 16) + 8)
\r
609 PARAM_lzma equ REG_ABI_PARAM_0
\r
610 PARAM_limit equ REG_ABI_PARAM_1
\r
611 PARAM_bufLimit equ REG_ABI_PARAM_2
\r
614 MY_PROC LzmaDec_DecodeReal_3, 3
\r
615 MY_PUSH_PRESERVED_ABI_REGS
\r
617 lea r0, [RSP - (SIZEOF CLzmaDec_Asm_Loc)]
\r
621 mov LOC_0 Old_RSP, r5
\r
622 mov LOC_0 lzmaPtr, PARAM_lzma
\r
624 mov LOC_0 remainLen, 0 ; remainLen must be ZERO
\r
626 mov LOC_0 bufLimit, PARAM_bufLimit
\r
627 mov sym_R, PARAM_lzma ; CLzmaDec_Asm_Loc pointer for GLOB_2
\r
628 mov dic, GLOB_2 dic_Spec
\r
629 add PARAM_limit, dic
\r
630 mov LOC_0 limit, PARAM_limit
\r
637 mov dicPos, GLOB_2 dicPos_Spec
\r
639 mov LOC_0 dicPos_Spec, dicPos
\r
640 mov LOC_0 dic_Spec, dic
\r
642 mov x1_L, GLOB_2 pb
\r
646 mov LOC_0 pbMask, t0
\r
648 ; unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
\r
649 ; unsigned lc = p->prop.lc;
\r
650 ; unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc);
\r
652 mov x1_L, GLOB_2 lc
\r
659 mov x1_L, GLOB_2 lp
\r
662 mov LOC_0 lpMask, t0
\r
665 ; mov probs, GLOB_2 probs_Spec
\r
666 ; add probs, kStartOffset SHL PSHIFT
\r
667 mov probs, GLOB_2 probs_1664
\r
668 mov LOC_0 probs_Spec, probs
\r
670 mov t0_R, GLOB_2 dicBufSize
\r
671 mov LOC_0 dicBufSize, t0_R
\r
673 mov x1, GLOB_2 checkDicSize
\r
674 mov LOC_0 checkDicSize, x1
\r
676 mov processedPos, GLOB_2 processedPos_Spec
\r
678 mov state, GLOB_2 state_Spec
\r
681 mov buf, GLOB_2 buf_Spec
\r
682 mov range, GLOB_2 range_Spec
\r
683 mov cod, GLOB_2 code_Spec
\r
684 mov kBitModelTotal_reg, kBitModelTotal
\r
687 ; if (processedPos != 0 || checkDicSize != 0)
\r
688 or x1, processedPos
\r
693 cmovnz t0_R, dicPos
\r
694 movzx sym, byte ptr[t0_R - 1]
\r
698 cmp state, 4 * PMULT
\r
700 cmp state, kNumLitStates * PMULT
\r
707 ; ---------- LITERAL ----------
\r
712 LIT_PROBS lpMask_reg
\r
714 ifdef _LZMA_SIZE_OPT
\r
716 PLOAD x1, probs + 1 * PMULT
\r
739 ; mov dic, LOC dic_Spec
\r
740 mov probs, LOC probs_Spec
\r
742 mov byte ptr[dicPos], sym_L
\r
747 IF_BIT_0_NOUP probs_state_R, pbPos_R, IsMatch, lit_start
\r
749 ; jmp IsMatch_label
\r
751 ; ---------- MATCHES ----------
\r
754 UPDATE_1 probs_state_R, pbPos_R, IsMatch
\r
755 IF_BIT_1 probs_state_R, 0, IsRep, IsRep_label
\r
757 add probs, LenCoder * PMULT
\r
758 add state, kNumStates * PMULT
\r
760 ; ---------- LEN DECODE ----------
\r
762 mov len_temp, 8 - 1 - kMatchMinLen
\r
763 IF_BIT_0_NOUP probs, 0, 0, len_mid_0
\r
764 UPDATE_1 probs, 0, 0
\r
765 add probs, (1 SHL (kLenNumLowBits + PSHIFT))
\r
766 mov len_temp, -1 - kMatchMinLen
\r
767 IF_BIT_0_NOUP probs, 0, 0, len_mid_0
\r
768 UPDATE_1 probs, 0, 0
\r
769 add probs, LenHigh * PMULT - (1 SHL (kLenNumLowBits + PSHIFT))
\r
771 PLOAD x1, probs + 1 * PMULT
\r
780 mov len_temp, (kLenNumHighSymbols - kLenNumLowSymbols * 2) - 1 - kMatchMinLen
\r
781 jmp short len_mid_2 ; we use short here for MASM that doesn't optimize that code as another assembler programs
\r
785 UPDATE_0 probs, 0, 0
\r
791 mov probs, LOC probs_Spec
\r
792 cmp state, kNumStates * PMULT
\r
796 ; ---------- DECODE DISTANCE ----------
\r
797 ; probs + PosSlot + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
\r
799 mov t0, 3 + kMatchMinLen
\r
800 cmp sym, 3 + kMatchMinLen
\r
802 add probs, PosSlot * PMULT - (kMatchMinLen SHL (kNumPosSlotBits + PSHIFT))
\r
803 shl t0, (kNumPosSlotBits + PSHIFT)
\r
807 ; mov LOC remainLen, sym
\r
810 ifdef _LZMA_SIZE_OPT
\r
812 PLOAD x1, probs + 1 * PMULT
\r
835 mov probs, LOC probs_Spec
\r
836 cmp x1, 32 + kEndPosModelIndex / 2
\r
839 ; unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));
\r
840 sub x1, (32 + 1 + kNumAlignBits)
\r
841 ; distance = (2 | (distance & 1));
\r
843 PLOAD x2, probs + 1 * PMULT
\r
844 shl sym, kNumAlignBits + 1
\r
845 lea sym2_R, [probs + 2 * PMULT]
\r
848 ; lea t1, [sym_R + (1 SHL kNumAlignBits)]
\r
849 ; cmp range, kTopValue
\r
852 ; ---------- DIRECT DISTANCE ----------
\r
865 lea sym, dword ptr [r2 + sym_R * 2 + 1]
\r
874 lea t1, [sym_R + (1 SHL kNumAlignBits)]
\r
875 cmp range, kTopValue
\r
876 jae near ptr direct_loop
\r
877 ; we align for 32 here with "near ptr" command above
\r
884 ; distance <<= kNumAlignBits;
\r
892 ; if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize))
\r
898 mov t0, LOC checkDicSize
\r
900 cmove t0, processedPos
\r
903 ; jmp end_of_payload ; for debug
\r
908 ; rep0 = distance + 1;
\r
912 ; mov sym, LOC remainLen
\r
918 ; state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
\r
919 cmp state, (kNumStates + kNumLitStates) * PMULT
\r
920 mov state, kNumLitStates * PMULT
\r
921 mov t0, (kNumLitStates + 3) * PMULT
\r
925 ; ---------- COPY MATCH ----------
\r
928 ; len += kMatchMinLen;
\r
929 ; add sym, kMatchMinLen
\r
931 ; if ((rem = limit - dicPos) == 0)
\r
933 ; p->dicPos = dicPos;
\r
934 ; return SZ_ERROR_DATA;
\r
936 mov cnt_R, LOC limit
\r
938 jz fin_dicPos_LIMIT
\r
940 ; curLen = ((rem < len) ? (unsigned)rem : len);
\r
942 ; cmovae cnt_R, sym_R ; 64-bit
\r
943 cmovae cnt, sym ; 32-bit
\r
945 mov dic, LOC dic_Spec
\r
950 ; processedPos += curLen;
\r
951 add processedPos, cnt
\r
954 mov LOC remainLen, sym
\r
958 ; pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);
\r
962 mov r1, LOC dicBufSize
\r
966 ja copy_match_cross
\r
968 ; if (curLen <= dicBufSize - pos)
\r
970 ; ---------- COPY MATCH FAST ----------
\r
971 ; Byte *dest = dic + dicPos;
\r
973 ; ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
\r
975 ; dicPos += curLen;
\r
977 ; const Byte *lim = dest + curLen;
\r
979 movzx sym, byte ptr[t0_R]
\r
982 ; lea r1, [dicPos - 1]
\r
989 ; r1 - dest_lim - 1
\r
997 mov byte ptr[cnt_R * 1 + dicPos], sym_L
\r
998 movzx sym, byte ptr[cnt_R * 1 + t0_R]
\r
1004 mov byte ptr[dicPos], sym_L
\r
1007 ; IsMatchBranch_Pre
\r
1010 IF_BIT_1_NOUP probs_state_R, pbPos_R, IsMatch, IsMatch_label
\r
1014 ; ---------- LITERAL MATCHED ----------
\r
1016 LIT_PROBS LOC lpMask
\r
1018 ; matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
\r
1020 ; mov dic, LOC dic_Spec
\r
1021 mov LOC dicPos_Spec, dicPos
\r
1023 ; state -= (state < 10) ? 3 : 6;
\r
1024 lea t0, [state_R - 6 * PMULT]
\r
1025 sub state, 3 * PMULT
\r
1026 cmp state, 7 * PMULT
\r
1032 add dicPos, LOC dicBufSize
\r
1037 cmovb t0_R, LOC dicBufSize
\r
1040 movzx match, byte ptr[dic + dicPos * 1]
\r
1042 ifdef _LZMA_SIZE_OPT
\r
1044 mov offs, 256 * PMULT
\r
1045 shl match, (PSHIFT + 1)
\r
1068 mov probs, LOC probs_Spec
\r
1070 ; mov dic, LOC dic_Spec
\r
1071 mov dicPos, LOC dicPos_Spec
\r
1072 mov byte ptr[dicPos], sym_L
\r
1077 IF_BIT_1_NOUP probs_state_R, pbPos_R, IsMatch, IsMatch_label
\r
1079 mov lpMask_reg, LOC lpMask
\r
1080 sub state, 3 * PMULT
\r
1085 ; ---------- REP 0 LITERAL ----------
\r
1087 IsRep0Short_label:
\r
1088 UPDATE_0 probs_state_R, pbPos_R, IsRep0Long
\r
1090 ; dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
\r
1091 mov dic, LOC dic_Spec
\r
1093 mov probBranch, LOC rep0
\r
1096 sub probs, RepLenCoder * PMULT
\r
1098 ; state = state < kNumLitStates ? 9 : 11;
\r
1099 or state, 1 * PMULT
\r
1101 ; the caller doesn't allow (dicPos >= limit) case for REP_SHORT
\r
1102 ; so we don't need the following (dicPos == limit) check here:
\r
1103 ; cmp dicPos, LOC limit
\r
1104 ; jae fin_dicPos_LIMIT_REP_SHORT
\r
1111 ; sub t0_R, probBranch_R
\r
1112 ; cmovb sym_R, LOC dicBufSize
\r
1114 sub t0_R, probBranch_R
\r
1116 add t0_R, LOC dicBufSize
\r
1118 movzx sym, byte ptr[dic + t0_R * 1]
\r
1124 UPDATE_1 probs_state_R, 0, IsRep
\r
1126 ; The (checkDicSize == 0 && processedPos == 0) case was checked before in LzmaDec.c with kBadRepCode.
\r
1127 ; So we don't check it here.
\r
1129 ; mov t0, processedPos
\r
1130 ; or t0, LOC checkDicSize
\r
1133 ; state = state < kNumLitStates ? 8 : 11;
\r
1134 cmp state, kNumLitStates * PMULT
\r
1135 mov state, 8 * PMULT
\r
1136 mov probBranch, 11 * PMULT
\r
1137 cmovae state, probBranch
\r
1139 ; prob = probs + RepLenCoder;
\r
1140 add probs, RepLenCoder * PMULT
\r
1142 IF_BIT_1 probs_state_R, 0, IsRepG0, IsRepG0_label
\r
1143 IF_BIT_0_NOUP probs_state_R, pbPos_R, IsRep0Long, IsRep0Short_label
\r
1144 UPDATE_1 probs_state_R, pbPos_R, IsRep0Long
\r
1149 UPDATE_1 probs_state_R, 0, IsRepG0
\r
1150 mov dist2, LOC rep0
\r
1151 mov dist, LOC rep1
\r
1152 mov LOC rep1, dist2
\r
1154 IF_BIT_1 probs_state_R, 0, IsRepG1, IsRepG1_label
\r
1155 mov LOC rep0, dist
\r
1160 UPDATE_1 probs_state_R, 0, IsRepG1
\r
1161 mov dist2, LOC rep2
\r
1162 mov LOC rep2, dist
\r
1164 IF_BIT_1 probs_state_R, 0, IsRepG2, IsRepG2_label
\r
1165 mov LOC rep0, dist2
\r
1170 UPDATE_1 probs_state_R, 0, IsRepG2
\r
1171 mov dist, LOC rep3
\r
1172 mov LOC rep3, dist2
\r
1173 mov LOC rep0, dist
\r
1178 ; ---------- SPEC SHORT DISTANCE ----------
\r
1183 jbe decode_dist_end
\r
1186 lea sym_R, [probs + sym_R * PMULT + SpecPos * PMULT + 1 * PMULT]
\r
1187 mov sym2, PMULT ; step
\r
1194 mov probs, LOC probs_Spec
\r
1196 sub sym, SpecPos * PMULT
\r
1200 jmp decode_dist_end
\r
1203 ; ---------- COPY MATCH CROSS ----------
\r
1206 ; r1 - len to dicBufSize
\r
1207 ; cnt_R - total copy len
\r
1209 mov t1_R, t0_R ; srcPos
\r
1211 mov r1, LOC dicBufSize ;
\r
1214 movzx sym, byte ptr[t1_R * 1 + t0_R]
\r
1216 mov byte ptr[cnt_R * 1 + dicPos], sym_L
\r
1221 movzx sym, byte ptr[t0_R]
\r
1228 ; fin_dicPos_LIMIT_REP_SHORT:
\r
1232 mov LOC remainLen, sym
\r
1234 ; For more strict mode we can stop decoding with error
\r
1239 fin_ERROR_MATCH_DIST:
\r
1244 ; rep0 = distance + 1;
\r
1246 add len_temp, kMatchSpecLen_Error_Data
\r
1247 mov LOC remainLen, len_temp
\r
1254 ; state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
\r
1255 cmp state, (kNumStates + kNumLitStates) * PMULT
\r
1256 mov state, kNumLitStates * PMULT
\r
1257 mov t0, (kNumLitStates + 3) * PMULT
\r
1266 jnz fin_ERROR_MATCH_DIST
\r
1268 mov LOC remainLen, kMatchSpecLenStart
\r
1269 sub state, kNumStates * PMULT
\r
1277 mov r1, LOC lzmaPtr
\r
1279 sub dicPos, LOC dic_Spec
\r
1280 mov GLOB dicPos_Spec, dicPos
\r
1281 mov GLOB buf_Spec, buf
\r
1282 mov GLOB range_Spec, range
\r
1283 mov GLOB code_Spec, cod
\r
1285 mov GLOB state_Spec, state
\r
1286 mov GLOB processedPos_Spec, processedPos
\r
1288 RESTORE_VAR(remainLen)
\r
1296 mov RSP, LOC Old_RSP
\r
1298 MY_POP_PRESERVED_ABI_REGS
\r
1301 _TEXT$LZMADECOPT ENDS
\r