x86_64/registers/
mxcsr.rs1#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
4pub use self::x86_64::*;
5
6use bitflags::bitflags;
7
8bitflags! {
9 #[repr(transparent)]
11 #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
12 pub struct MxCsr: u32 {
13 const INVALID_OPERATION = 1 << 0;
15 const DENORMAL = 1 << 1;
17 const DIVIDE_BY_ZERO = 1 << 2;
19 const OVERFLOW = 1 << 3;
21 const UNDERFLOW = 1 << 4;
23 const PRECISION = 1 << 5;
25 const DENORMALS_ARE_ZEROS = 1 << 6;
27 const INVALID_OPERATION_MASK = 1 << 7;
29 const DENORMAL_MASK = 1 << 8;
31 const DIVIDE_BY_ZERO_MASK = 1 << 9;
33 const OVERFLOW_MASK = 1 << 10;
35 const UNDERFLOW_MASK = 1 << 11;
37 const PRECISION_MASK = 1 << 12;
39 const ROUNDING_CONTROL_NEGATIVE = 1 << 13;
41 const ROUNDING_CONTROL_POSITIVE = 1 << 14;
43 const ROUNDING_CONTROL_ZERO = 3 << 13;
45 const FLUSH_TO_ZERO = 1 << 15;
47 }
48}
49
50impl Default for MxCsr {
51 #[inline]
53 fn default() -> Self {
54 MxCsr::INVALID_OPERATION_MASK
55 | MxCsr::DENORMAL_MASK
56 | MxCsr::DIVIDE_BY_ZERO_MASK
57 | MxCsr::OVERFLOW_MASK
58 | MxCsr::UNDERFLOW_MASK
59 | MxCsr::PRECISION_MASK
60 }
61}
62
63#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
64mod x86_64 {
65 use super::*;
66 use core::arch::asm;
67
68 #[inline]
70 pub fn read() -> MxCsr {
71 let mut mxcsr: u32 = 0;
72 unsafe {
73 asm!("stmxcsr [{}]", in(reg) &mut mxcsr, options(nostack, preserves_flags));
74 }
75 MxCsr::from_bits_truncate(mxcsr)
76 }
77
78 #[inline]
80 pub fn write(mxcsr: MxCsr) {
81 unsafe {
82 asm!("ldmxcsr [{}]", in(reg) &mxcsr, options(nostack, readonly));
83 }
84 }
85
86 #[cfg(test)]
87 mod test {
88 use crate::registers::mxcsr::*;
89
90 #[test]
91 fn mxcsr_default() {
92 let mxcsr = read();
93 assert_eq!(mxcsr, MxCsr::from_bits_truncate(0x1F80));
94 }
95
96 #[test]
97 fn mxcsr_read() {
98 let mxcsr = read();
99 assert_eq!(mxcsr, MxCsr::default());
100 }
101
102 #[test]
103 fn mxcsr_write() {
104 let mxcsr = read();
105 write(mxcsr);
106 assert_eq!(mxcsr, read());
107 }
108 }
109}