@@ -12,8 +12,8 @@ struct Cxx<T>(T);
12
12
13
13
use self :: OpKind :: * ;
14
14
enum OpKind {
15
- Unary ( Rust < char > , Cxx < & ' static str > ) ,
16
- Binary ( Rust < char > , Cxx < & ' static str > ) ,
15
+ Unary ( char ) ,
16
+ Binary ( char ) ,
17
17
Ternary ( Rust < & ' static str > , Cxx < & ' static str > ) ,
18
18
19
19
// HACK(eddyb) all other ops have floating-point inputs *and* outputs, so
@@ -39,22 +39,22 @@ impl Type {
39
39
impl OpKind {
40
40
fn inputs < ' a , T > ( & self , all_inputs : & ' a [ T ; 3 ] ) -> & ' a [ T ] {
41
41
match self {
42
- Unary ( .. ) | Roundtrip ( _) => & all_inputs[ ..1 ] ,
43
- Binary ( .. ) => & all_inputs[ ..2 ] ,
42
+ Unary ( _ ) | Roundtrip ( _) => & all_inputs[ ..1 ] ,
43
+ Binary ( _ ) => & all_inputs[ ..2 ] ,
44
44
Ternary ( ..) => & all_inputs[ ..3 ] ,
45
45
}
46
46
}
47
47
}
48
48
49
49
const OPS : & [ ( & str , OpKind ) ] = & [
50
50
// Unary (`F -> F`) ops.
51
- ( "Neg" , Unary ( Rust ( '-' ) , Cxx ( "changeSign" ) ) ) ,
51
+ ( "Neg" , Unary ( '-' ) ) ,
52
52
// Binary (`(F, F) -> F`) ops.
53
- ( "Add" , Binary ( Rust ( '+' ) , Cxx ( "add" ) ) ) ,
54
- ( "Sub" , Binary ( Rust ( '-' ) , Cxx ( "subtract" ) ) ) ,
55
- ( "Mul" , Binary ( Rust ( '*' ) , Cxx ( "multiply" ) ) ) ,
56
- ( "Div" , Binary ( Rust ( '/' ) , Cxx ( "divide" ) ) ) ,
57
- ( "Rem" , Binary ( Rust ( '%' ) , Cxx ( "mod" ) ) ) ,
53
+ ( "Add" , Binary ( '+' ) ) ,
54
+ ( "Sub" , Binary ( '-' ) ) ,
55
+ ( "Mul" , Binary ( '*' ) ) ,
56
+ ( "Div" , Binary ( '/' ) ) ,
57
+ ( "Rem" , Binary ( '%' ) ) ,
58
58
// Ternary (`(F, F) -> F`) ops.
59
59
( "MulAdd" , Ternary ( Rust ( "mul_add" ) , Cxx ( "fusedMultiplyAdd" ) ) ) ,
60
60
// Roundtrip (`F -> T -> F`) ops.
@@ -141,8 +141,8 @@ impl<HF> FuzzOp<HF>
141
141
" + & all_ops_map_concat ( |_tag, name, kind| {
142
142
let inputs = kind. inputs ( & [ "a" , "b" , "c" ] ) ;
143
143
let expr = match kind {
144
- Unary ( Rust ( op ) , _ ) => format ! ( "{op}{}" , inputs[ 0 ] ) ,
145
- Binary ( Rust ( op ) , _ ) => format ! ( "{} {op} {}" , inputs[ 0 ] , inputs[ 1 ] ) ,
144
+ Unary ( op ) => format ! ( "{op}{}" , inputs[ 0 ] ) ,
145
+ Binary ( op ) => format ! ( "{} {op} {}" , inputs[ 0 ] , inputs[ 1 ] ) ,
146
146
Ternary ( Rust ( method) , _) => {
147
147
format ! ( "{}.{method}({}, {})" , inputs[ 0 ] , inputs[ 1 ] , inputs[ 2 ] )
148
148
}
@@ -169,8 +169,8 @@ impl<RustcApFloat: rustc_apfloat::Float> FuzzOp<RustcApFloat> {
169
169
" + & all_ops_map_concat ( |_tag, name, kind| {
170
170
let inputs = kind. inputs ( & [ "a" , "b" , "c" ] ) ;
171
171
let expr = match kind {
172
- Unary ( Rust ( op ) , _ ) => format ! ( "{op}{}" , inputs[ 0 ] ) ,
173
- Binary ( Rust ( op ) , _ ) => format ! ( "({} {op} {}).value" , inputs[ 0 ] , inputs[ 1 ] ) ,
172
+ Unary ( op ) => format ! ( "{op}{}" , inputs[ 0 ] ) ,
173
+ Binary ( op ) => format ! ( "({} {op} {}).value" , inputs[ 0 ] , inputs[ 1 ] ) ,
174
174
Ternary ( Rust ( method) , _) => {
175
175
format ! ( "{}.{method}({}).value" , inputs[ 0 ] , inputs[ 1 ..] . join( ", " ) )
176
176
}
@@ -226,20 +226,29 @@ struct FuzzOp {
226
226
F a, b, c;
227
227
228
228
F eval() const {
229
+
230
+ // HACK(eddyb) 'scratch' variables used by expressions below.
231
+ APFloat r(0.0);
232
+ APSInt i;
233
+ bool isExact;
234
+
229
235
switch(tag) {
230
236
"
231
237
+ & all_ops_map_concat ( |_tag, name, kind| {
232
238
let inputs = kind. inputs ( & [ "a.to_apf()" , "b.to_apf()" , "c.to_apf()" ] ) ;
233
- let ( this, args) = inputs. split_first ( ) . unwrap ( ) ;
234
- let args = args. join ( ", " ) ;
235
- let stmt = match kind {
236
- // HACK(eddyb) `mod` doesn't take a rounding mode.
237
- Unary ( _, Cxx ( method) ) | Binary ( _, Cxx ( method @ "mod" ) ) => {
238
- format ! ( "r.{method}({args})" )
239
- }
239
+ let expr = match kind {
240
+ // HACK(eddyb) `APFloat` doesn't overload `operator%`, so we have
241
+ // to go through the `mod` method instead.
242
+ Binary ( '%' ) => format ! ( "((r = {}), r.mod({}), r)" , inputs[ 0 ] , inputs[ 1 ] ) ,
240
243
241
- Binary ( _, Cxx ( method) ) | Ternary ( _, Cxx ( method) ) => {
242
- format ! ( "r.{method}({args}, APFloat::rmNearestTiesToEven)" )
244
+ Unary ( op) => format ! ( "{op}{}" , inputs[ 0 ] ) ,
245
+ Binary ( op) => format ! ( "{} {op} {}" , inputs[ 0 ] , inputs[ 1 ] ) ,
246
+
247
+ Ternary ( _, Cxx ( method) ) => {
248
+ format ! (
249
+ "((r = {}), r.{method}({}, {}, APFloat::rmNearestTiesToEven), r)" ,
250
+ inputs[ 0 ] , inputs[ 1 ] , inputs[ 2 ]
251
+ )
243
252
}
244
253
245
254
Roundtrip ( ty @ ( Type :: SInt ( _) | Type :: UInt ( _) ) ) => {
@@ -248,21 +257,18 @@ struct FuzzOp {
248
257
Type :: UInt ( w) => ( w, false ) ,
249
258
} ;
250
259
format ! (
251
- "
252
- APSInt i({w}, !{signed});
253
- bool isExact;
254
- r.convertToInteger(i, APFloat::rmTowardZero, &isExact);
255
- r.convertFromAPInt(i, {signed}, APFloat::rmNearestTiesToEven)"
260
+ "((r = {}),
261
+ (i = APSInt({w}, !{signed})),
262
+ r.convertToInteger(i, APFloat::rmTowardZero, &isExact),
263
+ r.convertFromAPInt(i, {signed}, APFloat::rmNearestTiesToEven),
264
+ r)" ,
265
+ inputs[ 0 ]
256
266
)
257
267
}
258
268
} ;
259
269
format ! (
260
270
"
261
- case {name}: {{
262
- APFloat r = {this};
263
- {stmt};
264
- return F::from_apf(r);
265
- }}" ,
271
+ case {name}: return F::from_apf({expr});"
266
272
)
267
273
} )
268
274
+ "
@@ -309,8 +315,10 @@ struct __attribute__((packed)) {name} {{
309
315
}}
310
316
311
317
APFloat to_apf() const {{
312
- std::array<APInt::WordType, ({w} + APInt::APINT_BITS_PER_WORD - 1) / APInt::APINT_BITS_PER_WORD>
313
- words;
318
+ std::array<
319
+ APInt::WordType,
320
+ ({w} + APInt::APINT_BITS_PER_WORD - 1) / APInt::APINT_BITS_PER_WORD
321
+ > words;
314
322
for(int i = 0; i < {w}; i += APInt::APINT_BITS_PER_WORD)
315
323
words[i / APInt::APINT_BITS_PER_WORD] = bits >> i;
316
324
return APFloat({cxx_apf_semantics}, APInt({w}, words));
0 commit comments