I don't have the spare cycles to test this out for myself right now, but I'm curious if a 64kb table would be substantially faster. You'd cut it down from 8 indirections, 3 shifts, and 3 ORs to 4 indirections, 1 shift, and 1 OR.
uint32_t hex_to_u32_lookup(const uint8_t *src) {
uint16_t *wsrc = (uint16_t *) src;
uint32_t v1 = digittoval[wsrc[0]];
uint32_t v2 = digittoval[wsrc[1]];
return v2 << 8 | v1;
}
(Also, small note: The function is named `hex_to_u32_lookup` but it only gives a 16-bit result. Might want to clarify in the post.)