Last active
July 9, 2023 12:17
-
-
Save m1el/e16fc153076d5764c95835de2936afef 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
use std::arch::asm; | |
#[inline(always)] | |
fn pdep_u64(x: u64, mask: u64) -> u64 { | |
let mut _rv: u64; | |
unsafe { | |
asm !{ | |
"pdep {out}, {x}, {mask}", | |
out = out(reg) _rv, | |
x = in(reg) x, | |
mask = in(reg) mask, | |
options(pure, nomem, nostack), | |
} | |
} | |
_rv | |
} | |
#[inline(always)] | |
fn pext_u64(x: u64, mask: u64) -> u64 { | |
let mut _rv: u64; | |
unsafe { | |
asm !{ | |
"pext {out}, {x}, {mask}", | |
out = out(reg) _rv, | |
x = in(reg) x, | |
mask = in(reg) mask, | |
options(pure, nomem, nostack), | |
} | |
} | |
_rv | |
} | |
const MASK_MOD2: u64 = 0x5555555555555555; | |
#[inline(never)] | |
pub fn zorder_to_xy(z: u64)->(u32, u32) { | |
let x = pext_u64(z, MASK_MOD2) as u32; | |
let y = pext_u64(z >> 1, MASK_MOD2) as u32; | |
(x, y) | |
} | |
#[inline(never)] | |
pub fn zorder_from_xy(x: u32, y: u32) -> u64 { | |
let x = pdep_u64(x as u64, MASK_MOD2); | |
let y = pdep_u64(y as u64, MASK_MOD2); | |
x | (y << 1) | |
} | |
const MASK_MOD3: u64 = 0x1249249249249249; | |
#[inline(never)] | |
pub fn zorder_to_xyz(z: u64)->(u32, u32, u32) { | |
let x = pext_u64(z, MASK_MOD3) as u32; | |
let y = pext_u64(z >> 1, MASK_MOD3) as u32; | |
let z = pext_u64(z >> 2, MASK_MOD3) as u32; | |
(x, y, z) | |
} | |
#[inline(never)] | |
pub fn zorder_from_xyz(x: u32, y: u32, z: u32) -> u64 { | |
let x = pdep_u64(x as u64, MASK_MOD3); | |
let y = pdep_u64(y as u64, MASK_MOD3); | |
let z = pdep_u64(z as u64, MASK_MOD3); | |
x | (y << 1) | (z << 2) | |
} | |
fn main() { | |
println!("(25, 33) -> {:?}", zorder_from_xy(25, 33)); | |
println!("2371 -> {:?}", zorder_to_xy(2371)); | |
println!("(25, 33, 41) -> {:?}", zorder_from_xyz(25, 33, 41)); | |
println!("203271 -> {:?}", zorder_to_xyz(203271)); | |
// println!("{}", zorder64inv(3)); | |
} |
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
zorder_to_xy: | |
movabs rcx, 0x5555555555555555 | |
pext rax, rcx, rdi | |
shr rdi | |
pext rdx, rcx, rdi | |
ret | |
zorder_from_xy: | |
mov eax, edi | |
movabs rcx, 0x5555555555555555 | |
pdep rdx, rcx, rax | |
mov esi, esi | |
pdep rax, rcx, rsi | |
add rax, rax | |
or rax, rdx | |
ret | |
zorder_to_xyz: | |
movabs rax, 0x1249249249249249 | |
pext rcx, rax, rdi | |
mov rdx, rdi | |
shr rdx | |
pext rsi, rax, rdx | |
shr rdi, 2 | |
pext rdx, rax, rdi | |
shl rsi, 32 | |
mov eax, ecx | |
or rax, rsi | |
ret | |
zorder_from_xyz: | |
mov eax, edi | |
movabs rcx, 0x1249249249249249 | |
pdep rdi, rcx, rax | |
mov eax, esi | |
pdep rsi, rcx, rax | |
mov edx, edx | |
pdep rax, rcx, rdx | |
add rsi, rsi | |
or rsi, rdi | |
shl rax, 2 | |
or rax, rsi | |
ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment