use crate::gpu_only;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AddressSpace {
Global,
Shared,
Constant,
Local,
}
#[gpu_only]
pub unsafe fn is_in_address_space<T>(ptr: *const T, address_space: AddressSpace) -> bool {
let ret: u32;
asm!(".reg .pred p;");
match address_space {
AddressSpace::Global => asm!("isspacep.global p, {}", in(reg64) ptr),
AddressSpace::Shared => asm!("isspacep.shared p, {}", in(reg64) ptr),
AddressSpace::Constant => asm!("isspacep.const p, {}", in(reg64) ptr),
AddressSpace::Local => asm!("isspacep.local p, {}", in(reg64) ptr),
}
asm!("selp.u32 {}, 1, 0, p;", out(reg32) ret);
ret != 0
}
#[gpu_only]
pub unsafe fn convert_generic_to_specific_address_space<T>(
ptr: *const T,
address_space: AddressSpace,
) -> *const T {
let ret: *const T;
match address_space {
AddressSpace::Global => asm!(
"cvta.to.global.u64 {}, {}",
out(reg64) ret,
in(reg64) ptr
),
AddressSpace::Shared => asm!(
"cvta.to.shared.u64 {}, {}",
out(reg64) ret,
in(reg64) ptr
),
AddressSpace::Constant => asm!(
"cvta.to.const.u64 {}, {}",
out(reg64) ret,
in(reg64) ptr
),
AddressSpace::Local => asm!(
"cvta.to.local.u64 {}, {}",
out(reg64) ret,
in(reg64) ptr
),
}
ret
}
#[gpu_only]
pub unsafe fn convert_specific_address_space_to_generic<T>(
ptr: *const T,
address_space: AddressSpace,
) -> *const T {
let ret: *const T;
match address_space {
AddressSpace::Global => asm!(
"cvta.global.u64 {}, {}",
out(reg64) ret,
in(reg64) ptr
),
AddressSpace::Shared => asm!(
"cvta.shared.u64 {}, {}",
out(reg64) ret,
in(reg64) ptr
),
AddressSpace::Constant => asm!(
"cvta.const.u64 {}, {}",
out(reg64) ret,
in(reg64) ptr
),
AddressSpace::Local => asm!(
"cvta.local.u64 {}, {}",
out(reg64) ret,
in(reg64) ptr
),
}
ret
}