x86_64 0.13.5

Support for x86_64 specific instructions, registers, and structures.
Documentation
//! Access to various extended system registers
use bitflags::bitflags;

/// Extended feature enable mask register
#[derive(Debug)]
pub struct XCr0;

bitflags! {
    /// Configuration flags of the XCr0 register.
    pub struct XCr0Flags: u64 {
        /// Enables x87 FPU
        const X87 = 1;
        /// Enables 128-bit (legacy) SSE
        /// Must be set to enable AVX and YMM
        const SSE = 1<<1;
        /// Enables 256-bit SSE
        /// Must be set to enable AVX
        const YMM = 1<<2;
        /// When set, PKRU state management is supported by
        /// ZSAVE/XRSTOR
        const MPK = 1<<9;
        /// When set the Lightweight Profiling extensions are enabled
        const LWP = 1<<62;
    }
}

#[cfg(all(feature = "instructions", feature = "inline_asm"))]
mod x86_64 {
    use super::*;
    impl XCr0 {
        /// Read the current set of XCR0 flags.
        #[inline]
        pub fn read() -> XCr0Flags {
            XCr0Flags::from_bits_truncate(Self::read_raw())
        }

        /// Read the current raw XCR0 value.
        #[inline]
        pub fn read_raw() -> u64 {
            let low: u32;
            let high: u32;

            unsafe {
                asm!("
                    xor rcx, rcx
                    xgetbv
                    ",
                    lateout("rdx") high,
                    lateout("rax") low,
                    lateout("rcx") _,
                );
            }

            (high as u64) << 32 | (low as u64)
        }

        /// Write XCR0 flags.
        ///
        /// Preserves the value of reserved fields.
        ///
        /// ## Safety
        ///
        /// This function is unsafe because it's possible to
        /// enable features that are not supported by the architecture
        #[inline]
        pub unsafe fn write(flags: XCr0Flags) {
            let old_value = Self::read_raw();
            let reserved = old_value & !(XCr0Flags::all().bits());
            let new_value = reserved | flags.bits();

            Self::write_raw(new_value);
        }

        /// Write raw XCR0 flags.
        ///
        /// Does _not_ preserve any values, including reserved fields.
        ///
        /// ## Safety
        ///
        /// This function is unsafe because it's possible to
        /// enable features that are not supported by the architecture
        #[inline]
        pub unsafe fn write_raw(value: u64) {
            let high: u32 = (value >> 32) as u32;
            let low: u32 = (value) as u32;
            asm!("
                    xor ecx, ecx
                    xsetbv
                    ",
                    in("edx") high,
                    in("eax") low,
                    lateout("ecx") _,
            );
        }
    }
}