diff --git a/ci/docker/x86_64-unknown-linux-gnu/Dockerfile b/ci/docker/x86_64-unknown-linux-gnu/Dockerfile index 99bfd056fb..c9951a77ff 100644 --- a/ci/docker/x86_64-unknown-linux-gnu/Dockerfile +++ b/ci/docker/x86_64-unknown-linux-gnu/Dockerfile @@ -14,5 +14,3 @@ RUN tar -xJf sde.tar.xz --strip-components=1 -C intel-sde ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="/intel-sde/sde64 \ -cpuid-in /checkout/ci/docker/x86_64-unknown-linux-gnu/cpuid.def \ -rtm-mode full -tsx --" -# These tests fail with SDE as it doesn't support saving register data -ENV STDARCH_TEST_SKIP_FUNCTION="xsave,xsaveopt,xsave64,xsaveopt64" diff --git a/crates/core_arch/src/x86/xsave.rs b/crates/core_arch/src/x86/xsave.rs index 10266662e1..190cef929e 100644 --- a/crates/core_arch/src/x86/xsave.rs +++ b/crates/core_arch/src/x86/xsave.rs @@ -159,29 +159,39 @@ pub unsafe fn _xrstors(mem_addr: *const u8, rs_mask: u64) { xrstors(mem_addr, (rs_mask >> 32) as u32, rs_mask as u32); } +#[cfg(test)] +pub(crate) use tests::XsaveArea; + #[cfg(test)] mod tests { - use std::{fmt, prelude::v1::*}; + use std::boxed::Box; use crate::core_arch::x86::*; use stdarch_test::simd_test; - #[repr(align(64))] #[derive(Debug)] - struct XsaveArea { - // max size for 256-bit registers is 800 bytes: - // see https://software.intel.com/en-us/node/682996 - // max size for 512-bit registers is 2560 bytes: - // FIXME: add source - data: [u8; 2560], + pub(crate) struct XsaveArea { + data: Box<[AlignedArray]>, } + #[repr(align(64))] + #[derive(Copy, Clone, Debug)] + struct AlignedArray([u8; 64]); + impl XsaveArea { - fn new() -> XsaveArea { - XsaveArea { data: [0; 2560] } + #[target_feature(enable = "xsave")] + pub(crate) fn new() -> XsaveArea { + // `CPUID.(EAX=0DH,ECX=0):ECX` contains the size required to hold all supported xsave + // components. `EBX` contains the size required to hold all xsave components currently + // enabled in `XCR0`. We are using `ECX` to ensure enough space in all scenarios + let CpuidResult { ecx, .. } = unsafe { __cpuid(0x0d) }; + + XsaveArea { + data: vec![AlignedArray([0; 64]); ecx.div_ceil(64) as usize].into_boxed_slice(), + } } - fn ptr(&mut self) -> *mut u8 { - self.data.as_mut_ptr() + pub(crate) fn ptr(&mut self) -> *mut u8 { + self.data.as_mut_ptr().cast() } } diff --git a/crates/core_arch/src/x86_64/xsave.rs b/crates/core_arch/src/x86_64/xsave.rs index ca2367307f..fa1454a822 100644 --- a/crates/core_arch/src/x86_64/xsave.rs +++ b/crates/core_arch/src/x86_64/xsave.rs @@ -126,29 +126,10 @@ pub unsafe fn _xrstors64(mem_addr: *const u8, rs_mask: u64) { #[cfg(test)] mod tests { - use crate::core_arch::x86_64::xsave; - use std::fmt; + use crate::core_arch::x86::*; + use crate::core_arch::x86_64::*; use stdarch_test::simd_test; - #[repr(align(64))] - #[derive(Debug)] - struct XsaveArea { - // max size for 256-bit registers is 800 bytes: - // see https://software.intel.com/en-us/node/682996 - // max size for 512-bit registers is 2560 bytes: - // FIXME: add source - data: [u8; 2560], - } - - impl XsaveArea { - fn new() -> XsaveArea { - XsaveArea { data: [0; 2560] } - } - fn ptr(&mut self) -> *mut u8 { - self.data.as_mut_ptr() - } - } - #[simd_test(enable = "xsave")] #[cfg_attr(miri, ignore)] // Register saving/restoring is not supported in Miri unsafe fn test_xsave64() { @@ -156,9 +137,9 @@ mod tests { let mut a = XsaveArea::new(); let mut b = XsaveArea::new(); - xsave::_xsave64(a.ptr(), m); - xsave::_xrstor64(a.ptr(), m); - xsave::_xsave64(b.ptr(), m); + _xsave64(a.ptr(), m); + _xrstor64(a.ptr(), m); + _xsave64(b.ptr(), m); } #[simd_test(enable = "xsave,xsaveopt")] @@ -168,9 +149,9 @@ mod tests { let mut a = XsaveArea::new(); let mut b = XsaveArea::new(); - xsave::_xsaveopt64(a.ptr(), m); - xsave::_xrstor64(a.ptr(), m); - xsave::_xsaveopt64(b.ptr(), m); + _xsaveopt64(a.ptr(), m); + _xrstor64(a.ptr(), m); + _xsaveopt64(b.ptr(), m); } #[simd_test(enable = "xsave,xsavec")] @@ -180,8 +161,8 @@ mod tests { let mut a = XsaveArea::new(); let mut b = XsaveArea::new(); - xsave::_xsavec64(a.ptr(), m); - xsave::_xrstor64(a.ptr(), m); - xsave::_xsavec64(b.ptr(), m); + _xsavec64(a.ptr(), m); + _xrstor64(a.ptr(), m); + _xsavec64(b.ptr(), m); } }