@@ -182,6 +182,12 @@ pub enum BinaryNaNPropagationMode {
182
182
SecondFirstPreferringSNaN ,
183
183
}
184
184
185
+ #[ derive( Copy , Clone , Eq , PartialEq , Hash , Debug ) ]
186
+ pub enum UnaryNaNPropagationMode {
187
+ AlwaysCanonical ,
188
+ First ,
189
+ }
190
+
185
191
#[ derive( Copy , Clone , Eq , PartialEq , Hash , Debug ) ]
186
192
pub enum BinaryNaNPropagationResults {
187
193
Canonical ,
@@ -254,25 +260,41 @@ impl BinaryNaNPropagationMode {
254
260
}
255
261
256
262
#[ derive( Copy , Clone , Eq , PartialEq , Hash , Debug ) ]
257
- pub enum NaNPropagationResults {
263
+ pub enum UnaryNaNPropagationResults {
258
264
Canonical ,
259
265
First ,
260
- Second ,
261
- Third ,
262
266
}
263
267
264
- impl Default for NaNPropagationResults {
268
+ impl Default for UnaryNaNPropagationResults {
265
269
fn default ( ) -> Self {
266
270
Self :: Canonical
267
271
}
268
272
}
269
273
270
- impl From < NaNPropagationMode > for BinaryNaNPropagationMode {
271
- fn from ( v : NaNPropagationMode ) -> Self {
274
+ impl UnaryNaNPropagationMode {
275
+ pub fn calculate_propagation_results (
276
+ self ,
277
+ first_class : FloatClass ,
278
+ ) -> UnaryNaNPropagationResults {
279
+ match self {
280
+ UnaryNaNPropagationMode :: AlwaysCanonical => UnaryNaNPropagationResults :: Canonical ,
281
+ UnaryNaNPropagationMode :: First => {
282
+ if first_class. is_nan ( ) {
283
+ UnaryNaNPropagationResults :: First
284
+ } else {
285
+ UnaryNaNPropagationResults :: Canonical
286
+ }
287
+ }
288
+ }
289
+ }
290
+ }
291
+
292
+ impl From < TernaryNaNPropagationMode > for BinaryNaNPropagationMode {
293
+ fn from ( v : TernaryNaNPropagationMode ) -> Self {
272
294
use BinaryNaNPropagationMode :: * ;
273
- use NaNPropagationMode :: * ;
295
+ use TernaryNaNPropagationMode :: * ;
274
296
match v {
275
- NaNPropagationMode :: AlwaysCanonical => BinaryNaNPropagationMode :: AlwaysCanonical ,
297
+ TernaryNaNPropagationMode :: AlwaysCanonical => BinaryNaNPropagationMode :: AlwaysCanonical ,
276
298
FirstSecondThird | FirstThirdSecond | ThirdFirstSecond => FirstSecond ,
277
299
SecondFirstThird | SecondThirdFirst | ThirdSecondFirst => SecondFirst ,
278
300
FirstSecondThirdPreferringSNaN
@@ -285,8 +307,35 @@ impl From<NaNPropagationMode> for BinaryNaNPropagationMode {
285
307
}
286
308
}
287
309
310
+ impl From< BinaryNaNPropagationMode > for UnaryNaNPropagationMode {
311
+ fn from ( v : BinaryNaNPropagationMode ) -> Self {
312
+ use BinaryNaNPropagationMode :: * ;
313
+ use UnaryNaNPropagationMode :: * ;
314
+ match v {
315
+ BinaryNaNPropagationMode :: AlwaysCanonical => UnaryNaNPropagationMode :: AlwaysCanonical ,
316
+ FirstSecond | SecondFirst | FirstSecondPreferringSNaN | SecondFirstPreferringSNaN => {
317
+ First
318
+ }
319
+ }
320
+ }
321
+ }
322
+
323
+ #[ derive( Copy , Clone , Eq , PartialEq , Hash , Debug ) ]
324
+ pub enum TernaryNaNPropagationResults {
325
+ Canonical ,
326
+ First ,
327
+ Second ,
328
+ Third ,
329
+ }
330
+
331
+ impl Default for TernaryNaNPropagationResults {
332
+ fn default ( ) -> Self {
333
+ Self :: Canonical
334
+ }
335
+ }
336
+
288
337
#[ derive( Copy , Clone , Eq , PartialEq , Hash , Debug ) ]
289
- pub enum NaNPropagationMode {
338
+ pub enum TernaryNaNPropagationMode {
290
339
AlwaysCanonical ,
291
340
FirstSecondThird ,
292
341
FirstThirdSecond ,
@@ -302,22 +351,22 @@ pub enum NaNPropagationMode {
302
351
ThirdSecondFirstPreferringSNaN ,
303
352
}
304
353
305
- impl Default for NaNPropagationMode {
306
- fn default ( ) -> NaNPropagationMode {
307
- NaNPropagationMode :: AlwaysCanonical
354
+ impl Default for TernaryNaNPropagationMode {
355
+ fn default ( ) -> TernaryNaNPropagationMode {
356
+ TernaryNaNPropagationMode :: AlwaysCanonical
308
357
}
309
358
}
310
359
311
- impl NaNPropagationMode {
360
+ impl TernaryNaNPropagationMode {
312
361
pub fn calculate_propagation_results (
313
362
self ,
314
363
first_class : FloatClass ,
315
364
second_class : FloatClass ,
316
365
third_class : FloatClass ,
317
- ) -> NaNPropagationResults {
366
+ ) -> TernaryNaNPropagationResults {
318
367
#![ allow( clippy:: cognitive_complexity) ]
319
- use NaNPropagationMode :: * ;
320
- use NaNPropagationResults :: * ;
368
+ use TernaryNaNPropagationMode :: * ;
369
+ use TernaryNaNPropagationResults :: * ;
321
370
match self {
322
371
AlwaysCanonical => Canonical ,
323
372
FirstSecondThird => {
@@ -691,7 +740,8 @@ pub struct PlatformProperties {
691
740
pub canonical_nan_mantissa_msb : bool ,
692
741
pub canonical_nan_mantissa_second_to_msb : bool ,
693
742
pub canonical_nan_mantissa_rest : bool ,
694
- pub nan_propagation_mode : NaNPropagationMode ,
743
+ pub add_sub_mul_div_nan_propagation_mode : BinaryNaNPropagationMode ,
744
+ pub fma_nan_propagation_mode : TernaryNaNPropagationMode ,
695
745
pub fma_inf_zero_qnan_result : FMAInfZeroQNaNResult ,
696
746
}
697
747
@@ -735,8 +785,12 @@ macro_rules! platform_properties_constants {
735
785
& self . canonical_nan_mantissa_rest,
736
786
)
737
787
. field(
738
- "nan_propagation_mode" ,
739
- & self . nan_propagation_mode,
788
+ "add_sub_mul_div_nan_propagation_mode" ,
789
+ & self . add_sub_mul_div_nan_propagation_mode,
790
+ )
791
+ . field(
792
+ "fma_nan_propagation_mode" ,
793
+ & self . fma_nan_propagation_mode,
740
794
)
741
795
. field(
742
796
"fma_inf_zero_qnan_result" ,
@@ -756,31 +810,38 @@ platform_properties_constants! {
756
810
canonical_nan_mantissa_msb: true ,
757
811
canonical_nan_mantissa_second_to_msb: false ,
758
812
canonical_nan_mantissa_rest: false ,
759
- nan_propagation_mode: NaNPropagationMode :: ThirdFirstSecondPreferringSNaN ,
813
+ // FIXME: NaN propagation not known to be correct
814
+ add_sub_mul_div_nan_propagation_mode: BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
815
+ fma_nan_propagation_mode: TernaryNaNPropagationMode :: ThirdFirstSecondPreferringSNaN ,
760
816
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: CanonicalAndGenerateInvalid ,
761
817
} ;
762
818
pub const RISC_V : PlatformProperties = PlatformProperties {
763
819
canonical_nan_sign: Sign :: Positive ,
764
820
canonical_nan_mantissa_msb: true ,
765
821
canonical_nan_mantissa_second_to_msb: false ,
766
822
canonical_nan_mantissa_rest: false ,
767
- nan_propagation_mode: NaNPropagationMode :: AlwaysCanonical ,
823
+ add_sub_mul_div_nan_propagation_mode: BinaryNaNPropagationMode :: AlwaysCanonical ,
824
+ fma_nan_propagation_mode: TernaryNaNPropagationMode :: AlwaysCanonical ,
768
825
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: CanonicalAndGenerateInvalid ,
769
826
} ;
770
827
pub const POWER : PlatformProperties = PlatformProperties {
771
828
canonical_nan_sign: Sign :: Positive ,
772
829
canonical_nan_mantissa_msb: true ,
773
830
canonical_nan_mantissa_second_to_msb: false ,
774
831
canonical_nan_mantissa_rest: false ,
775
- nan_propagation_mode: NaNPropagationMode :: FirstThirdSecond ,
832
+ // FIXME: NaN propagation not known to be correct
833
+ add_sub_mul_div_nan_propagation_mode: BinaryNaNPropagationMode :: FirstSecond ,
834
+ fma_nan_propagation_mode: TernaryNaNPropagationMode :: FirstThirdSecond ,
776
835
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: PropagateAndGenerateInvalid ,
777
836
} ;
778
837
pub const MIPS_2008 : PlatformProperties = PlatformProperties {
779
838
canonical_nan_sign: Sign :: Positive ,
780
839
canonical_nan_mantissa_msb: true ,
781
840
canonical_nan_mantissa_second_to_msb: false ,
782
841
canonical_nan_mantissa_rest: false ,
783
- nan_propagation_mode: NaNPropagationMode :: ThirdFirstSecondPreferringSNaN ,
842
+ // FIXME: NaN propagation not known to be correct
843
+ add_sub_mul_div_nan_propagation_mode: BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
844
+ fma_nan_propagation_mode: TernaryNaNPropagationMode :: ThirdFirstSecondPreferringSNaN ,
784
845
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: PropagateAndGenerateInvalid ,
785
846
} ;
786
847
// X86_X87 is not implemented
@@ -789,31 +850,39 @@ platform_properties_constants! {
789
850
canonical_nan_mantissa_msb: true ,
790
851
canonical_nan_mantissa_second_to_msb: false ,
791
852
canonical_nan_mantissa_rest: false ,
792
- nan_propagation_mode: NaNPropagationMode :: FirstSecondThird ,
853
+ // FIXME: NaN propagation not known to be correct
854
+ add_sub_mul_div_nan_propagation_mode: BinaryNaNPropagationMode :: FirstSecond ,
855
+ fma_nan_propagation_mode: TernaryNaNPropagationMode :: FirstSecondThird ,
793
856
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: FollowNaNPropagationMode ,
794
857
} ;
795
858
pub const SPARC : PlatformProperties = PlatformProperties {
796
859
canonical_nan_sign: Sign :: Positive ,
797
860
canonical_nan_mantissa_msb: true ,
798
861
canonical_nan_mantissa_second_to_msb: true ,
799
862
canonical_nan_mantissa_rest: true ,
800
- nan_propagation_mode: NaNPropagationMode :: FirstSecondThirdPreferringSNaN ,
863
+ // FIXME: NaN propagation not known to be correct
864
+ add_sub_mul_div_nan_propagation_mode: BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
865
+ fma_nan_propagation_mode: TernaryNaNPropagationMode :: FirstSecondThirdPreferringSNaN ,
801
866
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: FollowNaNPropagationMode ,
802
867
} ;
803
868
pub const HPPA : PlatformProperties = PlatformProperties {
804
869
canonical_nan_sign: Sign :: Positive ,
805
870
canonical_nan_mantissa_msb: false ,
806
871
canonical_nan_mantissa_second_to_msb: true ,
807
872
canonical_nan_mantissa_rest: false ,
808
- nan_propagation_mode: NaNPropagationMode :: FirstSecondThirdPreferringSNaN ,
873
+ // FIXME: NaN propagation not known to be correct
874
+ add_sub_mul_div_nan_propagation_mode: BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
875
+ fma_nan_propagation_mode: TernaryNaNPropagationMode :: FirstSecondThirdPreferringSNaN ,
809
876
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: FollowNaNPropagationMode ,
810
877
} ;
811
878
pub const MIPS_LEGACY : PlatformProperties = PlatformProperties {
812
879
canonical_nan_sign: Sign :: Positive ,
813
880
canonical_nan_mantissa_msb: false ,
814
881
canonical_nan_mantissa_second_to_msb: true ,
815
882
canonical_nan_mantissa_rest: true ,
816
- nan_propagation_mode: NaNPropagationMode :: FirstSecondThirdPreferringSNaN ,
883
+ // FIXME: NaN propagation not known to be correct
884
+ add_sub_mul_div_nan_propagation_mode: BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
885
+ fma_nan_propagation_mode: TernaryNaNPropagationMode :: FirstSecondThirdPreferringSNaN ,
817
886
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: CanonicalAndGenerateInvalid ,
818
887
} ;
819
888
}
@@ -1880,10 +1949,10 @@ impl<Bits: FloatBitsType, FT: FloatTraits<Bits = Bits>> Float<FT> {
1880
1949
if self_class. is_signaling_nan ( ) || rhs_class. is_signaling_nan ( ) {
1881
1950
fp_state. status_flags |= StatusFlags :: INVALID_OPERATION ;
1882
1951
}
1883
- match BinaryNaNPropagationMode :: from (
1884
- properties . platform_properties . nan_propagation_mode ,
1885
- )
1886
- . calculate_propagation_results ( self_class, rhs_class)
1952
+ match properties
1953
+ . platform_properties
1954
+ . add_sub_mul_div_nan_propagation_mode
1955
+ . calculate_propagation_results ( self_class, rhs_class)
1887
1956
{
1888
1957
BinaryNaNPropagationResults :: First => self . to_quiet_nan ( ) ,
1889
1958
BinaryNaNPropagationResults :: Second => rhs. to_quiet_nan ( ) ,
@@ -1974,10 +2043,10 @@ impl<Bits: FloatBitsType, FT: FloatTraits<Bits = Bits>> Float<FT> {
1974
2043
if self_class. is_signaling_nan ( ) || rhs_class. is_signaling_nan ( ) {
1975
2044
fp_state. status_flags |= StatusFlags :: INVALID_OPERATION ;
1976
2045
}
1977
- match BinaryNaNPropagationMode :: from (
1978
- properties . platform_properties . nan_propagation_mode ,
1979
- )
1980
- . calculate_propagation_results ( self_class, rhs_class)
2046
+ match properties
2047
+ . platform_properties
2048
F438
+ . add_sub_mul_div_nan_propagation_mode
2049
+ . calculate_propagation_results ( self_class, rhs_class)
1981
2050
{
1982
2051
BinaryNaNPropagationResults :: First => self . to_quiet_nan ( ) ,
1983
2052
BinaryNaNPropagationResults :: Second => rhs. to_quiet_nan ( ) ,
@@ -2023,10 +2092,10 @@ impl<Bits: FloatBitsType, FT: FloatTraits<Bits = Bits>> Float<FT> {
2023
2092
if self_class. is_signaling_nan ( ) || rhs_class. is_signaling_nan ( ) {
2024
2093
fp_state. status_flags |= StatusFlags :: INVALID_OPERATION ;
2025
2094
}
2026
- match BinaryNaNPropagationMode :: from (
2027
- properties . platform_properties . nan_propagation_mode ,
2028
- )
2029
- . calculate_propagation_results ( self_class, rhs_class)
2095
+ match properties
2096
+ . platform_properties
2097
+ . add_sub_mul_div_nan_propagation_mode
2098
+ . calculate_propagation_results ( self_class, rhs_class)
2030
2099
{
2031
2100
BinaryNaNPropagationResults :: First => self . to_quiet_nan ( ) ,
2032
2101
BinaryNaNPropagationResults :: Second => rhs. to_quiet_nan ( ) ,
@@ -2058,7 +2127,7 @@ impl<Bits: FloatBitsType, FT: FloatTraits<Bits = Bits>> Float<FT> {
2058
2127
}
2059
2128
}
2060
2129
/// compute `(self * factor) + term`
2061
- pub fn mul_add (
2130
+ pub fn fused_mul_add (
2062
2131
& self ,
2063
2132
factor : & Self ,
2064
2133
term : & Self ,
@@ -2099,13 +2168,13 @@ impl<Bits: FloatBitsType, FT: FloatTraits<Bits = Bits>> Float<FT> {
2099
2168
}
2100
2169
match properties
2101
2170
. platform_properties
2102
- . nan_propagation_mode
2171
+ . fma_nan_propagation_mode
2103
2172
. calculate_propagation_results ( self_class, factor_class, term_class)
2104
2173
{
2105
- NaNPropagationResults :: First => self . to_quiet_nan ( ) ,
2106
- NaNPropagationResults :: Second => factor. to_quiet_nan ( ) ,
2107
- NaNPropagationResults :: Third => term. to_quiet_nan ( ) ,
2108
- NaNPropagationResults :: Canonical => {
2174
+ TernaryNaNPropagationResults :: First => self . to_quiet_nan ( ) ,
2175
+ TernaryNaNPropagationResults :: Second => factor. to_quiet_nan ( ) ,
2176
+ TernaryNaNPropagationResults :: Third => term. to_quiet_nan ( ) ,
2177
+ TernaryNaNPropagationResults :: Canonical => {
2109
2178
Self :: quiet_nan_with_traits ( self . traits . clone ( ) )
2110
2179
}
2111
2180
}
@@ -2314,7 +2383,8 @@ mod tests {
2314
2383
canonical_nan_sign: Negative, canonical_nan_mantissa_msb: false, \
2315
2384
canonical_nan_mantissa_second_to_msb: true, \
2316
2385
canonical_nan_mantissa_rest: true, \
2317
- nan_propagation_mode: FirstSecondThirdPreferringSNaN, \
2386
+ add_sub_mul_div_nan_propagation_mode: FirstSecondPreferringSNaN, \
2387
+ fma_nan_propagation_mode: FirstSecondThirdPreferringSNaN, \
2318
2388
fma_inf_zero_qnan_result: CanonicalAndGenerateInvalid, \
2319
2389
quiet_nan_format: MIPSLegacy }), \
2320
2390
bits: 0x1234, sign: Positive, exponent_field: 0x04, \
0 commit comments