Skip to content

Instantly share code, notes, and snippets.

@paniq
Last active June 25, 2021 22:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paniq/8c3b8d3385c365ffd5017229d51bb8ab to your computer and use it in GitHub Desktop.
Save paniq/8c3b8d3385c365ffd5017229d51bb8ab to your computer and use it in GitHub Desktop.
# 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
print
bits->str
u32->dec_u8x10
123:u32
# prints abcdef78
print
bits->str
u32->hex_u64 0xabcdef78
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment