summaryrefslogtreecommitdiff
path: root/upb_parse.c
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2009-06-17 15:19:19 -0700
committerJoshua Haberman <joshua@reverberate.org>2009-06-17 15:19:19 -0700
commit79d57263f59835277c2a9d855e69bf03c7ada506 (patch)
treef125a2c666ac93b9d051638b94ae8430ab62d7be /upb_parse.c
parentd1aa095cb30da50c1dac4263233b45c3a9ab726e (diff)
Improvements to one-branch varint reading function.
Diffstat (limited to 'upb_parse.c')
-rw-r--r--upb_parse.c29
1 files changed, 15 insertions, 14 deletions
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;
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback