]>
Commit | Line | Data |
---|---|---|
a2a8927a | 1 | //! FXSR floating-point context fast save and restore. |
0531ce1d XL |
2 | |
3 | #[cfg(test)] | |
416331ca | 4 | use stdarch_test::assert_instr; |
0531ce1d XL |
5 | |
6 | #[allow(improper_ctypes)] | |
7 | extern "C" { | |
8 | #[link_name = "llvm.x86.fxsave64"] | |
fc512014 | 9 | fn fxsave64(p: *mut u8); |
0531ce1d | 10 | #[link_name = "llvm.x86.fxrstor64"] |
fc512014 | 11 | fn fxrstor64(p: *const u8); |
0531ce1d XL |
12 | } |
13 | ||
14 | /// Saves the `x87` FPU, `MMX` technology, `XMM`, and `MXCSR` registers to the | |
15 | /// 512-byte-long 16-byte-aligned memory region `mem_addr`. | |
16 | /// | |
17 | /// A misaligned destination operand raises a general-protection (#GP) or an | |
18 | /// alignment check exception (#AC). | |
19 | /// | |
20 | /// See [`FXSAVE`][fxsave] and [`FXRSTOR`][fxrstor]. | |
21 | /// | |
22 | /// [fxsave]: http://www.felixcloutier.com/x86/FXSAVE.html | |
23 | /// [fxrstor]: http://www.felixcloutier.com/x86/FXRSTOR.html | |
83c7162d | 24 | /// |
353b0b11 | 25 | /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_fxsave64) |
0531ce1d XL |
26 | #[inline] |
27 | #[target_feature(enable = "fxsr")] | |
28 | #[cfg_attr(test, assert_instr(fxsave64))] | |
83c7162d | 29 | #[stable(feature = "simd_x86", since = "1.27.0")] |
0531ce1d XL |
30 | pub unsafe fn _fxsave64(mem_addr: *mut u8) { |
31 | fxsave64(mem_addr) | |
32 | } | |
33 | ||
34 | /// Restores the `XMM`, `MMX`, `MXCSR`, and `x87` FPU registers from the | |
35 | /// 512-byte-long 16-byte-aligned memory region `mem_addr`. | |
36 | /// | |
37 | /// The contents of this memory region should have been written to by a | |
38 | /// previous | |
39 | /// `_fxsave` or `_fxsave64` intrinsic. | |
40 | /// | |
41 | /// A misaligned destination operand raises a general-protection (#GP) or an | |
42 | /// alignment check exception (#AC). | |
43 | /// | |
44 | /// See [`FXSAVE`][fxsave] and [`FXRSTOR`][fxrstor]. | |
45 | /// | |
46 | /// [fxsave]: http://www.felixcloutier.com/x86/FXSAVE.html | |
47 | /// [fxrstor]: http://www.felixcloutier.com/x86/FXRSTOR.html | |
83c7162d | 48 | /// |
353b0b11 | 49 | /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_fxrstor64) |
0531ce1d XL |
50 | #[inline] |
51 | #[target_feature(enable = "fxsr")] | |
52 | #[cfg_attr(test, assert_instr(fxrstor64))] | |
83c7162d | 53 | #[stable(feature = "simd_x86", since = "1.27.0")] |
0531ce1d XL |
54 | pub unsafe fn _fxrstor64(mem_addr: *const u8) { |
55 | fxrstor64(mem_addr) | |
56 | } | |
57 | ||
58 | #[cfg(test)] | |
59 | mod tests { | |
532ac7d7 | 60 | use crate::core_arch::x86_64::*; |
8faf50e0 | 61 | use std::{cmp::PartialEq, fmt}; |
416331ca | 62 | use stdarch_test::simd_test; |
0531ce1d XL |
63 | |
64 | #[repr(align(16))] | |
65 | struct FxsaveArea { | |
66 | data: [u8; 512], // 512 bytes | |
67 | } | |
68 | ||
69 | impl FxsaveArea { | |
70 | fn new() -> FxsaveArea { | |
71 | FxsaveArea { data: [0; 512] } | |
72 | } | |
73 | fn ptr(&mut self) -> *mut u8 { | |
74 | &mut self.data[0] as *mut _ as *mut u8 | |
75 | } | |
76 | } | |
77 | ||
78 | impl PartialEq<FxsaveArea> for FxsaveArea { | |
79 | fn eq(&self, other: &FxsaveArea) -> bool { | |
80 | for i in 0..self.data.len() { | |
81 | if self.data[i] != other.data[i] { | |
82 | return false; | |
83 | } | |
84 | } | |
85 | true | |
86 | } | |
87 | } | |
88 | ||
89 | impl fmt::Debug for FxsaveArea { | |
cdc7bbd5 | 90 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
0531ce1d XL |
91 | write!(f, "[")?; |
92 | for i in 0..self.data.len() { | |
93 | write!(f, "{}", self.data[i])?; | |
94 | if i != self.data.len() - 1 { | |
95 | write!(f, ", ")?; | |
96 | } | |
97 | } | |
98 | write!(f, "]") | |
99 | } | |
100 | } | |
101 | ||
83c7162d | 102 | #[simd_test(enable = "fxsr")] |
0531ce1d XL |
103 | unsafe fn fxsave64() { |
104 | let mut a = FxsaveArea::new(); | |
105 | let mut b = FxsaveArea::new(); | |
106 | ||
107 | fxsr::_fxsave64(a.ptr()); | |
108 | fxsr::_fxrstor64(a.ptr()); | |
109 | fxsr::_fxsave64(b.ptr()); | |
110 | assert_eq!(a, b); | |
111 | } | |
112 | } |