33#![ allow( internal_features) ] // for the below config
44#![ feature( cfg_target_has_reliable_f16_f128) ]
55
6- mod apf_fuzz;
76mod exhaustive;
87
98use io:: IsTerminal ;
@@ -13,13 +12,11 @@ use std::path::PathBuf;
1312use std:: { fmt, fs} ;
1413
1514use clap:: { CommandFactory , Parser , Subcommand } ;
16- use num_derive:: FromPrimitive ;
17- use num_traits:: FromPrimitive ;
15+ use num_derive:: { FromPrimitive , ToPrimitive } ;
16+ use num_traits:: { FromPrimitive , ToPrimitive } ;
1817use rustc_apfloat:: ieee:: { Double , Single } ;
1918use rustc_apfloat:: { Float , FloatConvert , Round , Status , StatusAnd , ieee} ;
2019
21- use crate :: apf_fuzz:: Op ;
22-
2320#[ derive( Clone , Parser , Debug ) ]
2421struct Args {
2522 /// Disable comparison with C++ (LLVM's original) APFloat
@@ -244,7 +241,9 @@ macro_rules! float_reprs {
244241
245242 let rm = round_to_u8( rm) ;
246243 let mut out = 0 ;
247- let status = cxx:: $cxx_apf_eval_fuzz_op( op. to_u8( ) , rm, a. 0 , b. 0 , c. 0 , & mut out) ;
244+ let status = cxx:: $cxx_apf_eval_fuzz_op(
245+ op. to_u8( ) . unwrap( ) , rm, a. 0 , b. 0 , c. 0 , & mut out,
246+ ) ;
248247 let status = cxx:: decode_status( status) ;
249248
250249 status. and( Self ( out) )
@@ -365,6 +364,61 @@ impl FpKind {
365364 }
366365}
367366
367+ /// A testable operation, which can be encoded as a byte.
368+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , FromPrimitive , ToPrimitive ) ]
369+ pub enum Op {
370+ Neg = 0 ,
371+ Add = 1 ,
372+ Sub = 2 ,
373+ Mul = 3 ,
374+ Div = 4 ,
375+ Rem = 5 ,
376+ MulAdd = 6 ,
377+ FToI128ToF = 7 ,
378+ FToU128ToF = 8 ,
379+ FToSingleToF = 9 ,
380+ FToDoubleToF = 10 ,
381+ }
382+
383+ impl Op {
384+ pub const ALL : & [ Self ] = & [
385+ Self :: Neg ,
386+ Self :: Add ,
387+ Self :: Sub ,
388+ Self :: Mul ,
389+ Self :: Div ,
390+ Self :: Rem ,
391+ Self :: MulAdd ,
392+ Self :: FToI128ToF ,
393+ Self :: FToU128ToF ,
394+ Self :: FToSingleToF ,
395+ Self :: FToDoubleToF ,
396+ ] ;
397+
398+ pub fn airity ( self ) -> Arity {
399+ match self {
400+ Op :: Neg => Arity :: Unary ,
401+ Op :: Add => Arity :: Binary ,
402+ Op :: Sub => Arity :: Binary ,
403+ Op :: Mul => Arity :: Binary ,
404+ Op :: Div => Arity :: Binary ,
405+ Op :: Rem => Arity :: Binary ,
406+ Op :: MulAdd => Arity :: Ternary ,
407+ Op :: FToI128ToF => Arity :: Unary ,
408+ Op :: FToU128ToF => Arity :: Unary ,
409+ Op :: FToSingleToF => Arity :: Unary ,
410+ Op :: FToDoubleToF => Arity :: Unary ,
411+ }
412+ }
413+ }
414+
415+ /// Number of inputs to an operation.
416+ #[ derive( Copy , Clone , Debug ) ]
417+ pub enum Arity {
418+ Unary = 1 ,
419+ Binary = 2 ,
420+ Ternary = 3 ,
421+ }
368422/// Errors from improperly formed inputs that cause an exit from the fuzzer but do not raise
369423/// a test failing error.
370424#[ derive( Clone , Copy , Debug ) ]
@@ -1351,6 +1405,17 @@ mod tests {
13511405 assert_eq ! ( exp_mask | qnan_bit_mask, F :: RustcApFloat :: NAN . to_bits( ) ) ;
13521406 }
13531407
1408+ /* Check that `ALL` actually contains all variants. */
1409+
1410+ #[ test]
1411+ fn op_all_list ( ) {
1412+ let mut computed = ( 0u8 ..=u8:: MAX ) . filter_map ( Op :: from_u8) . collect :: < Vec < _ > > ( ) ;
1413+ let mut listed = Op :: ALL . to_vec ( ) ;
1414+ computed. sort_unstable ( ) ;
1415+ listed. sort_unstable ( ) ;
1416+ assert_eq ! ( computed, listed) ;
1417+ }
1418+
13541419 #[ test]
13551420 fn fpkind_all_list ( ) {
13561421 let mut computed = ( 0u8 ..=u8:: MAX )
0 commit comments