wok annotate memtest/stuff/unlzma.S @ rev 25076

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