rust-lang / rust-lang/stdarch

x86_64 MXCSR denormals are zero bit: add constant

Open
#852 5 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
694
Forks
336
Avg merge
5d 14h
Merged PRs (30d)
9

Description

On x86_64, the SSE floating point control register (MXCSR) has two bits concerned with denormal floating point values. The purpose of these bits is to enable a mode that avoids slowdowns from calculations with denormal numbers at the cost of getting incorrect results from underflows.

The more important one is the flush to zero bit (bit 15 in the register). When that bit is set, when a floating-point arithmetic instruction would output a denormal number (and would not raise an unmasked exception), then it instead outputs zero (and the denormal exception that it would normally flag is suppressed). The consts for this bit in the core::arch::x86_64 module are _MM_FLUSH_ZERO_ON, _MM_FLUSH_ZERO_OFF, _MM_FLUSH_ZERO_MASK.

The less important bit is the denormals are zero bit (bit 6 in the register). That bit affects the input arguments of floating-point arithmetic instructions, rather than the outputs. When the bit is set, when a floating-point arithmetic instruction has a number in a source argument that is a denormal number, the instruction behaves as if that number was zero instead. On x86_32, setting this bit is only conditionally supported, because old CPUs didn't have this mode. Testing and clearing the bit is always supported if the MXCSR register exists.

The crate does not have consts for the denormals are zero bit. This is probably an oversight, and this ticket asks to correct it. I suggest the following names, based on Intel's C interface, but I don't insist on them.

pub const _MM_DENORMALS_ZERO_MASK: u32 = 0x0040;
pub const _MM_DENORMALS_ZERO_ON: u32 = 0x0040;
pub const _MM_DENORMALS_ZERO_OFF: u32 = 0x0000;

(Please double-check the above values before commiting.)

The C interface also has convenience macros for getting and setting the bit, so you may add those too. Personally I think they're superfluous, because functions that access this bit will most likely set or clear the bits together with the flush to zero bits, eg.

_mm_setcsr(_mm_getcsr() | _MM_FLUSH_ZERO_ON | _MM_DENORMALS_ZERO_ON);
// XMM floating-point arithmetic computations here
_mm_setcsr(_mm_getcsr() & !_MM_FLUSH_ZERO_MASK & !_MM_DENORMALS_ZERO_MASK);

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in the core::arch::x86_64 module, where the existing MXCSR flush-to-zero constants are defined. Verify the proposed bit values against the x86_64 interface, add the denormals-zero constants, and confirm that the module builds and its existing architecture tests pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
devtools
Issue type
Feature
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.