66mod apf_fuzz;
77mod exhaustive;
88
9- use clap:: { CommandFactory , Parser , Subcommand } ;
109use io:: IsTerminal ;
11- use rustc_apfloat:: ieee:: { Double , Single } ;
12- use rustc_apfloat:: { Float , FloatConvert , Round , Status , StatusAnd , ieee} ;
13- use std:: io:: { self , Read } ;
10+ use io:: Read ;
11+ use std:: io;
1412use std:: path:: PathBuf ;
1513use std:: { fmt, fs} ;
1614
15+ use clap:: { CommandFactory , Parser , Subcommand } ;
16+ use num_derive:: FromPrimitive ;
17+ use num_traits:: FromPrimitive ;
18+ use rustc_apfloat:: ieee:: { Double , Single } ;
19+ use rustc_apfloat:: { Float , FloatConvert , Round , Status , StatusAnd , ieee} ;
20+
1721use crate :: apf_fuzz:: Op ;
1822
1923#[ derive( Clone , Parser , Debug ) ]
@@ -185,7 +189,6 @@ trait FloatRepr: Copy + Default + Eq + fmt::Display + fmt::Debug {
185189macro_rules! float_reprs {
186190 ( $( $name: ident( $repr: ty) {
187191 type RustcApFloat = $rs_apf_ty: ty;
188- const REPR_TAG = $repr_tag: expr;
189192 extern fn = $cxx_apf_eval_fuzz_op: ident;
190193 $( type HardFloat = $hard_float_ty: ty; ) ?
191194 } ) +) => {
@@ -198,26 +201,6 @@ macro_rules! float_reprs {
198201 } ;
199202 }
200203
201- #[ allow( non_camel_case_types) ]
202- #[ derive( Clone , Copy , Debug , PartialEq ) ]
203- enum FpKind {
204- $( $name = $repr_tag, ) +
205- }
206-
207- impl FpKind {
208- fn from_u8( tag: u8 ) -> Option <Self > {
209- let v = match tag {
210- $( x if x == Self :: $name. to_u8( ) => Self :: $name, ) +
211- _ => return None ,
212- } ;
213- Some ( v)
214- }
215-
216- fn to_u8( self ) -> u8 {
217- self as u8
218- }
219- }
220-
221204 $(
222205 #[ repr( C ) ]
223206 #[ derive( Copy , Clone , Default , PartialEq , Eq ) ]
@@ -312,52 +295,76 @@ macro_rules! float_reprs {
312295float_reprs ! {
313296 Ieee16 ( u16 ) {
314297 type RustcApFloat = rustc_apfloat:: ieee:: Half ;
315- const REPR_TAG = 16 ;
316298 extern fn = cxx_apf_eval_op_ieee16;
317299 }
318300 Ieee32 ( u32 ) {
319301 type RustcApFloat = rustc_apfloat:: ieee:: Single ;
320- const REPR_TAG = 32 ;
321302 extern fn = cxx_apf_eval_op_ieee32;
322303 type HardFloat = f32 ;
323304 }
324305 Ieee64 ( u64 ) {
325306 type RustcApFloat = rustc_apfloat:: ieee:: Double ;
326- const REPR_TAG = 64 ;
327307 extern fn = cxx_apf_eval_op_ieee64;
328308 type HardFloat = f64 ;
329309 }
330310 Ieee128 ( u128 ) {
331311 type RustcApFloat = rustc_apfloat:: ieee:: Quad ;
332- const REPR_TAG = 128 ;
333312 extern fn = cxx_apf_eval_op_ieee128;
334313 }
335314
336315 // Non-standard IEEE-like formats.
337316 F8E5M2 ( u8 ) {
338317 type RustcApFloat = rustc_apfloat:: ieee:: Float8E5M2 ;
339- const REPR_TAG = 8 + 0 ;
340318 extern fn = cxx_apf_eval_op_f8e5m2;
341319 }
342320 F8E4M3FN ( u8 ) {
343321 type RustcApFloat = rustc_apfloat:: ieee:: Float8E4M3FN ;
344- const REPR_TAG = 8 + 1 ;
345322 extern fn = cxx_apf_eval_op_f8e4m3fn;
346323 }
347324 BrainF16 ( u16 ) {
348325 type RustcApFloat = rustc_apfloat:: ieee:: BFloat ;
349- const REPR_TAG = 16 + 1 ;
350326 extern fn = cxx_apf_eval_op_brainf16;
351327 }
352328 X87_F80 ( u128 ) {
353329 type RustcApFloat = rustc_apfloat:: ieee:: X87DoubleExtended ;
354- const REPR_TAG = 80 ;
355330 extern fn = cxx_apf_eval_op_x87_f80;
356331 }
357332}
358333
359334pub ( crate ) use for_each_repr;
360335
336+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , FromPrimitive ) ]
337+ pub enum FpKind {
338+ // The tag is based on the bit count. These are specified so corpus inputs are stable.
339+ Ieee16 = 16 ,
340+ Ieee32 = 32 ,
341+ Ieee64 = 64 ,
342+ Ieee128 = 128 ,
343+ F8E5M2 = 8 ,
344+ F8E4M3FN = 8 + 1 ,
345+ BrainF16 = 16 + 1 ,
346+ #[ allow( non_camel_case_types) ]
347+ X87_F80 = 80 ,
348+ }
349+
350+ impl FpKind {
351+ #[ cfg_attr( not( test) , expect( unused) ) ]
352+ const ALL : & [ Self ] = & [
353+ Self :: Ieee16 ,
354+ Self :: Ieee32 ,
355+ Self :: Ieee64 ,
356+ Self :: Ieee128 ,
357+ Self :: F8E5M2 ,
358+ Self :: F8E4M3FN ,
359+ Self :: BrainF16 ,
360+ Self :: X87_F80 ,
361+ ] ;
362+
363+ pub fn to_u8 ( self ) -> u8 {
364+ self as u8
365+ }
366+ }
367+
361368/// Errors from improperly formed inputs that cause an exit from the fuzzer but do not raise
362369/// a test failing error.
363370#[ derive( Clone , Copy , Debug ) ]
@@ -1343,4 +1350,15 @@ mod tests {
13431350 }
13441351 assert_eq ! ( exp_mask | qnan_bit_mask, F :: RustcApFloat :: NAN . to_bits( ) ) ;
13451352 }
1353+
1354+ #[ test]
1355+ fn fpkind_all_list ( ) {
1356+ let mut computed = ( 0u8 ..=u8:: MAX )
1357+ . filter_map ( FpKind :: from_u8)
1358+ . collect :: < Vec < _ > > ( ) ;
1359+ let mut listed = FpKind :: ALL . to_vec ( ) ;
1360+ computed. sort_unstable ( ) ;
1361+ listed. sort_unstable ( ) ;
1362+ assert_eq ! ( computed, listed) ;
1363+ }
13461364}
0 commit comments