X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=include%2Fwimlib%2Flzms_common.h;h=093e50d2d0de1c073b926cf0a0001c6588088c50;hp=69b6e67b4dbbeebd76463be5a39e4322a838ca53;hb=5472f62361eb32dcb357a6b90ddc3f2481b68774;hpb=5343bde03c158cc767b1a347a7323d0e33c78d41 diff --git a/include/wimlib/lzms_common.h b/include/wimlib/lzms_common.h index 69b6e67b..093e50d2 100644 --- a/include/wimlib/lzms_common.h +++ b/include/wimlib/lzms_common.h @@ -76,11 +76,34 @@ lzms_update_probability_entry(struct lzms_probability_entry *entry, int bit) { BUILD_BUG_ON(LZMS_PROBABILITY_DENOMINATOR != sizeof(entry->recent_bits) * 8); - s32 delta_zero_bits = (s32)(entry->recent_bits >> - (LZMS_PROBABILITY_DENOMINATOR - 1)) - bit; - - entry->num_recent_zero_bits += delta_zero_bits; - entry->recent_bits = (entry->recent_bits << 1) | bit; +#ifdef __x86_64__ + if (__builtin_constant_p(bit)) { + /* Optimized implementation for x86_64 using carry flag */ + if (bit) { + __asm__("shlq %[recent_bits] \n" + "adcl $0xffffffff, %[num_recent_zero_bits] \n" + "orq $0x1, %[recent_bits] \n" + : [recent_bits] "+r" (entry->recent_bits), + [num_recent_zero_bits] "+mr" (entry->num_recent_zero_bits) + : + : "cc"); + } else { + __asm__("shlq %[recent_bits] \n" + "adcl $0x0, %[num_recent_zero_bits] \n" + : [recent_bits] "+m" (entry->recent_bits), + [num_recent_zero_bits] "+mr" (entry->num_recent_zero_bits) + : + : "cc"); + } + } else +#endif + { + s32 delta_zero_bits = (s32)(entry->recent_bits >> + (LZMS_PROBABILITY_DENOMINATOR - 1)) - bit; + + entry->num_recent_zero_bits += delta_zero_bits; + entry->recent_bits = (entry->recent_bits << 1) | bit; + } } /* Given a probability entry, return the chance out of @@ -91,10 +114,19 @@ lzms_get_probability(const struct lzms_probability_entry *prob_entry) u32 prob = prob_entry->num_recent_zero_bits; /* 0% and 100% probabilities aren't allowed. */ - if (prob == 0) - prob++; - else if (prob == LZMS_PROBABILITY_DENOMINATOR) - prob--; + + /* + * if (prob == 0) + * prob++; + */ + prob += (prob - 1) >> 31; + + /* + * if (prob == LZMS_PROBABILITY_DENOMINATOR) + * prob--; + */ + prob -= (prob >> LZMS_PROBABILITY_BITS); + return prob; }