From 79d57263f59835277c2a9d855e69bf03c7ada506 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 17 Jun 2009 15:19:19 -0700 Subject: Improvements to one-branch varint reading function. --- upb_parse.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'upb_parse.c') diff --git a/upb_parse.c b/upb_parse.c index 288fa2e..33ccb42 100644 --- a/upb_parse.c +++ b/upb_parse.c @@ -98,30 +98,31 @@ static upb_status_t get_v_uint64_t(void *restrict *buf, static upb_status_t get_v_uint64_t(void *restrict *buf, uint64_t *restrict val) { + uint8_t *b = *buf; /* Endian-specific! */ - uint64_t b0 = *(uint64_t*)*buf; + uint64_t b0 = *(uint64_t*)b; /* Put the 10 continuation bits in the bottom 10 bits of cont. */ uint32_t cont = (b0 & 0x8080808080808080ULL) * 0x2040810204081ULL >> 56; - cont |= (*(*buf+8) & 0x80) << 1 | (*(*buf+9) & 0x80) << 2; + cont |= (*(b+8) & 0x80) << 1 | (*(b+9) & 0x80) << 2; - int num_bytes = __builtin_ctzll(~cont) + 1; + int num_bytes = __builtin_ffs(~cont); uint32_t part0 = 0, part1 = 0, part2 = 0; switch(num_bytes) { default: return UPB_ERROR_UNTERMINATED_VARINT; - case 10: part2 |= ((*buf)[9] & 0x7F) << 7; - case 9: part2 |= ((*buf)[8] & 0x7F) ; - case 8: part1 |= ((*buf)[7] & 0x7F) << 21; - case 7: part1 |= ((*buf)[6] & 0x7F) << 14; - case 6: part1 |= ((*buf)[5] & 0x7F) << 7; - case 5: part1 |= ((*buf)[4] & 0x7F) ; - case 4: part0 |= ((*buf)[3] & 0x7F) << 21; - case 3: part0 |= ((*buf)[2] & 0x7F) << 14; - case 2: part0 |= ((*buf)[1] & 0x7F) << 7; - case 1: part0 |= ((*buf)[0] & 0x7F) ; + case 10: part2 |= (b[9] & 0x7F) << 7; + case 9: part2 |= (b[8] & 0x7F) ; + case 8: part1 |= (b[7] & 0x7F) << 21; + case 7: part1 |= (b[6] & 0x7F) << 14; + case 6: part1 |= (b[5] & 0x7F) << 7; + case 5: part1 |= (b[4] & 0x7F) ; + case 4: part0 |= (b[3] & 0x7F) << 21; + case 3: part0 |= (b[2] & 0x7F) << 14; + case 2: part0 |= (b[1] & 0x7F) << 7; + case 1: part0 |= (b[0] & 0x7F) ; } - *buf += num_bytes; + *buf = b + num_bytes; *val = (uint64_t)part0 | ((uint64_t)part1 << 28) | ((uint64_t)part2 << 56); return UPB_STATUS_OK; } -- cgit v1.2.3