diff options
author | Lasse Collin <lasse.collin@tukaani.org> | 2024-02-12 17:09:10 +0200 |
---|---|---|
committer | Lasse Collin <lasse.collin@tukaani.org> | 2024-02-14 18:31:16 +0200 |
commit | eb518446e578acf079abae5f1ce28db7b6e59bc1 (patch) | |
tree | d601fa14937bfc9d79b62a2c3c25e7b5579dbb52 /src/liblzma/lzma/lzma_decoder.c | |
parent | liblzma: LZMA decoder improvements. (diff) | |
download | xz-eb518446e578acf079abae5f1ce28db7b6e59bc1.tar.xz |
liblzma: LZMA decoder: Get rid of next_state[].
It's not completely obvious if this is better in the decoder.
It should be good if compiler can avoid creating a branch
(like using CMOV on x86).
This also makes lzma_encoder.c use the new macros.
Diffstat (limited to 'src/liblzma/lzma/lzma_decoder.c')
-rw-r--r-- | src/liblzma/lzma/lzma_decoder.c | 30 |
1 files changed, 8 insertions, 22 deletions
diff --git a/src/liblzma/lzma/lzma_decoder.c b/src/liblzma/lzma/lzma_decoder.c index 0788558f..c5049a48 100644 --- a/src/liblzma/lzma/lzma_decoder.c +++ b/src/liblzma/lzma/lzma_decoder.c @@ -307,24 +307,6 @@ lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr, might_finish_without_eopm = true; } - // Lookup table used to update the literal state. - // Compared to other state updates, this would need two branches. - // The lookup table is used by both Resumable and Non-resumable modes. - static const lzma_lzma_state next_state[] = { - STATE_LIT_LIT, - STATE_LIT_LIT, - STATE_LIT_LIT, - STATE_LIT_LIT, - STATE_MATCH_LIT_LIT, - STATE_REP_LIT_LIT, - STATE_SHORTREP_LIT_LIT, - STATE_MATCH_LIT, - STATE_REP_LIT, - STATE_SHORTREP_LIT, - STATE_MATCH_LIT, - STATE_REP_LIT - }; - // The main decoder loop. The "switch" is used to resume the decoder at // correct location. Once resumed, the "switch" is no longer used. // The decoder loops is split into two modes: @@ -381,16 +363,18 @@ lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr, dict.pos, dict_get(&dict, 0)); if (is_literal_state(state)) { + update_literal_normal(state); + // Decode literal without match byte. rc_bittree8(probs, 0); } else { + update_literal_matched(state); + // Decode literal with match byte. rc_matched_literal(probs, dict_get(&dict, rep0)); } - state = next_state[state]; - // Write decoded literal to dictionary dict_put(&dict, symbol); continue; @@ -705,6 +689,8 @@ slow: symbol = 1; if (is_literal_state(state)) { + update_literal_normal(state); + // Decode literal without match byte. // The "slow" version does not unroll // the loop. @@ -714,6 +700,8 @@ slow: SEQ_LITERAL); } while (symbol < (1 << 8)); } else { + update_literal_matched(state); + // Decode literal with match byte. len = (uint32_t)(dict_get(&dict, rep0)) << 1; @@ -742,8 +730,6 @@ slow: } while (symbol < (1 << 8)); } - state = next_state[state]; - case SEQ_LITERAL_WRITE: if (dict_put_safe(&dict, symbol)) { coder->sequence = SEQ_LITERAL_WRITE; |