aboutsummaryrefslogtreecommitdiff
path: root/src/liblzma/lzma/lzma_decoder.c
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2024-02-12 17:09:10 +0200
committerLasse Collin <lasse.collin@tukaani.org>2024-02-14 18:31:16 +0200
commiteb518446e578acf079abae5f1ce28db7b6e59bc1 (patch)
treed601fa14937bfc9d79b62a2c3c25e7b5579dbb52 /src/liblzma/lzma/lzma_decoder.c
parentliblzma: LZMA decoder improvements. (diff)
downloadxz-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.c30
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;