Skip to content

Commit 676f161

Browse files
committed
Format and update description
- Rename doubledouble to f64f64 - Add architecture info about x86 and arm (as suggested) - Add description to target related types (as suggested) - Add link to IEEE-754 and LLVM LangRef
1 parent 4953919 commit 676f161

File tree

1 file changed

+31
-14
lines changed

1 file changed

+31
-14
lines changed

text/3451-additional-float-types.md

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@
66
# Summary
77
[summary]: #summary
88

9-
This RFC proposes new floating point types `f16` and `f128` into core language and standard library. Also this RFC introduces `f80`, `doubledouble`, `bf16` into `core::arch` for inter-op with existing native code.
9+
This RFC proposes new floating point types `f16` and `f128` into core language and standard library. Also, this RFC introduces `f80`, `f64f64`, and `bf16` into `core::arch` for target-specific support, and `core::ffi::c_longdouble` for FFI interop.
1010

1111
# Motivation
1212
[motivation]: #motivation
1313

14-
IEEE-754 standard defines binary floating point formats, including binary16, binary32, binary64 and binary128. The binary32 and binary64 correspond to `f32` and `f64` types in Rust, while binary16 and binary128 are used in multiple scenarios (machine learning, scientific computing, etc.) and accepted by some modern architectures (by software or hardware).
14+
[IEEE-754] standard defines binary floating point formats, including `binary16`, `binary32`, `binary64` and `binary128`. `binary32` and `binary64` correspond to `f32` and `f64` types in Rust, but there is currently no representation for `binary16` or `binary128`; these have uses in multiple scenarios (machine learning, scientific computing, etc.) and accepted by some modern architectures (by software or hardware), so this RFC proposes to add representations for them to the language.
1515

16-
In C/C++ world, there're already types representing these formats, along with more legacy non-standard types specific to some platform. Introduce them in a limited way would help improve FFI against such code.
16+
In C/C++ world, there are already types representing these formats, along with more legacy non-standard types specific to some platform. Introduce them in a limited way would help improve FFI against such code.
1717

1818
# Guide-level explanation
1919
[guide-level-explanation]: #guide-level-explanation
2020

21-
`f16` and `f128` are primitive floating types, they can be used just like `f32` or `f64`. They always conform to binary16 and binary128 format defined in IEEE-754, which means size of `f16` is always 16-bit, and size of `f128` is always 128-bit.
21+
`f16` and `f128` are primitive floating types, they can be used just like `f32` or `f64`. They always conform to the `binary16` and `binary128` formats defined in [IEEE-754], which means size of `f16` is always 16-bit, and size of `f128` is always 128-bit.
2222

2323
```rust
2424
let val1 = 1.0; // Default type is still f64
@@ -31,7 +31,9 @@ println!("Size of f128 in bytes: {}", std::mem::size_of_val(&val2)); // 16
3131
println!("Size of f16 in bytes: {}", std::mem::size_of_val(&val3)); // 2
3232
```
3333

34-
Because not every target supports `f16` and `f128`, compiler provides conditional guards for them:
34+
`f16` and `f128` will only be available on hardware that supports or natively emulates these type via LLVM's `half` and `fp128`, as mentioned in the [LLVM reference for floating types]. This means that the semantics of `f16` and `f128` are fixed as IEEE compliant in every supported platform, different from `long double` in C.
35+
36+
Because not every target supports `f16` and `f128`, compiler provides conditional guards.
3537

3638
```rust
3739
#[cfg(target_has_f128)]
@@ -43,14 +45,16 @@ fn get_f16() -> f16 { 1.0f16 }
4345

4446
All operators, constants and math functions defined for `f32` and `f64` in core, are also defined for `f16` and `f128`, and guarded by respective conditional guards.
4547

46-
`f80` type is defined in `core::arch::{x86, x86_64}`. `doubledouble` type is defined in `core::arch::{powerpc, powerpc64}`. `bf16` type is defined in `core::arch::{arm, aarch64, x86, x86_64}`. They do not have literal representation.
48+
- The `f80` type is defined in `core::arch::{x86, x86_64}` as 80-bit extended precision.
49+
- The `f64f64` type is defined in `core::arch::{powerpc, powerpc64}` and represent's PowerPC's non-IEEE double-double format (two `f64`s used to aproximate `f128`).
50+
- `bf16` type is defined in `core::arch::{arm, aarch64, x86, x86_64}` and represents the "brain" float, a truncated `f32` with SIMD support on some hardware. These types do not have literal representation.
4751

4852
# Reference-level explanation
4953
[reference-level-explanation]: #reference-level-explanation
5054

5155
## `f16` type
5256

53-
`f16` consists of 1 bit of sign, 5 bits of exponent, 10 bits of mantissa.
57+
`f16` consists of 1 bit of sign, 5 bits of exponent, 10 bits of mantissa. It is always in accordance with [IEEE-754].
5458

5559
The following `From` and `TryFrom` traits are implemented for conversion between `f16` and other types:
5660

@@ -70,7 +74,7 @@ impl From<i8> for f16 { /* ... */ }
7074

7175
`f128` is available for on targets having (1) hardware instructions or software emulation for 128-bit float type; (2) backend support for `f128` type on the target; (3) essential target features enabled (if any).
7276

73-
The list of targets supporting `f128` type may change over time. Initially, it includes `powerpc64le-*`.
77+
The list of targets supporting `f128` type may change over time. Initially, it includes `powerpc64le-*`, `x86_64-*` and `aarch64-*`
7478

7579
The following traits are also implemented for conversion between `f128` and other types:
7680

@@ -91,14 +95,24 @@ impl From<i64> for f128 { /* ... */ }
9195

9296
`f128` will generate `fp128` type in LLVM IR.
9397

98+
For `f64f64` type, conversion intrinsics are available under `core::arch::{powerpc, powerpc64}`. For `f80` type, conversion intrinsics are available under `core::arch::{x86, x86_64}`.
9499

95-
`std::simd` defines new vector types with `f16` or `f128` element: `f16x2` `f16x4` `f16x8` `f16x16` `f16x32` `f128x2` `f128x4`.
100+
## Architectures specific types
96101

97-
For `doubledouble` type, conversion intrinsics are available under `core::arch::{powerpc, powerpc64}`. For `f80` type, conversion intrinsics are available under `core::arch::{x86, x86_64}`.
102+
- `core::arch::{x86, x86_64}::f80` generates LLVM's `x86_fp80`, 80-bit extended precision
103+
- `core::arch::{powerpc, powerpc64}::f64f64` generates LLVM's `ppc_fp128`, a `f128` emulated type via dual `f64`s
104+
- `core::arch::{arm, aarch64, x86, x86_64}::bf16` generates LLVM's `bfloat`, 16-bit "brain" floats used in AVX and ARMv8.6-A
98105

99-
## Architectures specific types
106+
Where possible, `From` will be implemented to convert `f80` and `f64f64` to `f128`.
100107

101-
As for non-standard types, `f80` generates `x86_fp80`, `doubledouble` generates `ppc_fp128`, `bf16` generates `bfloat`.
108+
## FFI types
109+
110+
`core::ffi::c_longdouble` will always represent whatever `long double` does in C. Rust will defer to the compiler backend (LLVM) for what exactly this represents, but it will approximately be:
111+
112+
- 80-bit extended precision (f80) on `x86` and `x86_64`:
113+
- `f64` double precision with MSVC
114+
- `f128` quadruple precision on AArch64
115+
- `f64f64` on PowerPC
102116

103117
# Drawbacks
104118
[drawbacks]: #drawbacks
@@ -129,11 +143,14 @@ We have a previous proposal on `f16b` type to represent `bfloat16`: https://gith
129143
# Unresolved questions
130144
[unresolved-questions]: #unresolved-questions
131145

132-
This proposal does not introduce `c_longdouble` type for FFI, because it means one of `f128`, `doubledouble`, `f64` or `f80` on different cases. Also for `c_float128`.
146+
This proposal does not introduce `c_longdouble` type for FFI, because it means one of `f128`, `f64f64`, `f64` or `f80` on different cases. Also for `c_float128`.
133147

134148
# Future possibilities
135149
[future-possibilities]: #future-possibilities
136150

137-
More functions will be added to those platform dependent float types, like casting between `f128` and `doubledouble`.
151+
More functions will be added to those platform dependent float types, like casting between `f128` and `f64f64`.
138152

139153
For targets not supporting `f16` or `f128`, we may be able to introduce a 'limited mode', where the types are not fully functional, but user can load, store and call functions with such arguments.
154+
155+
[LLVM reference for floating types]: https://llvm.org/docs/LangRef.html#floating-point-types
156+
[IEEE-754]: https://en.wikipedia.org/wiki/IEEE_754

0 commit comments

Comments
 (0)