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