@@ -130,10 +130,14 @@ mod tests {
130
130
// float/mul.rs
131
131
Mulsf3 ,
132
132
Muldf3 ,
133
+ Mulsf3vfp ,
134
+ Muldf3vfp ,
133
135
134
136
// float/div.rs
135
137
Divsf3 ,
136
138
Divdf3 ,
139
+ Divsf3vfp ,
140
+ Divdf3vfp ,
137
141
138
142
// int/addsub.rs
139
143
AddU128 ,
@@ -4203,6 +4207,171 @@ fn muldf3() {
4203
4207
}
4204
4208
}
4205
4209
4210
+ #[ derive( Eq , Hash , PartialEq ) ]
4211
+ pub struct Mulsf3vfp {
4212
+ a : u32 , // f32
4213
+ b : u32 , // f32
4214
+ c : u32 , // f32
4215
+ }
4216
+
4217
+ impl TestCase for Mulsf3vfp {
4218
+ fn name ( ) -> & ' static str {
4219
+ "mulsf3vfp"
4220
+ }
4221
+
4222
+ fn generate < R > ( rng : & mut R ) -> Option < Self >
4223
+ where
4224
+ R : Rng ,
4225
+ Self : Sized ,
4226
+ {
4227
+ let a = gen_large_f32 ( rng) ;
4228
+ let b = gen_large_f32 ( rng) ;
4229
+ let c = a * b;
4230
+ // TODO accept NaNs. We don't do that right now because we can't check
4231
+ // for NaN-ness on the thumb targets (due to missing intrinsics)
4232
+ if a. is_nan ( ) || b. is_nan ( ) || c. is_nan ( ) {
4233
+ return None ;
4234
+ }
4235
+
4236
+ Some (
4237
+ Mulsf3vfp {
4238
+ a : to_u32 ( a) ,
4239
+ b : to_u32 ( b) ,
4240
+ c : to_u32 ( c) ,
4241
+ } ,
4242
+ )
4243
+ }
4244
+
4245
+ fn to_string ( & self , buffer : & mut String ) {
4246
+ writeln ! (
4247
+ buffer,
4248
+ "(({a}, {b}), {c})," ,
4249
+ a = self . a,
4250
+ b = self . b,
4251
+ c = self . c
4252
+ )
4253
+ . unwrap ( ) ;
4254
+ }
4255
+
4256
+ fn prologue ( ) -> & ' static str {
4257
+ r#"
4258
+ #[cfg(all(target_arch = "arm",
4259
+ not(any(target_env = "gnu", target_env = "musl")),
4260
+ target_os = "linux",
4261
+ test))]
4262
+ use core::mem;
4263
+ use compiler_builtins::float::mul::__mulsf3vfp;
4264
+
4265
+ fn mk_f32(x: u32) -> f32 {
4266
+ unsafe { mem::transmute(x) }
4267
+ }
4268
+
4269
+ fn to_u32(x: f32) -> u32 {
4270
+ unsafe { mem::transmute(x) }
4271
+ }
4272
+
4273
+ static TEST_CASES: &[((u32, u32), u32)] = &[
4274
+ "#
4275
+ }
4276
+
4277
+ fn epilogue ( ) -> & ' static str {
4278
+ "
4279
+ ];
4280
+
4281
+ #[test]
4282
+ fn mulsf3vfp() {
4283
+ for &((a, b), c) in TEST_CASES {
4284
+ let c_ = __mulsf3vfp(mk_f32(a), mk_f32(b));
4285
+ assert_eq!(((a, b), c), ((a, b), to_u32(c_)));
4286
+ }
4287
+ }
4288
+ "
4289
+ }
4290
+ }
4291
+
4292
+ #[ derive( Eq , Hash , PartialEq ) ]
4293
+ pub struct Muldf3vfp {
4294
+ a : u64 , // f64
4295
+ b : u64 , // f64
4296
+ c : u64 , // f64
4297
+ }
4298
+
4299
+ impl TestCase for Muldf3vfp {
4300
+ fn name ( ) -> & ' static str {
4301
+ "muldf3vfp"
4302
+ }
4303
+
4304
+ fn generate < R > ( rng : & mut R ) -> Option < Self >
4305
+ where
4306
+ R : Rng ,
4307
+ Self : Sized ,
4308
+ {
4309
+ let a = gen_large_f64 ( rng) ;
4310
+ let b = gen_large_f64 ( rng) ;
4311
+ let c = a * b;
4312
+ // TODO accept NaNs. We don't do that right now because we can't check
4313
+ // for NaN-ness on the thumb targets (due to missing intrinsics)
4314
+ if a. is_nan ( ) || b. is_nan ( ) || c. is_nan ( ) {
4315
+ return None ;
4316
+ }
4317
+
4318
+ Some (
4319
+ Muldf3vfp {
4320
+ a : to_u64 ( a) ,
4321
+ b : to_u64 ( b) ,
4322
+ c : to_u64 ( c) ,
4323
+ } ,
4324
+ )
4325
+ }
4326
+
4327
+ fn to_string ( & self , buffer : & mut String ) {
4328
+ writeln ! (
4329
+ buffer,
4330
+ "(({a}, {b}), {c})," ,
4331
+ a = self . a,
4332
+ b = self . b,
4333
+ c = self . c
4334
+ )
4335
+ . unwrap ( ) ;
4336
+ }
4337
+
4338
+ fn prologue ( ) -> & ' static str {
4339
+ r#"
4340
+ #[cfg(all(target_arch = "arm",
4341
+ not(any(target_env = "gnu", target_env = "musl")),
4342
+ target_os = "linux",
4343
+ test))]
4344
+ use core::mem;
4345
+ use compiler_builtins::float::mul::__muldf3vfp;
4346
+
4347
+ fn mk_f64(x: u64) -> f64 {
4348
+ unsafe { mem::transmute(x) }
4349
+ }
4350
+
4351
+ fn to_u64(x: f64) -> u64 {
4352
+ unsafe { mem::transmute(x) }
4353
+ }
4354
+
4355
+ static TEST_CASES: &[((u64, u64), u64)] = &[
4356
+ "#
4357
+ }
4358
+
4359
+ fn epilogue ( ) -> & ' static str {
4360
+ "
4361
+ ];
4362
+
4363
+ #[test]
4364
+ fn muldf3vfp() {
4365
+ for &((a, b), c) in TEST_CASES {
4366
+ let c_ = __muldf3vfp(mk_f64(a), mk_f64(b));
4367
+ assert_eq!(((a, b), c), ((a, b), to_u64(c_)));
4368
+ }
4369
+ }
4370
+ "
4371
+ }
4372
+ }
4373
+
4374
+
4206
4375
#[ derive( Eq , Hash , PartialEq ) ]
4207
4376
pub struct Divsf3 {
4208
4377
a : u32 , // f32
@@ -4384,6 +4553,176 @@ fn divdf3() {
4384
4553
}
4385
4554
}
4386
4555
4556
+ #[ derive( Eq , Hash , PartialEq ) ]
4557
+ pub struct Divsf3vfp {
4558
+ a : u32 , // f32
4559
+ b : u32 , // f32
4560
+ c : u32 , // f32
4561
+ }
4562
+
4563
+ impl TestCase for Divsf3vfp {
4564
+ fn name ( ) -> & ' static str {
4565
+ "divsf3vfp"
4566
+ }
4567
+
4568
+ fn generate < R > ( rng : & mut R ) -> Option < Self >
4569
+ where
4570
+ R : Rng ,
4571
+ Self : Sized ,
4572
+ {
4573
+ let a = gen_large_f32 ( rng) ;
4574
+ let b = gen_large_f32 ( rng) ;
4575
+ if b == 0.0 {
4576
+ return None ;
4577
+ }
4578
+ let c = a / b;
4579
+ // TODO accept NaNs. We don't do that right now because we can't check
4580
+ // for NaN-ness on the thumb targets (due to missing intrinsics)
4581
+ if a. is_nan ( ) || b. is_nan ( ) || c. is_nan ( ) || c. abs ( ) <= unsafe { mem:: transmute ( 16777215u32 ) } {
4582
+ return None ;
4583
+ }
4584
+
4585
+ Some (
4586
+ Divsf3vfp {
4587
+ a : to_u32 ( a) ,
4588
+ b : to_u32 ( b) ,
4589
+ c : to_u32 ( c) ,
4590
+ } ,
4591
+ )
4592
+ }
4593
+
4594
+ fn to_string ( & self , buffer : & mut String ) {
4595
+ writeln ! (
4596
+ buffer,
4597
+ "(({a}, {b}), {c})," ,
4598
+ a = self . a,
4599
+ b = self . b,
4600
+ c = self . c
4601
+ )
4602
+ . unwrap ( ) ;
4603
+ }
4604
+
4605
+ fn prologue ( ) -> & ' static str {
4606
+ r#"
4607
+ #[cfg(all(target_arch = "arm",
4608
+ not(any(target_env = "gnu", target_env = "musl")),
4609
+ target_os = "linux",
4610
+ test))]
4611
+ use core::mem;
4612
+ use compiler_builtins::float::div::__divsf3vfp;
4613
+
4614
+ fn mk_f32(x: u32) -> f32 {
4615
+ unsafe { mem::transmute(x) }
4616
+ }
4617
+
4618
+ fn to_u32(x: f32) -> u32 {
4619
+ unsafe { mem::transmute(x) }
4620
+ }
4621
+
4622
+ static TEST_CASES: &[((u32, u32), u32)] = &[
4623
+ "#
4624
+ }
4625
+
4626
+ fn epilogue ( ) -> & ' static str {
4627
+ "
4628
+ ];
4629
+
4630
+ #[test]
4631
+ fn divsf3vfp() {
4632
+ for &((a, b), c) in TEST_CASES {
4633
+ let c_ = __divsf3vfp(mk_f32(a), mk_f32(b));
4634
+ assert_eq!(((a, b), c), ((a, b), to_u32(c_)));
4635
+ }
4636
+ }
4637
+ "
4638
+ }
4639
+ }
4640
+
4641
+ #[ derive( Eq , Hash , PartialEq ) ]
4642
+ pub struct Divdf3vfp {
4643
+ a : u64 , // f64
4644
+ b : u64 , // f64
4645
+ c : u64 , // f64
4646
+ }
4647
+
4648
+ impl TestCase for Divdf3vfp {
4649
+ fn name ( ) -> & ' static str {
4650
+ "divdf3vfp"
4651
+ }
4652
+
4653
+ fn generate < R > ( rng : & mut R ) -> Option < Self >
4654
+ where
4655
+ R : Rng ,
4656
+ Self : Sized ,
4657
+ {
4658
+ let a = gen_large_f64 ( rng) ;
4659
+ let b = gen_large_f64 ( rng) ;
4660
+ if b == 0.0 {
4661
+ return None ;
4662
+ }
4663
+ let c = a / b;
4664
+ // TODO accept NaNs. We don't do that right now because we can't check
4665
+ // for NaN-ness on the thumb targets (due to missing intrinsics)
4666
+ if a. is_nan ( ) || b. is_nan ( ) || c. is_nan ( )
4667
+ || c. abs ( ) <= unsafe { mem:: transmute ( 4503599627370495u64 ) } {
4668
+ return None ;
4669
+ }
4670
+
4671
+ Some (
4672
+ Divdf3vfp {
4673
+ a : to_u64 ( a) ,
4674
+ b : to_u64 ( b) ,
4675
+ c : to_u64 ( c) ,
4676
+ } ,
4677
+ )
4678
+ }
4679
+
4680
+ fn to_string ( & self , buffer : & mut String ) {
4681
+ writeln ! (
4682
+ buffer,
4683
+ "(({a}, {b}), {c})," ,
4684
+ a = self . a,
4685
+ b = self . b,
4686
+ c = self . c
4687
+ )
4688
+ . unwrap ( ) ;
4689
+ }
4690
+
4691
+ fn prologue ( ) -> & ' static str {
4692
+ r#"
4693
+ #[cfg(all(target_arch = "arm",
4694
+ not(any(target_env = "gnu", target_env = "musl")),
4695
+ target_os = "linux",
4696
+ test))]
4697
+ use core::mem;
4698
+ use compiler_builtins::float::div::__divdf3vfp;
4699
+
4700
+ fn mk_f64(x: u64) -> f64 {
4701
+ unsafe { mem::transmute(x) }
4702
+ }
4703
+
4704
+ fn to_u64(x: f64) -> u64 {
4705
+ unsafe { mem::transmute(x) }
4706
+ }
4707
+
4708
+ static TEST_CASES: &[((u64, u64), u64)] = &[
4709
+ "#
4710
+ }
4711
+
4712
+ fn epilogue ( ) -> & ' static str {
4713
+ "
4714
+ ];
4715
+
4716
+ #[test]
4717
+ fn divdf3vfp() {
4718
+ for &((a, b), c) in TEST_CASES {
4719
+ let c_ = __divdf3vfp(mk_f64(a), mk_f64(b));
4720
+ assert_eq!(((a, b), c), ((a, b), to_u64(c_)));
4721
+ }
4722
+ }
4723
+ "
4724
+ }
4725
+ }
4387
4726
4388
4727
#[ derive( Eq , Hash , PartialEq ) ]
4389
4728
pub struct Udivdi3 {
0 commit comments