-
-
Save paniq/8c3b8d3385c365ffd5017229d51bb8ab to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# loop & branchless conversion of integers to strings | |
let USE_VECTORIZATION = true | |
fn... u32->hex_u64 (x : u32) | |
static-if USE_VECTORIZATION | |
let u8x8 = (vector u8 8) | |
# part | |
let x = (zext (bitcast x (vector (integer 4) 8)) u8x8) | |
# reverse | |
let x = (shufflevector x x (vectorof i32 7 6 5 4 3 2 1 0)) | |
# offset bytes by 48 (0) if < 10, otherwise 97 (a) | |
bitcast | |
+ x | |
? (x < (bitcast 0x0a0a0a0a0a0a0a0a:u64 u8x8)) | |
(bitcast 0x3030303030303030:u64 u8x8) | |
(bitcast 0x5757575757575757:u64 u8x8) | |
u64 | |
else | |
let hi = | |
# 0x----DCBA -> 0x-A-B-C-D | |
| | |
(x & 0x0000000f:u32) << 24:u32 | |
(x & 0x000000f0:u32) << 12:u32 | |
(x & 0x00000f00:u32) | |
(x & 0x0000f000:u32) >> 12:u32 | |
let lo = | |
# 0xDCBA---- -> 0x-A-B-C-D | |
| | |
(x & 0x00f00000:u32) >> 4:u32 | |
(x & 0x000f0000:u32) << 8:u32 | |
(x & 0x0f000000:u32) >> 16:u32 | |
x >> 28:u32 | |
let x = | |
lo as u64 | hi as u64 << 32:u64 | |
# offset bytes by 48 (0) if < 10, otherwise 97 (a) | |
+ x | |
0x3030303030303030:u64 | |
39:u64 * # 7:u64 for big letters | |
& (x >> 3:u64) | |
(x >> 1:u64) | (x >> 2:u64) | |
0x0101010101010101:u64 | |
let U8_48x10 = (vector.smear 48:u8 10) | |
let D10 = (vector.smear 10:u32 10) | |
let DEXP10 = | |
vectorof u32 | |
va-map | |
inline (x) | |
10:u32 ** (9 - x) | |
va-range 10 | |
static-assert (constant? D10) | |
static-assert (constant? DEXP10) | |
fn... u32->dec_u8x10 (x : u32) | |
let u8x10 = (vector u8 10) | |
let i80 = (integer 80) | |
let x = (vector.smear x 10) | |
# extract all digits at once | |
x := (x // DEXP10) % D10 | |
x := (itrunc x u8x10) | |
# to byte characters, truncate leading zeroes with a bitshift | |
nz := (min 9:u8 (((findlsb (bitcast x i80)) as u8) // 8:u8)) * 8:u8 | |
bitcast ((bitcast (U8_48x10 + x) i80) >> (nz as i80)) u8x10 | |
fn... bits->str (x) | |
using import String | |
local str : String | |
let T = (typeof x) | |
'resize str (sizeof T) | |
(@ (bitcast (& (str @ 0)) (mutable @T))) = x | |
str | |
# prints 123 | |
bits->str | |
u32->dec_u8x10 | |
123:u32 | |
# prints abcdef78 | |
bits->str | |
u32->hex_u64 0xabcdef78 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment