xref: /DragonOS/kernel/src/arch/x86_64/fpu.rs (revision fae6e9ade46a52976ad5d099643d51cc20876448)
1 use core::arch::x86_64::{_fxrstor64, _fxsave64};
2 
3 /// https://www.felixcloutier.com/x86/fxsave#tbl-3-47
4 #[repr(C, align(16))]
5 #[derive(Debug, Copy, Clone)]
6 pub struct FpState {
7     //0
8     fcw: u16,
9     fsw: u16,
10     ftw: u16,
11     fop: u16,
12     word2: u64,
13     //16
14     word3: u64,
15     mxcsr: u32,
16     mxcsr_mask: u32,
17     //32
18     mm: [u64; 16],
19     //160
20     xmm: [u64; 32],
21     //416
22     rest: [u64; 12],
23 }
24 
25 impl Default for FpState {
26     fn default() -> Self {
27         Self {
28             fcw: 0x037f,
29             fsw: Default::default(),
30             ftw: Default::default(),
31             fop: Default::default(),
32             word2: Default::default(),
33             word3: Default::default(),
34             mxcsr: 0x1f80,
35             mxcsr_mask: Default::default(),
36             mm: Default::default(),
37             xmm: Default::default(),
38             rest: Default::default(),
39         }
40     }
41 }
42 impl FpState {
43     #[inline]
44     pub fn new() -> Self {
45         assert!(core::mem::size_of::<Self>() == 512);
46         return Self::default();
47     }
48 
49     #[inline]
50     pub fn save(&mut self) {
51         unsafe {
52             _fxsave64(self as *mut FpState as *mut u8);
53         }
54     }
55 
56     #[inline]
57     pub fn restore(&self) {
58         unsafe {
59             _fxrstor64(self as *const FpState as *const u8);
60         }
61     }
62 
63     /// 清空浮点寄存器
64     #[allow(dead_code)]
65     pub fn clear(&mut self) {
66         *self = Self::default();
67         self.restore();
68     }
69 }
70