Skip to content

Commit 39e3779

Browse files
RalfJungAmanieu
authored andcommitted
riscv: remove intrinsics that cannot be used from Rust
1 parent e504eff commit 39e3779

File tree

1 file changed

+25
-89
lines changed
  • crates/core_arch/src/riscv_shared

1 file changed

+25
-89
lines changed

crates/core_arch/src/riscv_shared/mod.rs

+25-89
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,29 @@
11
//! Shared RISC-V intrinsics
2-
2+
//!
3+
//! ## Missing floating-point register instructions
4+
//!
5+
//! We are deliberately *not* providing instructions that could change the floating-point rounding
6+
//! mode or exception behavior or read the accrued exceptions flags: `frcsr`, `fscsr`, `fsrm`,
7+
//! `frflags`, `fsflags`.
8+
//!
9+
//! Rust makes no guarantees whatsoever about the contents of the accrued exceptions register: Rust
10+
//! floating-point operations may or may not result in this register getting updated with exception
11+
//! state, and the register can change between two invocations of this function even when no
12+
//! floating-point operations appear in the source code (since floating-point operations appearing
13+
//! earlier or later can be reordered).
14+
//!
15+
//! Modifying the rounding mode leads to **immediate Undefined Behavior**: Rust assumes that the
16+
//! default rounding mode is always set and will optimize accordingly. This even applies when the
17+
//! rounding mode is altered and later reset to its original value without any floating-point
18+
//! operations appearing in the source code between those operations (since floating-point
19+
//! operations appearing earlier or later can be reordered).
20+
//!
21+
//! If you need to perform some floating-point operations and check whether they raised an
22+
//! exception, use a single inline assembly block for the entire sequence of operations.
23+
//!
24+
//! If you need to perform some floating-point operations under a differen rounding mode, use a
25+
//! single inline assembly block and make sure to restore the original rounding mode before the end
26+
//! of the block.
327
mod p;
428
mod zb;
529
mod zk;
@@ -531,44 +555,6 @@ pub unsafe fn hinval_gvma_all() {
531555
asm!(".insn r 0x73, 0, 0x33, x0, x0, x0", options(nostack))
532556
}
533557

534-
/// Reads the floating-point control and status register `fcsr`
535-
///
536-
/// Register `fcsr` is a 32-bit read/write register that selects the dynamic rounding mode
537-
/// for floating-point arithmetic operations and holds the accrued exception flag.
538-
///
539-
/// According to "F" Standard Extension for Single-Precision Floating-Point, Version 2.2,
540-
/// register `fcsr` is defined as:
541-
///
542-
/// | Bit index | Meaning |
543-
/// |:----------|:--------|
544-
/// | 0..=4 | Accrued Exceptions (`fflags`) |
545-
/// | 5..=7 | Rounding Mode (`frm`) |
546-
/// | 8..=31 | _Reserved_ |
547-
///
548-
/// For definition of each field, visit [`frrm`] and [`frflags`].
549-
///
550-
/// [`frrm`]: fn.frrm.html
551-
/// [`frflags`]: fn.frflags.html
552-
#[inline]
553-
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
554-
pub fn frcsr() -> u32 {
555-
let value: u32;
556-
unsafe { asm!("frcsr {}", out(reg) value, options(nomem, nostack)) };
557-
value
558-
}
559-
560-
/// Swaps the floating-point control and status register `fcsr`
561-
///
562-
/// This function swaps the value in `fcsr` by copying the original value to be returned,
563-
/// and then writing a new value obtained from input variable `value` into `fcsr`.
564-
#[inline]
565-
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
566-
pub fn fscsr(value: u32) -> u32 {
567-
let original: u32;
568-
unsafe { asm!("fscsr {}, {}", out(reg) original, in(reg) value, options(nomem, nostack)) }
569-
original
570-
}
571-
572558
/// Reads the floating-point rounding mode register `frm`
573559
///
574560
/// According to "F" Standard Extension for Single-Precision Floating-Point, Version 2.2,
@@ -591,53 +577,3 @@ pub fn frrm() -> u32 {
591577
unsafe { asm!("frrm {}", out(reg) value, options(nomem, nostack)) };
592578
value
593579
}
594-
595-
/// Swaps the floating-point rounding mode register `frm`
596-
///
597-
/// This function swaps the value in `frm` by copying the original value to be returned,
598-
/// and then writing a new value obtained from the three least-significant bits of
599-
/// input variable `value` into `frm`.
600-
#[inline]
601-
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
602-
pub fn fsrm(value: u32) -> u32 {
603-
let original: u32;
604-
unsafe { asm!("fsrm {}, {}", out(reg) original, in(reg) value, options(nomem, nostack)) }
605-
original
606-
}
607-
608-
/// Reads the floating-point accrued exception flags register `fflags`
609-
///
610-
/// The accrued exception flags indicate the exception conditions that have arisen
611-
/// on any floating-point arithmetic instruction since the field was last reset by software.
612-
///
613-
/// According to "F" Standard Extension for Single-Precision Floating-Point, Version 2.2,
614-
/// the accrued exception flags is defined as a bit vector of 5 bits.
615-
/// The meaning of each binary bit is listed in the table below.
616-
///
617-
/// | Bit index | Mnemonic | Meaning |
618-
/// |:--|:---|:-----------------|
619-
/// | 4 | NV | Invalid Operation |
620-
/// | 3 | DZ | Divide by Zero |
621-
/// | 2 | OF | Overflow |
622-
/// | 1 | UF | Underflow |
623-
/// | 0 | NX | Inexact |
624-
#[inline]
625-
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
626-
pub fn frflags() -> u32 {
627-
let value: u32;
628-
unsafe { asm!("frflags {}", out(reg) value, options(nomem, nostack)) };
629-
value
630-
}
631-
632-
/// Swaps the floating-point accrued exception flags register `fflags`
633-
///
634-
/// This function swaps the value in `fflags` by copying the original value to be returned,
635-
/// and then writing a new value obtained from the five least-significant bits of
636-
/// input variable `value` into `fflags`.
637-
#[inline]
638-
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
639-
pub fn fsflags(value: u32) -> u32 {
640-
let original: u32;
641-
unsafe { asm!("fsflags {}, {}", out(reg) original, in(reg) value, options(nomem, nostack)) }
642-
original
643-
}

0 commit comments

Comments
 (0)