/rust/registry/src/index.crates.io-1949cf8c6b5b557f/x86-0.47.0/src/bits64/rflags.rs
Line | Count | Source |
1 | | //! Processor state stored in the RFLAGS register. |
2 | | //! |
3 | | //! In 64-bit mode, EFLAGS is extended to 64 bits and called RFLAGS. |
4 | | //! The upper 32 bits of RFLAGS register is reserved. |
5 | | //! The lower 32 bits of RFLAGS is the same as EFLAGS. |
6 | | |
7 | | use bitflags::*; |
8 | | |
9 | | use crate::Ring; |
10 | | |
11 | | #[cfg(target_arch = "x86_64")] |
12 | | use core::arch::asm; |
13 | | |
14 | | bitflags! { |
15 | | /// The RFLAGS register. |
16 | | /// This is duplicated code from bits32 eflags.rs. |
17 | | pub struct RFlags: u64 { |
18 | | /// ID Flag (ID) |
19 | | const FLAGS_ID = 1 << 21; |
20 | | /// Virtual Interrupt Pending (VIP) |
21 | | const FLAGS_VIP = 1 << 20; |
22 | | /// Virtual Interrupt Flag (VIF) |
23 | | const FLAGS_VIF = 1 << 19; |
24 | | /// Alignment Check (AC) |
25 | | const FLAGS_AC = 1 << 18; |
26 | | /// Virtual-8086 Mode (VM) |
27 | | const FLAGS_VM = 1 << 17; |
28 | | /// Resume Flag (RF) |
29 | | const FLAGS_RF = 1 << 16; |
30 | | /// Nested Task (NT) |
31 | | const FLAGS_NT = 1 << 14; |
32 | | /// I/O Privilege Level (IOPL) 0 |
33 | | const FLAGS_IOPL0 = 0b00 << 12; |
34 | | /// I/O Privilege Level (IOPL) 1 |
35 | | const FLAGS_IOPL1 = 0b01 << 12; |
36 | | /// I/O Privilege Level (IOPL) 2 |
37 | | const FLAGS_IOPL2 = 0b10 << 12; |
38 | | /// I/O Privilege Level (IOPL) 3 |
39 | | const FLAGS_IOPL3 = 0b11 << 12; |
40 | | /// Overflow Flag (OF) |
41 | | const FLAGS_OF = 1 << 11; |
42 | | /// Direction Flag (DF) |
43 | | const FLAGS_DF = 1 << 10; |
44 | | /// Interrupt Enable Flag (IF) |
45 | | const FLAGS_IF = 1 << 9; |
46 | | /// Trap Flag (TF) |
47 | | const FLAGS_TF = 1 << 8; |
48 | | /// Sign Flag (SF) |
49 | | const FLAGS_SF = 1 << 7; |
50 | | /// Zero Flag (ZF) |
51 | | const FLAGS_ZF = 1 << 6; |
52 | | /// Auxiliary Carry Flag (AF) |
53 | | const FLAGS_AF = 1 << 4; |
54 | | /// Parity Flag (PF) |
55 | | const FLAGS_PF = 1 << 2; |
56 | | /// Bit 1 is always 1. |
57 | | const FLAGS_A1 = 1 << 1; |
58 | | /// Carry Flag (CF) |
59 | | const FLAGS_CF = 1 << 0; |
60 | | } |
61 | | } |
62 | | |
63 | | impl RFlags { |
64 | | /// Creates a new Flags entry. Ensures bit 1 is set. |
65 | 0 | pub const fn new() -> RFlags { |
66 | 0 | RFlags::FLAGS_A1 |
67 | 0 | } |
68 | | |
69 | | /// Creates a new Flags with the given I/O privilege level. |
70 | 0 | pub const fn from_priv(iopl: Ring) -> RFlags { |
71 | 0 | RFlags { |
72 | 0 | bits: (iopl as u64) << 12, |
73 | 0 | } |
74 | 0 | } |
75 | | |
76 | 0 | pub const fn from_raw(bits: u64) -> RFlags { |
77 | 0 | RFlags { bits } |
78 | 0 | } |
79 | | } |
80 | | |
81 | | #[cfg(target_arch = "x86_64")] |
82 | | #[inline(always)] |
83 | 0 | pub fn read() -> RFlags { |
84 | | let r: u64; |
85 | 0 | unsafe { asm!("pushfq; popq {0}", out(reg) r, options(att_syntax)) }; |
86 | 0 | RFlags::from_bits_truncate(r) |
87 | 0 | } |
88 | | |
89 | | #[cfg(target_arch = "x86_64")] |
90 | | #[inline(always)] |
91 | 0 | pub fn set(val: RFlags) { |
92 | 0 | unsafe { |
93 | 0 | asm!("pushq {0}; popfq", in(reg) val.bits(), options(att_syntax)); |
94 | 0 | } |
95 | 0 | } |
96 | | |
97 | | // clac and stac are also usable in 64-bit mode |
98 | | pub use crate::bits32::eflags::{clac, stac}; |