Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions library/core/src/hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ pub fn spin_loop() {
#[inline]
#[unstable(feature = "test", issue = "50297")]
#[allow(unreachable_code)] // this makes #[cfg] a bit easier below.
pub fn black_box<T>(dummy: T) -> T {
pub fn black_box<T>(mut dummy: T) -> T {
// We need to "use" the argument in some way LLVM can't introspect, and on
// targets that support it we can typically leverage inline assembly to do
// this. LLVM's interpretation of inline assembly is that it's, well, a black
Expand All @@ -121,7 +121,8 @@ pub fn black_box<T>(dummy: T) -> T {
#[cfg(not(miri))] // This is just a hint, so it is fine to skip in Miri.
// SAFETY: the inline assembly is a no-op.
unsafe {
llvm_asm!("" : : "r"(&dummy));
// FIXME: Cannot use `asm!` because it doesn't support MIPS and other architectures.
llvm_asm!("" : : "r"(&mut dummy));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incidentally the old asm had bugs: you need volatile and memory clobbers to have the proper black_box effect. Currently rustc automatically adds volatile and LLVM adds memory when volatile is set, but we probably shouldn't rely on this.

}

dummy
Expand Down
20 changes: 17 additions & 3 deletions library/core/src/num/dec2flt/algorithm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,19 @@ mod fpu_precision {
fn set_cw(cw: u16) {
// SAFETY: the `fldcw` instruction has been audited to be able to work correctly with
// any `u16`
unsafe { llvm_asm!("fldcw $0" :: "m" (cw) :: "volatile") }
unsafe {
asm!(
"fldcw ({})",
in(reg) &cw,
// FIXME: We are using ATT syntax to support LLVM 8 and LLVM 9.
options(att_syntax, nostack),
)
}
}

/// Sets the precision field of the FPU to `T` and returns a `FPUControlWord`.
pub fn set_precision<T>() -> FPUControlWord {
let cw = 0u16;
let mut cw = 0_u16;

// Compute the value for the Precision Control field that is appropriate for `T`.
let cw_precision = match size_of::<T>() {
Expand All @@ -78,7 +85,14 @@ mod fpu_precision {
// `FPUControlWord` structure is dropped
// SAFETY: the `fnstcw` instruction has been audited to be able to work correctly with
// any `u16`
unsafe { llvm_asm!("fnstcw $0" : "=*m" (&cw) ::: "volatile") }
unsafe {
asm!(
"fnstcw ({})",
in(reg) &mut cw,
// FIXME: We are using ATT syntax to support LLVM 8 and LLVM 9.
options(att_syntax, nostack),
)
}

// Set the control word to the desired precision. This is achieved by masking away the old
// precision (bits 8 and 9, 0x300) and replacing it with the precision flag computed above.
Expand Down