use crate::structures::gdt::SegmentSelector;
#[inline]
pub unsafe fn set_cs(sel: SegmentSelector) {
#[cfg(feature = "inline_asm")]
#[inline(always)]
unsafe fn inner(sel: SegmentSelector) {
asm!(
"push {sel}",
"lea {tmp}, [1f + rip]",
"push {tmp}",
"retfq",
"1:",
sel = in(reg) u64::from(sel.0),
tmp = lateout(reg) _,
);
}
#[cfg(not(feature = "inline_asm"))]
#[inline(always)]
unsafe fn inner(sel: SegmentSelector) {
crate::asm::x86_64_asm_set_cs(u64::from(sel.0))
}
inner(sel)
}
#[inline]
pub unsafe fn load_ss(sel: SegmentSelector) {
#[cfg(feature = "inline_asm")]
asm!("mov ss, {0:x}", in(reg) sel.0, options(nostack));
#[cfg(not(feature = "inline_asm"))]
crate::asm::x86_64_asm_load_ss(sel.0);
}
#[inline]
pub unsafe fn load_ds(sel: SegmentSelector) {
#[cfg(feature = "inline_asm")]
asm!("mov ds, {0:x}", in(reg) sel.0, options(nostack));
#[cfg(not(feature = "inline_asm"))]
crate::asm::x86_64_asm_load_ds(sel.0);
}
#[inline]
pub unsafe fn load_es(sel: SegmentSelector) {
#[cfg(feature = "inline_asm")]
asm!("mov es, {0:x}", in(reg) sel.0, options(nostack));
#[cfg(not(feature = "inline_asm"))]
crate::asm::x86_64_asm_load_es(sel.0);
}
#[inline]
pub unsafe fn load_fs(sel: SegmentSelector) {
#[cfg(feature = "inline_asm")]
asm!("mov fs, {0:x}", in(reg) sel.0, options(nostack));
#[cfg(not(feature = "inline_asm"))]
crate::asm::x86_64_asm_load_fs(sel.0);
}
#[inline]
pub unsafe fn load_gs(sel: SegmentSelector) {
#[cfg(feature = "inline_asm")]
asm!("mov gs, {0:x}", in(reg) sel.0, options(nostack));
#[cfg(not(feature = "inline_asm"))]
crate::asm::x86_64_asm_load_gs(sel.0);
}
#[inline]
pub unsafe fn swap_gs() {
#[cfg(feature = "inline_asm")]
asm!("swapgs", options(nostack));
#[cfg(not(feature = "inline_asm"))]
crate::asm::x86_64_asm_swapgs();
}
#[inline]
pub fn cs() -> SegmentSelector {
#[cfg(feature = "inline_asm")]
{
let segment: u16;
unsafe { asm!("mov {0:x}, cs", out(reg) segment, options(nostack, nomem)) };
SegmentSelector(segment)
}
#[cfg(not(feature = "inline_asm"))]
{
let segment: u16 = unsafe { crate::asm::x86_64_asm_get_cs() };
SegmentSelector(segment)
}
}
#[inline]
pub unsafe fn wrfsbase(val: u64) {
#[cfg(feature = "inline_asm")]
#[inline(always)]
unsafe fn inner(val: u64) {
asm!("wrfsbase {}", in(reg) val, options(nomem, nostack));
}
#[cfg(not(feature = "inline_asm"))]
#[inline(always)]
unsafe fn inner(val: u64) {
crate::asm::x86_64_asm_wrfsbase(val)
}
inner(val)
}
#[inline]
pub unsafe fn rdfsbase() -> u64 {
#[cfg(feature = "inline_asm")]
#[inline(always)]
unsafe fn inner() -> u64 {
let val: u64;
asm!("rdfsbase {}", out(reg) val, options(nomem, nostack));
val
}
#[cfg(not(feature = "inline_asm"))]
#[inline(always)]
unsafe fn inner() -> u64 {
crate::asm::x86_64_asm_rdfsbase()
}
inner()
}
#[inline]
pub unsafe fn wrgsbase(val: u64) {
#[cfg(feature = "inline_asm")]
#[inline(always)]
unsafe fn inner(val: u64) {
asm!("wrgsbase {}", in(reg) val, options(nomem, nostack))
}
#[cfg(not(feature = "inline_asm"))]
#[inline(always)]
unsafe fn inner(val: u64) {
crate::asm::x86_64_asm_wrgsbase(val)
}
inner(val)
}
#[inline]
pub unsafe fn rdgsbase() -> u64 {
#[cfg(feature = "inline_asm")]
#[inline(always)]
unsafe fn inner() -> u64 {
let val: u64;
asm!("rdgsbase {}", out(reg) val, options(nomem, nostack));
val
}
#[cfg(not(feature = "inline_asm"))]
#[inline(always)]
unsafe fn inner() -> u64 {
crate::asm::x86_64_asm_rdgsbase()
}
inner()
}