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