Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

unlzma.S 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  1. /*
  2. * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. */
  19. FILE_LICENCE ( GPL2_OR_LATER );
  20. /****************************************************************************
  21. *
  22. * This file provides the decompress() and decompress16() functions
  23. * which can be called in order to decompress an LZMA-compressed
  24. * image. The code is modelled on the public-domain "XZ Embedded"
  25. * implementation as used by the Linux kernel. Symbol names are
  26. * chosen to match the XZ Embedded implementation where possible, for
  27. * ease of reference.
  28. *
  29. * This code is optimised for size rather than speed, since the amount
  30. * of data to be decompressed is trivially small by modern standards.
  31. *
  32. * The same basic assembly code is used to compile both decompress()
  33. * and decompress16().
  34. *
  35. * Note that these functions require large amounts of stack space.
  36. *
  37. ****************************************************************************
  38. */
  39. .text
  40. .arch i586
  41. .section ".prefix.lib", "ax", @progbits
  42. #ifdef CODE16
  43. #define ADDR16
  44. #define ADDR32 addr32
  45. #define decompress decompress16
  46. .code16
  47. #else /* CODE16 */
  48. #define ADDR16 addr16
  49. #define ADDR32
  50. .code32
  51. #endif /* CODE16 */
  52. /****************************************************************************
  53. * Debugging (via 0xe9 debug port)
  54. ****************************************************************************
  55. */
  56. #define DEBUG 0
  57. #if DEBUG
  58. .macro print_character, char
  59. pushw %ax
  60. movb $\char, %al
  61. outb %al, $0xe9
  62. popw %ax
  63. .endm
  64. .macro print_hex_nibble
  65. cmpb $10, %al
  66. sbb $0x69, %al
  67. das
  68. outb %al, $0xe9
  69. .endm
  70. .macro print_hex_byte, reg
  71. pushfl
  72. pushw %ax
  73. movb \reg, %al
  74. pushw %ax
  75. shrb $4, %al
  76. print_hex_nibble
  77. popw %ax
  78. andb $0x0f, %al
  79. print_hex_nibble
  80. popw %ax
  81. popfl
  82. .endm
  83. .macro print_hex_word, reg
  84. pushw %ax
  85. movw \reg, %ax
  86. print_hex_byte %ah
  87. print_hex_byte %al
  88. popw %ax
  89. .endm
  90. .macro print_hex_dword, reg
  91. pushl %eax
  92. movl \reg, %eax
  93. rorl $16, %eax
  94. print_hex_word %ax
  95. rorl $16, %eax
  96. print_hex_word %ax
  97. popl %eax
  98. .endm
  99. #else
  100. .macro print_character, char
  101. .endm
  102. .macro print_hex_byte, reg
  103. .endm
  104. .macro print_hex_word, reg
  105. .endm
  106. .macro print_hex_dword, reg
  107. .endm
  108. #endif
  109. /****************************************************************************
  110. * LZMA parameters and data structures
  111. ****************************************************************************
  112. */
  113. /* LZMA decompressor states (as used in XZ Embedded) */
  114. #define STATE_LIT_LIT 0x00
  115. #define STATE_MATCH_LIT_LIT 0x01
  116. #define STATE_REP_LIT_LIT 0x02
  117. #define STATE_SHORTREP_LIT_LIT 0x03
  118. #define STATE_MATCH_LIT 0x04
  119. #define STATE_REP_LIT 0x05
  120. #define STATE_SHORTREP_LIT 0x06
  121. #define STATE_LIT_MATCH 0x07
  122. #define STATE_LIT_LONGREP 0x08
  123. #define STATE_LIT_SHORTREP 0x09
  124. #define STATE_NONLIT_MATCH 0x0a
  125. #define STATE_NONLIT_REP 0x0b
  126. /* LZMA maximum decompressor state in which most recent symbol was a literal */
  127. #define STATE_LIT_MAX 0x06
  128. /* LZMA number of literal context bits ("lc=" parameter) */
  129. #define LZMA_LC 2
  130. .struct 0
  131. lzma_len_dec:
  132. choice: .word 0
  133. choice2: .word 0
  134. low: .rept ( 1 << 3 )
  135. .word 0
  136. .endr
  137. mid: .rept ( 1 << 3 )
  138. .word 0
  139. .endr
  140. high: .rept ( 1 << 8 )
  141. .word 0
  142. .endr
  143. .equ sizeof__lzma_len_dec, . - lzma_len_dec
  144. .previous
  145. .struct 0
  146. lzma_dec:
  147. in_start: .long 0
  148. out_start: .long 0
  149. rc_code: .long 0
  150. rc_range: .long 0
  151. len: .word 0
  152. reps:
  153. rep0: .long 0
  154. rep1: .long 0
  155. rep2: .long 0
  156. rep3: .long 0
  157. probs:
  158. is_match: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  159. is_rep: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  160. is_rep0: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  161. is_rep1: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  162. is_rep2: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  163. is_rep0_long: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  164. dist_slot: .rept ( 4 * ( 1 << 6 ) )
  165. .word 0
  166. .endr
  167. dist_special: .rept ( ( 1 << ( 14 / 2 ) ) - 14 )
  168. .word 0
  169. .endr
  170. dist_align: .rept ( 1 << 4 )
  171. .word 0
  172. .endr
  173. match_len_dec: .space sizeof__lzma_len_dec
  174. rep_len_dec: .space sizeof__lzma_len_dec
  175. literal: .rept ( ( 1 << LZMA_LC ) * 0x300 )
  176. .word 0
  177. .endr
  178. .align 4
  179. .equ sizeof__lzma_dec, . - lzma_dec
  180. .previous
  181. /*****************************************************************************
  182. * Normalise range encoder
  183. *
  184. * Parameters:
  185. * %ss:%ebp : LZMA parameter block
  186. * %ds:%esi : compressed input data pointer
  187. * Returns:
  188. * %ds:%esi : compressed input data pointer (possibly updated)
  189. * %eax : current range
  190. * Corrupts:
  191. * %eax
  192. *****************************************************************************
  193. */
  194. rc_normalise:
  195. /* Check if rc_range is less than 1<<24 */
  196. testb $0xff, (rc_range+3)(%ebp)
  197. jnz 1f
  198. /* If it is, shift in a new byte from the compressed input data */
  199. shll $8, rc_range(%ebp)
  200. shll $8, rc_code(%ebp)
  201. ADDR32 lodsb
  202. movb %al, (rc_code+0)(%ebp)
  203. 1: /* Return current range */
  204. movl rc_range(%ebp), %eax
  205. ret
  206. .size rc_normalise, . - rc_normalise
  207. /*****************************************************************************
  208. * Decode single range-encoded bit using a probability estimate
  209. *
  210. * Parameters:
  211. * %ss:%ebp : LZMA parameter block
  212. * %ds:%esi : compressed input data pointer
  213. * %ebx : probability estimate pointer (offset from %ebp)
  214. * Returns:
  215. * %ds:%esi : compressed input data pointer (possibly updated)
  216. * CF : decoded bit
  217. * ZF : inverse of decoded bit
  218. * Corrupts:
  219. * none
  220. *****************************************************************************
  221. */
  222. rc_bit:
  223. /* Preserve registers */
  224. pushl %eax
  225. pushl %edx
  226. /* Perform normalisation */
  227. call rc_normalise
  228. /* Calculate bound in %eax and probability estimate in %dx */
  229. shrl $11, %eax
  230. movzwl (%ebp,%ebx), %edx
  231. mul %edx /* will zero %edx */
  232. movw (%ebp,%ebx), %dx
  233. /* Compare code against bound */
  234. cmpl %eax, rc_code(%ebp)
  235. jae 2f
  236. 1: /* Code is less than bound */
  237. movl %eax, rc_range(%ebp)
  238. negw %dx
  239. addw $(1<<11), %dx
  240. shrw $5, %dx
  241. addw %dx, (%ebp,%ebx)
  242. xorw %ax, %ax /* Clear CF, set ZF */
  243. jmp 99f
  244. 2: /* Code is greater than or equal to bound */
  245. subl %eax, rc_range(%ebp)
  246. subl %eax, rc_code(%ebp)
  247. shrw $5, %dx
  248. subw %dx, (%ebp,%ebx)
  249. incw %dx /* Clear ZF (%dx is 11-bit; can never wrap) */
  250. stc /* Set CF */
  251. 99: /* Restore registers and return */
  252. popl %edx
  253. popl %eax
  254. ret
  255. .size rc_bit, . - rc_bit
  256. /*****************************************************************************
  257. * Decode MSB-first bittree
  258. *
  259. * Parameters:
  260. * %ss:%ebp : LZMA parameter block
  261. * %ds:%esi : compressed input data pointer
  262. * %ebx : probability estimate set pointer (offset from %ebp)
  263. * %cx : number of bits to decode
  264. * Returns:
  265. * %ds:%esi : compressed input data pointer (possibly updated)
  266. * %eax : decoded bittree
  267. * Corrupts:
  268. * none
  269. *****************************************************************************
  270. */
  271. rc_bittree:
  272. /* Preserve registers */
  273. pushl %edi
  274. pushw %cx
  275. movl %ebx, %edi
  276. /* Initialise registers */
  277. movl $1, %eax
  278. 1: /* Decode bit */
  279. leaw (%edi,%eax,2), %bx /* high word always zero anyway */
  280. call rc_bit
  281. rclw %ax
  282. ADDR16 loop 1b
  283. /* Restore registers, clear unwanted high bit of result, and return */
  284. movl %edi, %ebx
  285. popw %cx
  286. popl %edi
  287. btrw %cx, %ax
  288. ret
  289. .size rc_bittree, . - rc_bittree
  290. /*****************************************************************************
  291. * Decode LSB-first bittree
  292. *
  293. * Parameters:
  294. * %ss:%ebp : LZMA parameter block
  295. * %ds:%esi : compressed input data pointer
  296. * %ebx : probability estimate set pointer (offset from %ebp)
  297. * %cx : number of bits to decode
  298. * Returns:
  299. * %ds:%esi : compressed input data pointer (possibly updated)
  300. * %eax : decoded bittree
  301. * Corrupts:
  302. * none
  303. *****************************************************************************
  304. */
  305. rc_bittree_reverse:
  306. /* Preserve registers */
  307. pushw %cx
  308. /* Decode bittree */
  309. call rc_bittree
  310. 1: /* Reverse result */
  311. rcrb %al
  312. rclb %ah
  313. ADDR16 loop 1b
  314. shrw $8, %ax
  315. /* Restore registers and return */
  316. popw %cx
  317. ret
  318. .size rc_bittree_reverse, . - rc_bittree_reverse
  319. /*****************************************************************************
  320. * Decode MSB-first bittree with optional match byte
  321. *
  322. * Parameters:
  323. * %ss:%ebp : LZMA parameter block
  324. * %ds:%esi : compressed input data pointer
  325. * %ebx : probability estimate set pointer (offset from %ebp)
  326. * %cl : match byte
  327. * %ch : 1 to use match byte, 0 to ignore match byte
  328. * Returns:
  329. * %ds:%esi : compressed input data pointer (possibly updated)
  330. * %eax : decoded bittree
  331. * Corrupts:
  332. * none
  333. *****************************************************************************
  334. */
  335. rc_bittree_match:
  336. /* Preserve registers */
  337. pushl %edi
  338. pushw %cx
  339. pushw %dx
  340. movl %ebx, %edi
  341. /* Initialise registers */
  342. movl $1, %eax
  343. 1: /* Decode bit */
  344. rolb $1, %cl
  345. movw %cx, %dx
  346. andb %dh, %dl /* match_bit in %dl */
  347. movw %dx, %bx
  348. addb %bl, %bh
  349. xorb %bl, %bl
  350. addw %ax, %bx /* offset + match_bit + symbol */
  351. leaw (%edi,%ebx,2), %bx /* high word always zero anyway */
  352. call rc_bit
  353. rclw %ax
  354. movb %al, %dh
  355. notb %dh
  356. xorb %dh, %dl
  357. andb %dl, %ch /* offset &= ( match_bit ^ bit ) */
  358. testb %ah, %ah
  359. jz 1b
  360. /* Restore registers, clear unwanted high bit of result, and return */
  361. movl %edi, %ebx
  362. popw %dx
  363. popw %cx
  364. popl %edi
  365. xorb %ah, %ah
  366. ret
  367. .size rc_bittree_match, . - rc_bittree_match
  368. /*****************************************************************************
  369. * Decode direct bits (no probability estimates)
  370. *
  371. * Parameters:
  372. * %ss:%ebp : LZMA parameter block
  373. * %ds:%esi : compressed input data pointer
  374. * %cx : number of bits to decode
  375. * Returns:
  376. * %ds:%esi : compressed input data pointer (possibly updated)
  377. * %eax : decoded bits
  378. * Corrupts:
  379. * none
  380. *****************************************************************************
  381. */
  382. rc_direct:
  383. /* Preserve registers */
  384. pushl %ebx
  385. pushw %cx
  386. pushl %edx
  387. /* Initialise registers */
  388. xorl %edx, %edx
  389. 1: /* Perform normalisation */
  390. call rc_normalise
  391. /* Decode bit */
  392. shrl $1, %eax
  393. movl %eax, rc_range(%ebp)
  394. movl rc_code(%ebp), %ebx
  395. subl %eax, %ebx
  396. js 2f
  397. movl %ebx, rc_code(%ebp)
  398. 2: rcll %ebx
  399. rcll %edx
  400. xorb $1, %dl
  401. ADDR16 loop 1b
  402. /* Restore registers and return */
  403. movl %edx, %eax
  404. popl %edx
  405. popw %cx
  406. popl %ebx
  407. ret
  408. .size rc_direct, . - rc_direct
  409. /*****************************************************************************
  410. * Decode an LZMA literal
  411. *
  412. * Parameters:
  413. * %ss:%ebp : LZMA parameter block
  414. * %ds:%esi : compressed input data pointer
  415. * %es:%edi : uncompressed output data pointer
  416. * %edx : LZMA state
  417. * Returns:
  418. * %ds:%esi : compressed input data pointer (possibly updated)
  419. * %es:%edi : uncompressed output data pointer (updated)
  420. * %edx : LZMA state
  421. * CF : end of payload marker found (always zero)
  422. * Corrupts:
  423. * %eax
  424. * %ebx
  425. * %ecx
  426. *****************************************************************************
  427. *
  428. * Literals are coded as an eight-bit tree, using a match byte if the
  429. * previous symbol was not a literal.
  430. *
  431. */
  432. lzma_literal:
  433. /* Get most recent output byte, if available */
  434. xorl %ebx, %ebx
  435. cmpl %esi, in_start(%ebp)
  436. je 1f
  437. movb %es:-1(%edi), %bh
  438. 1: /* Locate probability estimate set */
  439. shrb $( 8 - LZMA_LC ), %bh
  440. shlb $1, %bh
  441. leaw literal(%ebx,%ebx,2), %bx
  442. /* Get match byte, if applicable */
  443. xorw %cx, %cx
  444. cmpb $STATE_LIT_MAX, %dl
  445. jbe 1f
  446. movl rep0(%ebp), %eax
  447. notl %eax
  448. movb %es:(%edi,%eax), %cl
  449. movb $1, %ch
  450. 1: /* Decode bittree */
  451. call rc_bittree_match
  452. /* Store output byte */
  453. ADDR32 stosb
  454. print_hex_byte %al
  455. print_character ' '
  456. /* Update LZMA state */
  457. subb $3, %dl
  458. jns 1f
  459. xorb %dl, %dl
  460. 1: cmpb $7, %dl
  461. jb 1f
  462. subb $3, %dl
  463. 1: /* Clear CF and return */
  464. clc
  465. ret
  466. .size lzma_literal, . - lzma_literal
  467. /*****************************************************************************
  468. * Decode an LZMA length
  469. *
  470. * Parameters:
  471. * %ss:%ebp : LZMA parameter block
  472. * %ds:%esi : compressed input data pointer
  473. * %ebx : length parameter pointer (offset from %ebp)
  474. * Returns:
  475. * %ds:%esi : compressed input data pointer (possibly updated)
  476. * Corrupts:
  477. * %ebx
  478. *****************************************************************************
  479. *
  480. * Lengths are encoded as:
  481. *
  482. * "0" + 3 bits : lengths 2-9 ("low")
  483. * "10" + 3 bits : lengths 10-17 ("mid")
  484. * "11" + 8 bits : lengths 18-273 ("high")
  485. */
  486. lzma_len:
  487. /* Preserve registers */
  488. pushl %eax
  489. pushl %ecx
  490. pushl %edi
  491. movl %ebx, %edi
  492. /* Start by assuming three bits and a base length of 2 */
  493. movw $3, %cx
  494. movw $2, len(%ebp)
  495. /* Check low-length choice bit */
  496. leal choice(%edi), %ebx
  497. call rc_bit
  498. leal low(%edi), %ebx
  499. jz 1f
  500. /* Check high-length choice bit */
  501. leal choice2(%edi), %ebx
  502. call rc_bit
  503. leal mid(%edi), %ebx
  504. movb $10, len(%ebp)
  505. jz 1f
  506. leal high(%edi), %ebx
  507. movb $8, %cl
  508. movb $18, len(%ebp)
  509. 1: /* Get encoded length */
  510. call rc_bittree
  511. addw %ax, len(%ebp)
  512. /* Restore registers and return */
  513. movl %edi, %ebx
  514. popl %edi
  515. popl %ecx
  516. popl %eax
  517. ret
  518. .size lzma_len, . - lzma_len
  519. /*****************************************************************************
  520. * Copy (possibly repeated) matched data
  521. *
  522. * Parameters:
  523. * %ss:%ebp : LZMA parameter block
  524. * %ds:%esi : compressed input data pointer
  525. * %es:%edi : uncompressed output data pointer
  526. * %cl : repeated match distance index (for repeated matches)
  527. * %eax : match distance (for non-repeated matches)
  528. * Returns:
  529. * %ds:%esi : compressed input data pointer (possibly updated)
  530. * %es:%edi : uncompressed output data pointer
  531. * CF : match distance is out of range
  532. * Corrupts:
  533. * %eax
  534. * %ebx
  535. * %ecx
  536. *****************************************************************************
  537. */
  538. match: /* Update repeated match list */
  539. print_character '['
  540. movl $3, %ecx
  541. jmp 1f
  542. match_rep:
  543. print_character '['
  544. print_character 'R'
  545. print_hex_byte %cl
  546. print_character '='
  547. movzbl %cl, %ecx
  548. movl reps(%ebp,%ecx,4), %eax
  549. jcxz 2f
  550. 1: movl (reps-4)(%ebp,%ecx,4), %ebx
  551. movl %ebx, reps(%ebp,%ecx,4)
  552. loop 1b
  553. movl %eax, rep0(%ebp)
  554. 2: /* Preserve registers */
  555. pushl %esi
  556. /* Get stored match length */
  557. movzwl len(%ebp), %ecx
  558. print_hex_dword %eax
  559. print_character '+'
  560. print_hex_word %cx
  561. print_character ']'
  562. print_character ' '
  563. /* Abort with CF set if match distance is out of range */
  564. movl out_start(%ebp), %esi
  565. negl %esi
  566. leal -1(%edi,%esi), %esi
  567. cmpl %eax, %esi
  568. jc 99f
  569. /* Perform copy */
  570. notl %eax
  571. leal (%edi,%eax), %esi
  572. ADDR32 es rep movsb
  573. 99: /* Restore registers and return */
  574. popl %esi
  575. ret
  576. .size match, . - match
  577. /*****************************************************************************
  578. * Decode an LZMA match
  579. *
  580. * Parameters:
  581. * %ss:%ebp : LZMA parameter block
  582. * %ds:%esi : compressed input data pointer
  583. * %es:%edi : uncompressed output data pointer
  584. * %edx : LZMA state
  585. * Returns:
  586. * %ds:%esi : compressed input data pointer (possibly updated)
  587. * %es:%edi : uncompressed output data pointer
  588. * %edx : LZMA state
  589. * CF : end of payload marker found
  590. * Corrupts:
  591. * %eax
  592. * %ebx
  593. * %ecx
  594. *****************************************************************************
  595. *
  596. * Matches are encoded as an LZMA length followed by a 6-bit "distance
  597. * slot" code, 0-26 fixed-probability bits, and 0-5 context encoded
  598. * bits.
  599. */
  600. lzma_match:
  601. /* Preserve registers */
  602. pushl %edi
  603. /* Update LZMA state */
  604. cmpb $STATE_LIT_MAX, %dl
  605. movb $STATE_LIT_MATCH, %dl
  606. jbe 1f
  607. movb $STATE_NONLIT_MATCH, %dl
  608. 1: /* Decode length */
  609. movl $match_len_dec, %ebx
  610. call lzma_len
  611. /* Decode distance slot */
  612. movw len(%ebp), %bx
  613. subw $2, %bx
  614. cmpw $4, %bx
  615. jb 1f
  616. movw $3, %bx
  617. 1: shlw $7, %bx
  618. addw $dist_slot, %bx
  619. movw $6, %cx
  620. call rc_bittree
  621. /* Distance slots 0-3 are literal distances */
  622. cmpb $4, %al
  623. jb 99f
  624. /* Determine initial bits: 10/11 for even/odd distance codes */
  625. movl %eax, %edi
  626. andw $1, %di
  627. orw $2, %di
  628. /* Determine number of context-encoded bits */
  629. movw %ax, %cx
  630. shrb $1, %cl
  631. decb %cl
  632. /* Select context to be used in absence of fixed-probability bits */
  633. movl %edi, %ebx
  634. shlw %cl, %bx
  635. subw %ax, %bx
  636. leaw (dist_special-2)(%ebx,%ebx), %bx
  637. /* Decode fixed-probability bits, if any */
  638. cmpb $6, %cl
  639. jb 1f
  640. subb $4, %cl
  641. shll %cl, %edi
  642. call rc_direct
  643. orl %eax, %edi
  644. /* Select context to be used in presence of fixed-probability bits */
  645. movb $4, %cl
  646. movl $dist_align, %ebx
  647. 1: /* Decode context-encoded bits */
  648. shll %cl, %edi
  649. call rc_bittree_reverse
  650. orl %edi, %eax
  651. 99: /* Restore registers and tail-call */
  652. popl %edi
  653. jmp match
  654. .size lzma_match, . - lzma_match
  655. /*****************************************************************************
  656. * Decode an LZMA repeated match
  657. *
  658. * Parameters:
  659. * %ss:%ebp : LZMA parameter block
  660. * %ds:%esi : compressed input data pointer
  661. * %es:%edi : uncompressed output data pointer
  662. * %edx : LZMA state
  663. * Returns:
  664. * %ds:%esi : compressed input data pointer (possibly updated)
  665. * %es:%edi : uncompressed output data pointer
  666. * %edx : LZMA state
  667. * CF : end of payload marker found
  668. * Corrupts:
  669. * %eax
  670. * %ebx
  671. * %ecx
  672. *****************************************************************************
  673. *
  674. * Repeated matches are encoded as:
  675. *
  676. * "00" : shortrep0 (implicit length 1)
  677. * "01" + len : longrep0
  678. * "10" + len : longrep1
  679. * "110" + len : longrep2
  680. * "111" + len : longrep3
  681. */
  682. lzma_rep_match:
  683. /* Initially assume longrep0 */
  684. movw $(STATE_LIT_LONGREP << 8), %cx
  685. /* Get is_rep0 bit */
  686. leal is_rep0(,%edx,2), %ebx
  687. call rc_bit
  688. jnz 1f
  689. /* Get is_rep0_long bit */
  690. leal is_rep0_long(,%edx,2), %ebx
  691. call rc_bit
  692. jnz 98f
  693. movw $1, len(%ebp)
  694. movb $STATE_LIT_SHORTREP, %ch
  695. jmp 99f
  696. 1: /* Get is_rep1 bit */
  697. incb %cl
  698. leal is_rep1(,%edx,2), %ebx
  699. call rc_bit
  700. jz 98f
  701. /* Get is_rep2 bit */
  702. incb %cl
  703. leal is_rep2(,%edx,2), %ebx
  704. call rc_bit
  705. adcb $0, %cl
  706. 98: /* Decode length */
  707. movl $rep_len_dec, %ebx
  708. call lzma_len
  709. 99: /* Update LZMA state */
  710. cmpb $STATE_LIT_MAX, %dl
  711. movb %ch, %dl
  712. jbe 1f
  713. movb $STATE_NONLIT_REP, %dl
  714. 1: /* Tail call */
  715. jmp match_rep
  716. .size lzma_match, . - lzma_match
  717. /*****************************************************************************
  718. * Decode one LZMA symbol
  719. *
  720. * Parameters:
  721. * %ss:%ebp : LZMA parameter block
  722. * %ds:%esi : compressed input data pointer
  723. * %es:%edi : uncompressed output data pointer
  724. * %edx : LZMA state
  725. * Returns:
  726. * %ds:%esi : compressed input data pointer (possibly updated)
  727. * %es:%edi : uncompressed output data pointer (updated)
  728. * %edx : LZMA state
  729. * CF : end of payload marker found
  730. * Corrupts:
  731. * %eax
  732. * %ebx
  733. * %ecx
  734. *****************************************************************************
  735. */
  736. lzma_decode:
  737. /* Get is_match bit */
  738. leal is_match(,%edx,2), %ebx
  739. call rc_bit
  740. jz lzma_literal
  741. /* Get is_rep bit */
  742. leal is_rep(,%edx,2), %ebx
  743. call rc_bit
  744. jz lzma_match
  745. jmp lzma_rep_match
  746. .size lzma_decode, . - lzma_decode
  747. /****************************************************************************
  748. * Undo effect of branch-call-jump (BCJ) filter
  749. *
  750. * Parameters:
  751. * %es:%esi : start of uncompressed output data (note %es)
  752. * %es:%edi : end of uncompressed output data
  753. * Returns:
  754. * Corrupts:
  755. * %eax
  756. * %ebx
  757. * %ecx
  758. * %edx
  759. * %esi
  760. *****************************************************************************
  761. */
  762. bcj_filter:
  763. /* Store (negative) start of data in %edx */
  764. movl %esi, %edx
  765. negl %edx
  766. /* Calculate limit in %ecx */
  767. leal -5(%edi,%edx), %ecx
  768. 1: /* Calculate offset in %ebx */
  769. leal (%esi,%edx), %ebx
  770. /* Check for end of data */
  771. cmpl %ecx, %ebx
  772. ja 99f
  773. /* Check for an opcode which would be followed by a rel32 address */
  774. ADDR32 es lodsb
  775. andb $0xfe, %al
  776. cmpb $0xe8, %al
  777. jne 1b
  778. /* Get current jump target value in %eax */
  779. ADDR32 es lodsl
  780. /* Convert absolute addresses in the range [0,limit) back to
  781. * relative addresses in the range [-offset,limit-offset).
  782. */
  783. cmpl %ecx, %eax
  784. jae 2f
  785. subl %ebx,%es:-4(%esi)
  786. 2: /* Convert negative numbers in the range [-offset,0) back to
  787. * positive numbers in the range [limit-offset,limit).
  788. */
  789. notl %eax /* Range is now [0,offset) */
  790. cmpl %ebx, %eax
  791. jae 1b
  792. addl %ecx,%es:-4(%esi)
  793. jmp 1b
  794. 99: /* Return */
  795. ret
  796. .size bcj_filter, . - bcj_filter
  797. /****************************************************************************
  798. * decompress (real-mode or 16/32-bit protected-mode near call)
  799. *
  800. * Decompress data
  801. *
  802. * Parameters (passed via registers):
  803. * %ds:%esi : Start of compressed input data
  804. * %es:%edi : Start of output buffer
  805. * Returns:
  806. * %ds:%esi - End of compressed input data
  807. * %es:%edi - End of decompressed output data
  808. * All other registers are preserved
  809. *
  810. * NOTE: It would be possible to build a smaller version of the
  811. * decompression code for -DKEEP_IT_REAL by using 16-bit registers
  812. * where possible.
  813. ****************************************************************************
  814. */
  815. .globl decompress
  816. decompress:
  817. /* Preserve registers */
  818. pushl %eax
  819. pushl %ebx
  820. pushl %ecx
  821. pushl %edx
  822. pushl %ebp
  823. /* Allocate parameter block */
  824. subl $sizeof__lzma_dec, %esp
  825. movl %esp, %ebp
  826. /* Zero parameter block and set all probabilities to 0.5 */
  827. pushl %edi
  828. pushw %es
  829. pushw %ss
  830. popw %es
  831. movl %ebp, %edi
  832. xorl %eax, %eax
  833. movl $( sizeof__lzma_dec / 4 ), %ecx
  834. ADDR32 rep stosl
  835. leal probs(%ebp), %edi
  836. movw $( ( 1 << 11 ) / 2 ), %ax
  837. movl $( ( sizeof__lzma_dec - probs ) / 2 ), %ecx
  838. ADDR32 rep stosw
  839. popw %es
  840. popl %edi
  841. /* Initialise remaining parameters */
  842. movl %esi, in_start(%ebp)
  843. movl %edi, out_start(%ebp)
  844. print_character '\n'
  845. ADDR32 lodsb /* discard initial byte */
  846. print_hex_byte %al
  847. ADDR32 lodsl
  848. bswapl %eax
  849. print_hex_dword %eax
  850. print_character '\n'
  851. movl %eax, rc_code(%ebp)
  852. decl rc_range(%ebp)
  853. movl $STATE_LIT_LIT, %edx
  854. 1: /* Decompress until we reach end of buffer */
  855. call lzma_decode
  856. jnc 1b
  857. print_character '\n'
  858. /* Undo BCJ filter */
  859. pushl %esi
  860. movl out_start(%ebp), %esi
  861. call bcj_filter
  862. popl %esi
  863. /* Restore registers and return */
  864. addl $sizeof__lzma_dec, %esp
  865. popl %ebp
  866. popl %edx
  867. popl %ecx
  868. popl %ebx
  869. popl %eax
  870. ret
  871. /* Specify minimum amount of stack space required */
  872. .globl _min_decompress_stack
  873. .equ _min_decompress_stack, ( sizeof__lzma_dec + 512 /* margin */ )