wok annotate syslinux/stuff/iso2exe/unlzma.S @ rev 13713

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