wok-current annotate plop/stuff/unlzma.S @ rev 25385

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